srs/ /********************************************************************************* SRS and the copyright and other intellectual property rights in SRS are the property of Dr. Thure Etzold and the EMBL. We are willing to licence SRS to you only on the following terms and your use of SRS indicates acceptance of these terms. You have a non-exclusive, non-transferable, royalty free license to use SRS for your own research purposes only. You may not sub-licence, copy or redistribute SRS to any other person and in particular your rights do not extend to any form of commercial use [other than use internally for research purposes by commercial organisations]. Your licence will terminate immediately if you do not comply with all of these terms. *********************************************************************************/ SRS Version 5.0.4 ================= To install ---------- Change directory to the 'srs' directory and run ./srsinstall all This will ask you a few questions regarding 'make' and 'cc' and then configure the installation and compile the programs. It is important that you do this the first time you run srsinstall. In this way, the 'etc/prep_srs' and 'etc/prep_srs.sh' and the make procedure are configured for your site. To complete the installation ---------------------------- To install the SRSWWW change directory to the 'srs' directory again and invoke ./srsinstall www You will be asked for the names of both the doc root and bin root of SRSWWW. You must define aliases for these and restart the httpd. You can access SRSWWW with the URL "http://your-httpd/srs/" The top page of SRSWWW has a link to the documentation which you can install on your site with ./srsinstall doc Generating the documentation requires so much of the installation to be working that once it has successfully completed, you can be certain that the installation works, and is ready to be used. To set the SRS environment -------------------------- To set the SRS environment in the shell you are using, you should prepare the shell for your installation of SRS by executing one of the following two commands, based upon the type of shell you are using. For C-shell and compatibles source etc/prep_srs For Bourne-shell and compatibles . etc/prep_srs.sh Icarus mode for emacs --------------------- An Icarus mode for editing Icarus code inside emacs is located in the file 'srs/etc/icarus.el' . Installation instructions are provided in this file. To customize ------------ The documentation contains a section "Adding Databanks - a Guided Tour" which is well worth working through before customizing. You will need to have the SRS environment set before performing customizations (see above). The Icarus files are in 'srs/icarus'. All databank defining files are in the 'db' subdirectory. Right now there are definitions for swissprot, prosite, enzyme ...you must edit srsdb.i and get the paths right - don't forget to run 'srssection' after that. All databanks are defined by two files (eg, 'prosite.i' and 'prosite.is') After a change in the .i file 'srssection' must be invoked. The .is file is interpreted - so you can just run the program again. srscheck This will report the status of the libraries and links. You should now update these. Run srsupdate Please read the first chapters in the section "SRS Server Maintenance" to get further information about setting up WWW servers and keeping indices up to date. 19/3/1997 Thure Etzold etzold@ebi.ac.uk Giorgio Verde verde@ebi.ac.uk , 'prosite.i' andsrs/bin/ #include #include "srs.h" #include "dict.h" int main () { DICTv dict; struct X{ int a; char b[100]; }x[100], *tmp; Iter i; dict = DictCreate(DictCreateClassPtrKey ((KeyAccessor)KeyItself , 0, FALSE)); x[0].a = 10; x[5].a = 5; x[1].a = 1; x[3].a = 3; DictSet (&dict, &x[0], struct X*) = &x[0]; DictSet (&dict, &x[5], struct X*) = &x[5]; DictSet (&dict, &x[1], struct X*) = &x[1]; DictSet (&dict, &x[3], struct X*) = &x[3]; DictDebug (dict); if ((i = DictWith (dict, &x[3]))) { tmp = DictIn (i, struct X*); printf ("found %d\n", tmp->a); } else printf ("not found\n"); } [100], *tmp; Iter i; dict = DictCreate(DictCreateClassPtrKey ((KeyAccessor)KeyItself , 0, FALSE)); x[0].a = 10; x[5].a = 5; x[1].a = 1; x[3].a = 3; DictSet (&dict, &x[0], struct X*) = &x[0]; DictSet (&dict, &x[5], struct X*) = &x[5]; DictSet (&dict, &x[1], struct X*) = &x[1]; Dicsrs/demo/first.i $Print:"hello world\n" DictDebug (dict); if ((i = DictWith (dict, &x[3]))) { tmp = DictIn (i, struct X*); printf ("found %d\n", tmp->a); } else printf ("not found\n"); } [100], *tmp; Iter i; dict = DictCreate(DictCreateClassPtrKey ((KeyAccessor)KeyItself , 0, FALSE)); x[0].a = 10; x[5].a = 5; x[1].a = 1; x[3].a = 3; DictSet (&dict, &x[0], struct X*) = &x[0]; DictSet (&dict, &x[5], struct X*) = &x[5]; DictSet (&dict, &x[1], struct X*]; Dicsrs/demo/genes.dat DATE 07-JUN-1960 DEFINITION Human amphiphysin mRNA, complete cds. CITATION DLOZTE95 SEQUENCE 1 ccaggtgcct actgactcct tcagaaatgt cagttcctgt cccatgccct taatatttcc 61 cacatgcagg gctctgtgca caatgcgtga caatggcttt tagat // LOCUS BTCHGE8 DATE 26-MAR-1970 DEFINITION Bovine chymosin (cPC) gene, exon 8, clone lambda-CR72. CITATION ERAEW96 SEQUENCE 1 tgttctttag tttgacatcga ctgcgacaa cctgagctac atgcccactg tggtctttga 61 gatcaatggc aaaatgtaccc actgacccc ctccgcctat accagccagg tatgcatct // LOCUS PPTHGE1 DATE 17-JUN-1965 DEFINITION Pongo pygmaeus tyrosine hydroxylase gene, exon 1. CITATION EDREV93 SEQUENCE 1 gcagaggcca tcatggtaaga gggcaggta ggtgcccggc ggccgcagtg gaccggagcc 61 cagggctggt gccagctgcct ctgccactc cccaatctgg ctggcagcc // PC) gene, exon 8, clone lambda-CR72. CITATION ERAEW96 SEQUENCE 1 tgttctttag tttgacatcga ctgcgacaa cctgagctac atgcccactg tggtctttga 61 gatcaatggc aaaatgtasrs/demo/genes.i format:@GENES_FORMAT maxNameLen:10 files:{ $file:genes } ] GENES_FORMAT:$libformat:[fileType:@MYSEQ_FILE syntax:@GENES_SYNTAX fields:{ $field:[@DF_ID code:id index:id indexToken:id] $field:[@DF_Description code:def index:str indexToken:def] $field:[@DF_Date code:date index:int indexToken:date] $field:[@DF_Citation code:cit] } ] GENES_SYNTAX:$syntax:[file:'SRSDEMO:genes.is'] MYSEQ_FILE:$filetype:[typename:dat maxline:100] $link:[@GENES_DB to:@?REFLIST_DB fromField:@DF_Citation toField:@DF_ID token:cit] :10 files:{ $file:genes } ] GENES_FORMAT:$libformat:[fileType:@MYSEQ_FILE syntax:@GENES_SYNTAX fields:{ $field:[@DF_ID code:id index:id indexToken:id] $field:[@DF_Description code:def index:str indexToken:def] $field:[@DF_Date code:date index:int indexToken:date] $field:[@DF_Citation code:cit] } ] GENES_SYNTAX:$syntax:[file:'SRSDEMO:genes.is'] MYSEQ_FILE:$filetype:[typename:dat maxline:100] $linksrs/demo/genes.is $rules={ # the entry entry: ~ {$In:[file:text] $Out pre{$Skip:0}} ('LOCUS' {$entryFip=$Fip $Wrt} ln {$App} ('LOCUS' {$Not} ln {$App})*)? ~ ln: ~ /[^\n]*\n/ ~ # the data-fields fields: ~ {$In:entry $Out $Skip:1} id date def cit seq ~ id: ~ {$wrt:id} 'LOCUS' ln ~ date: ~ {$wrt:date} 'DATE' ln ~ def: ~ {$wrt:def} 'DEFINITION' ln (' ' ln)* ~ cit: ~ {$wrt:cit} 'CITATION' ln ~ seq: ~ {$wrt:seq} 'SEQUENCE' ln (' ' ln)* ~ # indexing word: ~ /[a-zA-Z0-9_]+/ ~ i_id: ~ {$In:[fields c:id] $out:id} word word {$Wrt} ~ i_date: ~ {$In:[fields c:date] $out:date init{$month={JAN:1 FEB:2 MAR:3 APR:4 MAY:5 JUN:6 JUL:7 AUG:8 SEP:9 OCT:10 NOV:11 DEC:12} } } word /([0-9]+)-([A-Z][A-Z][A-Z])-([0-9]+)/ {$Wrt:[s:$3 * 10000 + $month.$2 * 100 + $1]} ~ i_def: ~ {$In:[fields c:def] $out:def} word ( '('? /[^)., \n]+/ {$Wrt} /[).,\n]+/? )* ~ i_cit: ~ {$In:[fields c:cit] $out:cit} word word {$Wrt} ~ } if: $TestMode { $job = $JobNew:[prod:$rules skip:'\t ' fileName:"SRSDEMO:genes.dat"] while:$JobHasInput:$job { $JobTokens:[$job name:fields print:1] $JobNext:$job } } AUG:8 SEP:9 OCT:10 NOV:11 DEC:12} } } word /([0-9]+)-([A-Z][A-Z][A-Z])-([0-9]+)/ {$Wrt:[s:$3 * 10000 + $month.$2 * 100 + $1]} ~ i_def: ~ {$In:[fields c:def] $out:def} word ( '('? /[^)., \n]+/ srs/demo/genes.it description: |A demonstration databank used to demonstrate SRS. |

literature: |

    |
  1. See the online documentation | |
# address: contact: |
|Thure Etzold
|EMBL
|
|Giorgio Verde
|EMBL
|

|

|Johnathon Weare
|EMBL
|

|

www: |\ |http://www.embl-heidelberg.de address: |EMBL
telephone: '+49 (0)6221 387451' telefax: '+49 (0)6221 387517' email: 'weare@embl-heidelberg.de' fields:{ Date: | This is the DATE field Description: | This is the DEFINITION field } } |EMBL
|
|Giorgio Verde
|EMBL
|

|

|Johnathon Weare
|EMBL
|

|

www: |\ |http://www.embl-heidelberg.de address: |Esrs/demo/genes_debug.is $rules={ # the entry entry: ~ {$In:[file:text] $Out pre{$Skip:0}} ('LOCUS' {$entryFip=$Fip $Wrt} ln {$App} ('LOCUS' {$Not} ln {$App})*)? ~ ln: ~ /[^\n]*\n/ ~ # the data-fields fields: ~ {$In:entry $Out $Skip:1} id {pre{$Print:"...before: $It\n"} $Print:"...after: $It\n"} date def cit seq ~ id: ~ {$wrt:id} 'LOCUS' ln ~ date: ~ {$wrt:date} 'DATE' ln ~ def: ~ {$wrt:def} 'DEFINITION' ln (' ' ln)* ~ cit: ~ {$wrt:cit} 'CITATION' ln ~ seq: ~ {$wrt:seq} 'SEQUENCE' ln (' ' ln)* ~ # indexing word: ~ /[a-zA-Z0-9_]+/ ~ i_id: ~ {$In:[fields c:id] $out:id} word word {$Wrt} ~ i_date: ~ {$In:[fields c:date] $out:date init{$month={JAN:1 FEB:2 MAR:3 APR:4 MAY:5 JUN:6 JUL:7 AUG:8 SEP:9 OCT:10 NOV:11 DEC:12} } } word /([0-9]+)-([A-Z][A-Z][A-Z])-([0-9]+)/ {$Wrt:[s:$3 * 10000 + $month.$2 * 100 + $1]} ~ i_def: ~ {$In:[fields c:def] $out:def} word ( '('? /[^)., \n]+/ {$Wrt} /[).,\n]+/? )* ~ i_cit: ~ {$In:[fields c:cit] $out:cit} word word {$Wrt} ~ } if: $TestMode { $job = $JobNew:[prod:$rules skip:'\t ' fileName:"SRSDEMO:genes.dat"] while:$JobHasInput:$job { $JobTokens:[$job name:fields print:1] $JobNext:$job } } AUG:8 SEP:9 OCT:10 NOV:11 DEC:12} } } word /([0-9]+)-([A-Z][A-Z][A-Z])-([0-9]+)/ {$Wrt:[s:$3 * 10000 + $month.$2 * 100 +srs/demo/libinfo.c and their data-fields */ #include #include "srs.h" int main () { SLBo *lib; SRSoGROUP *group; SLBoFIELD *field; int c1, c2, c3; SrsEnv (); LibOpen ("srswin"); for (c1=0; (group = LibNextLibGroup (&c1));) { printf ("Group: %s\n", LibGetGroupName (group, "full")); for (c2=0; (lib = LibNextLib (group, &c2));) { printf (" Library: %s\n", LibName (lib)); for (c3=0; (field = LibNextField (lib, &c3));) { printf (" Data-field: %s\n", FieldGetName (field)); /* see what can be done with the fields */ if (FieldIs (field, "index")) printf (" ... is indexed\n"); else if (FieldIs (field, "show") || FieldIs (field, "link")) printf (" ... can be displayed only\n"); } } } } GroupName (group, "full")); for (c2=0; (lib = LibNextLib (group, &c2));) { printf (" Library: %s\n", LibName (lib)); for (c3=0; (field = Lsrs/demo/libinfo2.c #include #include "srs.h" int main () { SLBo *lib; LIBoINDEX *libInx; char *tmp; SrsEnv (); LibOpen ("srswin"); lib = (SLBo *) LibObjByName ("library", "swissprot"); libInx = LibIndexOpen (lib, LibGetIdField (lib), 0); printf ("Library \"%s\"\n", LibName (lib)); if ((tmp = IdxGetReleaseName (libInx->idx))) printf (" Release: \"%s\"\n", tmp); printf (" Entries: %d\n", BtrGetRecordN (libInx->btree)); } accesses information about an individual databank */ #include #include "srs.h" int main () { SLBo *lib; LIBoINDEX *libInx; char *tmp; SrsEnv (); LibOpen ("srswin"); lib = (SLBo *) LibObjByName ("library", "swissprot"); libInx = LibIndexOpen (lib, LibGetIdField (lib), 0); printf ("Library \"%s\"\n", LibName (lib)); if ((tmp = IdxGetReleaseName (libInx->idx))) printf (" Release: \"%s\"\n", tmp); printf (" Entries: %d\n", BtrGetRecordN (libsrs/demo/msguse.c #include #include #include "srs.h" int MyPrintMessage (MSGo *msg) { switch (msg->msg_code) { case e__objectunknown: fprintf (stderr, "ERROR: (%s) %s, %s\n", msg->msg_nm, msg->primsg, msg->secmsg); break; default: if (msg->msg_t != MSGxINFO) fprintf (stderr, "ERROR: %s, %s\n", msg->primsg, msg->secmsg); else fprintf (stderr, "INFO: %s\n", msg->secmsg); break; } return 1; } int main () { SrsEnv (); LibOpen ("srswin"); MsgSetFnct (MyPrintMessage); Query ("[swisprot-des:acetylchol*]", "Q"); Query ("[swissprot-des:acetylchol*]", "Q"); Query ("[swissprot-des:acetylchol*]", "Q"); ParDefStr ("fieldList", "desription"); } sg_nm, msg->primsg, msg->secmsg); break; default: if (msg->msg_t != MSGxINFO) fprintf (stderr, "ERROR: %s, %s\n", msg->primsg, msg->secmsg); else fprintf (stderr, "INFO: %s\n", msg->secmsg); break; } retsrs/demo/oddemo.c #define _INITOBJS #include "oddemo.h" int main () { int k; for (k=0; k < topval->myObj2N; k++) { printf ("%d\n", topval->myObj2[k].a); printf (" %d\n", topval->myObj2[k].cc->a); } } l*]", "Q"); ParDefStr ("fieldList", "desription"); } sg_nm, msg->primsg, msg->secmsg); break; default: if (msg->msg_t != MSGxINFO) fprintf (stderr, "ERROR: %s, %s\n", msg->primsg, msg->secmsg); else fprintf (stderr, "INFO: %s\n", msg->secmsg);  } retsrs/demo/oddemo.i X2:$myObj X3:$myObj:[a:10] $myObj2:[cc:@X1 a:1] $myObj2:[cc:@X2 a:3] $myObj2:[cc:@X3 a:3] $top printf ("%d\n", topval->myObj2[k].a); printf (" %d\n", topval->myObj2[k].cc->a); } } l*]", "Q"); ParDefStr ("fieldList", "desription"); } sg_nm, msg->primsg, msg->secmsg); break; default: if (msg->msg_t != MSGxINFO) fprintf (stderr, "ERROR: %s, %s\n", msg->primsg, msg->secmsg); else fprintf (stderr, "INFO: %s\n", msg->secmsg);  } retsrs/demo/oddemo.ic myClass2: $object:[myObj2 typname:myObj2 declname:myObj2val attrs: { $attribute:[a type:int] $attribute:[b type:string] $attribute:[cc type:object defaultval:@myClass] } ] myClass: $object:[myObj typname:myObj declname:myObjval attrs: { $attribute:[a type:int] $attribute:[b type:string] } ] Top:$object:[top typname:TOP declname:topval attrs: { $attribute:[myObj type:allobjects defaultval:@myClass] $attribute:[myObjN type:nr_of_objects defaultval:@myClass] $attribute:[myObj2 type:allobjects defaultval:@myClass2] $attribute:[myObj2N type:nr_of_objects defaultval:@myClass2] } ] $def:[infile:"oddemo.i" outfile:"oddemo.h"] ltval:@myClass] } ] myClass: $object:[myObj typname:myObj declname:myObjval attrs: { $attribute:[a type:int] $attribute:[b type:string] } ] Top:$object:[top typname:TOP declname:topval attrs: { $attribute:[myObj type:allobjects defaultval:@myClass] $attribute:[myObjN type:nr_of_objects defaultvsrs/demo/prfields.c #include #include "srs.h" int main () { SETo *set; IDoENTRY id; ENTRYv entry; int n, entryN; SrsEnv (); LibOpen (); ParDefStr ("fieldList", "ID"); ParDefStr ("fieldList", "Description"); if (Query ("[swissprot-des:transferase]", "Q")) { set = SetGet ("Q"); entryN = SetSize ("Q"); for (n=1; n <= entryN; n++) { SetGetID (set, n, &id); entry = EntryOpen (&id); EntryPrintFields (entry, NULL); EntryClose (&entry); } } } #include "srs.h" int main () { SETo *set; IDoENTRY id; ENTRYv entry; int n, entryN; SrsEnv (); LibOpen (); ParDefStr ("fieldList", "ID"); ParDefStr ("fieldList", "Description"); if (Query ("[swissprot-des:transferase]", "Q")) { set = SetGet ("Q"); entryN = SetSize ("Q"); for (n=1; n <= entryN; n++) { SetGetID (set, n, &id); entry = EntryOpen (&id); srs/demo/qasuse.c building an SRS query expression */ #include #include "srs.h" int main () { QASvQUERY qas; QASvRETRIEVE r; char s[1000]; SrsEnv (); LibOpen (); /* search "swissprot" and "prosite" in the "description" and "seqlength" fields */ qas = QasNew (); QasSetLibrary (qas, "swissprot"); QasSetLibrary (qas, "prosite"); r = QasNewRetrieve (qas, "description"); QasSetRetrieveStr (qas, r, "kinase"); r = QasNewRetrieve (qas, "seqlength"); QasSetRangeBegin (qas, r, "400"); QasSetRangeEnd (qas, r, "500"); QasSetOp (qas, "and"); strcpy (s, QasGetQueryString (qas)); printf ("the query: \"%s\"\n", s); /* make a logical AND between current query and set Q1 */ QasMakeOperand (qas); QasSetOp (qas, "and"); QasAddOperand (qas, "Q1"); strcpy (s, QasGetQueryString (qas)); printf ("the query: \"%s\"\n", s); /* link the result to "prosite" and "pfam" */ QasInitLink (qas); QasSetQueryToLink (qas, s); QasSetLinkWith (qas, "prosite"); QasSetLinkWith (qas, "pfam"); QasSetLinkType (qas, "notToSet"); printf ("the query linked: \"%s\"\n", QasGetQueryString (qas)); } ry: \"%s\"\n", s); /* make a logical AND between current query and set Q1 */ QasMakeOperand (qas); QasSetOp (qas, "and"); QasAddOperand (qas, "Q1"); strcpy (s, QasGetQueryString (qas)); printf ("the query: \"%s\"\n", s); /* link the result to "prosite" and "pfam" */ QasInitLink (qas); QasSetQueryToLink (qasrs/demo/query.c #include #include "srs.h" int main () { SrsEnv (); LibOpen (); if (Query ("[embl-des:receptor]", "Q1")) { printf ("Q1 has %d entries\n", SetSize ("Q1")); Query ("[embl-des:acetylchol*] & Q1", "Q2"); printf ("Q2 has %d entries\n", SetSize ("Q2")); Query ("Q2 > SWISSPROT", "Q3"); printf ("%d SWISSPROT entries are linked to entries in Q2\n", SetSize ("Q3")); Query ("Q2 < SWISSPROT", "Q4"); printf ("%d entries in Q2 are linked to SWISSPROT\n", SetSize ("Q4")); } else printf ("no entries could be found\n"); } if (Query ("[embl-des:receptor]", "Q1")) { printf ("Q1 has %d entries\n", SetSize ("Q1")); Query ("[embl-des:acetylchol*] & Q1", "Q2"); printf ("Q2 has %d entries\n", SetSize ("Q2")); Query ("Q2 > SWISSPROT", "Q3"); printf ("%d SWISSPROT entries are linked to entries in Q2\n", SetSize ("Q3")); Query ("Q2 < SWISSPROT",srs/demo/reflist.dat RA Icarus J., Dedalus F.; RT Primary structure of human amphiphysin, the dominant autoantigen RT of paraneoplastic Stiff-Man syndrome, and mapping of its gene RT (AMPH) to chromosome 7. RL Hum. Mol. Genet. 4:265-268(1995). // ID ERAEW96 RA Tonic G.A., Mary B., Walker J.; RT Cloning and structural analysis of the calf prochymosin gene. RL Nature 13:197-203(1996). // ID EDREV93 RA Out A., Ceecee G., Macs E.; RT Increased heterogeneity of tyrosine hydroxylase in humans. RL Biochem. Biophys. Res. Commun. 195:158-165(1993). // tructure of human amphiphysin, the dominant autoantigen RT of paraneoplastic Stiff-Man syndrome, and mapping of its gene RT (AMPH) to chromosome 7. RL Hum. Mol. Genet. 4:265-268(1995). // ID ERAEW96 RA Tonic G.A., Mary B., Walker J.; RT Cloning and structural analysis of the calf prochymosin gene. RL Nature 13:197-203(1996). // ID EDREV93 RA Out A., Ceecee G., Macs E.; RT Increased heterogeneity of tyrosine hydroxylase in humans. RLsrs/demo/reflist.i REFLIST_DB:$library:[REFLIST group:@SEQUENCE_LIBS format:@REFLIST_FORMAT cachesize:512 maxNameLen:10 files:{ $file:reflist } ] REFLIST_FORMAT:$libformat:[fileType:@DAT_FILE syntax:@REFLIST_SYNTAX fields:{ $field:[@DF_ID code:id index:id indexToken:id] $field:[@DF_Authors code:refaut index:str indexToken:authors] $field:[@DF_Title code:title index:str indexToken:title] $field:[@DF_MyReference code:ref index:str indexToken:ref] } ] REFLIST_SYNTAX:$syntax:[file:'SRSDEMO:reflist.is' level3:1] DF_MyReference:$srsfield:[SeqReference short:rff] T_FORMAT cachesize:512 maxNameLen:10 files:{ $file:reflist } ] REFLIST_FORMAT:$libformat:[fileType:@DAT_FILE syntax:@REFLIST_SYNTAX fields:{ $field:[@DF_ID code:id index:id indexToken:id] $field:[@DF_Authors code:refaut index:str indexToken:authors] $field:[@DF_Title code:title index:str indexToken:title] $field:[@DF_MyReference code:ref index:str indexToken:ref] } ] REFLIST_SYNTAX:$syntax:[file:'SRSDEMO:reflsrs/demo/reflist.is $rules={ # the entry entry: ~ {$In:[file:text] $Out} ('ID' {$Not} ln)* ('ID ' {$entryFip=$Fip $Wrt} ln {$App} ('ID' {$Not} ln {$App})*)? ~ # the data-fields fields: ~ {$In:entry $Out} id ra? rt? rl? ~ id: ~ {$Wrt:id} 'ID ' ln ~ ra: ~ {$Wrt:ra} ('RA ' ln)+ ~ rt: ~ {$Wrt:rt} ('RT ' ln)+ ~ rl: ~ {$Wrt:rl} ('RL ' ln)+ ~ # indexing i_id: ~ {$In:[fields c:id] $Out:id} 'ID' /[A-Z0-9_]+/ {$Wrt} ~ authors: ~ {$In:[fields c:ra] $Out} ('RA' ( author {$Wrt} /[,;]/ )* )* ~ title: ~ {$In:[fields c:rt] $Out} ('RT' /[";]/? /[^ .,";\n]+/* {$Wrt} ln )* ~ ref: ~ {$In:[fields c:rl] $Out} unpubl | journal ~ author: ~ name /[^,;]+/ ~ unpubl: ~ 'RL Unpublished' ln ~ address: ~ ( 'RL' ( /[^ .,\n]+/ {$Wrt:adr} /[.,]+/? )* ln )* ~ journal: ~ 'RL' /[^0-9]+/ {$Wrt:jrn} /([0-9]+):([0-9]+)-([0-9]+)\\(([0-9]+)\\)/ {$Wrt:[vol s:$1] $Wrt:[pg1 s:$2] $Wrt:[pg2 s:$3] $Wrt:[year s:$4]} ~ # useful name: ~ /[a-zA-Z0-9_'-]+/ ~ num: ~ /[0-9]+/ ~ ln: ~ /[^\n]*\n/ ~ } if: $TestMode { $job = $JobNew:[prod:$rules skip:'\t ' fileName:"SRSDEMO:reflist.dat"] while:$JobHasInput:$job { $JobTokens:[$job name:entry print:1] $JobNext:$job } } ]+/? )* ln )* ~ journal: ~ 'RL' /[^0-9]srs/demo/reflist.it description: |A demonstration databank used to demonstrate SRS. |

literature: |

    |
  1. See the online documentation | |
# address: contact: |
|Thure Etzold
|EMBL
|
|Giorgio Verde
|EMBL
|

|

|Johnathon Weare
|EMBL
|

|

www: |\ |http://www.embl-heidelberg.de address: |EMBL
telephone: '+49 (0)6221 387451' telefax: '+49 (0)6221 387517' email: 'weare@embl-heidelberg.de' fields:{ Citation: | This is the RT field SeqReference: | This is the RL field } date: |6 Dec 1996 signature: |Johnathon Weare } } BL
|

|

|Johnathon Weare
|EMBL
|

|

www: |\ |http://www.embl-heidelberg.de address: |Esrs/demo/useappl.c #include #include "srs.h" int main () { APPLo *appl; APPLoOpt *opt; APPLoOptVal *val; STRv str; int k, l; SrsEnv (); LibOpen ("srswin"); appl = ApplNamed ("clustalw"); printf ("application: %s\n", ApplGetName (appl)); for (k=0; (opt=ApplNextOpt (appl, &k)); ) { printf (" option: %s\n", ApplOptGetName (opt)); if (ApplOptIs (opt, "list")) for (l=0; (val=ApplOptNextVal (opt, &l)); ) { printf (" value: %s\n", ApplOptValGetName (val)); if (ApplOptIs (opt, "real")) printf ("%f", ApplOptValGetValue (opt, val)); } } ParDefStr ("outFormat", "GDE"); ParDefStr ("outOrder", "ALIGNED"); ApplInit (appl); str = StrNew (); StrAppS (&str, "$opt.outFormat=$ParStr:outFormat\n"); StrAppS (&str, "$opt.outOrder=$ParStr:outOrder\n"); ApplEval (appl, _Str(str)); printf ("\ncommand: %s\n", ApplGetCommand (appl)); ApplLaunch (appl); } pplOptNextVal (opt, &l)); ) { printf (" value: %s\n", ApplOptsrs/demo/views.c #include #include "srs.h" int main () { VIEWv view; VIEWvLIB vlib; VIEWvFIELD vfield; IDoENTRY id; ENTRYv entry; SETo *set; int n, entryN; SrsEnv (); LibOpen (); IcaInitSyntax (LibObjByName ("syntax", "icarus")); view = ViewNew (1, "swiss1"); ViewSetFormat (view, "table"); ViewAddRootLib (view, LibObjByName ("library", "swissprot")); ViewAddRootField (view, LibGetFieldType ("swissprot", "description")); ViewAddRootField (view, LibGetFieldType ("swissprot", "seqlength")); vfield = ViewAddRootField (view, LibGetFieldType ("swissprot", "sequence")); ViewSetFieldFormat (vfield, "gcg"); vlib = ViewAddLeafLib (view, LibObjByName ("library", "prosite")); ViewAddField (vlib, LibGetFieldType ("prosite", "description")); ViewAddField (vlib, LibGetFieldType ("prosite", "patterns")); if (Query ("[swissprot-des:kinase]", "Q")) { set = SetGet ("Q"); entryN = SetSize ("Q"); printf ("query has %d entries\n", entryN); for (n=1; n <= entryN; n++) { SetGetID (set, n, &id); entry = EntryOpen (&id); EntryView (entry, view); EntryClose (&entry); } } } iewAddLeafLib (view, LibObjByName ("library", "prosite")); ViewAddField (vlib, LibGetFieldType ("prosite", "description")); ViewAddField (vlib, LibGetFieldType ("prosite", "patterns")); if (Query ("[swissprot-des:kinase]", "Q")) { set = SetGet ("Q"); entrsrs/etc/ #defines an 'alias' for the old srssection command nodd $SRSICA/builtin.ic $SRSICA/builtin.i ) { SetGetID (set, n, &id); entry = EntryOpe EntryView (entry, view); rtp (&entryxX (reafLib (~ {bObjByNa ( ( ;; This file is NOT part of GNU Emacs. ;; ;; To install: ;; 1. Put the file icarus.el in your Emacs Lisp directory ;; 2. You can byte compile the file icarus.el if you want to ;; 3. Put the following code in your .emacs: ;; (autoload 'icarus-mode "icarus") ;; (setq auto-mode-alist ;; (append '(("\\.i$" . icarus-mode) ;; ("\\.is$" . icarus-mode) ;; ("\\.it$" . icarus-mode) ;; ("\\.ic$" . icarus-mode)) ;; auto-mode-alist)) ;; 4. And if you don't have a global-font-lock on (emacs 19.32 or later), then ;; also add ;; (add-hook 'icarus-mode-hook (function 'turn-on-font-lock) (defvar icarus-font-lock-keywords (list ; '("\\(/\\([^/\\n]\\|\\\\/\\)*/\\)" 1 my-id-create-face nil t) '("\\(~\\)[^~]*$" 1 font-lock-icarusprod-face t t) '("[a-zA-Z0-9_-]+ *: *\\(~\\)" 1 font-lock-icarusprod-face t t) '("\\([a-zA-Z0-9_-]+\\) *:" 1 font-lock-icarusargname-face t t) ; '("\\([a-zA-Z0-9_-]+\\) *: *#" 1 font-lock-icarusprod-face t t) ; '("[a-zA-Z0-9_'/\*-]+ *\\(<[^<>]*>\\)" ; 1 font-lock-keyword-face t t ) ; '("[a-zA-Z0-9_'/\*-]+ *\\(<[^\n<>]*>\\)" ; 1 font-lock-other-emphasized-face t t ) '("\\(\$[a-zA-Z0-9_-]+\\)" 1 font-lock-keyword-face t t) '("[^a-zA-z]\\(pre\\|init\\|for\\|if\\|foreach\\|while\\|else\\|elif\\)[ \t\n]*[:{$]" 1 icarus-reserved-face t t) '("\\(/[^/\n]+/\\)" 1 my-id-create-face t t) '("\\('[^'\n]+'\\)" 1 my-reference-face t t) '("\\(@[?]*[a-zA-Z0-9_]+\\)" 1 my-oddreference-face t t) ; '("\\(\"[^\"\n]+\"\\)" 1 font-lock-string-face t t) ; '("<[^\n<>]*\\(\"[^>\"\n]+\"\\)[^\n<>]*>" 1 font-lock-other-string-face t t) '(")\\([0-9:]*\\(?\\|\*\\|\+\\)\\)" 1 font-lock-icarusprod-face t t) '("\\(#[^\n]*\\)" 1 font-lock-comment-face t t)) "Additional expressions to highlight in Icarus mode.") (defun icarus-mode () "Major Mode for editing Icarus code. Support for font locking, no support for indentation, although the indentation advice is: curly brackets 2, square brackets 2, parenthesis 1." (interactive) (kill-all-local-variables) (setq mode-name "Icarus") (setq major-mode 'icarus-mode) ;; Font lock. (make-local-variable 'font-lock-defaults) (make-local-variable 'comment-start) (make-local-variable 'comment-start-skip) (setq comment-start "#") (setq comment-end "") (setq font-lock-defaults '(icarus-font-lock-keywords)) (run-hooks 'icarus-mode-hook) ) ;;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;; Define ICARUS face attributes ;;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (setq font-lock-face-attributes ;;; font-name fgcolor bgcolor bold? slant? underl? '((font-lock-comment-face "springgreen4" "lemonchiffon2" nil t) (font-lock-doc-string-face "sienna4" nil nil t) (font-lock-string-face "sienna4" nil nil t) (font-lock-keyword-face "firebrick2") (font-lock-function-name-face "blue4" nil t) (font-lock-icarusprod-face "maroon3" nil t) (font-lock-icarusargname-face "darkorange2") (font-lock-type-face "firebrick1" nil t) (font-lock-reference-face "sienna1") (font-lock-variable-name-face "sienna1") (my-face "sienna1") (my-reference-face "blue") (my-oddreference-face "blue4" nil t) (my-id-create-face "DarkSlateGray4" nil) (my-production-face "maroon" nil t) (icarus-reserved-face "maroon" nil t) )) (provide 'icarus-mode) ction-name-face "blue4" nil t) (font-lock-icarusprod-face "maroon3" nil t) (font-lock-icarusargname-facsrs/etc/killrunaway # # Identify srsbuild processes run by user www which have exceeded 15 # minutes of cpu time, and kill them. # # Run periodically from www's crontab on phenix (IRIX64). # Not portable! # # David Starks-Browning # starks@embl-heidelberg.de # 20 Feb 97 # Username under which offending processes, and this script, run. # user=srswww # Can be extended to work on multiple commands. # Just make a space separated list here. # cmds='srsbuild wgetz' # Threshold in minutes. Commands running longer are killed. # mins='15' # Notification by email. Omit if none needed. # #maillist="$user etzold" for cmd in $cmds ; do # First translate ':' to '.' so awk interprates min:sec field # as decimal fraction. Then match on running jobs named $cmd taking more # than $mins minutes, printing the pid. Note reliance of particular format of ps # output. THIS IS NOT PORTABLE! # pids=`ps -lu $user | tr ':' '.' | awk '$2 == "R" && $14 == cmd && $13 > mins { print $4 }' cmd=$cmd mins=$mins` if [ -n "$pids" ] ; then if [ -n "$maillist" ] ; then echo "Killing $cmd pids at `hostname` (TERM): $pids" | Mail -s "$0 output" $maillist fi kill -TERM $pids 1>/dev/null 2>&1 sleep 5 # # Still there? Try harder this time. # pids=`ps -lu$user | tr ':' '.' | awk '$2 == "R" && $14 == cmd && $13 > mins { print $4 }' cmd=$cmd mins=$mins` if [ -n "$pids" ] ; then if [ -n "$maillist" ] ; then echo "Killing $cmd pids at `hostname` (KILL): $pids" | Mail -s " $0 output" $maillist fi kill -KILL $pids 1>/dev/null 2>&1 fi fi done i kill -TERM $pids 1>/dev/null 2>&1 sleep 5 # # Still there? Try harder this time. # pids=`ps -lu$user | tr ':' '.' | awk '$2 == "R" && $14 == cmd && $13 > mins { print $4 }' cmd=$cmd mins=$mins` if [ -n "$pids" ] ; then if [ -n "$maillist" ] ; then echo "Kilsrs/etc/makedoc cp $SRSDOC/srsman.html $SRSMAN/srsman.html cp $SRSDOC/contents.html $SRSMAN/contents.html echo "...making the Icarus class documentation" $SRSEXE/icarus -class $SRSICA/srs.ic > $SRSMAN/class.html echo "...making the Icarus function reference" $SRSEXE/icarus -ci > $SRSMAN/icafunc.html echo "...making the C API documentation" $SRSEXE/icarus $SRSICA/man_capi.i echo "...making the program usage" $SRSEXE/icarus $SRSICA/man_usage.i echo "...inserting additional HTML commands" $SRSEXE/icarus $SRSICA/man_chap.i echo "...making the index" $SRSEXE/icarus $SRSICA/man_inx.i echo "...making the table of contents" $SRSEXE/icarus $SRSICA/man_toc.i rm $SRSMAN/mff_* icarus -class $SRSICA/srs.ic > $SRSMAN/class.html echo "...making the Icarus function reference" $SRSEXE/icarus -ci > $SRSMAN/icafunc.html echo "...making the C API documentation" $SRSEXE/icarus $SRSICA/man_capi.i echo "...making the program usage" $SRSEXE/icarus $SRSICA/man_usage.i echo "...inserting additional HTML commands" $SRSEXE/icarus $SRSICA/man_srs/etc/makefile.mms LIB = srsexe:srs.olb CFLAGS = $(XCFLAGS) /define="SRSINCLUDE=""srswin.h""" .c.olb cc $(CFLAGS) $(mms$source) $(libr) $(librflags) $(mms$target) $(mms$target_name).obj delete $(mms$target_name).obj; .c.obj cc $(CFLAGS)/obj=$(mms$target) $(mms$source) LIBSRCS = futil.c message.c sm.c - script.c oddfncts.c oddtools.c parser.c - sdl.c sdlget.c - index.c btree.c ids.c hash.c - idx.c seq.c par.c - seqlib.c library.c entry.c - query.c set.c id.c - link.c stack.c expr.c - lst.c map.c regexp.c - arglist.c tm.c rtl.c EXES = srsexe:srsbuild.exe srsexe:getz.exe srsexe:odd.exe srsexe:srscheck.exe - srsexe:trembl.exe all : $(LIB) $(EXES) continue $(LIB) : $(LIB)($(LIBSRCS)) continue srsexe:srsbuild.exe : srsexe:srsbuild.obj srsexe:srs.lib link /execu=srsexe:srsbuild srsexe:srsbuild,$(LIB)/lib srsexe:srscheck.exe : srsexe:srscheck.obj link /execu=srsexe:srscheck srsexe:srscheck,$(LIB)/lib srsexe:odd.exe : srsexe:bs_odd.obj srsexe:bs_parser.obj - srsexe:bs_sdl.obj srsexe:bs_sdlget.obj link /execute=srsexe:odd srsexe:bs_odd,srsexe:bs_parser,- srsexe:bs_sdl,srsexe:bs_sdlget,$(LIB)/lib srsexe:getz.exe : srsexe:getz.obj srsexe:srs.lib link /execute=srsexe:getz srsexe:getz,$(LIB)/lib srsexe:trembl.exe : srsexe:trembl.obj link /execute=srsexe:trembl srsexe:trembl,$(LIB)/lib srsexe:bs_parser.obj : parser.c $(CC) $(CFLAGS) /object=srsexe:bs_parser /define=BOOTSTRAP parser srsexe:bs_sdl.obj : srssou:sdl.c $(CC) $(CFLAGS) /object=srsexe:bs_sdl /define=BOOTSTRAP sdl srsexe:bs_sdlget.obj : srssou:sdlget.c $(CC) $(CFLAGS) /object=srsexe:bs_sdlget /define=BOOTSTRAP sdlget srsexe:bs_odd.obj : srssou:odd.c $(CC) $(CFLAGS) /object=srsexe:bs_odd /define=BOOTSTRAP odd .c.obj: $(CC) $(CFLAGS) $< #$(SRSSOU)/message.h : $(SRSETC)/message.dat # msgdef # mv -f message.h $(SRSSOU)/message.h #depend $(LIB)(futil.c) : futil.c message.h msg.h futil.h sm.h $(LIB)(message.c) : message.c futil.h sm.h msg.h $(LIB)(sm.c) : sm.c message.h msg.h sm.h $(LIB)(oddfncts.c) : oddfncts.c message.h msg.h sm.h futil.h sdl.h sdl_def.h $(LIB)(oddtools.c) : oddtools.c message.h msg.h oddtools.h srsexe:bs_parser.obj $(LIB)(parser.c) : parser.c futil.h parser.h - message.h msg.h sm.h srsexe:bs_sdl.obj $(LIB)(sdl.c) : sdl.c message.h msg.h futil.h sm.h parser.h - sdlparser.h map.h sdl_def.h sdl.h srsexe:bs_sdlget.obj $(LIB)(sdlget.c) : sdlget.c futil.h message.h - msg.h sdl.h sdl_def.h $(LIB)(index.c) : index.c sm.h message.h msg.h futil.h map.h binpack.h - btree.h id.h ids.h idx.h index.h $(LIB)(btree.c) : btree.c message.h msg.h futil.h tm.h binpack.h - btree.h ids.h $(LIB)(ids.c) : ids.c message.h msg.h binpack.h futil.h tm.h id.h - ids.h set.h idx.h library.h map.h $(LIB)(idx.c) : idx.c sm.h message.h msg.h futil.h binpack.h idx.h $(LIB)(seq.c) : seq.c sm.h message.h msg.h futil.h lst.h seq.h $(LIB)(par.c) : par.c message.h msg.h futil.h lst.h par.h $(LIB)(seqlib.c) : seqlib.c message.h msg.h lst.h futil.h par.h - parser.h id.h library.h entry.h seq.h query.h seqlib.h stack.h expr.h srswin.h $(LIB)(library.c) : library.c message.h msg.h futil.h sm.h tm.h - btree.h ids.h par.h parser.h library.h srswin.h $(LIB)(entry.c) : entry.c message.h msg.h sm.h tm.h futil.h par.h - parser.h id.h library.h entry.h srswin.h $(LIB)(query.c) : query.c message.h msg.h futil.h parser.h par.h - regexp.h ids.h btree.h sm.h tm.h library.h id.h entry.h set.h link.h - query.h srswin.h $(LIB)(set.c) : set.c lst.h sm.h message.h msg.h futil.h parser.h - id.h set.h library.h srswin.h $(LIB)(id.c) : id.c message.h msg.h futil.h binpack.h id.h $(LIB)(link.c) : link.c message.h msg.h futil.h sm.h id.h set.h link.h - map.h btree.h ids.h library.h query.h srswin.h $(LIB)(stack.c) : stack.c stack.h message.h msg.h futil.h parser.h $(LIB)(expr.c) : expr.c message.h msg.h futil.h parser.h stack.h - expr.h srswin.h $(LIB)(hash.c) : hash.c hash.h $(LIB)(lst.c) : lst.c lst.h $(LIB)(map.c) : map.c message.h msg.h futil.h map.h $(LIB)(script.c) : script.c script.h $(LIB)(regexp.c) : regexp.c regexp.h regmagic.h $(LIB)(arglist.c) : arglist.c message.h msg.h futil.h parser.h par.h - srswin.h arglist.h $(LIB)(tm.c) : tm.c message.h msg.h tm.h $(LIB)(rtl.c) : rtl.c rtl.h srsexe:getz.obj : getz.c message.h msg.h futil.h parser.h seq.h par.h - arglist.h id.h set.h entry.h library.h seqlib.h query.h srswin.h - arglist.h entry.h id.h set.h ids.h library.h link.h index.h srswin.h srsexe:trembl.exe : trembl.c srsexe:srsbuild.obj : srsbuild.c message.h msg.h futil.h sm.h - parser.h seq.h par.h btree.h srsexe:srscheck.obj : srscheck.c message.h msg.h futil.h sm.h - seq.h par.h btree.h srsexe:msgdef.obj : msgdef.c msg.h srsexe:bs_odd.obj : futil.h message.h msg.h sm.h parser.h sdl.h sdl_def.h srsexe:bs_sdl.obj : message.h msg.h futil.h sm.h parser.h sdlparser.h - map.h sdl_def.h sdl.h query.h srswin.h - arglist.h entry.h id.h set.h ids.h library.h link.h index.h srswin.h srsexe:trembl.exe : trembl.c srsexe:srsbuild.obj : srsbuild.c message.h msg.h futil.h sm.h - parser.h seq.h par.h btree.h srsexe:srschsrs/etc/message.dat # $RCSfile: message.dat,v $ # $Revision: 1.16 $ # $Date: 1997/03/07 11:32:43 $ # $Author: srs $ # e__msgfail, invalid message address - rebuild system e__allocfail, insufficient memory - error during malloc "could not allocate \"%s\"\n\n" e__freefail, allocated memory could not be freed "could not free \"%s\"\n\n" e__settoobig, set size would exceed MAXIDS e__readerr, error during fgets or fread e__novalop, OR may not performed with sets of mixed type e__novaltyp, set types may not be mixed in logical expression "types of set A: %d, set B: %d\n" e__nosetfree, all sets occupied e__userabort, name entered is empty e__filnotopen, file is not opened for specified access e__filnotok, file could not be opened "\"%s\"\n\a\n " e__filopenerr, file could not be opened "\"%s\"\n\a\n " e__eof, end of file encountered e__ltoolong, line read is too long for output array e__invnodenum, invalid node number or step specification missing e__missnode, step definition contains no number of target node e__toomansym, symboltable already contains max number of symbols e__eot, end of symbol table is reached, no more symbols can be loaded e__parsefail, syntax error "Line nr. %d in file %s\n%s\n" e__bldparsefail, error during parsing "in %s, entry nr.: %d, name: \"%s\", field: %s \n%s\n\n" e__strprsfail, syntax error "at \"%s\" \n\n" e__lnotsaved, line cannot be restored - was not saved e__novalpnam, parameter name not known "Line nr. %d in file %s\nname: \"%s\"\n\n" e__novalsnam, structure name not known "Line nr. %d in file %s\nname: \"%s\"\n\n" e__invalnum, parameters value does not meet constraints "Line nr. %d in file %s\n%s\n\n" e__procfail, program execution stopped due to reported errors e__symnotuniq, symbol is already defined "symbol: \"%s\" value: %d\n\n" o__parnotok, parameter does not meet constraints "Line nr. %d in file %s\n%s\n\n" o__nossbeg, no begin of sub structure block was found "Line nr. %d in file %s\n\n" o__nossend, end of sub structure block ('}') missing "Line nr. %d in file %s\n\n" o__parismiss, required parameter is missing "before line nr. %d in file %s\nParameter name: \"%s\"\n\n" e__toomanstrct, number of structures is greater than allocated for "structure nr.: %d - memory allocated for %d structures\n\n" e__startismiss, no root node in parsing tree specified e__isnotss, structure cannot be a substructure as declared "Line nr. %d in file %s \nstructure name: %s\n\n" e__novalid, id of structure is not same as local count "Line nr. %d in file %s\nstructure: %s\n\n" e__missingchar, expected character(s) not found "Line nr. %d in file %s %s\n\n" e__unknownnterm, nonterminal symbol is not defined "\"%s\"\n\n" e__charnotknown, character is not valid in this context "Line nr. %d in file %s\ncharacter: %c\n\n" e__symnotknown, symbol is not defined "Line nr. %d in file %s\nsymbol: %s\n\n" e__novalsyminfo, symbol information is not valid "Line nr. %d in file %s \n<%s>\n\n" e__novalarg, invalid argument in command line "Argument nr. %d must be %s\n\n" e__novalcommand, invalid command line "At least %d argument expected\n\n" e__bnfbuildfail, could not process Backus-Naur expressions "before Line nr. %d\n\n" e__wrongpartyp, parameter value has incorrect type "Line nr. %d in file %s\n %s\n\n" e__novalptyp, parameter value is not allowed "Line nr. %d in file %s\nvalue: %d\n\n" e__novalopt, option value unknown "value %d for \"%s\"" e__misscolon, colon is missing "in line: \"%s\"" e__nammismatch, names are not identical "\"%s\" and \"%s\"\n\n" e__namnotuniq, name already exists in database "\"%s\"\n\n" e__novalauthor, invalid author name "in \"%s\", entry nr.: %d, author: \"%s\"\n" i__slbreportbeg, 4 parameters "\n________________________________________________________________________________\n\n" "Statistics of processing library \"%s\"\n\n" " total nr. of entries: %d\n" " nr. of new entries: %d\n" "nr. of updated entries: %d\n\n" "List of processed fields:\n" i__slbreportend, 0 parameters "\n_______________________________________________________________________________\n\n" i__inxreport, "%10s: %6d new keys, %6d key references, index-file size: %d blocks\n" i__processing, 1 parameter "...processing %s" e__eom, attempt to write beyond map section "section name: %s, size of section (bytes): %d\n" i__inxcmprss, 4 parameters "compressed file %s to %d blocks\n\n" e__nofieldend, end-of-field-mark is missing "%s\n" e__wrongfieldcnt, nr. of defined fields does not correspond with actual nr. "actual: %d, defined: %d \n" e__strtoolong, string is too long "string: %s, max. len %d\n" e__linenotexst, line is not pasted "row number: %d\n" e__invalstr, invalid string "length must be between %d and %d " e__invalnumber, invalid number "value must be between %d and %d " e__invalifn, invalid input file name "file \"%s\" could not be opened" e__invalofn, invalid output file name "file \"%s\" could not be opened" e__activesubmenu, can't delete menu with active submenu "menu-ID: %d, submenu-ID: %d; e__allwinused, no free window available e__exceedsize, attempt to write beyond end of block "name of block:%s, size: %d\n" e__eob, end of buffer was reached e__novalfield, inivalid field name "%s\n" e__novalnam, invalid name "\"%s\"\n" e__unexpectnum, number not as expected "%s, expected: %d found: %d\n" e__noinit, item not initialized "%s\n" e__strnotfou, string was not found "string %s in %s\n" e__strnotfound, string was not found "\"%s\"\n" e__novalstr, string is not valid "\"%s\"\n" e__novalfadd, invalid fadd specified "%u, max fadd: %u\n" e__novalnum, number to high or to small, not valid in this context "%d\n" e__libnotinx, library has not index "Library: \"%s\", Index: \"%s\"\n" i__wrotefile, wrote file "\"%s\"\n" i__wrotefiles, ...done "wrote total of %d files\n" e__novalpos, invalid begin/end positions "in \"%s\": %s\n" e__novalseqlen, sequence length does not meet constraints "in \"%s\" - length: %d\n" e__seqfrg, sequence fragmentary "in \"%s\": %s\n" e__seekfail, fseek failure "in file \"%s\"\n" e__crmpscfail, map section too small "requested: %d blocks, got: %d blocks\n" e__maxlinksexceed, exceeded nr. of links per node "max. nr. of links: %d\n" e__unknownnam, name is not known "\"%s\"\n" e__novallink, link cannot be performed "\"%s < %s\"\n" e__toofew, array is too small "actual size:%d, minimum size:%d\n" e__namreserved, name is reserved for internal use "\"%s\"\n" i__sdlreport, 7 parameters "\n________________________________________________________________________________\n\n" " made section files:\n" " \"%s\" with %d blocks \n" " \"%s\" with %d blocks \n\n" " from input: \"%s\"\n\n" " defined %d objects of %d different classes\n" "\n_______________________________________________________________________________\n\n" e__nopath, no linkage found "from \"%s\" to \"%s\"\n" e__ambigouslink, linkage ambiguity "from \"%s\" to \"%s\"\n" o__novalcol, invalid column number "\"%d\"\n" o__novalrow, invalid row number "\"%d\"\n" e__badarglist, wrong number of argument in function call e__namnotdef, name is not defined "%s name: \"%s\"\n" e__invaloutdir, invalid output directory name "\"%s\"\n" i__wroteseq, wrote sequence "\"%s\"\n" i__wroteseqsfile, ...done "wrote %d entries to file \"%s\"\n" e__complement, feature cannot be reverse complemented yet - have patience "\nin \"%s\": %s\n" e__novalreference, link cannot be performed "between libraries %s and %s using reference \"%s\"\n" i__lnkreport, "%10s: references to \"%s\": %d valid, %d invalid\n" e__exceedquota, exceeded quota "%s\n" e__rtlfail, RTL-function failed "function name: \"%s\"\n" e__novalsettyp, no set operation with different set types "\"%s\", \"%s\"\n" e__collidsfail, collected incorrect number of ID's "actual:%d, should be:%d"\n" e__inheritfail, invalid inheritance "\"%s\" cannot inherit \"%s\"\n" e__objnotfound, object is not defined "Line nr. %d in file %s\n Object-ID: %s\n\n" e__objnotnhrt, object is not yet inherited - change order of attributes "Line nr. %d in file %s\n Object: %s\n" e__missdefattr, attribute is missing in object class definition "Line nr. %d in file %s\n, Attribute: %s\n" o__nolibslct, no libraries were selected - use the \"Library\" option! e__symappendfail, cannot append symbol - table is still empty "Symbol: %s" e__exceedarr, too many elements "maximum number: %d\n" e__novalterm, invalid terminal symbol "Line nr. %d in file %s \"%s\"\n\n" i__mappedset, libraries "Mapped to \"%s\" -> %d entries" i__loadlinkset, "...loading link set \"%s\"" e__novalseqform, invalid format "\"%s\", expected \"%s\"" i__wroteseqlen, wrote sequence "\"%s\" with %d characters\n" o__obsoletemsg, value is not defined "Line nr. %d in file %s\nvalue: %s\n\n" e__novalpar, invalid parameter group value "%d, current number of groups: %d\n\n" e__toomanpar, maximum number of parameter groups exceeded "%d, increase mm->maxpar\n\n" i__procsubset, processing subset "first: %d, last: %d, from %d entries\n\n" e__sicinvalgroups, groups add not to total sequence number "should be: %d, group sum: %d\n\n" e__unknowncommand, unknown command "\"%c\"\b\n" i__readingname, ...reading name "nr. %d in list: %s\n" e__interrupt, aborted by Ctrl-C i__wroteset, ...done "%d entries written to set \"%s\"\n" e__sftop, location operator cannot be processed yet! "in \"%s\": %s\n" e__libnotlinked, library has no links "\b\"%s\"" e__filnotfound, file was not found or could not be opened "\"%s\"\n\n" e__filcloseerr, could not close file "\b\"%s\"\n\n " e__filwriteerr, could not write to file "File: \"%s\", Number of bytes attempted to write: %d\n\n" i__noentriesfound, no entries found e__nonounix, internal SRS-unix error "The routine \"%s\" should not be called " i__listtolib, read file of names "%d entries were successfully read from file \"%s\"\n" e__eostack, end of stack f__limitexceeded, limitexceeded "Maximum number of \"%s\" is %d\n" e__nontermexpect, name of nonterminal expected e__novalformat, line has incorrect format "<%s\n>" e__parnottype, parameter has not requested type "parameter \"%s\" is not of type \"%s\"\n" e__foundoneof, one-of operator encountered "in subentry \"%s\"\n" e__unknownoption, option is not known in this context "\"%s\"\n" e__parisdefined, parameter cannot be defined twice "\"%s\"\n" e__parnotdefined, parameter is not defined "\"%s\"\n" e__notwriteopen, file is not open for write access "\"%s\"\n" e__indexisbusy, index is busy or was never completed "\"%s\"\n" e__doesnotexistfunction, function name does not exist "\"%s\"\n" e__overflowstack, stack overflow "current stack size is \"%d\"\n" f__failedtomovelist, FATAL: failed to move list "\"%s\"\n" e__couldnotgetsequence, could not get sequence for accession number "\"%s\"\n" e__nothingtoevaluate, nothing to evaluate e__failureinslbgetx, could not get feature or sequence for entry "\"%s\"\n" e__joinillegalpar, join has illegal parameter "\"%s\"\n" e__entryparsefail, syntax error "in entry \"%s\"\n" e__illegalposition, illegal position (pos<=0) in range "in entry \"%s\"\n" e__illegalvalueonstack, illegal value (float) on stack "illegal value *%8.2f* on stack: position must be INT" e__illegalvaluesonstack, illegal values (float) on stack "illegal values *%8.2f* *%8.2f* on stack: position must be INT" e__illegaldirectioninrange, illegal direction in range "in entry \"%s\"\n" e__operatorbeforenotallowed, operator BEFORE not allowed e__operatorafternotallowed, operator AFTER not allowed e__postoohigh, position too high in range "in entry \"%s\"\n" i__entry, That was "entry \"%s\"\n" e__objectunknown, unknown object "%s \"%s\" does not exist\n" e__noseqinlist, no sequence in range list e__noresult, failed to evaluate result e__illegalrangemod, illegal modification of position prohibited e__illegalmodparam, illegal combination of modification parameters e__illegalqueryparam, illegal combination of query parameters e__noparamlist, parameter list for join missing e__negativelength, negative length of subsequence in SlbEvalSequence e__incorrectlength, incorrect length of subsequence in SlbEvalSequence e__fnctnotdefined, function associated to ODD-object is not defined "you must define %s_M before including ODD generated header file e__btreenotprep, btree is not prepared for building "could not start build phase %d\n" i__writeindex, writing index "...writing index \"%s\" with %d records" e__invalidid, invalid entry ID "record with number %d cannot be accessed\n" e__hasnotfixedrecord, index has not fixed length records "index: \"%s\"\n" e__fieldnotindex, data-field can not be indexed "\"%s\"\n" e__iscompressed, index is already compressed "\"%s\"\n" e__notcompressed, index needs to be compressed before use "\"%s\"\n" i__processingentry, "...no. %d, %s" i__wrotebtree, wrote btree file "\n...wrote index file \"%s\"\n" " size: %d kbytes, bucket size: %d, records: %d" i__wroteidfile, wrote file with id-lists "...wrote IDs file \"%s\"\n" " size: %d kbytes, IDs: %d" e__inxnotcompress, index cannot be compressed "\"%s\"\n" e__listnotfilled, list is not completed "list \"%s\", expected: %d, received: %d\n" e__buffexceeded, buffer size exceeded "buffer \"%s\", size %d\n" i__openedidpatch, opened Id patch file "...opened ID patch file generated for \"%s\"" e__dupllibid, duplicate library ID "ID \"%d\" defined for \"%s\" is already occupied by \"%s\"\n" e__novallibid, invalid library ID ...must range from 1 to 255 "ID \"%d\" defined for \"%s\"\n e__libidexst, library has already an ID "ID \"%d\" for \"%s\" with already defined ID \"%d\"\n" e__libidnotknown, library ID does not exist "no library with ID \"%d\" is defined\n" e__settoosmall, set has not enough space for IDs "attempt to copy %d IDs where only for %d is space\n" i__builtlink, wrote link file "...wrote link from \"%s\" to \"%s\"\n" " valid references: %d, invalid references: %d, \n" " total number of links: %d\n" i__checkinglib, "...checking library \"%s\"\n" e__novalentryidlen, length of ID hexnum string is not correct "length: %d, hexnum ID string: \"%s\"" e__indexnotuptodate, index not up to date "ID-index for entry \"%s\" is from %s, library from %s\n e__indexwrongversion, invalid index "can't open index \"%s\" with version %d ...should be %d" e__regerror, regexp: "%s\n" i__mustbuildinx, "======> must build indices for library \"%s\"\n" i__mustbuildlink, "------> must build link between \"%s\" and \"%s\"\n" i__diffentrynum, "library \"%s\" had previously %d, now %d entries\n" e__labelnotfound, label not found in script file "label: \"%s\" in script file \"%s\"\n" i__givinguplib, "cannot do anything about library \"%s\" now\n e__strnotinset, invalid string value "string \"%s\" is not in value set for parameter \"%s\"\n" e__numnotinset, invalid number value "number \"%d\" is not in value set for parameter \"%s\"\n" e__realnotinset, invalid real value "real \"%f\" is not in value set for parameter \"%s\"\n" e__functionnotinset, invalid function value "function is not in value set for parameter \"%s\"\n" e__charnotallowed, invalid character "character \"%c\" is not allowed within parameter \"%s\"\n" e__realnotinrange, value is not in range "%f is outside the range of %f to %f for parameter \"%s\"\n" e__checkerr, invalid value "for parameter \"%s\"\n" e__setopneedsidtype, at least one of the two sets must have ID-type "set "\%s", set "\%s\"\n" e__nolinklibselected, no library is selected for linking "use option \"%s\" first \n" i__querynegative, no entries found "query: \"%s\"\n" e__novalvar, invalid value of variable "%s is: %d, should be: %s" e__novalvar2, invalid value of variable "%s is: %s, should be: %s" e__novalvar3, invalid value of variable "%s is: %d, should be: %d" e__formatnomatch, string and format do not match, "format \"%s\" does not match string \"%s\"\n" e__relbegandend, invalid shift - cannot be relative to both begin and end "\"%s\"" e__invalidshift, invalid shift "\"%s\": begin: %d, end: %d, both relative to %s" e__shiftseqisfrag, shifted sequence is fragmentary "\"%s\"" e__seqwithneglen, cannot extract subsequence "from \"%s\", beg: %d, end %d" e__badfile, file cannot be accessed "%s\n" i__indexnotexist, "++++++> must build index \"%s\" for %s, does not exist\n" i__indexnotcompleted, "++++++> must rebuild index \"%s\" for %s, was never completed\n" i__indexnotuptodate, "++++++> must rebuild index \"%s\" for %s, is not up to date\n" i__indexnotcompressed, "++++++> must compress index \"%s\" for %s, is not compressed\n" e__rangewithundefval, begin or end position is not defined "in entry \"%s\"\n" e__argwrongnum, wrong number of arguments "label: %s, arguments sent: %d, expected: %d\n" e__argwrongtype, wrong argument type "label: %s, argument no: %d, type sent: %c, expected: %c\n" e__argsendnull, sent NULL pointer "label: %s, argument no: %d\n" e__fatal, fatal error e__unknownarg, unknown argument name "\"%s\" for command \"%s\"\n" e__nocurrentcommand, commands must be defined before their arguments "\"%s\"" e__onlyoneunnamed, only one unnamed argument allowed per command "\"%s\" for command \"%s\"" o__obsoletemess, wrong variable type "variable \"%s\" has type \"%s\", requested \"%s\" requires \"%s\"\n" e__varwrongclass, incompatible classes in assignment "variable \"%s\" has object of class \"%s\", not \"%s\"\n" e__varisreadonly, variable is readonly "variable \"%s\"\n" o__parsererror, parser error "production `%s' :\n%s ...\n%s\n pattern ``%s'' did not fit.\n" e__seqillegallength, sequence cannot be translated "begin position %d, sequence length\n" e__novalchar, invalid character "%s \"%c\" is not valid\n" e__missingarg, missing argument "insufficient number of arguments for %s\n" e__nosetorlib, unknown set or databank "\"%s\"\n" e__functionnotexist, function does not exist "\"%s\"\n" e__emptyquerystring, empty query string e__illegalbaseconv, illegal base conversion "Maximum possible base for conversion is %d, continuing...\n" e__dbnotlegal, databank name not legal in context "databank \"%s\" can not be an operator in logical operation\n" e__noviewselect, no view selected for edit "No view selected for view edit .... \n" e__querynotfound, query does not exist "query with number %d\n" e__dbhasnotfield, non existing field "data bank \"%s\" does not have field \"%s\".\n" e__icastackempty, stack is empty "stack number: %d\n" e__icaunknownattr, unknown attribute "class \"%s\" has no attribute \"%s\"\n" o__icavartype, invalid type "variable: \"%s\", type: %s, %s operation requires %s\n" e__icaenumval, unknown value "\"%s\" for attribute \"%s\"\n" e__icarequiredattr, attribute value is required "attribute \"%s\" of class \"%s\"\n" e__icaattrval, invalid attribute value %s\n" e__templNoCurrTemplate, no current template object selected e__unknownformat, unknown format option "field \"%s\" has no format \"%s\"\n" e__templEndOfHistory, invalid TemplEndWith "no more contexts on the stack\n" i__invalidentry, invalid or empty entry name "entry: \"%s\"\n" e__setnotuniqname, set with this name exists already set "\"%s\"\n" e__icainvalidselect, attempt to access an element of a NON-list variable "\"%s\" cannot be an element of \"$%s\"\n" e__icainvallistassign, attempt to assign a nonzero value to a list variable "only 0 can be assigned to \"$%s\" which deletes the list\n" e__icaopTask, prodName not def for task "prdName: \"%s\" task: \"%s\"\n" e__icaopEdit, Format has wrong numer of arguments "format: \"%s\" args: %d listSize: %d\n" e__icaopAssign, assigment has a wrong type "Variable name: \"%s\" Value name: \"%s\"\n" e__icaopRestrictLen, cursor length restriction has a wrong type "Value name: \"%s\"\n" e__icaopMove, cursor move has a wrong type "Value name: \"%s\"\n" e__icabnfGetProd, production name is not uniq "Name: \"%s\" Syntax: \"%s\"\n" e__icabnfExpression, Too many choice statments "Choice: \"%s\" Syntax: \"%s\"\n" e__icabnfProgram, Wrong syntax "Syntax: \"%s\" Action: \"%s\"\n" e__icabnfLinkBnfNet, production not defined "Production name: \"%s\"\n" e__icabnfParser, wrt expected but found "Current token \"%s\"\n" e__icarusFatal, (NULL) name for IcaGetTokenList call e__toklistFind, Wrong token list name "Name: \"%s\"\n" e__toklistReplace, toklist has ECHO style "Name: \"%s\"\n" e__toklistIsUniq, toklist has FILE style "Name: \"%s\"\n" e__parsererror1, syntax error "\n|%s|\n%s\n -- end of input expected\n" e__parsererror2, syntax error "production `%s' :\n -- no more input\n" e__parsererror3, syntax error "production `%s' :\n|%s|\n%s\n no match with |%s|\n" e__wwwnomatchingview, not all databanks represented by query are defined as root databanks in the view. "View \"%s\" is not suitable for displaying query \"%s\". e__nolibslct, no libraries were selected. e__wwwNoQueryOrEntriesSelected, no query or entries were selected "Try again!" e__wwwNoQuerySpecified, no query was specified "Try again!" e__toktablenotwritable, not possible to write to token table "\"%s\"" i__bldReadLink, processing read link "...reading links to \"%s\"" e__bldNoReadLinks, databank has no active read links "\"%s\"" f__noVarScope, variable scope does not exist "Please contact the program developer." e__bldLibNotMerge, no indices to merge "Library \"%s\" is not partitioned and index merging not required." e__genNoObjWithNo, object with specified number does not exist "No %s with no %d available.\n" e__checkInvalidLibInfo, incorrect library information "Correct error in \"SRSDB:srsdb.i\" or \"%s\".\n" e__icaMissingString, no string or NULL pointer to string was specified as argument o__exception, fatal error "reason: \"%s\"\n" e__duplicatekey, duplicate key during list insertion "\"%s\"\n" f__exception, fatal error "reason: \"%s\", file: \"%s\", line: %d\n" o__anyIsReadOnly, attempt to write to readonly ANY e__icaUnknownClass, attempt to define object of unknown class "object named: \"%s\"\n" e__icaErrorsQuit, exiting due to previous error(s) e__icavartype, invalid type "\n\"%s\" operation requires type "%s".\nVariable %s" e__anyIsReadOnly, attempt to write to readonly ANY "\nvariable %s" _duplicatekey, duplicate key during list insertion "\"%s\"\n" f__excesrs/etc/prep_srs #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # $RCSfile: prep_srs,v $ # $Revision: 1.22 $ # $Date: 1997/03/19 21:15:33 $ # $Author: srs $ # # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # define the SRS root directory setenv SRSROOT /u1/srs/srs5 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # find out operating system and define a symbolic name setenv OS `uname` if ($OS == "SunOS" && `uname -r` =~ [56]*) setenv OS 'Solaris' switch($OS) case Linux: set OS_SPECIFIC = linux breaksw case AIX: set OS_SPECIFIC = aix breaksw case HP-UX: set OS_SPECIFIC = hpux breaksw case IRIX: set OS_SPECIFIC = irix breaksw case IRIX64: set OS_SPECIFIC = irix64 breaksw case SunOS: set OS_SPECIFIC = sunos breaksw case Solaris: set OS_SPECIFIC = solaris breaksw case OSF1: set OS_SPECIFIC = osf breaksw case ULTRIX: set OS_SPECIFIC = ultrix breaksw default: echo "SRS does not support $OS" exit endsw #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # SRS internal directories setenv SRSDAT ${SRSROOT}/etc setenv SRSDB ${SRSROOT}/icarus/db setenv SRSICA ${SRSROOT}/icarus/util setenv SRSSOU ${SRSROOT}/src setenv SRSETC ${SRSROOT}/etc setenv SRSWWW ${SRSROOT}/www setenv SRSWWWTMP ${SRSROOT}/tmp setenv SRSDOC ${SRSWWW}/doc setenv SRSDEMO ${SRSROOT}/demo setenv SRSMAN ${SRSWWW}/man setenv SRSINX ${SRSROOT}/index setenv SRSSEC ${SRSROOT}/etc/${OS_SPECIFIC} setenv SRSEXE ${SRSROOT}/bin/${OS_SPECIFIC} #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # create OS specific directories if (!(-e $SRSSEC)) then echo "directory SRSSEC does not exist ... $SRSSEC is created." mkdir -p $SRSSEC endif if (!(-e $SRSEXE)) then echo "directory SRSEXE does not exist ...$SRSEXE is created." mkdir -p $SRSEXE endif if (!(-e $SRSINX)) then echo "directory SRSINX does not exist ...$SRSINX is created." mkdir -p $SRSINX endif #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # SRS commands # # add to the path the srs/etc and the srs/bin directory ...remove any # other srs..etc or srs..bin directory (from other versions) from the path first # set DIR = ($path) set newpath = () while ($#DIR != 0) if (!($DIR[1] =~ */srs*etc || $DIR[1] =~ */srs*bin*)) then set newpath=($newpath $DIR[1]) endif shift DIR end set path = ($newpath) set path = ($SRSEXE $SRSETC $path) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # type banner and exit echo "---------- Welcome to SRS 5.0.4 -------------" exit srs/bin directory ...remove any # other srs..etc or srs..bin directory (from other versions) from the path first # set DIR = ($path) set newpath = () while ($#DIR != 0) if (!($DIR[1] =~ */srs*etc || $DIR[1] =~ */srs*bin*)) then set newpath=($newpath $DIR[1]) endif shift DIR end set path = ($newpath) set path = ($SRSEXE $SRSETC $path) #~~~~~~~~~~~~~~~~~~~srs/etc/prep_srs.com $ SAVE_VERIFY = f$VERIFY("NO") $ say := "write sys$output" $ ! $ !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $ ! $ ! $File: /home/etzold/srs/src/RCS/file.c,v $ $ ! $Revision: 1.1 $ $ ! $Date: 1996/05/06 16:24:30 $ $ ! $Author: srs $ $ ! $ ! DCL script defines environment for either the SRS user or the $ ! SRS administrator (call script with parameter "admin"). $ ! $ ! $ !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $ ! define the SRS root directory $ ! $ assign /nolog /tran=CONCEALED $2:[ETZOLD.SRS4_0.] SRSROOT $ ! $ ! $ !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $ ! determine the mode: user or srs-administrator $ ! $ if P1 .eqs. "SRSADMIN" $ then $ ADMIN = 1 $ else $ ADMIN = 0 $ endif $ ! $ ! $ !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $ ! find out operating system and define a symbolic name $ ! $ if f$getsyi ("HW_MODEL") .gt. 1024 $ then $ OS_SPECIFIC = "ALPHA" $ else $ OS_SPECIFIC = "VAX" $ endif $ ! $ ! $ !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $ ! SRS internal directories $ ! $ define /nolog SRSCOM SRSROOT:[ETC] $ define /nolog SRSINX SRSROOT:[INDEX] $ define /nolog SRSSOU SRSROOT:[SRC] $ define /nolog SRSEXE SRSROOT:[BIN.'OS_SPECIFIC'] $ define /nolog SRSDAT SRSROOT:[ETC] $ define /nolog SRSHELP SRSROOT:[ETC] $ define /nolog SRSSDL SRSROOT:[ODD] $ define /nolog SRSSEC SRSROOT:[ETC] $ define /nolog SRSETC SRSROOT:[ETC] $ ! $ ! $ !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $ ! create OS specific directories $ ! $ if ADMIN $ then $ if f$search ("SRSROOT:[BIN]''OS_SPECIFIC'.DIR") .eqs. "" $ then $ say "directory SRSEXE does not exist ... will be created just now" $ create /dir SRSEXE $ endif $ endif $ ! $ ! $ !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $ ! SRS commands $ ! $ getz :== $SRSEXE:GETZ $ trembl :== $SRSEXE:TREMBL $ ! $ if ADMIN $ then $ odd :== $SRSEXE:odd $ etcdir = f$trnlnm ("SRSROOT") - "]" + "ETC]" $ srscheck :== $SRSEXE:srscheck $ srsu*pdate :== @SRSETC:SRSUPDATE $ srsb*uild :== $SRSEXE:SRSBUILD $ srsm*ake :== @SRSCOM:SRSMAKE $ msgdef :== $SRSEXE:MSGDEF $ srssec*tion :== "''odd' -ds srswin" $ endif $ ! $ ! $ !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $ ! type banner and exit $ ! $ say "" $ say " *** Welcome to SRS, version 4.0 ***" $ if ADMIN then - say " Administration environment $ say "" $ ! Restore verification to the status quo ante $ if "''SAVE_VERIFY'" then set verify $ exit $ say "" $ ! Restore verification to the status quo ante $ if "''SAVE_VERIFY'" then set verify $ exit # define the SRS root directory SRSROOT=/u1/srs/srs5 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # find out operating system and define a symbolic name OS=`uname` if [ "$OS" = "SunOS" ]; then case "`uname -r`" in [56]*) OS='Solaris' ;; esac fi export OS case "$OS" in "Linux") OS_SPECIFIC="linux" ;; "AIX") OS_SPECIFIC="aix" ;; "HP-UX") OS_SPECIFIC="hpux" ;; "IRIX") OS_SPECIFIC="irix" ;; "IRIX64") OS_SPECIFIC="irix64" ;; "SunOS") OS_SPECIFIC="sunos" ;; "Solaris") OS_SPECIFIC="solaris" ;; "OSF1") OS_SPECIFIC="osf" ;; "ULTRIX") OS_SPECIFIC="ultrix" ;; *) echo "SRS does not support $OS" ; exit 1 esac export OS_SPECIFIC #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # SRS internal directories SRSDAT=$SRSROOT/etc export SRSDAT SRSDB=$SRSROOT/icarus/db export SRSDB SRSICA=$SRSROOT/icarus/util export SRSICA SRSSOU=$SRSROOT/src export SRSSOU SRSETC=$SRSROOT/etc export SRSETC SRSWWW=$SRSROOT/www export SRSWWW SRSWWWTMP=$SRSROOT/tmp export SRSWWWTMP SRSDOC=$SRSWWW/doc export SRSDOC SRSDEMO=$SRSROOT/demo export SRSDEMO SRSMAN=$SRSWWW/man export SRSMAN SRSINX=$SRSROOT/index export SRSINX SRSSEC=$SRSROOT/etc/$OS_SPECIFIC export SRSSEC SRSEXE=$SRSROOT/bin/$OS_SPECIFIC export SRSEXE pd=/data/prosite export pd #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # create OS specific directories if [ ! -d $SRSSEC ]; then echo "directory SRSSEC does not exist ... $SRSSEC is created." mkdir -p $SRSSEC fi if [ ! -d $SRSEXE ]; then echo "directory SRSEXE does not exist ...$SRSEXE is created." mkdir -p $SRSEXE fi if [ ! -d $SRSINX ]; then echo "directory SRSINX does not exist ...$SRSINX is created." mkdir -p $SRSINX fi #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # SRS commands # # add to the path the srs/etc and the srs/bin directory ...remove any # other srs..etc or srs..bin directory (from other versions) from the path first # PATH=`echo "$PATH" | awk -F: '{ for ( i = 1; i <= NF; i++ ) if ( $i !~ /.*\/srs.*(etc|bin)/ ) printf ":"$i }'` PATH="${SRSEXE}:${SRSETC}${PATH}" export PATH #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # type banner and exit #echo '---------- Welcome to SRS 5.0.3 -------------' ~~~~~~~~~~~~~~~~~~~~~~~~~ # SRS commands # # add to the path the srs/etc and the srs/bin directory ...remove any # other srs..etc or srs..bin directory (from other versions) from the patsrs/etc/rcsalldiff for i in $1 ; do rcsdiff $i >> /dev/null 2>&1 if [ $? = 1 ]; then echo $i rcsdiff $i fi done }'` PATH="${SRSEXE}:${SRSETC}${PATH}" export PATH #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # type banner and exit #echo '---------- Welcome to SRS 5.0.3 -------------' ~~~~~~~~~~~~~~~~~~~~~~~~~ # SRS commands # # add to the path the srs/etc and the srs/bin directory ...remove any # other srs..etc or srs..bin directory (from other versio the patsrs/etc/rmtmpdir /bin/find $SRSTMP -mtime +7 -exec /bin/rm -rf {} \; [ $? = 1 ]; then echo $i rcsdiff $i fi done }'` PATH="${SRSEXE}:${SRSETC}${PATH}" export PATH #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # type banner and exit #echo '---------- Welcome to SRS 5.0.3 -------------' ~~~~~~~~~~~~~~~~~~~~~~~~~ # SRS commands # # add to the path the srs/etc and the srs/bin directory ...remove any # other srs..etc or srs..bin directory (from other versio the patsrs/etc/srscron i rcsdiff $i fi done }'` PATH="${SRSEXE}:${SRSETC}${PATH}" export PATH #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # type banner and exit #echo '---------- Welcome to SRS 5.0.3 -------------' ~~~~~~~~~~~~~~~~~~~~~~~~~ # SRS commands # # add to the path the srs/etc and the srs/bin directory ...remove any # other srs..etc or srs..bin directory (from other versio the patsrs/etc/srsinstall.com $ say := "write sys$output" $ !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $ ! $ ! $File: /home/etzold/srs/src/RCS/file.c,v $ $ ! $Revision: 1.1 $ $ ! $Date: 1996/05/06 16:24:36 $ $ ! $Author: srs $ $ ! $ ! DCL script builds the srs system $ ! $ !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $ ! $ ! $ !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $ ! change the file "prep_srs.com" to assign the correct SRSROOT $ ! $ open/read RFILE [.etc]prep_srs.com $ open/write WFILE [.etc]prep_srs.com $ ! $ NEXT_LINE: $ read /end_of_file=FILE_END RFILE LINE $ if f$locate ("CONCEALED", LINE) .lt. f$length (LINE) $ then $ PDIR = f$directory () $ PWD = f$parse (PDIR,,,"DEVICE",) + PDIR $ LINE = "$ assign /nolog /tran=CONCEALED " + PWD - "]" + ".]" + " SRSROOT" $ endif $ write WFILE LINE $ goto NEXT_LINE $ FILE_END: $ close RFILE $ close WFILE $ ! $ ! $ !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $ ! build the programs $ ! $ @[.etc]prep_srs srsadmin $ srsmake all $ odd -ds srswin $ exit read /end_of_file=FILE_END RFILE LINE $ if f$locate ("CONCEALED", LINE) .lt. f$length (LINE) $ then $ PDIR = f$directory () $ PWD = f$parse (PDIR,,,"DEVICE",) + PDIR $ LINE = "$ assign /nolog /tran=CONCEALED " + PWD - "]" + ".]" + " SRSROOT" $ endif $ write WFILE LINE $ goto NEXT_LINE $ FILE_END: $ close RFILE $ close WFILE $ ! $ ! $ !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~srs/etc/srsmake #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # $RCSfile: srsmake,v $ # $Revision: 1.16 $ # $Date: 1997/03/03 18:39:57 $ # $Author: srs $ # # Bourne-shell script that calls make on different UNIX operating systems; # # script builds either all sources (call without parameters) or individual # programs (program name as parameter); # are parameters specified for calling this script will be handed over to # make # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ERR='srsmake: Stopping due to Error' #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # find out current operating system OS=`uname` if [ "$OS" = "SunOS" ]; then case "`uname -r`" in [56]*) OS='Solaris' ;; esac fi export OS #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # define system dependend make command # ranlib not defined on all systems ...search path PLIST="`echo $PATH | sed -e 's/:/ /g'`" RANLIB=touch for DIR in ${PLIST}; do if [ -r ${DIR}/ranlib ]; then RANLIB=ranlib fi done # this part is edited by srsinstall case "$OS" in Linux) MAKE='make SPEZ_FLAGS= CCOMP=cc RANLIB='$RANLIB ;; AIX) MAKE='make SPEZ_FLAGS=-Daix CCOMP=cc MALLOC= LIBS=-lPW' ;; HP-UX) MAKE='make SPEZ_FLAGS=-Dhpux' ;; IRIX) MAKE='make SPEZ_FLAGS= CCOMP=cc RANLIB='$RANLIB ;; IRIX64) MAKE='make SPEZ_FLAGS=-32 CCOMP=cc RANLIB='$RANLIB #MAKE='make SPEZ_FLAGS=-Dirix64 CCOMP=cc RANLIB='$RANLIB ;; OSF1) MAKE='make SPEZ_FLAGS=-Dosf CCOMP=cc MALLOC= RM= TO=\$@' ;; SunOS) MAKE='gmake SPEZ_FLAGS=-Dsun CCOMP=gcc MALLOC=' ;; Solaris) MAKE='make SPEZ_FLAGS=-Xa LIBS=/usr/ccs/lib/libgen.a CCOMP=gcc MALLOC= RANLIB='$RANLIB ;; ULTRIX) MFLAGS='' export MFLAGS MAKE='make SPEZ_FLAGS=-Dultrix LFLAGS=-g CCOMP=gcc' ;; *) echo 'cannot make SRS on that operating system' echo 'srsmake: Stopping make procedure.' exit 1 esac #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # now make SRS, if no parameter is specified build all executables. if [ $# = 0 ]; then echo "$ERR - at least one argument required" exit 1 elif [ "$1" = 'depend' ]; then echo 'producing makefile dependencies for include files' cd ${SRSSOU} ; $MAKE -f ${SRSETC}/srsmakefile $* STATUS="$?" elif [ "$1" = 'tags' ]; then echo 'making new tags file' cd ${SRSSOU} ; $MAKE -f ${SRSETC}/srsmakefile $* STATUS="$?" elif [ "$1" = 'clean' ]; then echo 'making clean' $MAKE -f ${SRSETC}/srsmakefile $* STATUS="$?" elif [ "$1" = 'cleanall' ]; then echo 'making cleanall' $MAKE -f ${SRSETC}/srsmakefile $* STATUS="$?" else echo "make for $OS with parameters: $*" cd ${SRSSOU} ; $MAKE -f ${SRSETC}/srsmakefile ${SRSEXE}/$* STATUS="$?" fi # pass any error status back up if [ ! "$STATUS" = 0 ]; then echo "$ERR $STATUS" exit 1 fi echo 'srsmake: end' ${SRSSOU} ; $MAKE -f ${SRSETC}/srsmakefile $* STATUS="$?" elif [ "$1" = 'cleasrs/etc/srsmake.com $ say := "write sys$output" $ !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $ ! $ ! $File: /home/etzold/srs/src/RCS/file.c,v $ $ ! $Revision: 1.1 $ $ ! $Date: 1996/05/06 16:24:39 $ $ ! $Author: srs $ $ ! $ ! DCL script calls mms on VMS or OpenVMS; $ ! SRS-administrator environment must be defined before calling; $ ! $ ! script builds either all sources (call with parameter all) or individual $ ! programs (program name as parameter); $ ! all parameters specified for calling this script will be handed over to $ ! make $ ! $ ! $ !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $ ! find out whether script is running on an alpha or not $ ! $ if f$getsyi ("ARCH_NAME") .eqs. "Alpha" $ then $ XCFLAGS = """XCFLAGS = /nomember/standard=vaxc""" $ LINK_OPT = """LINK_OPT = /lib""" $ else $ XCFLAGS = """XCFLAGS =""" $ LINK_OPT = """LINK_OPT = /opt""" $ endif $ ! $ ! $ !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $ ! set default to both SRSSOU (sources) and SRSEXE (objects and images) using $ ! a logical defined for that purpose $ ! $ ! $ ! create a new library if not already there $ if f$search ("srsexe:srs.olb") .eqs. "" then library /create srsexe:srs.olb $ ! $ ! save current directory $ PDIR = f$directory () $ PWD = f$parse (PDIR,,,"DEVICE",) + PDIR $ ! $ define /nolog MAKELOC SRSSOU,SRSEXE $ set default MAKELOC $ ! $ if P1 .eqs. "ALL" $ then $ mms /descript=SRSETC:makefile /ignore /macro=('XCFLAGS', 'LINK_OPT') - 'P1' 'P2' 'P3' 'P4' 'P5' 'P6' 'P7' 'P8' $ else $ mms /descript=SRSETC:makefile /ignore /macro=('XCFLAGS', 'LINK_OPT') - SRSEXE:'P1'.exe 'P2' 'P3' 'P4' 'P5' 'P6' 'P7' 'P8' $ endif $ ! $ set def 'PWD' $ exit srs.olb $ ! $ ! save current directory $ PDIR = f$directory () $ PWD = f$parse (PDIR,,,"DEVICE",) + PDIR $ ! $ define /nolog MAKELOC SRSSOU,SRSEXE $ set default MAKELOC $ ! $ if P1 .eqs. "ALL" $ then $ mms /descript=SRSETC:makefile /ignore /macro=('XCFLAGSsrs/etc/srsmakefile # # $RCSfile: srsmakefile,v $ # $Revision: 1.24 $ # $Date: 1997/03/12 16:22:43 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # SHELL=/bin/sh .SUFFIXES : .c .o .i .m .h .a #os specific flags (specified in 'srsmake') SPEZ_FLAGS = #for compiling ALL c-files # This is edited by srsinstall - leave these comments in! # CFLAGS Optimised #CFLAGS = -O2 -D__ODD -DSRSINCLUDE=\"srs5.h\" # CFLAGS Not Optimised #CFLAGS = -D__ODD -DSRSINCLUDE=\"srs5.h\" # CFLAGS Debug CFLAGS = -g -D__ODD -DSRSINCLUDE=\"srs5.h\" #default compiler SRSH = srs5.h CCOMP = cc CC = $(CCOMP) $(SPEZ_FLAGS) -I$(SRSEXE) MALLOC = -lmalloc BIN = $(SRSEXE)/ LIB = $(BIN)libsrs.a #variable for the target object name TO = $% #add. flags for compiling to normal objects OCFLAGS = -c -o $@ #add. flags for compiling lib members LOCFLAGS = -c -o $(TO) #LIBENTER = /usr/ccs/bin/ar rv $(LIB) $(TO) #command puts object into archive LIBENTER = ar r $(LIB) $(TO) #RANLIB = ls RANLIB = ranlib RMCMD = /bin/rm -f RM = $(RMCMD) $% ODD_OBJS = $(BIN)bs_odd.o \ $(BIN)oddfncts.o \ $(BIN)bs_parser.o \ $(BIN)bs_sdl.o \ $(BIN)bs_sdlget.o LOCAL_OBJS = $(BIN)local.o LIB_OBJS = $(LIB)($(BIN)arglist.o) \ $(LIB)($(BIN)lst.o) \ $(LIB)($(BIN)oddfnctsnew.o) \ $(LIB)($(BIN)sdlnew.o) \ $(LIB)($(BIN)error.o) \ $(LIB)($(BIN)toklist.o) \ $(LIB)($(BIN)cursor.o) \ $(LIB)($(BIN)icarus.o) \ $(LIB)($(BIN)icabnf.o) \ $(LIB)($(BIN)icaop.o) \ $(LIB)($(BIN)icaarg.o) \ $(LIB)($(BIN)icatask.o) \ $(LIB)($(BIN)icadebug.o) \ $(LIB)($(BIN)ica2c.o) \ $(LIB)($(BIN)bnf2c.o) \ $(LIB)($(BIN)icainit.o) \ $(LIB)($(BIN)dict.o) \ $(LIB)($(BIN)strv.o) \ $(LIB)($(BIN)listv.o) \ $(LIB)($(BIN)def.o) \ $(LIB)($(BIN)sm.o) \ $(LIB)($(BIN)message.o) \ $(LIB)($(BIN)futil.o) \ $(LIB)($(BIN)set.o) \ $(LIB)($(BIN)unix_map.o) \ $(LIB)($(BIN)logicals.o) \ $(LIB)($(BIN)sdlget.o) \ $(LIB)($(BIN)btree.o) \ $(LIB)($(BIN)ids.o) \ $(LIB)($(BIN)idx.o)\ $(LIB)($(BIN)index.o) \ $(LIB)($(BIN)library.o) \ $(LIB)($(BIN)field.o) \ $(LIB)($(BIN)query.o) \ $(LIB)($(BIN)queryass.o) \ $(LIB)($(BIN)link.o) \ $(LIB)($(BIN)seq.o) \ $(LIB)($(BIN)par.o) \ $(LIB)($(BIN)variable.o) \ $(LIB)($(BIN)id.o) \ $(LIB)($(BIN)entry.o) \ $(LIB)($(BIN)regexp.o) \ $(LIB)($(BIN)templ.o) \ $(LIB)($(BIN)tm.o) \ $(LIB)($(BIN)view.o) \ $(LIB)($(BIN)merge.o) \ $(LIB)($(BIN)hash.o) \ $(LIB)($(BIN)seqdb.o)\ $(LIB)($(BIN)appl.o)\ $(LIB)($(BIN)termio.o) $(BIN)srs : echo MAKE FOR COMPLETE SRS SYSTEM FINISHED $(LIB) : $(LIB_OBJS) $(RANLIB) $(LIB) $(BIN)odd : $(BIN)bs_odd.o $(LIB) $(ODD_OBJS) $(CC) -o $@ $(ODD_OBJS) $(LIB) $(BIN)srsbuild : $(BIN)srsbuild.o $(LIB) $(LOCAL_OBJS) $(CC) -o $@ $(BIN)srsbuild.o $(LOCAL_OBJS) $(LIB) $(BIN)reflink : $(BIN)reflink.o $(LIB) $(CC) -o $@ $(BIN)reflink.o $(LIB) $(BIN)trembl : $(BIN)trembl.o $(LIB) $(CC) -o $@ $(BIN)trembl.o $(LIB) $(BIN)icarus : $(BIN)icarusi.o $(LIB) $(LOCAL_OBJS) $(CC) -o $@ $(BIN)icarusi.o $(LOCAL_OBJS) $(LIB) $(BIN)x : $(BIN)x.o $(LIB) $(LOCAL_OBJS) $(CC) -o $@ $(BIN)x.o $(LOCAL_OBJS) $(LIB) $(BIN)nodd : $(BIN)nodd.o $(LIB) $(LOCAL_OBJS) $(CC) -o $@ $(BIN)nodd.o $(LOCAL_OBJS) $(LIB) $(BIN)getz : $(BIN)getz.o $(LIB) $(LOCAL_OBJS) $(CC) -o $@ $(BIN)getz.o $(LOCAL_OBJS) $(LIB) $(BIN)srscheck : $(BIN)srscheck.o $(LIB) $(CC) -o $@ $(BIN)srscheck.o $(LOCAL_OBJS) $(LIB) $(BIN)msgdef : $(BIN)msgdef.o $(CC) -o $@ $(BIN)msgdef.o $(BIN)wgetz : $(BIN)wgetz.o $(BIN)srswww.o $(LIB) $(LOCAL_OBJS) $(CC) -o $@ $(BIN)srswww.o $(BIN)wgetz.o $(LOCAL_OBJS) $(LIB) cp $(BIN)wgetz $(SRSWWW)/bin/wgetz $(BIN)srspict : $(BIN)srspict.o $(BIN)gd.o $(LIB) $(CC) -o $@ $(BIN)gd.o $(BIN)srspict.o $(LIB) # some modules of the ODD compiler must be compiled with BOOTSTRAP # $(BIN)bs_parser.o : parser.c futil.h message.h msg.h sm.h $(CC) $(CFLAGS) $(OCFLAGS) -DBOOTSTRAP parser.c $(BIN)bs_sdl.o : sdl.c message.h msg.h futil.h sm.h map.h odd.h $(CC) $(CFLAGS) $(OCFLAGS) -DBOOTSTRAP sdl.c $(BIN)bs_sdlget.o : sdlget.c futil.h message.h msg.h odd.h $(CC) $(CFLAGS) $(OCFLAGS) -DBOOTSTRAP sdlget.c $(BIN)bs_odd.o : odd.c futil.h message.h msg.h sm.h odd.h $(CC) $(CFLAGS) $(OCFLAGS) -DBOOTSTRAP odd.c $(BIN)oddfncts.o : oddfncts.c message.h msg.h sm.h futil.h odd.h $(CC) $(CFLAGS) $(OCFLAGS) -DBOOTSTRAP oddfncts.c #$(BIN)oddfnctsnew.o : oddfnctsnew.c message.h msg.h sm.h futil.h odd.h # $(CC) $(CFLAGS) $(OCFLAGS) -DBOOTSTRAP oddfnctsnew.c $(BIN)oddtools.o : oddtools.c message.h msg.h oddtools.h $(CC) $(CFLAGS) $(OCFLAGS) -DBOOTSTRAP oddtools.c $(BIN)local.o : local.c message.h msg.h sm.h lst.h futil.h $(CC) $(CFLAGS) $(OCFLAGS) local.c #depend $(LIB)($(BIN)bs_sdlnew.o): sdlnew.c message.h msg.h futil.h sm.h map.h odd.h $(CC) $(CFLAGS) $(LOCFLAGS) sdlnew.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)futil.o): futil.c message.h msg.h regexp.h futil.h sm.h ($(CC) $(CFLAGS) $(LOCFLAGS) futil.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)message.o): message.c msg.h futil.h sm.h ($(CC) $(CFLAGS) $(LOCFLAGS) message.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)sm.o): sm.c message.h msg.h sm.h ($(CC) $(CFLAGS) $(LOCFLAGS) sm.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)parser.o): parser.c message.h msg.h futil.h sm.h ($(CC) $(CFLAGS) $(LOCFLAGS) parser.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)error.o): error.c error.h message.h msg.h futil.h sm.h toklist.h cursor.h ($(CC) $(CFLAGS) $(LOCFLAGS) error.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)toklist.o): toklist.c toklist.h message.h msg.h futil.h sm.h ($(CC) $(CFLAGS) $(LOCFLAGS) toklist.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)cursor.o): cursor.c cursor.h message.h msg.h futil.h sm.h ($(CC) $(CFLAGS) $(LOCFLAGS) cursor.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)icarus.o): icarus.c icarus.h message.h msg.h regexp.h futil.h par.h sm.h ($(CC) $(CFLAGS) $(LOCFLAGS) icarus.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)icabnf.o): icabnf.c icarus.h icabnf.h message.h msg.h regexp.h futil.h par.h sm.h ($(CC) $(CFLAGS) $(LOCFLAGS) icabnf.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)icastack.o): icastack.c icastack.h message.h msg.h par.h ($(CC) $(CFLAGS) $(LOCFLAGS) icastack.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)icatask.o): icatask.c icatask.h icarus.h message.h msg.h par.h ($(CC) $(CFLAGS) $(LOCFLAGS) icatask.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)icadebug.o): icadebug.c icadebug.h icarus.h message.h msg.h par.h ($(CC) $(CFLAGS) $(LOCFLAGS) icadebug.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)ica2c.o): ica2c.c ica2c.h message.h msg.h variable.h strv.h ($(CC) $(CFLAGS) $(LOCFLAGS) ica2c.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)bnf2c.o): bnf2c.c message.h msg.h variable.h strv.h ($(CC) $(CFLAGS) $(LOCFLAGS) bnf2c.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)icainit.o): icainit.c icarus.h ($(CC) $(CFLAGS) $(LOCFLAGS) icainit.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)icaop.o): icaop.c message.h msg.h icarus.h sm.h ($(CC) $(CFLAGS) $(LOCFLAGS) icaop.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)icaarg.o): icaarg.c message.h msg.h icarus.h sm.h builtin.h ($(CC) $(CFLAGS) $(LOCFLAGS) icaarg.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)sdl.o): sdl.c message.h msg.h futil.h sm.h tm.h map.h par.h \ odd.h ($(CC) $(CFLAGS) $(LOCFLAGS) sdl.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)sdlnew.o): sdlnew.c message.h msg.h futil.h sm.h tm.h map.h par.h ($(CC) $(CFLAGS) $(LOCFLAGS) sdlnew.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)sdlget.o): sdlget.c message.h msg.h futil.h odd.h ($(CC) $(CFLAGS) $(LOCFLAGS) sdlget.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)index.o): index.c message.h msg.h sm.h futil.h binpack.h btree.h id.h ids.h hash.h \ index.h ($(CC) $(CFLAGS) $(LOCFLAGS) index.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)btree.o): btree.c message.h msg.h futil.h sm.h tm.h binpack.h btree.h ids.h ($(CC) $(CFLAGS) $(LOCFLAGS) btree.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)ids.o): ids.c message.h msg.h binpack.h futil.h tm.h id.h ids.h set.h library.h map.h ($(CC) $(CFLAGS) $(LOCFLAGS) ids.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)idx.o): idx.c message.h msg.h sm.h tm.h futil.h binpack.h idx.h ($(CC) $(CFLAGS) $(LOCFLAGS) idx.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)seq.o): seq.c message.h msg.h sm.h futil.h lst.h par.h seq.h ($(CC) $(CFLAGS) $(LOCFLAGS) seq.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)par.o): par.c message.h msg.h sm.h futil.h sdlget.h lst.h par.h $(SRSH) ($(CC) $(CFLAGS) $(LOCFLAGS) par.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)variable.o): variable.c message.h msg.h sm.h futil.h lst.h variable.h ($(CC) $(CFLAGS) $(LOCFLAGS) variable.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)seqlib.o): seqlib.c message.h msg.h sm.h lst.h futil.h par.h id.h library.h \ entry.h seq.h query.h seqlib.h $(SRSH) ($(CC) $(CFLAGS) $(LOCFLAGS) seqlib.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)seqdb.o): seqdb.c message.h msg.h sm.h lst.h futil.h icaarg.h \ icarus.h seq.h listv.h ($(CC) $(CFLAGS) $(LOCFLAGS) seqdb.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)appl.o): appl.c message.h msg.h sm.h lst.h futil.h appl.h library.h srs5.h ($(CC) $(CFLAGS) $(LOCFLAGS) appl.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)library.o): library.c message.h msg.h futil.h sm.h tm.h btree.h sdlget.h ids.h idx.h \ par.h library.h $(SRSH) ($(CC) $(CFLAGS) $(LOCFLAGS) library.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)field.o): field.c message.h msg.h futil.h sm.h tm.h btree.h sdlget.h ids.h idx.h \ par.h field.h $(SRSH) ($(CC) $(CFLAGS) $(LOCFLAGS) field.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)entry.o): entry.c message.h msg.h sm.h tm.h futil.h par.h icarus.h id.h set.h \ library.h entry.h $(SRSH) ($(CC) $(CFLAGS) $(LOCFLAGS) entry.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)queryass.o): queryass.c queryass.h message.h msg.h futil.h par.h sm.h library.h ($(CC) $(CFLAGS) $(LOCFLAGS) queryass.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)query.o): query.c message.h msg.h futil.h par.h regexp.h ids.h btree.h \ sm.h tm.h library.h id.h entry.h set.h link.h seqlib.h lst.h query.h \ $(SRSH) ($(CC) $(CFLAGS) $(LOCFLAGS) query.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)set.o): set.c message.h msg.h lst.h sm.h futil.h id.h set.h library.h \ $(SRSH) ($(CC) $(CFLAGS) $(LOCFLAGS) set.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)id.o): id.c message.h msg.h futil.h binpack.h id.h library.h ($(CC) $(CFLAGS) $(LOCFLAGS) id.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)link.o): link.c message.h msg.h futil.h sm.h id.h set.h par.h link.h map.h btree.h \ ids.h library.h binpack.h query.h $(SRSH) ($(CC) $(CFLAGS) $(LOCFLAGS) link.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)stack.o): stack.c message.h msg.h futil.h ($(CC) $(CFLAGS) $(LOCFLAGS) stack.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)expr.o): expr.c message.h msg.h futil.h $(SRSH) ($(CC) $(CFLAGS) $(LOCFLAGS) expr.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)lst.o): lst.c lst.h sdlget.h ($(CC) $(CFLAGS) $(LOCFLAGS) lst.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)unix_map.o): unix_map.c message.h msg.h futil.h map.h ($(CC) $(CFLAGS) $(LOCFLAGS) unix_map.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)regexp.o): regexp.c regexp.h regmagic.h message.h msg.h ($(CC) $(CFLAGS) $(LOCFLAGS) regexp.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)arglist.o): arglist.c message.h msg.h futil.h par.h $(SRSH) arglist.h ($(CC) $(CFLAGS) $(LOCFLAGS) arglist.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)logicals.o): logicals.c ($(CC) $(CFLAGS) $(LOCFLAGS) logicals.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)tm.o): tm.c message.h msg.h tm.h ($(CC) $(CFLAGS) $(LOCFLAGS) tm.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)script.o): script.c message.h msg.h futil.h sm.h lst.h ($(CC) $(CFLAGS) $(LOCFLAGS) script.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)templ.o): templ.c message.h icarus.h msg.h futil.h sm.h lst.h templ.h ($(CC) $(CFLAGS) $(LOCFLAGS) templ.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)view.o): view.c message.h sm.h futil.h library.h set.h par.h view.h ($(CC) $(CFLAGS) $(LOCFLAGS) view.c;$(LIBENTER); $(RM)) $(LIB)($(BIN)merge.o): merge.c message.h sm.h futil.h library.h set.h par.h view.h ($(CC) $(CFLAGS) $(LOCFLAGS) merge.c;$(LIBENTER); $(RM)) $(LIB)($(BIN)hash.o): hash.c message.h msg.h hash.h ($(CC) $(CFLAGS) $(LOCFLAGS) hash.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)termio.o): termio.c termio.h message.h msg.h strv.h ($(CC) $(CFLAGS) $(LOCFLAGS) termio.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)oddfnctsnew.o): oddfnctsnew.c message.h msg.h sm.h futil.h odd.h ($(CC) $(CFLAGS) $(LOCFLAGS) -DBOOTSTRAP oddfnctsnew.c; $(LIBENTER); $(RM)) $(BIN)icarusi.o: icarusi.c message.h msg.h futil.h sm.h seq.h par.h arglist.h id.h \ idx.h set.h entry.h library.h seqlib.h query.h $(SRSH) $(SRSEXE)/srsenv.h $(CC) $(CFLAGS) $(OCFLAGS) icarusi.c $(BIN)x.o: x.c $(CC) $(CFLAGS) $(OCFLAGS) x.c $(BIN)nodd.o: nodd.c odd.h message.h msg.h futil.h sm.h seq.h par.h arglist.h id.h \ idx.h set.h entry.h library.h seqlib.h query.h $(SRSH) $(SRSEXE)/srsenv.h $(CC) $(CFLAGS) $(OCFLAGS) nodd.c $(BIN)tryz.o: tryz.c $(CC) $(CFLAGS) $(OCFLAGS) tryz.c $(BIN)ntry.o: ntry.c $(CC) $(CFLAGS) $(OCFLAGS) ntry.c $(BIN)getz.o: getz.c icarus.h message.h msg.h futil.h sm.h seq.h par.h arglist.h id.h \ idx.h set.h entry.h library.h seqlib.h query.h $(SRSH) $(SRSEXE)/srsenv.h $(CC) $(CFLAGS) $(OCFLAGS) getz.c $(BIN)srsbuild.o: srsbuild.c message.h msg.h futil.h sm.h seq.h seqlib.h par.h \ btree.h arglist.h entry.h id.h set.h ids.h idx.h library.h link.h index.h $(SRSH) $(CC) $(CFLAGS) $(OCFLAGS) srsbuild.c $(BIN)msgdef.o: msgdef.c msg.h futil.h $(CC) $(CFLAGS) $(OCFLAGS) msgdef.c $(LIB)($(BIN)dict.o): dict.c dict.h strv.h ($(CC) $(CFLAGS) $(LOCFLAGS) dict.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)print.o): print.c print.h strv.h ($(CC) $(CFLAGS) $(LOCFLAGS) print.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)oldlistbuf.o): oldlistbuf.c oldlistbuf.h strv.h ($(CC) $(CFLAGS) $(LOCFLAGS) oldlistbuf.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)strv.o): strv.c strv.h ($(CC) $(CFLAGS) $(LOCFLAGS) strv.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)listv.o): listv.c listv.h ($(CC) $(CFLAGS) $(LOCFLAGS) listv.c; $(LIBENTER); $(RM)) $(LIB)($(BIN)def.o): def.c def.h ($(CC) $(CFLAGS) $(LOCFLAGS) def.c; $(LIBENTER); $(RM)) $(BIN)reflink.o: reflink.c message.h msg.h futil.h library.h par.h arglist.h id.h \ set.h entry.h seq.h seqlib.h query.h lst.h $(SRSH) $(SRSEXE)/srsenv.h $(CC) $(CFLAGS) $(OCFLAGS) reflink.c $(BIN)trembl.o: trembl.c message.h msg.h futil.h library.h par.h arglist.h id.h \ set.h entry.h seq.h seqlib.h query.h lst.h $(SRSH) $(SRSEXE)/srsenv.h $(CC) $(CFLAGS) $(OCFLAGS) trembl.c $(BIN)srscheck.o: srscheck.c message.h msg.h futil.h sm.h tm.h arglist.h par.h library.h \ id.h ids.h set.h btree.h link.h $(SRSH) $(CC) $(CFLAGS) $(OCFLAGS) srscheck.c $(BIN)odd.o: odd.c message.h msg.h futil.h sm.h arglist.h par.h odd.h $(CC) $(CFLAGS) $(OCFLAGS) odd.c $(BIN)wgetz.o: wgetz.c icarus.h message.h msg.h arglist.h sm.h tm.h futil.h library.h \ par.h id.h set.h entry.h query.h srswww.h view.h $(SRSH) $(SRSEXE)/srsenv.h $(CC) $(CFLAGS) $(OCFLAGS) wgetz.c $(BIN)srswww.o: srswww.c message.h msg.h sm.h tm.h lst.h futil.h par.h \ id.h set.h library.h btree.h idx.h entry.h link.h seq.h query.h seqlib.h \ srswww.h $(SRSH) $(CC) $(CFLAGS) $(OCFLAGS) srswww.c $(BIN)srspict.o: srspict.c srs.h gd.h $(CC) $(CFLAGS) $(OCFLAGS) srspict.c $(BIN)gd.o: gd.c gd.h $(CC) $(CFLAGS) $(OCFLAGS) gd.c clean: -$(RMCMD) $(BIN)*.o -$(RMCMD) $(BIN)*.a cleanall: -$(RMCMD) -r $(SRSEXE) srswww.h view.h $(SRSH) $(SRSEXE)/srsenv.h $(CC) $(CFLAGS) $(OCFLAGS) wgetz.c $(BIN)srswwwsrs/etc/srsnet.tcl # # $RCSfile: srsnet.tcl,v $ # $Revision: 1.1 $ # $Date: 1996/05/06 16:24:42 $ # $Author: srs $ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # global variable initialisation #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ set gvar(ch) 800 set gvar(cw) 600 set gvar(ZOOM) 100 set gvar(OLDSCALE) 1.0 #unix command for calling getz set getz getz set isQuery 0 #set color(0) chocolate1 #set color(1) turquoise #set color(2) darkgoldenrod1 #set color(3) plum #set color(4) palevioletred #set color(5) grey set color(0) turquoise set color(1) turquoise set color(2) turquoise set color(3) turquoise set color(4) turquoise set color(5) turquoise wm title . "SRS-Network" wm maxsize . 1200 1200 wm minsize . 100 100 wm iconname . "SRS-Network" #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # widgets and layout #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # buttons on right hand side frame .f2 -relief ridge scale .f2.zoom -label "Zoom" -orient horiz -relief raised -length 150 -from 50 -to 250 \ -command "resize .f1.c" .f2.zoom set 100 button .f2.quit -text "QUIT" -relief raised \ -command exit button .f2.savedbs -text "SAVE" -relief raised -command "SaveDBs" button .f2.loaddbs -text "LOAD" -relief raised -command "LoadDBs" pack .f2.zoom -side top -padx 5 -pady 2 -ipady 5 pack .f2.loaddbs -side top -padx 5 -pady 2 -ipady 5 -fill x pack .f2.savedbs -side top -padx 5 -pady 2 -ipady 5 -fill x pack .f2.quit -side top -padx 5 -pady 2 -ipady 5 -fill x # # canvas with scroll bars # frame .f1 -relief ridge scrollbar .f1.scx -width 15 -orient horiz -relief flat \ -command ".f1.c xview" frame .f1.f1 -relief flat frame .f1.f1.spacer -height 15.p -width 15.p scrollbar .f1.f1.scy -width 15 -orient verti -relief flat -command ".f1.c yview" pack .f1.f1.spacer -side bottom -expand n pack .f1.f1.scy -side top -expand yes -fill both pack .f1.f1 -side right -expand n -fill both pack .f1.scx -side bottom -expand n -fill x canvas .f1.c -w 200 -height 200 -bg bisque1 -yscrollc ".f1.f1.scy set" -xscrollc ".f1.scx set" pack .f1.c -side left -fill both -expand yes pack .f1 -side right -fill both -expand yes pack .f2 -side left -fill y #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # list of procedures #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ proc resize { c z } { global gvar isMustScaleCoord set sreg "0 0 [expr $z*$gvar(cw)/100.0] [expr $z*$gvar(ch)/100.0]" $c configure -scrollregion $sreg set sc [expr 1.0*$z/$gvar(ZOOM)] set gvar(ZOOM) $z set gvar(SCALE) [expr $z/100.0] $c scale all 0 0 $sc $sc set isMustScaleCoord 1 } proc SaveDBs {} { global nodeX nodeY DBNodeName allDBs if (![info exists allDBs]) { error "Nothing to save!" return } set stat "[catch {set file [open "srsnet.dat" w]} msg]" if {$stat} { puts "$msg" return } foreach node [.f1.c find withtag node] { puts $file "coord: $DBNodeName($node) $nodeX($node) $nodeY($node)" } close $file } proc ReadDBCoord {} { global nodeX nodeY DBname DBnodeX DBnodeY set stat "[catch {set file [open "srsnet.dat" r]} msg]" if {$stat} { puts "$msg" return } while {[gets $file line] >= 0} { if [regexp {coord: +([^ ]+) +([0-9]+) +([0-9]+)} \ $line match libName x y ] { set DBnodeX($libName) $x set DBnodeY($libName) $y } } close $file } proc LoadDBs {} { global nodeX nodeY edgeFirst edgeSecond isActive DB DBname DBcolor getz \ DBnodeX DBnodeY node curX curY color allDBs fields DBNodeName set yy 10 set xx 40 ReadDBCoord set f1 [open "|$getz -si" r] set groups {} while {[gets $f1 line] >= 0} { if [regexp {lib: ([^ ,]+), .*group: ([^ ,]+)} \ $line match libName group ] { set index [lsearch $groups $group] if {$index == -1} { lappend groups $group } set index [lsearch $groups $group] if {[info exists DBnodeX($libName)]} { set tmpx $DBnodeX($libName) set tmpy $DBnodeY($libName) } else { set tmpx $xx set tmpy $yy } set tmp [string tolower $libName] button .f1.c.$tmp -text "$libName" -relief raised -height 1\ -bg $color($index) \ -highlightcolor white -highlightbackground bisque1 set new [.f1.c create window $tmpx $tmpy -window .f1.c.$tmp \ -tags node ] # # key bindings for each button in the graph ...don't know how to do one # binding for all # bind .f1.c.$tmp { global curX curY set curX %X set curY %Y } bind .f1.c.$tmp { global node moveNode $node(%W) [expr (%X-$curX)] [expr (%Y-$curY)] set curX %X set curY %Y } set node(.f1.c.$tmp) $new set DB($libName) $new set DBcolor(.f1.c.$tmp) $color($index) set isActive($libName) 0 set nodeX($new) $tmpx set nodeY($new) $tmpy set edgeFirst($new) {} set edgeSecond($new) {} set DBname(.f1.c.$tmp) $libName set DBNodeName($new) $libName lappend allDBs $libName if {$tmpy == $yy} { set yy [expr $yy + 20] } } elseif [regexp {field: +([^ ,]+), type: +(index|num|real|id)} \ $line match fieldName ] { lappend fields($libName) $fieldName } elseif [regexp {link: +([^ ]+) +([^ ]+)} $line \ match libName1 libName2] { mkEdge $DB($libName1) $DB($libName2) } } } proc mkNode {x y} { global nodeX nodeY edgeFirst edgeSecond isActive set new [.f1.c create text [expr $x] [expr $y] -text "hallo" \ -fill black -tags node ] set isActive($new) 0 set nodeX($new) $x set nodeY($new) $y set edgeFirst($new) {} set edgeSecond($new) {} } proc mkEdge {first second} { global nodeX nodeY edgeFirst edgeSecond set edge [.f1.c create line $nodeX($first) $nodeY($first) \ $nodeX($second) $nodeY($second) \ -width 1 -fill blue1] .f1.c lower $edge lappend edgeFirst($first) $edge lappend edgeSecond($second) $edge } focus .f1.c proc moveNode {node xDist yDist} { global isMustScaleCoord nodeX nodeY edgeFirst edgeSecond gvar .f1.c move $node $xDist $yDist incr nodeX($node) $xDist incr nodeY($node) $yDist if {$isMustScaleCoord == 1} { set isMustScaleCoord 0 foreach node [.f1.c find withtag node] { set nodeX($node) [expr int ($nodeX($node) * \ $gvar(SCALE) / $gvar(OLDSCALE))] set nodeY($node) [expr int ($nodeY($node) * \ $gvar(SCALE) / $gvar(OLDSCALE))] } set gvar(OLDSCALE) $gvar(SCALE) } foreach edge $edgeFirst($node) { .f1.c coords $edge \ $nodeX($node) $nodeY($node) \ [lindex [.f1.c coords $edge] 2] \ [lindex [.f1.c coords $edge] 3] } foreach edge $edgeSecond($node) { .f1.c coords $edge [lindex [.f1.c coords $edge] 0] \ [lindex [.f1.c coords $edge] 1] \ $nodeX($node) $nodeY($node) } } var(OLDSCALE))] set nodeY($node) [expr int ($nodeY($node) * \ $gvar(SCALE) / $gvar(OLDSCALE))] } set gvar(OLDSCALE) $gvar(SCALE) } foreach edge $edgeFirst($node) { .f1.c coords $edge \ $nodeX($node) $nodeY($node) \ [lindex [.f1.c coords $edge] 2] \ [lindex [.f1.c coords $edge] 3] } foreach edge $edgeSecond($node) { .f1.c coords $edge [lindex [.f1.srs/etc/srssection # defines an 'alias' for the old srssection command nodd -s $SRSICA/srs.ic $SRSICA/srs.i exit (OLDSCALE))] set nodeY($node) [expr int ($nodeY($node) * \ $gvar(SCALE) / $gvar(OLDSCALE))] } set gvar(OLDSCALE) $gvar(SCALE) } foreach edge $edgeFirst($node) { .f1.c coords $edge \ $nodeX($node) $nodeY($node) \ [lindex [.f1.c coords $edge] 2] \ [lindex [.f1.c coords $edge] 3] } foreach edge $edgeSecond($node) { .f1.c coords $edex [.f1.srs/etc/srsupd.pl # modify by : Antoine de Daruvar # date: March 17, 1995 # # - move the logfile to /data/update/trace_job # - move the update file to /data/update/temp # - control the size of the log file (run file_restriction) # # ===================================================================== $tmp = `ps -edalf`; @proc = split ("\n", $tmp); foreach (@proc) { if (/srsbuild/ || /srscheck/ ) { exit; # some indexing job is running already } } $srsupd = "\$\SRSETC/srsupd.csh"; system ("date"); $com = "srscheck -o $srsupd;" . "$srsupd"; system ("$com"); system ("date"); exit; date/trace_job # - move the update file to /data/update/temp # - control the size of the log file (run file_restriction) # # ===================================================================== $tmp = `ps -edalf`; @proc = split ("\n", $tmp); foreach (@proc) { if (/srsbuild/ || /srscheck/ ) { exit; # some indexing job is running alresrs/etc/srsupdate echo '*** use srscheck to create the REAL srsupdate script ***' srscheck -o $srsupd;" . "$srsupd"; system ("$com"); system ("date"); exit; date/trace_job # - move the update file to /data/update/temp # - control the size of the log file (run file_restriction) # # ===================================================================== $tmp = `ps -edalf`; @proc = split ("\n", $tmp); foreach (@proc) { if (/srsbuild/ || /srscheck/ ) { exit; # some indexing jobing alresrs/etc/srsversion if [ $# = 0 ]; then echo 'name of program (without path) required' exit 1 fi if [ "$SRSEXE" = "" ]; then echo 'The SRS environment is not setup.' echo "Looking for $1 in your path instead" EXE="`which $1`" else EXE="$SRSEXE/$1" fi strings $EXE | grep '$Id' | sed 's/.*\(\$Id.* \$\)/\1/' exit ======================================== $tmp = `ps -edalf`; @proc = split ("\n", $tmp); foreach (@proc) { if (/srsbuild/ || /srscheck/ ) { exit; # some indexing jobing alresrs/icarus/ # # $RCSfile: appl.i,v $ # $Revision: 1.3 $ # $Date: 1997/03/18 13:16:24 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GENERAL_OPTS:$optGroup:[General] MULTALI_OPTS:$optGroup:['Multiple Alignment'] SLOWPAIRS_OPTS:$optGroup:['For Fast Pairwise Alignments'] FASTPAIRS_OPTS:$optGroup:['For Slow Pairwise Alignments'] CLUSTALW_APP:$application:[CLUSTALW type:multi title: 'Multiple Sequence Alignment' options:{ $AppOpt:[output type:string prompt:'name of alignment' defStr:temp] # general options $appOpt:[outFormat type:string guiType:menu group:@GENERAL_OPTS prompt:|Output format values:{ $optVal:[CLUSTAL on:y] $optVal:GDE $optVal:PHILIP $optVal:PIR } ] $appOpt:[outOrder guiType:menu group:@GENERAL_OPTS prompt:|Order of sequences in alignment values:{ $optVal:[INPUT on:y] $optVal:ALIGNED } ] $appOpt:[guideTree type:string group:@GENERAL_OPTS guiType:radio prompt:|use for the alignment guide tree values:{ $optVal:[valStr:FAST prompt:FAST on:y] $optVal:[valStr:SLOW prompt:'SLOW algorithm'] } ] # multiple alignment options $appOpt:[matrix group:@MULTALI_OPTS guiType:menu prompt:|use substitution matrix values:{ $optVal:[blosum on:y] $optVal:pam $optVal:md $optVal:id } ] $appOpt:[gapOpen group:@MULTALI_OPTS type:real prompt:'gap opening penalty' defReal:10.00 ] $appOpt:[gapExt group:@MULTALI_OPTS type:real prompt:'gap extension penalty' defReal:0.05 ] $appOpt:[endGap group:@MULTALI_OPTS type:bool prompt:'no end gap penalty' defInt:0 ] # fast pairwise alignment options $appOpt:[ktup group:@SLOWPAIRS_OPTS type:int defInt:1 prompt:'word size (ktup)' ] $appOpt:[topDiagsN group:@SLOWPAIRS_OPTS type:int prompt:'number of best diagonals' ] $appOpt:[diagsWindow group:@SLOWPAIRS_OPTS type:int prompt:'window around best diagonals' ] $appOpt:[pairgap group:@SLOWPAIRS_OPTS type:real prompt:'gap penalty' ] $appOpt:[useScore group:@SLOWPAIRS_OPTS type:string guiType:menu prompt:'use score' values:{ $optVal:[percent on:y] $optVal:[absolute] } ] # slow pairwise alignment options $appOpt:[pairMatrix group:@FASTPAIRS_OPTS guiType:menu prompt:'use substitution matrix' values:{ $optVal:[blosum on:y] $optVal:pam $optVal:md $optVal:id } ] $appOpt:[pairGapOpen group:@FASTPAIRS_OPTS type:real prompt:'gap opening penalty' ] $appOpt:[pairGapExt group:@FASTPAIRS_OPTS type:real prompt:'gap extension penalty' ] } command:@{ $opt.command= |/u/usr/local/bin/clustalw tmp.seq \ |($Alt:[($opt.outFormat!=CLUSTAL) t:"/output=($opt.outFormat) "])\ |/outorder=($opt.outOrder) \ |($Alt:[$opt.guideTree==FAST t:"/quicktree "])\ |/matrix=($opt.matrix) \ |/gapopen=($opt.gapOpen) \ |/gapext=($opt.gapExt) \ |($Alt:[$opt.endGap t:'/endgaps '])\ | }@ launch:@{ $System:[scriptName:"($Env:SRSWWWTMP)/($userId)/clustalw.sh" out:stdout error:stdout script: |#!/bin/csh |# |# clustalw script |# |cd ($Env:SRSWWWTMP)/($userId); ($opt.command)\ |echo '\\!Alignment: ($opt.output)' > ($opt.output).aln |grep '^\\!' tmp.seq >> ($opt.output).aln |cat tmp.aln >> ($opt.output).aln |rm tmp.aln |echo '' |(source ($Env:SRSETC)/prep_srs;\ |\$SRSEXE/srsbuild clustalw;\ |\$SRSEXE/srsbuild -c clustalw;\ |\$SRSEXE/srsbuild -l clustalw ) >& tmp.log |unsetenv REQUEST_METHOD # otherwise wgetz does not read command line |($Env:SRSEXE)/wgetz -id ($userId) -e -mime none \ | '[clustalw-id:($opt.output)]' |exit ] }@ ] BLAST_APP:$application:[BLAST type:{single search} title:'Sequence Similarity Search' options:{ $AppOpt:[search type:string guiType:menu prompt:'Search' values:{ $OptVal:['SWISS-PROT' valStr:swiss] $OptVal:['PIR' valStr:pir] } ] $AppOpt:[output type:string prompt:'name of search'] # output options $AppOpt:[inclGenInfo group:@OUTPUT_OPTS type:bool defInt:1 prompt:'include general information' ] $AppOpt:[b group:@OUTPUT_OPTS type:int defInt:200 prompt:'no. of high scoring alignments' ] $AppOpt:[hspMax group:@OUTPUT_OPTS type:int defInt:100 prompt:'limit number of HSPS reported' ] $AppOpt:[v group:@OUTPUT_OPTS type:int defInt:500 prompt:'no. of entries with one line descriptions' ] $AppOpt:[echoFilter group:@OUTPUT_OPTS type:bool defInt:1 prompt:'filtered query sequence' ] $AppOpt:[prune group:@OUTPUT_OPTS type:bool defInt:1 prompt:'include HSPs not statistically significant' ] $AppOpt:[filter group:@OUTPUT_OPTS type:string guiType:multi type:bool prompt:'filter' values:{ $OptVal:[xnu prompt:'short repeat'] $OptVal:[seg prompt:'low complexity sequences'] } ] $AppOpt:[sort group:@OUTPUT_OPTS type:bool guiType:multi type:bool prompt:'sort by' values:{ $OptVal:[sortByValue prompt:pValue] $OptVal:[sortByCount prompt:count] $OptVal:[sortByHighScore prompt:'high score'] $OptVal:[sortByTotalScore prompt:'total score'] } ] # search parameters $AppOpt:[matrix group:@SEARCH_OPTS type:string guiType:menu prompt:'scoring matrix' values:{ $OptVal:[blosum62 on:y] $OptVal:[dayhoff] $OptVal:[gonnet] $OptVal:[identity] $OptVal:[pam30] $OptVal:[pam60] $OptVal:[pam90] $OptVal:[pam120] $OptVal:[pam150] $OptVal:[pam180] $OptVal:[pam210] $OptVal:[pam240] } ] $AppOpt:[e group:@SEARCH_OPTS type:real guiType:menu prompt: 'The E value' values:{ $OptVal:[valReal:0.0001] $OptVal:[valReal:1] $OptVal:[valReal:10 on:y] $OptVal:[valReal:100] $OptVal:[valReal:1000] } ] $AppOpt:[e2 group:@SEARCH_OPTS type:int prompt:'exp. number of HSPs (E2)' ] $AppOpt:[s2 group:@SEARCH_OPTS type:real prompt:'cutoff score (s2)' ] $AppOpt:[s group:@SEARCH_OPTS type:real prompt:'exp. score for MSP' ] $AppOpt:[w group:@SEARCH_OPTS type:int guiType:menu prompt:'word length' values:{ $OptVal:[valInt:3 on:y] $OptVal:[valInt:4] $OptVal:[valInt:5] $OptVal:[valInt:6] } ] # other options $AppOpt:[sump group:@OTHER_OPTS type:string guiType:radio prompt:'use' values:{ $OptVal:[valStr:'sump' on:y prompt:'sum statistics'] $OptVal:[valStr:'poissonp' prompt:'poisson statistics'] } ] $AppOpt:[consistency group:@OTHER_OPTS type:bool guiType:multi prompt:'' values:{ $OptVal:[consistency valInt:1 prompt:consistency] $OptVal:[span2 prompt:span2] $OptVal:[span1 prompt:span1] $OptVal:[span prompt:span] } ] } command: @{ $opt.command= |/usr/local/bin/blastp ($opt.search) tmp.seq\ | -matrix ($opt.matrix)\ |($Alt:[$opt.e t:" E=($opt.e)"])\ |($Alt:[$opt.e2 t:" E2=($opt.e2)"])\ |($Alt:[$opt.s2 t:" S2=($opt.s2)"])\ |($Alt:[$opt.s t:" S=($opt.s)"])\ |($Alt:[$opt.h t:" H=($opt.h)"])\ |($Alt:[$opt.v t:" V=($opt.v)"])\ |($Alt:[$opt.w t:" W=($opt.w)"])\ |($Alt:[$opt.span1 t:' -span1'])\ |($Alt:[$opt.span2 t:' -span2'])\ |($Alt:[$opt.span t:' -span'])\ |($Alt:[$opt.sump t:' -sump'])\ |($Alt:[$opt.poissonp t:' -poissonp'])\ |($Alt:[$opt.prune t:' -prune'])\ |($Alt:[$opt.consistency t:' -consistency'])\ |($Alt:[$opt.hspMax t:" -hspmax ($opt.hspMax)"])\ |($Alt:[$opt.sortByPvalue t:' -sort_by_pvalue'])\ |($Alt:[$opt.sortByPvalue t:' -sort_by_count'])\ |($Alt:[$opt.sortByHighScore t:' -sort_by_highscore'])\ |($Alt:[$opt.sortByTotalScore t:' -sort_by_totalscore'])\ | > tmp.blast\ }@ launch:@{ $System:[scriptName:"($Env:SRSWWWTMP)/($userId)/blast.csh" out:stdout error:stdout script: |#!/bin/csh -f |# |# blast command file |# |cd ($Env:SRSWWWTMP)/($userId) |cp /usr/local/bin/.ncbirc . |rsh columba '\ |setenv BLASTDB /data/research/db; \ |setenv BLASTMAT /u/usr/local/blast/matrix; \ |cd ($Env:SRSWWWTMP)/($userId); ($opt.command)' |# |# |sed -n '/^>/q;p' tmp.blast |# Create SRS indices for blast |# |(source ($Env:SRSETC)/prep_srs;\ |cd \$SRSWWWTMP/($userId);\ |\$SRSEXE/srsbuild blast;\ |\$SRSEXE/srsbuild -c blast;\ |\$SRSEXE/srsbuild -l blast)>& /dev/null |exit ] }@ ] FASTA_APP:$application:[FASTA type:{single search} title:"Sequence Similarity Search" options:{ $AppOpt:[search type:string guiType:menu prompt:'Search' values:{ $OptVal:['SWISS-PROT' valStr:'/data/research/db/swiss'] $OptVal:['PIR' valStr:pir] } ] $AppOpt:[output type:string prompt:'name of search'] # search options $AppOpt:[matrix group:@SEARCH_OPTS type:string guiType:menu prompt:'scoring matrix' values:{ $OptVal:[blosum50] $OptVal:[pam50] } ] $AppOpt:[ktup group:@SEARCH_OPTS type:int guiType:menu prompt:'ktup (word size)' values:{ $OptVal:[valInt:1 on:y] $OptVal:[valInt:2] } ] $AppOpt:[gapInit group:@SEARCH_OPTS type:int defInt:-12 prompt:'penalty for first resudue in gap' ] $AppOpt:[gapExtend group:@SEARCH_OPTS type:int defInt:-2 prompt:'penalty for additional residues in gap' ] # Output options $AppOpt:[ranking group:@OUTPUT_OPTS type:string guiType:radio prompt:'' values:{ $OptVal:[valStr:z prompt:'rank with Z-score' on:y] $OptVal:[valStr:raw prompt:'raw score'] } ] $AppOpt:[nScores group:@OUTPUT_OPTS type:int defInt:200 prompt:'number of top scores in list' ] $AppOpt:[nAlign group:@OUTPUT_OPTS type:int defInt:200 prompt:'number of alignments' ] } command:@{ $opt.command= |/usr/local/bin/fasta3_t -Q -t4\ |($Alt:[$opt.matrix==PAM250 t:"-s 250 "]) \ |-f ($opt.gapInit) \ |-g ($opt.gapExtend) \ |($Alt:[$opt.ranking==raw t:"-z "])\ |-b ($opt.nAlign) \ |-d ($opt.nScores) \ |tmp.seq \ |($opt.search) \ |($opt.ktup) \ |> tmp.fasta\ }@ launch:@{ $System:[scriptName:"($Env:SRSWWWTMP)/($userId)/fasta.csh" out:stdout error:stdout script: |#!/bin/csh |# |# fasta script |# |cd ($Env:SRSWWWTMP)/($userId) |rsh columba '\ |cd ($Env:SRSWWWTMP)/($userId); ($opt.command)' |# print hit list to user |sed -n '/>>/q;p' tmp.fasta |# Create SRS indices for fasta |(source ($Env:SRSETC)/prep_srs;\ |cd \$SRSWWWTMP/($userId);\ |srsbuild fasta;\ |srsbuild -c fasta;\ |srsbuild -l fasta) >& /dev/null |exit ] }@ ] SW_APP:$application:[SW type:{search single} title:'(Smith & Waterman) Search on the Bioccelerator' inSeqFormat:gcg options:{ $AppOpt:[search type:string guiType:menu prompt:'Search' values:{ $OptVal:['SWISS-PROT' valStr:'swiss:*'] $OptVal:['PIR' valStr:'pir:*'] } ] $AppOpt:[output type:string prompt:'name of search'] # Search Parameters $AppOpt:[gapInit group:@SEARCH_OPTS type:real defReal:10.0 prompt:'gap creation penalty' ] $AppOpt:[gapExt group:@SEARCH_OPTS type:real defReal:0.5 prompt:'gap extension penalty' ] $AppOpt:[doNorm group:@SEARCH_OPTS type:string guiType:menu prompt:|adjust score for sequence length using method values:{ $OptVal:[log] $OptVal:[gcg] $OptVal:[akc] } ] $AppOpt:[minSeq group:@SEARCH_OPTS type:int defInt:50 prompt:|minimum length sequence to examine in search ] $AppOpt:[doAverage group:@SEARCH_OPTS type:bool prompt:|adjust quality scores for sequence composition ] # Output Options $AppOpt:[nAlign group:@OUTPUT_OPTS type:int defInt:100 prompt:|alignments done after search ] $AppOpt:[list group:@OUTPUT_OPTS type:int defInt:100 prompt:|no. of sequences reported in the output list ] $AppOpt:[minList group:@OUTPUT_OPTS type:real defReal:2.5 prompt:|lowest Z-score to report in output list ] $AppOpt:[minQual group:@OUTPUT_OPTS type:real defReal:1 prompt:|minimum quality score to report ] $AppOpt:[doPlot group:@OUTPUT_OPTS type:bool defInt:1 prompt:|create histogram of score distribution ] } command:@{ $opt.command= |/data/gcg8/Bic/exe/bic_sw \ |-in1=tmp.seq \ |-in2='($opt.search)' \ |-gap=($opt.gapInit) \ # |-pamfile=($opt.matrix) \ |-len=($opt.gapExt) \ |-align=($opt.nAlign) \ |-list=($opt.list) \ |-minlist=($opt.minList) \ |-minseq=($opt.minSeq) \ |-minqual=($opt.minQual) \ |($Alt:[$opt.doNorm t:" -norm=($opt.norm)"])\ |($Alt:[$opt.doAverage t:" -ave"]) \ |($Alt:[$opt.doPlot t:" -plot"]) \ |-out=tmp.sw -mon -def\ }@ launch:@{ $System:[scriptName:"($Env:SRSWWWTMP)/($userId)/sw.csh" out:stdout error:stdout script: |#!/bin/csh -f |# |# Smith/Waterman search with Bioaccelerator |# |source /data/gcg8/gcgstartup |source /homes/srswww/genetics |cd ($Env:SRSWWWTMP)/($userId); ($opt.command) |# print list of entries |cd ($Env:SRSWWWTMP)/($userId);sed -n '/^ to:/q;p' tmp.sw |#create SRS indices for SW |(source ($Env:SRSETC)/prep_srs;\ |cd \$SRSWWWTMP/($userId);\ |srsbuild sw;\ |srsbuild -c sw;\ |srsbuild -l sw ) >& /dev/null |exit ] }@ ] SEARCH_OPTS:$optGroup:['Search Parameters'] OUTPUT_OPTS:$optGroup:['Output Options'] OTHER_OPTS:$optGroup:['Others'] |source /homes/srswww/genetics |cd ($Env:SRSWWWTMP)/($userId); ($opt.command) |# print list of entries |cd ($Env:SRSWWWTMP)/($userId);sed -n '/^ to:/q;p' tmp.sw |#create SRS indices for SW |(source ($Env:SRSETC)/prep_srs;\ |cd \$SRSWWWTMP/($userId);\ |srsbuild sw;\ |srsbuild -c sw;\ srs/icarus/db/blast.i # $RCSfile: blast.i,v $ # $Revision: 1.4 $ # $Date: 1997/03/03 18:33:46 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ BLAST_DB:$library:[BLAST group:@APPLICATION_LIBS comment:"" format:@BLAST_FORMAT maxNameLen:40 ifiles:{"blast.i" "blast.is"} type:user files:{ $file:tmp } ] BLAST_FORMAT:$libformat:[fileType:@BLAST_FILE syntax:@BLAST_SYNTAX fields:{ $field:[@DF_ID code:title index:id indexToken:id] $field:[@DF_TopMatch code:tmatch tableToken:t_tmatch tableFormat:left] $field:[@DF_TopScore code:tscore1 index:int indexToken:score tableToken:score tableFormat:right] $field:[@DF_PercIdent code:tscore2 index:int indexToken:percIdent tableToken:percIdent tableFormat:right] $field:[@DF_QueryBeg code:tmatch index:int indexToken:queryBeg tableToken:queryBeg tableFormat:right] $field:[@DF_QueryEnd code:tmatch index:int indexToken:queryEnd tableToken:queryEnd tableFormat:right] $field:[@DF_MatchLen code:tmatch index:int indexToken:matchLen tableToken:matchLen tableFormat:right] $field:[@DF_LINK index:link code:link indexToken:link] } ] DF_TopMatch:$srsfield:[TopMatch short:tma] DF_TopScore:$srsfield:[TopScore short:tsc] DF_PercIdent:$srsfield:[PercentIdentity short:pid] DF_QueryBeg:$srsfield:[QueryMatchBeginPos short:qbp] DF_QueryEnd:$srsfield:[QueryMatchEndPos short:qep] DF_MatchLen:$srsfield:[MatchLength short:mtl] BLAST_SYNTAX:$syntax:[file:"SRSDB:blast.is" ignore:" "] BLAST_FILE:$filetype:[typename:blast maxline:100] $link:[@BLAST_DB to:@?SWISSPROT_DB token:'link|swiss' toField:@DF_Accession] link code:link indexToken:link] } ] DF_TopMatch:$srsfield:[TopMatch short:tma] DF_TopScore:$srsfield:[TopScore short:tsc] DF_PercIdent:$srsfield:[PercentIdentity short:pid] DF_QueryBeg:$srsfield:[QueryMatchBeginPos short:qbp] DF_QueryEnd:$srsfield:[QueryMatchEndPos short:qep] DF_MatchLen:$srsrs/icarus/db/blast.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: blast.is,v $ # $Revision: 1.9 $ # $Date: 1997/03/03 18:33:47 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $rules={ entry: ~ {$In:[file:text] init{$count=0} $Out $count+=1 pre $skip:0} ('>' {$Not} ln)* '>' {$entryFip=$Fip $Wrt} appLn (/>/ {$Not} appLn)* ~ # data fields fields: ~ {$In:entry $Out $Skip:1} title length tscores1 tscores2 tmatch (scores1 scores2 match)* ~ title: ~ {$Wrt:title} '>' ln (/ *Length/ {$Not} ln)* ~ length: ~ {$Wrt:length} / *Length/ ln ln ~ tscores1: ~ {$Wrt:tscore1} / *Score/ ln ~ tscores2: ~ {$Wrt:tscore2} / *Identities/ ln ln ~ tmatch: ~ {$Wrt:tmatch} ('Query' ln ln ln ln)* ~ scores1: ~ {$Wrt:score1} / *Score / ln ~ scores2: ~ {$Wrt:score2} / *Identities/ ln ln ~ match: ~ {$Wrt:match} ('Query' ln ln ln ln)* ~ # indexing id: ~ {$In:[fields c:title] $Out} />([a-zA-Z]+)\\|([a-zA-Z0-9]+)/ {$Wrt:[s:"$count\_$1\_$2"]} ~ score: ~ {$In:[fields c:tscore1] $Out} /.*Score = ([0-9]+)/{$Wrt:[s:$1]} ~ percIdent:~ {$In:[fields c:tscore2] $Out} /.*Identities[^a-z]*\\(([0-9]+)%/ {$Wrt:[s:$1]} ~ queryBeg: ~ {$In:[fields c:tmatch] $Out} /Query: *([0-9]+)/ {$b=$1 $Wrt:[s:$1]} ~ queryEnd: ~ {$In:[fields c:tmatch] $Out} /.*Query: *[0-9]+[^\n0-9]*([0-9]+)/ {$e=$1 $Wrt:[s:$1]} ~ matchLen: ~ {$In:entry $Out pre{$Request:queryEnd $Request:queryBeg}} x{$Wrt:[s:($e-$b+1)]} ~ link: ~ {$Out $In:[fields c:title]} '>' (/(sp|swiss)\\|/ name {$Wrt:swiss})? ~ # table display t_tmatch: ~ {$Out $In:[fields c:tmatch]} /.+/ {$Wrt:[s:| ] } ~ # other appLn: ~ /[^\n]*\n/ {$App} ~ ln: ~ /[^\n]*\n/ ~ name: ~ /[a-zA-Z][a-zA-Z0-9]+/~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/u1/srs/srs5/tmp/4kuFL163SPJ/tmp.blast'] while:$JobHasInput:$job { $JobTokens:[$job name:fields print:1] # $JobTokens:[$job name:so print:1] $JobNext:$job $print:"-------->entry\n" } } 0>\ |$Ct ] } ~ # other apsrs/icarus/db/blocks.i # Description: icarus/srs structure description for BLOCKS (9.0) # Author: Martin Hilbers # Date: 3-9-1996 # Note: The accession and id fields are crossed - the ID in BLOCKS is # not unique, the accession number is. SRSWWW however uses the # The ID to retrieve sequences. So the accession number is used # as ID. The Shortaccession number (Accession number without # the [A-Z] at the end is used for links from prints. # BLOCKS_DB:$library:[BLOCKS group:@SEQRELATED_LIBS format:@BLOCKS_FORMAT maxNameLen:30 ifiles:{"blocks.i" "blocks.is"} files:{ $file:blocks } ] BLOCKS_FORMAT:$libformat:[fileType:@DAT_FILE syntax:@BLOCKS_SYNTAX fields:{ $field:[@DF_ALL] $field:[@DF_ID code:acc index:id indexToken:acc] $field:[@DF_Accession code:id index:str indexToken:id] $field:[@DF_Shortaccession code:tacc index:str indexToken:tacc] $field:[@DF_Description code:def index:str indexToken:def] $field:[@DF_Motif code:mot index:str indexToken:mot] $field:[@DF_Width code:wid index:int indexToken:wid] $field:[@DF_Sequences code:seqs index:int indexToken:seqs] $field:[@DF_Rawscore code:raw index:int indexToken:raw] $field:[@DF_Medianscore code:med index:int indexToken:med] $field:[@DF_LINK code:link] } ] BLOCKS_SYNTAX:$syntax:[file:"SRSDB:blocks.is" ignore:" "] DF_Shortaccession:$srsfield:[Shortaccession short:sac] DF_Motif:$srsfield:[Motif short:mot] DF_Width:$srsfield:[Width short:wid] DF_Sequences:$srsfield:[Sequences short:nsq] DF_Rawscore:$srsfield:[Rawscore short:raw] DF_Medianscore:$srsfield:[Medianscore short:med] $link:[@BLOCKS_DB to:@?SWISSPROT_DB token:'link|swiss' toField:@DF_ID] raw] $field:[@DF_Medianscore code:med index:int indexToken:med] $field:[@DF_LINK code:link] } ] BLOCKS_SYNTAX:$syntax:[file:"SRSDB:blocks.is" ignore:" "] DF_Shortaccession:$srsfield:[Shortaccession short:sac] DF_Motif:$srsfield:[Motif short:mot] DF_Width:$srsfield:[Width shosrs/icarus/db/blocks.is # # File: blocks.is # Description: icarus syntax file for BLOCKS # Author: Martin Hilbers # Date: 3-9-1996 # Note: # $rules={ # entry: ~ {$Out:entry pre{$Skip:0}} entry: ~ { $In:[file:text] $Out:entry pre{$Skip:0}} ('ID' {$Not} ln)* ('ID ' {$entryFip=$Fip $Wrt} ln {$App} ) ('//' {$Not} ln {$App})* ('//' {$App} ln {$App}) ~ # fields fields: ~ {$In:entry $Out} f_id f_acc f_def f_bl f_links* ~ f_id: ~ {$Wrt:id} 'ID ' ln ~ f_acc: ~ {$Wrt:acc} 'AC ' ln ~ f_def: ~ {$Wrt:def} 'DE ' ln ~ f_bl: ~ {$Wrt:bl} 'BL ' ln ~ f_links: ~ {$Wrt:link} ln ~ # indexing id: ~ {$In:[fields c:id] $Out} 'ID ' /[A-Z0-9_]+/ {$Wrt} ~ acc: ~ {$In:[fields c:acc] $Out} 'AC ' /[A-Z0-9_]+/ {$Wrt} ~ tacc: ~ {$In:[fields c:acc] $Out} 'AC ' /BL[0-9]+/ {$Wrt} ~ def: ~ {$In:[fields c:def] $Out} 'DE ' ( /[A-Za-z0-9_]+/ {$Wrt} | /[^A-Za-z0-9_]+/ )* ~ motif: ~ {$In:[fields c:bl] pre{$Skip:1} $Out:motif} 'BL ' /[A-Z]+/ {$Wrt:mot} 'motif; width=' /[0-9]+/ {$Wrt:wid} '; seqs=' /[0-9]+/ {$Wrt:seqs} '; 99.5%=' /[0-9]+/ {$Wrt:raw} '; strength=' /[0-9]+/ {$Wrt:med} ~ mot: ~{$In:[motif c:mot] $Out} /.+/ {$Wrt} ~ wid: ~{$In:[motif c:wid] $Out} /.+/ {$Wrt} ~ seqs: ~{$In:[motif c:seqs] $Out} /.+/ {$Wrt}~ raw: ~{$In:[motif c:raw] $Out} /.+/ {$Wrt} ~ med: ~{$In:[motif c:med] $Out} /.+/ {$Wrt} ~ link: ~ {$In:[fields c:link] pre{$Skip:1} $Out} (/[A-Z0-9_]+/ {$Wrt:swiss}|ln) ~ # html display hl_links:~ {$In:[fields c:link t:hl] pre{$Skip:1}} (name {$Rep:{$ParStr:swissIR $Ct $Ct}} ln | ln) * ~ # other name: ~ /[a-zA-Z0-9_]+/ ~ ln: ~ /[^\n]*\n/ ~ } Out} /.+/ {$Wrt} ~ seqs: ~{$In:[motif c:seqs] $Out} /.+/ {$Wrt}~ raw: srs/icarus/db/btkbase.i # $RCSfile: btkbase.i,v $ # $Revision: 1.2 $ # $Date: 1997/03/03 18:33:48 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ BTKBASE_DB:$library:[BTKBASE group:@MUTATION_LIBS format:@BTKBASE_FORMAT maxNameLen:30 ifiles:{"btkbase.i" "btkbase.is"} files:{ $file:btkbase } ] BTKBASE_FORMAT:$libformat:[fileType:@TXT_FILE syntax:@BTKBASE_SYNTAX tableFormat:left fields:{ $field:[@DF_ID code:id index:id indexToken:pin tableToken:pin] $field:[@DF_Code code:code index:str indexToken:code tableToken:code] # $field:[@DF_NuclPos code:nucl index:int indexToken:nucPos] $field:[@DF_NuclChange code:feature index:str indexToken:nuclChange tableToken:nuclChange] $field:[@DF_DnaChangePos code:feature index:int indexToken:dnaPos tableToken:dnaPos tableFormat:right] $field:[@DF_TranslEffect code:feature index:str indexToken:translEff tableToken:translEff] $field:[@DF_AaChange code:feature index:str indexToken:aaChange tableToken:aaChange] $field:[@DF_ProtChangePos code:feature index:int indexToken:protPos tableToken:protPos tableFormat:right] $field:[@DF_ProteinDomain code:dom index:str indexToken:domain tableToken:domain] } ] BTKBASE_SYNTAX:$syntax:[file:"SRSDB:btkbase.is" ignore:" "] DF_Code:$srsfield:[Code short:cod] DF_NuclPos:$srsfield:[NucleotidePosition short:nup] DF_ProteinDomain:$srsfield:[ProteinDomain short:dom] :[@DF_AaChange code:feature index:str indexToken:aaChange tableToken:aaChange] $field:[@DF_ProtChangePos code:feature index:int indexToken:protPos tableToken:protPos tableFormat:right] $field:[@DF_ProteinDomain code:dom index:str indexToken:domain tableToken:domain] } ] BTKBASE_SYNTAX:$syntax:[file:"SRSDB:btkbase.is" ignore:" "] DF_Code:$srsfield:[Code short:cod] DF_NuclPos:$srsfield:[NucleotidePosition short:nup] DF_ProteinDomain:$srsfieldsrs/icarus/db/btkbase.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: btkbase.is,v $ # $Revision: 1.3 $ # $Date: 1997/03/03 18:33:48 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $fn={ 'ID':id 'Symptoms':symptoms 'Original code':code 'Sex':sex 'Accession':acc 'Age':age 'Description':des 'Relative':relative 'Date':date 'Ethnic origin':ethnicOrig 'RefNumber':refNo 'Family history':famHist 'RefCrossRef':refXRef 'IgA':iga 'RefAuthors':refAut 'IgG':igg 'Refauthors':refAut 'IgG1':igg1 'RefAuthros':refAut 'IgG2':igg2 'RefTitle':refTtl 'IgG3':igg3 'RefLoc':refLoc 'IgG4':igg4 'Feature':feature 'IgM':igm 'mRNA level':mrnaLevel 'B cells':bcells 'Protein level':protLevel 'CD19':cd19 'Protein struct':protStruct 'CD20':cd20 } $rules={ entry: ~ {$In:[file:text] $Out pre $Skip:0} ('ID' {$Not} ln)* ('ID' {$Wrt $entryFip=$Fip} ln {$App} ('ID' {$Not} ln {$App})+)? ~ # fields fields: ~ {$In:entry $Out $Skip:1} id f_code? acc des date (refNo refXRef? refAut? refTtl? refLoc?)* feature? mrnaLevel? protLevel? protStruct? symptoms? sex? age? relative? famhist? iga? igg? igg1? igg2? igg3? igg4? igm? bcells? cd19? cd20? ~ id: ~ {$Wrt:id} ('ID' ln)+ ~ f_code: ~ {$Wrt:code} ('Original code' ln)+ ~ acc: ~ {$Wrt:acc} ('Accession' ln)+ ~ des: ~ {$Wrt:des} ('Description' ln)+ ~ date: ~ {$Wrt:date} ('Date' ln)+ ~ refNo: ~ {$Wrt:refNo} ('RefNumber' ln)+ ~ refXRef: ~ {$Wrt:refXRef} ('RefCrossRef' ln)+ ~ refAut: ~ {$Wrt:refAut} (/RefAuthors|Refauthors|RefAuthros/ ln)+ ~ refTtl: ~ {$Wrt:refTtl} ('RefTitle' ln)+ ~ refLoc: ~ {$Wrt:refLoc} ('RefLoc' ln)+ ~ feature: ~ {$Wrt:feature} ('Feature' ln)+ ~ mrnaLevel: ~ {$Wrt:mrnaLevel} ('mRNA level' ln)+ ~ protLevel: ~ {$Wrt:protLevel} ('Protein level' ln)+ ~ protStruct: ~ {$Wrt:protStruct} ('Protein struct' ln)+ ~ symptoms: ~ {$Wrt:symptoms} ('Symptoms' ln)+ ~ sex: ~ {$Wrt:sex} ('Sex' ln)+ ~ age: ~ {$Wrt:age} ('Age' ln)+ ~ relative: ~ {$Wrt:relative} ('Relative' ln)+ ~ ethnicOrig: ~ {$Wrt:ethnicOrig} ('Ethnic origin' ln)+ ~ famhist: ~ {$Wrt:famhist} ('Family history' ln)+ ~ iga: ~ {$Wrt:iga} ('IgA' ln)+ ~ igg: ~ {$Wrt:igg} ('IgG' ln)+ ~ igg1: ~ {$Wrt:igg1} ('IgG1' ln)+ ~ igg2: ~ {$Wrt:igg2} ('IgG2' ln)+ ~ igg3: ~ {$Wrt:igg3} ('IgG3' ln)+ ~ igg4: ~ {$Wrt:igg4} ('IgG4' ln)+ ~ igm: ~ {$Wrt:igm} ('IgM' ln)+ ~ bcells: ~ {$Wrt:bcells} ('B cells' ln)+ ~ cd19: ~ {$Wrt:cd19} ('CD19' ln)+ ~ cd20: ~ {$Wrt:cd20} ('CD20' ln)+ ~ # indexing pin: ~ {$In:[fields c:id] $Out} tag /[^;]+/ {$Wrt} ~ code: ~ {$In:[fields c:code] $Out} tag /[^\n ]+/ {$Wrt} ~ nuclChange: ~ {$In:[fields c:feature] $Out} /.*\/change: *([a-z]) -> ([a-z])/ {$Wrt:[s:"$1>$2"]} ~ aaChange: ~ {$In:[fields c:feature] $Out} /.*aa_change: *([A-Z]) -> ([A-Z])/ {$Wrt:[s:"$1>$2"]} ~ domain: ~ {$In:[fields c:feature] $Out} /.*\/domain: *([A-Z0-9'_-]+)/ {$Wrt:[s:$1]} ~ translEff: ~ {$In:[fields c:feature] $Out} /.*translation_effect: *([a-zA-Z0-9'_-]+)/ {$Wrt:[s:$1]} ~ dnaPos: ~ {$In:[fields c:feature] $Out} /.*EMBL[^\n]+ ([0-9]+)\n/ {$Wrt:[s:$1]} ~ protPos: ~ {$In:[fields c:feature] $Out} /.*SWISS-PROT[^\n]+ ([0-9]+)\n/ {$Wrt:[s:$1]} ~ # html t_feature: ~ {$In:[fields c:feature t:html]} (/[^\/\n]+/ ('/' (emblRef | swissRef)?)? ln)+ ~ emblRef: ~ 'EMBL:' name {$Rep:{$ParStr:emblR $Ct $Ct}} ~ swissRef: ~ 'SWISS-PROT;' name {$Rep:{$ParStr:swissR $Ct $Ct}} ~ # others ln: ~ /[^\n]*\n/ ~ tag: ~ /./ {$Len:15} ~ name: ~ /[A-Za-z][a-zA-Z0-9_]+/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/opt/srs/data/mutdb/btkbase/btkbase.txt'] while:$JobHasInput:$job { $JobTokens:[$job name:pin print:1] $JobTokens:[$job name:nuclChange print:1] $JobTokens:[$job name:aaChange print:1] $JobNext:$job $print:"-------->entry\n" } } T;' name {$Rep:{$ParStr:swissR $Ct $Ct}} ~ # others ln: ~ /[^\n]*\n/ ~ tag: ~ /./ {$Len:15} ~ name: ~ /[A-Za-z][a-zA-Z0-9_]+/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/opt/srs/data/mutdb/btkbase/btkbase.txt'] while:$JobHasInput:$job { $JobTokens:[$jobsrs/icarus/db/btkbase.it description: |X-linked agammaglobulinemia (XLA) is a hereditary immunodeficiency caused |by mutations in the gene coding for Bruton's agammaglobulinemia tyrosine |kinase (BTK). XLA patients have decreased number of mature B cells in |their peripheral blood and show a lack of all immunoglobulin isotypes |causing susceptibility to severe bacterial infections. The 37.5 kb gene |contains 19 exons, 18 of which code for a 77 kDa protein. BTK is expressed |in all hematopoietic lineages except for T lymphocytes and plasma cells. |

|To coordinate BTK mutation analysis, an international study group was |established in 1994. BTK mutation data, both published and directly |submitted information, are collected into the BTKbase. This database |contains information about the mutations and XLA patients including |immunoglobulin levels, B cell numbers, age of diagnosis, symptoms, |mRNA and protein data and structural consequences. The study group gives |for each patient an individual patient identity number (PIN) and a |running accession number. |

|The PIN consists of the type of mutation and a running number indicating |mutations affecting the same amino acid or the same non-coding region. |The PIN is given as soon as a mutation is available to the study group. |

|Scientists are encouraged to contact the study group before |publishing their |mutation data to get the accession numbers and PINs. Data can be kept |confidential until published. literature: |

    |
  1. Vihinen, M., Cooper, M. D., de Saint Basile, G., Fischer, A., Good, |R. A., Hendriks, R. W., Kinnon, C., Kwan, S.-P., Litman, G. W., |Notarangelo, L. D., Ochs, H. D., Rosen, F. S., Vetrie, D., Webster, |A. D. B., Zegers, B. J. M., and Smith, C. I. E., BTKbase: a database of |XLA causing mutations, Immunol. Today 16:460-465 (1995). | |
  2. Vihinen, M., Iwata, T., Kinnon, C., Kwan, S.-P., Ochs, H. D., |Vorechovsky, I, and Smith, C. I. E., BTKbase, mutation database for |X-linked agammaglobulinemia, Nucleic Acids Res. 24:160-165 (1996). |
# address: contact: |
|Mauno Vihinen
|Department of Biosciences
|Division of Biochemistry
|University of Helsinki
|FIN-00014 Helsinki, FINLAND
|

|

|Heikki Lehvaslaiho
|CSC Scientific Computing
|P.O.BOX 405
|Tietotie 6
|02101 Espoo, FINLAND
|

|

|C. I. Edvard Smith
|Center for BioTechnology
|Department of Bioscience at NOVUM
|Karolinska Institute
|S-141 57 Huddinge
|Sweden
|
www: |\ |http://www.helsinki.fi/science/signal/btkbase.html address: |Department of Biosciences
|Division of Biochemistry
|University of Helsinki
|FIN-00014 Helsinki
|Finland
telephone: '+358-0-708 59081' telefax: '+358-0-708 59068' email: 'Mauno.Vihinen@Helsinki.Fi' fields:{ Identifier: |This name is the primary means of identifying the sequence within a |given release. The name indicates the type of mutation using the PIN |convention. |

|PINs are formed as follows. Point mutations in the coding region are |numbered according to the affected amino acids. The complete PIN |contains 1) the single letter amino acid code of the wild type |residue, 2) the number of the amino acid, 3) the single letter amino |acid code of the mutated residue, 4) running number for mutations at |this site, so that eg. R525Q(1) means the first listed mutation of |arginine 525 to glutamine. Members of the same family having the very |same mutation are indicated with alphabets following the PIN, |eg. R525Q(1a) and (1b). The relatives are also cross- referenced using |database "Relative" lines (see section 3.18) with the exact |description of the relation. |

|Insertions are marked with sign "@" and deletions with "#" in front of |the mutation site. If mutation causes a stop codon it is marked with X |and the number of the codon with the newly introduced stop |codon. Thus, @V377X404(1b) means insertion at codon 377 causing |frameshift mutation leading to appearance of the stop signal at codon |404. The last number in parentheses indicates the second patient in |this family. |

| |In the rare occasion of inframe insertions or deletions the number of |added of deleted residues is indicated by denoting the number of |residues preceded by "+" or "-", respectively. @V103+7(1) describes an |addition of seven residues inframe after valine 103. |

| |The nucleotide and amino acid numbering is according to Vetrie et |al. (1993). Due to possible variations in the size of non-coding |regions requiring future renumbering, the up- and downstream and |intron PINs have only running numbers without giving the actual |mutated nucleotide(s). Intron mutations are indicated by the intron |number followed by running number of mutations in the intron. Thus, |Intron 5(7) indicates the seventh described mutation affecting intron |5. Similar notation is used for up- and downstream sequences where |either "Upstream" of "Downstream" is written before number of the |mutation. |

| |Partially characterized gene rearrangements are listed separately, so |that eg. gross deletions have PINs starting from Deletion (1). |

| |In vitro mutations are indicated by using character "&" preceeding the |actual mutation site and natural polymorphisms have "%" character |before the affected location. |

| |If a PIN has to be changed and a mutation renamed eg. due to errors in |reported information, the original PIN will not be reused. The PIN |used previously will in that case be mentioned in the line |Original code. MutationType: |Mutations come in four main types. |

|
point_mutation
change of a single nucleotide to another |
deletion
absense of one or more nucleotides |
insertion
addition of one or more nucleotides |
repeat
absense or addition of a short repeated region |e.g. dinu | TranslationEffect: |Verbal description of the effect of the nucleotide mutation |at amino acid level. aaChange: |Description of the change in the reference sequence. |Format:
  • character(s)>character(s), e.g., A>T |
  • +character(s) |
  • -character |
} } r more nucleotides |
insertion
addition of one or more nucleotides |
repeat
absense or addition of a short repeated region |e.g. dinu | TranslationEffecsrs/icarus/db/cabi.is init = * <$hb := "* "; $he := " * "; $fe := "
"; com:s2a f:IcaFunny2Ascii; arg:funny unnamed:y; return:ascii>; entry = '
' ln { // ln }; # # the fields # fields = dt cd sn jn aj cp yr vl no pp la it au aa cc ti [ab] ls de pb lp ; dt = '
' /(.+)<\/DT>/ ln; cd = '' /(.+)<\/CD>/ ln; sn = '' /(.+)<\/SN>/ ln; jn = '' /(.+)<\/JN>/ ln; aj = '' /(.+)<\/AJ>/ ln; cp = '' /(.+)<\/CP>/ ln; yr = '' /(.+)<\/YR>/ ln; vl = '' /(.+)<\/VL>/ ln; no = '' /(.+)<\/NO>/ ln; pp = '' /(.+)<\/PP>/ ln; la = '' /(.+)<\/LA>/ ln; it = '' /(.+)<\/IT>/ ln; au = '' * auLn '' * ln; aa = '' * auAddr '' * ln; cc = '' /(.+)<\/CC>/ ln; ti = '' * tiLn '' * ln; ab = '' * abLn '' * ln; ls = '' /(.+)<\/LS>/ ln; de = '' /(.+)<\/DE>/ ln; pb = '' /(.+)<\/PB>/ ln; lp = '' /(.+)<\/LP>/ ln; nr = '' /(.+)<\/NR>/ ; # # contents of fields # ln = /[^$]*$?/; auLn = { '' repLn } [/$/] ; auAddr = { '' repLn } [/$/] ; abLn = { '' repLn } [/$/] ; tiLn = { '' repLn } [/$/] ; repLn = ( '' "> | '' "> | '' | '' | '' | '' | /&[a-zA-Z0-9]+;/ | /[^$]/ ). { '' repLn } [/$/] ; auAddr = { '' repLn } [/$/] ; abLn = { '' repLn } [/$/] ; tiLn = { '' repLn } [/$/] ; repLn = ( '' ([a-zA-Z])/ {$Wrt:[s:"$1>$2"]} | /./)+ ~ aaChange: ~ {$In:[fields c:cons] $Out init $aa={Ile:I Leu:L Met:M Ala:A Val:V Ser:S Thr:T Phe:F Tyr:Y Gly:G Pro:P Trp:W Cys:C Gln:Q Asn:N Arg:R Lys:K Asp:D Glu:E His:H Stop:Stop}} (/([A-Za-z]+)->([a-zA-Z]+)/ {$Wrt:[s:"($aa.$1)>($aa.$2)"]} | /./)+ . ~ # table format t_class: ~ {$In:[fields c:class] $Out} tag /.*/ {$Wrt} ~ t_patOri: ~ {$In:[fields c:patOri] $Out} tag /.*/ {$Wrt} ~ t_lab: ~ {$In:[fields c:lab] $Out} tag /.*/ {$Wrt} ~ t_cmnt: ~ {$In:[fields c:cmnt] $Out} tag /.*/ {$Wrt} ~ # table: ~ {$In:[fields c:{cmnt patOri lab cmnt}] $Out} # tag /.*/ {$Wrt:$Itc} ~ # html h_fields: ~ { $In:[fields t:html] init $f={id: Id mut:Mutation exon:Exon cons: Consequence dom:Domain ref:Reference} } /.*/ {if:$ParInt:[isTable]==0 $Rep:"($f.$Itc)$Ct" } ~ # other stuff ln: ~ /[^\n]*\n/ ~ mut: ~ /([A-Z])([0-9]+)([A-Z*])/ {$Wrt:[s:"$2" c:pos] $Wrt:[s:"$1>$3" c:subst]} | /[A-Za-z0-9]+/ {$Wrt:subst} ~ num: ~ /[0-9]+/ ~ tag: ~ /[^:]+:/ ~ word: ~ /[a-zA-Z0-9_$]+/ {$Uniq} ~ sep: ~ /[^a-zA-Z0-9_$]+/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/opt/srs/data/mutdb/cftr/CFmutations96-1.txt'] while:$JobHasInput:$job { $JobTokens:[$job name:id print:1] $JobTokens:[$job name:aaSubst print:1] $JobNext:$job $print:"-------->entry\n" } } ] $Wrt:[s:"$1>$3" c:subst]} | srs/icarus/db/cftr.it # # $RCSfile: cftr.it,v $ # $Revision: 1.1 $ # $Date: 1996/11/05 19:54:17 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $dbInfo={ description: |Cystic Fibrosis Mutation Data Base www: |\ |http://www.genet.sickkids.on.ca/cftr/ email: |lctsui@genet.sickkids.on.ca fax: |+1 416 813 4931 contact: |Lap-Chee Tsui,
|Department of Genetics,
|The Hospital for Sick Children,
|555 University Avenue, Toronto,
|Ontario M5G 1X8, CANADA. fields:{ } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $dbInfo={ description: |Cystic Fibrosis Mutation Data Base www: |\ |http://www.genet.sickkids.on.ca/cftr/ email: |lctsui@genet.sickkids.on.ca fax: |+1 416 81srs/icarus/db/clustalw.i # $RCSfile: clustalw.i,v $ # $Revision: 1.1 $ # $Date: 1997/03/03 18:36:21 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CLUSTALW_DB:$library:[CLUSTALW group:@APPLICATION_LIBS comment:"" format:@CLUSTALW_FORMAT maxNameLen:40 ifiles:{"clustalw.i" "clustalw.is"} type:user ] CLUSTALW_FORMAT:$libformat:[fileType:@CLUSTALW_FILE syntax:@CLUSTALW_SYNTAX tableFormat:left fields:{ $field:[@DF_ID code:title index:id indexToken:id] $field:[@DF_NAlign code:seqList index:int indexToken:nali] $field:[@DF_SeqList code:seqList tableToken:t_seqList tableFormat:listing] $field:[@DF_Alignment code:ali tableToken:t_ali] } ] DF_SeqList:$srsfield:[SeqList short:sql] CLUSTALW_SYNTAX:$syntax:[file:"SRSDB:clustalw.is" ignore:" "] CLUSTALW_FILE:$filetype:[typename:aln maxline:100 singleEntry:y] $link:[@CLUSTALW_DB to:@?SWISSPROT_DB token:'link|swiss' toField:@DF_ID] ft fields:{ $field:[@DF_ID code:title index:id indexToken:id] $field:[@DF_NAlign code:seqList index:int indexToken:nali] $field:[@DF_SeqList code:seqList tableToken:t_seqList tableFormat:listing] $field:[@DF_Alignment code:ali tableToken:t_ali] } ] DF_SeqList:$srsfield:[SeqList short:sql] CLUSTALW_SYNTAX:$syntax:[file:"SRSDB:clustalw.is" ignore:" "] CLUSTALW_FILE:$filetype:[typename:aln maxline:100 singleEntry:y] $link:[@CLUSTALW_DB to:@?SWISSPROT_DB token:'link|swiss' toFiesrs/icarus/db/clustalw.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: clustalw.is,v $ # $Revision: 1.1 $ # $Date: 1997/03/03 18:36:23 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $rules={ entry: ~ {$In:[file:text] $Out pre $skip:0} ln {$Wrt $entryFip=0} (ln {$App})+ ~ # data fields fields: ~ {$In:entry $Out $Skip:1} title seqList space alignment ~ title: ~ {$Wrt:title} ln ~ seqList: ~ {$Wrt:seqList} (/!.*Length:/ ln)+ ~ space: ~ {$Wrt:space} (/[^ \n]+ *[A-Z-]+\n/ {$Not} ln)+ ~ alignment:~ {$Wrt:ali} ln+ ~ # indexing id: ~ {$In:[fields c:title] $Out} /[^:]+:/ name {$Wrt} ~ link: ~ {$In:[fields c:seqList] $Out} ('!' name {$lib=$Ct} ':' name {$Wrt:swiss} ln)+ ~ nali: ~ {$In:[fields c:seqList] $Out pre $n=0} (ln {$n+=1})+ x {$Wrt:[s:$n]} ~ # table display t_ali: ~ {$Out $In:[fields c:ali]} /.+/ {$Wrt:[s:| ] } ~ t_seqList:~ {$Out $In:[fields c:seqList]} ('!' ln {$Wrt})+ ~ # html display h_seqList:~ {$In:[fields c:seqList t:html]} ('!' name ':' name {$Rep:{$ParStr:swissidR $Ct $Ct}} ln)+ ~ # other appLn: ~ /[^\n]*\n/ {$App} ~ ln: ~ /[^\n]*\n/ ~ name: ~ /[a-zA-Z0-9][a-zA-Z0-9_]+/~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/scrap/etzold/otto.aln'] while:$JobHasInput:$job { $JobTokens:[$job name:fields print:1 task:html] $JobTokens:[$job name:id print:1] $JobTokens:[$job name:link print:1] $JobNext:$job $print:"-------->entry\n" } } ('!' name ':' name {$Rep:{$ParStr:swissidR $Ct $Ct}} ln)+ ~ # other appLn: ~ /[^\n]*\n/ {$App} ~ ln: ~ /[^\n]*\n/ ~ name: ~ /[a-zA-Z0-9][a-zA-Z0-9_]+/~ } # debugging if:$Testsrs/icarus/db/dssp.i # $RCSfile: dssp.i,v $ # $Revision: 1.5 $ # $Date: 1997/03/19 21:06:52 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DSSP_DB:$library:[DSSP group:@PROTSTRUCT_LIBS format:@DSSP_FORMAT maxNameLen:5 ifiles:{"dssp.i" "dssp.is"} ] DSSP_FORMAT:$libformat:[fileType:@DSSP_FILE syntax:@DSSP_SYNTAX fields:{ $field:[@DF_ID code:header index:id indexToken:id] $field:[@DF_Compound code:compnd index:str indexToken:comp] $field:[@DF_Source code:source index:str indexToken:src] $field:[@DF_Authors code:author index:str indexToken:authors] $field:[@DF_Histograms code:hist] $field:[@DF_Residues code:data] $field:[@DF_ResiduesN code:nums index:int indexToken:'n|resN'] $field:[@DF_ChainN code:nums index:int indexToken:'n|chainN'] $field:[@DF_SsBridgeTotN code:nums index:int indexToken:'n|ssbtot'] $field:[@DF_SsBridgeIntraN code:nums index:int indexToken:'n|ssbintra'] $field:[@DF_SsBridgeInterN code:nums index:int indexToken:'n|ssbinter'] $field:[@DF_AccSurface code:surf index:real indexToken:surf] $field:[@DF_HydBondsJN code:hb index:int indexToken:'hb|hb'] $field:[@DF_HydBondsParaP code:hb_pb index:int indexToken:'hb|hb_pb'] $field:[@DF_HydBondsAntiP code:hb_ab index:int indexToken:'hb|hb_ab'] } ] DF_Histograms: $srsfield:[Histograms short:his] DF_Residues: $srsfield:[Residues short:res] DF_ResiduesN: $srsfield:[NResiduesN short:rsn] DF_ChainN: $srsfield:[NChains short:chn] DF_SsBridgeTotN: $srsfield:[NSsBridgeTot short:ssn] DF_SsBridgeIntraN:$srsfield:[NSsBridgeIntra short:ran] DF_SsBridgeInterN:$srsfield:[NSsBridgeInter short:ern] DF_AccSurface: $srsfield:[AccSurface short:sur] DF_HydBondsJN: $srsfield:[NHydBondsJ short:hb] DF_HydBondsParaP: $srsfield:[NHBondsParaBridge short:hpb] DF_HydBondsAntiP: $srsfield:[NHBondsAntiParBridge short:hab] DSSP_SYNTAX:$syntax:[file:"SRSDB:dssp.is" ignore:" "] DSSP_FILE:$FileType:[typename:'dssp' singleEntry:y maxline:500 saveName:file saveNameLength:20] $link:[@DSSP_DB to:@?PDB_DB fromField:@DF_ID toField:@DF_ID] dgeIntra short:ran] DF_SsBridgeInterN:$srsfield:[NSsBridgeInter short:ern] DF_AccSurface: $srsfield:[AccSurface short:sur] DF_HydBondsJN: $srsfield:[NHydBondsJ short:hb] DF_HydBondsParaP: $srsfield:[NHBondsParaBridge short:hpb] DF_HydBondsAntiP: $srsfield:[NHBondsAntiParBridge short:hab] DSSP_SYNTAX:$syntax:[file:"SRSDB:dssp.is" ignore:"srs/icarus/db/dssp.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: dssp.is,v $ # $Revision: 1.1 $ # $Date: 1996/12/06 22:26:34 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $rules={ # the entry entry: ~ {$In:[file:text] $Out pre $Skip:0} ln {$entryFip=$Fip $Wrt} appLn+ ~ # fields from text fields: ~ {$In:entry $Out $Skip:1} title header compnd source author nums hist data ~ title: ~ {$Wrt:title} ln ln ~ header: ~ {$Wrt:header} ('HEADER' ln)+ ~ compnd: ~ {$Wrt:compnd} ('COMPND' ln)+ ~ source: ~ {$Wrt:source} ('SOURCE' ln)+ ~ author: ~ {$Wrt:author} ('AUTHOR' ln)+ ~ nums: ~ ln {$Wrt:nums} ln {$Wrt:surf} ln {$Wrt:hb} ln {$Wrt:hb_pb} ln {$Wrt:hb_ab} ln {$Wrt:hb_im5} ln {$Wrt:hb_im4} ln {$Wrt:hb_im3} ln {$Wrt:hb_im2} ln {$Wrt:hb_im1} ln {$Wrt:hb_ip0} ln {$Wrt:hb_ip1} ln {$Wrt:hb_ip2} ln {$Wrt:hb_ip3} ln {$Wrt:hb_ip4} ln {$Wrt:hb_ip5} ~ hist: ~ {$Wrt:hist} (/ +#/ {$Not} ln)+ ~ data: ~ {$Wrt:data} ln+ ~ # indexing production id: ~ {$In:[fields c:header] $Out $Mov:62} /[A-Z0-9]+/ {$Wrt} ~ comp: ~ {$In:[fields c:compnd] $Out} (x{$Mov:10} words {$Len:60} ln)+ ~ src: ~ {$In:[fields c:source] $Out} (x{$Mov:10} words {$Len:60} ln)+ ~ authors: ~ {$In:[fields c:author] $Out} (x{$Mov:10} auts {$Len:60} ln)+ ~ auts: ~ aut (',' aut?)* ~ aut: ~ / *([^ ,]*\\.)([^ ,]*)/ {$Uniq:[s:"$2,$1"]} ~ words: ~ (/[A-Z0-9]+/ {$Uniq:$Itc} | /[^A-Z0-9]+/)+ ~ n: ~ {$In:[fields c:nums] $Out} num {$Wrt:resN} num {$Wrt:chainN} num {$Wrt:ssbtot} num {$Wrt:ssbintra} num {$Wrt:ssbinter} ~ surf: ~ {$In:[fields c:surf] $Out} num {$Wrt} ~ hb: ~ {$In:[fields c:{hb hb_pb hb_ab hb_im5 hb_im4 hb_im3 hb_im2 hb_im1 hb_ip0 hb_ip1 hp_ip2 hb_ip3 hb_ip4 hb_ip5}] $Out} num {$Wrt:$Itc} ~ # html display h_com: ~ {$In:[fields c:compnd t:html]} (/(E\\.C\\.|EC: *)([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)/ {$Rep:{"$1($ParStr:enzymeR)" $2 $2}} | /./)+ ~ # other productions name: ~ /[a-zA-Z0-9_]+/ ~ num: ~ /[0-9.]+/ ~ word: ~ /[^ ]+/ ~ ln: ~ /[^\n]*\n/ ~ appLn: ~ /[^\n]*\n/ {$App} ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/dssp/3apr.dssp'] $JobTokens:[$job name:fields print:1] $JobNext:$job } :compnd t:html]} (/(E\\.C\\.|EC: *)([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)/ {$Rep:{"$1($ParStr:enzymeR)" $2 $2}} | /./)+ ~ # other productions name: ~ /[a-zA-Z0-9_]+/ ~ num: ~ /[0-9.]+/ ~ word: ~ /[^ ]+/ ~ ln: ~ /[^\n]*\n/ ~ appLn: ~ /[^\n]*\n/ {$App} ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fisrs/icarus/db/ecdc.is $rules={ entry: ~ {init{$count=0} $out:entry $count=$count+1} ('ID' {$not} ln)* ('ID ' {pre {$entryFip = $fip} $wrt} ln {$app} ('//' {$not} ln {$app})* '//' {$app $fip:on})? ~ # fields fields: ~ {$in:entry $out} f_id f_xx f_acc f_xx f_def f_xx f_key? f_xx f_org f_xx f_rl f_xx f_dr f_xx f_func f_map f_links ~ f_id: ~ {$wrt:id} 'ID ' ln ~ f_xx: ~ ('XX' ln)* ~ f_acc: ~ {$wrt:acc} ('AC ' ln)* ~ f_date: ~ {$wrt:date} ('DT ' ln)* ~ f_def: ~ {$wrt:def} ('DE ' ln)* ~ f_key: ~ {$wrt:key} ('KW ' ln)+ ~ f_org: ~ {$wrt:org} ('OS ' ln)* ~ f_rl: ~ {$wrt:rl} ('RL ' ln)* ~ f_dr: ~ {$wrt:dr} ('DR ' ln)* ~ f_func: ~ {$wrt:func} ('FT FUNCTION' ln)* ~ f_map: ~ {$wrt:map} ('FT MAP' ln)* ~ f_links: ~ {$wrt:link} ('FT ' /(CDS|CONTIG)/ ln)* ~ # indexing id: ~ {$in:[fields c:id] $out:id} 'ID ' (/[A-Za-z0-9_][A-Za-z0-9_() -]+/ {$wrt} | ',' | /[^a-zA-Z0-9_ -]+/ )* ~ acc: ~ {$in:[fields c:acc] $out:acc} 'AC' /[A-Z0-9_]+/? {$wrt} ~ def: ~ {$in:[fields c:def] $out} ( 'DE' ( /[A-Za-z0-9_]+/ {$wrt} | /[^A-Za-z0-9_]+/ )* )* ~ org: ~ {$in:[fields c:org] $out:org} 'OS' /[A-Za-z0-9_ ]+/ {$wrt} ~ key: ~ {$in:[fields c:key] $out:key} ('KW' /[A-Za-z0-9_ -]+/? {$wrt} ln)* ~ date: ~ {$in:[fields c:date] $out} 'DT' datenum {$wrt:[s:$date c:cre]} '(CREATED);' datenum {$wrt:[s:$date c:dupd]} '(DATA UPDATE);' datenum {$wrt:[s:$date c:iupd]} '(INFO UPDATE).' ~ allpos: ~ {$in:[fields c:rule] $out} (/.*POSITIVE=([0-9]+)/ {$wrt:[s:$1]})? ~ datenum: ~ {init {$month={JAN:1 FEB:2 MAR:3 APR:4 MAY:5 JUN:6 JUL:7 AUG:8 SEP:9 OCT:10 NOV:11 DEC:12}}} /([A-Z][A-Z][A-Z])-([0-9]+)/ {$date=$month.$1 * 100 + $2 * 10000} ~ links: ~ {$in:[fields c:link] $out} (/DR/ (name {$wrt:swiss} ',' name ',' /[A-Z?]/ ';')* ln)* (/3D/ (name {$wrt:pdb} (';'|'.'))* ln)* /DO/ name {$wrt:pd} ~ # table display t_date: ~ {$in:[fields c:date] $out} /.* ([A-Z0-9-]+) *CREATED/ {$wrt:[s:$1]} ~ # html display hl_links:~ {$in:[fields c:dr t:hl]} ('DR' 'EMBL;' name {$rep:{$parStr:emblR $ct $ct}} ln)* ~ # other name: ~ /[a-zA-Z0-9_]+/ ~ ln: ~ /[^\n]*\n/ ~ } $fil = $fileOpen:"/data/ecdc/div.dat" $job = $jobNew:[prod:$rules skip:" "] $jobNext:[$job file:$fil] #for:{1 $jobTokens:[$job name:fields code:dr task:hl print:1] 1} { $print:"-------->entry\n" for:{1 $jobTokens:[$job name:fields code:id print:1] 1} { # $jobTokens:[$job name:acc print:1] # $jobTokens:[$job name:def print:1] $jobTokens:[$job name:fields print:1] # $jobTokens:[$job name:key print:1] # $jobTokens:[$job name:org print:1] # $jobTokens:[$job name:fields code:dr task:hl print:1] $jobEnd:$job $jobNext:[$job file:$fil] $print:"-------->entry\n" } skip:" "] $jobNext:[$job file:$fil] #for:{1 $jobTokens:[$job name:fields code:dr task:hl print:1] 1} { $print:"-------->entry\n" for:{1 $jobTokens:[$job name:fields code:id print:1] 1} { # $jobTokens:[$job name:acc print:1] # $jobTokens:[$job name:def print:1] $jobTokens:[$job name:fields print:1] # $jobTokens:[$job name:key print:1] # $jobTokens:[$job name:org print:1] # $jobTokens:[$job name:fields code:dr task:hlsrs/icarus/db/embl.i # # $RCSfile: embl.i,v $ # $Revision: 1.15 $ # $Date: 1997/03/12 19:06:40 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ EMBLNEW_DB:$library:[EMBLNEW group:@SEQUENCE_LIBS format:@EMBL_FORMAT cachesize:6000 maxNameLen:12 subentries:@EmblnewFeatures_DB files:$file:em_new ] EMBL_DB:$library:[EMBL group:@SEQUENCE_LIBS partSize:100000 subentries:@EmblFeatures_DB format:@EMBL_FORMAT cachesize:6000 maxNameLen:12 files:{ #orig format # $file:est1 # $file:est2 # $file:est3 # $file:est4 # $file:est5 # $file:est6 # $file:est7 # $file:fun # $file:gss # $file:htg # $file:hum1 # $file:hum2 # $file:inv # $file:mam # $file:org # $file:patent # $file:phg # $file:pln # $file:pro # $file:rod # $file:sts # $file:syn # $file:unc # $file:vrl # $file:vrt #gcg format $file:em_est1 $file:em_est2 $file:em_est3 $file:em_est4 $file:em_est5 $file:em_est6 $file:em_est7 $file:em_est8 $file:em_est9 $file:em_ba $file:em_fun $file:em_gss $file:em_htg $file:em_hum1 $file:em_hum2 $file:em_in $file:em_om $file:em_or $file:em_ov $file:em_pat $file:em_ph $file:em_pl $file:em_ro $file:em_sts $file:em_sy $file:em_un $file:em_vi } ] EMBL_FORMAT:$libformat:[syntax:@EMBL_SYNTAX contains:@DNASEQ_DATA tableFormat:left #fileType:{@DAT_FILE @SEQ_FILE} #orig format fileType:{@GCGREF_FILE @GCGSEQ_FILE} #GCG format fields:{ $field:[@DF_ID code:id index:id indexToken:id] $field:@DF_ALL $field:[@DF_Accession code:acc index:str indexToken:acc tableToken:acc tableFormat:left] $field:[@DF_Division code:id index:str indexToken:div tableToken:div tableFormat:left] $field:[@DF_Molecule code:id index:str indexToken:mol tableToken:mol tableFormat:left] # $field:[@DF_DBOrigin code:acc index:str indexToken:dbOri # tableToken:dbOri tableFormat:left] # $field:[@DF_AccessionKey code:acc index:str indexToken:accKey # tableToken:accKey tableFormat:center] $field:[@DF_Description code:des index:str indexToken:des tableToken:'clFields|des'] $field:[@DF_Keywords code:key index:str indexToken:key] $field:[@DF_Organism code:org index:str indexToken:org] $field:[@DF_Authors code:ra index:str indexToken:authors] $field:[@DF_Title code:rt index:str indexToken:ttl tableToken:'clFields|rt'] $field:[@DF_Citation code:rl index:str indexToken:cit tableToken:'clFields|rl'] $field:[@DF_Date code:date index:int indexToken:date tableToken:t_date] $field:[@DF_SeqLength code:sq index:int indexToken:seqLen tableToken:seqLen tableFormat:right] $field:[@DF_LINK code:dr] EMBLSeq:$field:[@DF_DNASequence token:gcgseq format:embl] #GCG format # EMBLSeq:$field:[@DF_DNASequence token:sequence format:embl] #orig format $field:[@DF_HeaderField name:'Feature Table Fields'] $field:[@DF_FtKey code:ft index:str indexToken:ftKey indexId:@SUBENTRY_ID tableToken:ftKey tableFormat:left] $field:[@DF_FtQualifier code:ft index:str indexToken:ftQual indexId:@SUBENTRY_ID] $field:[@DF_PID code:ft index:str indexToken:pid indexId:@SUBENTRY_ID] $field:[@DF_FtDescription code:ft index:str indexToken:ftDes indexId:@SUBENTRY_ID] $field:[@DF_FtSource code:ft index:str indexToken:ftSrc indexId:@SUBENTRY_ID] $field:[@DF_ChrsNo code:ft index:str indexToken:chrsNo indexId:@SUBENTRY_ID] $field:[@DF_FtMap code:ft index:str indexToken:map indexId:@SUBENTRY_ID] # $field:[@DF_FtLength index:int indexToken:ftLen code:ft # indexId:@SUBENTRY_ID] } ] EMBL_SYNTAX:$syntax:[file:"SRSDB:embl.is" ignore:" \t"] $syntax:[name:ftseq file:"SRSDB:ftseq.is" ignore:" \t\n"] #$link:[@EMBL_DB to:@?GENBANK_DB toField:@DF_ACCNO] #$link:[@EMBL_DB to:@?PIR_DB toField:@DF_ACCNO] #$link:[@EMBL_DB to:@?REBASE_DB toField:@DF_ID] #$link:[@EMBL_DB to:@?OMIM_DB toField:@DF_ID] #$link:[@EMBL_DB to:@?MEDLINE_DB toField:@DF_ID] EmblFeatures_DB:$library:[EMBL_features format:@EmblFeature_Format] EmblnewFeatures_DB:$library:[EMBLNEW_features format:@EmblFeature_Format] EmblFeature_Format:$libformat:[syntax:@EMBL_SYNTAX #idType:@SUBENTRY_ID tableFormat:left fields:{ $field:[@DF_ID token:ftId] # $field:[@DF_Accession code:acc fromParent:y] # $field:[@DF_Description code:des fromParent:y] $field:[@DF_FtKey token:ft tableToken:'t_ft|key'] $field:[@DF_FtQualifier token:ft tableToken:'t_ft|qual'] $field:[@DF_PID token:ft tableToken:'t_ft|db_xref'] $field:[@DF_FtDescription token:ft tableToken:'t_ft|note'] $field:[@DF_FtGene token:ft tableToken:'t_ft|gene'] $field:[@DF_FtProduct token:ft tableToken:'t_ft|product'] $field:[@DF_FtPartial token:ft tableToken:'t_ft|partial'] $field:[@DF_FtPseudo token:ft tableToken:'t_ft|pseudo'] $field:[@DF_FtNumber token:ft tableToken:'t_ft|number'] $field:[@DF_FtSource token:ft tableToken:ftSrc] $field:[@DF_ChrsNo token:ft tableToken:'t_ft|chromosome'] $field:[@DF_FtMap token:ft tableToken:'t_ft|map'] $field:[@DF_DNALocation token:ftLocat parent:@EMBLSeq tableFormat:listing] } ] DF_FtGene:$srsfield:[Gene short:gen] DF_FtProduct:$srsfield:[Product short:pro] DF_FtPartial:$srsfield:[Partial short:par] DF_FtPseudo:$srsfield:[Pseudo short:pse] DF_FtNumber:$srsfield:[Number short:num] F_FtNusrs/icarus/db/embl.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: embl.is,v $ # $Revision: 1.16 $ # $Date: 1997/03/17 23:21:01 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $fn={ ID:id OG:org KW:key RN:rn '//':sep AC:acc OC:org RP:rp RT:rt FH: fh DT:date OS:org SQ:sq RC:rc DE:des CC:cmnt RL:rl RA:ra NI:nid DR:link RX:rx XX:sep } $rules={ entry: ~ {$In:[file:text] $Out pre $Skip:0} ('ID ' {$not} lnT?)* (/ID +([A-Z0-9]+)/ {$entryFip=$Fip $Wrt $entryName=$1} lnT {$App} (/( |ID|>>)/ {$Not} lnT {$App})+ )? ~ lnT: ~ /[^\n]+\n?/ ~ # line terminator may be missing if truncated # extracting data fields fields: ~ {$In:entry $Out $Skip:1} (ftln | /../ { if:$Ct==$prev $App else $Wrt:$fn.$Ct if:$fn.$Ct=="" $dp:"+++ unknown: $Ct in $entryName +++" $prev=$Ct } ln {$App})+ ~ ftln: ~ {$Wrt:ft} 'FT' ln ('FT ' ln)* ~ clFields: ~ {$In:fields $Out $Skip:1} /.. */ ln {$Wrt:$Itc} (/.. */ ln {$App})* ~ # parsing the sequence part from separate stream gcgseq: ~ { $In:[file:seq] $Out} '>>>>' {$seqFip=$Fip} (/[A-Z0-9]+_0/ {$Wrt:[s:$Ct] $s=$SeqNew:$Ct} seq (/>>>>[A-Z0-9]+_[1-9]+/ {$SeqTrunc:[$s len:10000]} seq)+ | /[A-Z0-9]+/ {$Wrt:[s:$Ct] $s=$SeqNew:$Ct} seq) ~ seq: ~ /.*2BIT *Len:/ /[0-9]+/ {$len=$Ct} ln ln {$SeqGet2Bit:[$s file:$File len:$len]} ('>>>>'{$Not} ln)* | /.*ASCII/ ln ln ('>>>>' {$Not} /.*/ {$SeqApp:[$s s:$Ct]})+ x{$SeqMake:$s} ~ sequence: ~ {$In:[file:seq share:text] $Out pre {$s=$SeqNew:$entryName $seqFip=$Fip} $Wrt:[s:$entryName] $SeqMake:$s} ('ID' {$Not} ln {$SeqApp:[$s s:$Ct]})* ~ # for indexing i_id: ~ {$In:[entry] $Out:id} /ID +/ name {$Wrt} ~ i_div: ~ {$In:[fields c:id] $Out:div} /ID +/ name /[^;]+/ ';' /[^;]+/ ';' name {$Wrt} ~ i_mol: ~ {$In:[fields c:id] $Out:mol} /ID +/ name /[^;]+/ ';' /[^;]+/ {$Wrt} ~ i_acc: ~ {$In:[fields c:acc] $Out:acc} ('AC' (name {$Wrt} ';')+)+ ~ i_nid: ~ {$In:[fields c:nid] $Out:nid} 'NI' name {$Wrt} ~ i_dates: ~ { $In:[fields c:date] $Out:date init $month={JAN:1 FEB:2 MAR:3 APR:4 MAY:5 JUN:6 JUL:7 AUG:8 SEP:9 OCT:10 NOV:11 DEC:12} } /.* ([0-9]+)-([A-Z]+)-([0-9]+)[^\n]+Cre/ {$Wrt:[credate s:($1 + $month.$2*100 + $3*10000)]} ~ des: ~ {$In:[fields c:des] $Out} ('DE' (/\\(EC *([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)/ {$Wrt:[s:$1]}| word{$Wrt} | sp)+ ln)+ ~ org: ~ {$In:[fields c:org] $Out} ('OC' (/[^;.\n]+/ {$Wrt} | /[^\n]/)*)+ | 'OS' /[^(\n]+/ {$Wrt:[s:$Trim:$Ct]} ('(' (/[^ \n)]+/ | /[^)]/)+)? | 'OG' /[^\n;.]+/ {$Wrt} ~ key: ~ {$In:[fields c:key] $Out} ('KW' (/[^\n;.]+/ {$Wrt} | /[^\n]/)+)+ ~ authors: ~ {$In:[fields c:ra] $Out} (/RA/ (/([^.,\n]+) +([^,;\n]+)/ {$Uniq:[s:"$1,$2"]} /[,;]/)* ln)* ~ ttl: ~ {$In:[fields c:rt] $Out} (tag (word {$Wrt} | sp)* ln)+ ~ cit: ~ {$In:[fields c:rl] $Out} tag / *([^\n]+) ([0-9]+):([0-9]+)-[0-9]+\\(([0-9]+)\\)/? {$Uniq:[jnl s:$Trim:$1] $Uniq:[vol s:$2] $Uniq:[page s:"$3-"] $Uniq:[year s:$4]} ~ accKey: ~ {$In:[fields c:acc] $Out} 'AC' /[A-Z]+/ {$Wrt} ~ dbOri: ~ {$In:[fields c:acc] $Out init { $dbOriN={ A:1 F:1 V:1 X:1 Y:1 Z:1 AA:2 AC:2 AD:2 B:2 G:2 H:2 I:2 J:2 K:2 L:2 M:2 N:2 R:2 S:2 T:2 U:2 W:2 AB:3 C:3 D:3 E:3} $dbName={1:EMBL 2:GenBank 3:DDBJ} } } 'AC' /[A-Z]+/ {$Wrt:[s:$dbName.$dbOriN.$Ct]} ~ i_seqLen: ~ {$In:[fields c:sq] $Out:seqLen} 'SQ Sequence' /[0-9]+/ {$Wrt} ~ # indexing features ftWord: ~ /[^" ,;:()\n.-]+/ ~ #" ftSep: ~ /[ ,;.:()-]+/ ~ ftKey: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} 'FT' /[^ ]+/ {$Wrt:[n:$ftN]} ~ ftQual: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} /[^\/]+/ (/\/([a-zA-Z0-9_]+)/ {$Wrt:[s:$1 n:$ftN]} (/=[a-zA-Z0-9_]+/ | /="[^"]+"/)? /[^\/]+/)* ~ #" chrsNo: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} /.+\/chromosome="?/ (/[^\n\" ]+/ {$Uniq:[n:$ftN]} | '\nFT' | ' ')+ ~ #" ftSrc: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} (/[^\/]+\// ( /(tissue_type|cell_line|organism|strain|dev_stage|sex|clone_lib)="/ ('\nFT' | ftWord {$Uniq:[n:$ftN]} | ftSep)+)?)* ~ ftDes: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} (/[^\/]+\// (/[^\/]+\/(product|note|gene)="/ ('\nFT' | /NCBI gi: *[0-9]+/ | ftWord {$Uniq:[n:$ftN]} | ftSep)+)?)* ~ map: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} /.+\/map="/ (/[^a-zA-Z0-9"]+/|/[a-zA-Z0-9]+/{$Wrt:[n:$ftN]})+ #" ~ pid: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} (/db_xref="?PID:([0-9a-zA-Z]+)/ {$Wrt:[n:$ftN s:$1]} | /[^\/]+\// )+ ~ range: ~ /([A-Z0-9]+:)?([0-9]+)\\. *\\.([0-9A-Z]+:)?([0-9]+)/ {$l=$4-$2+1} ~ ftLen: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} /[^ ]+/ (range {$Wrt:[n:$ftN s:$l]} | /.*join\\(/ {$ftl=0} (range{$ftl+=$l} ','?)* ')'? {$Wrt:[n:$ftN s:$ftl]})? ~ # displaying features ftClean: ~ {$In:[fields c:ft count:ft var:$ftN select:$subEntryN] $Out } 'FT' ln {$Wrt} ('FT' ln {$App})* ~ ftLoc: ~ {$In:ftClean $Out} /[^ ]+/ /[^\/]+/ {$Wrt} ~ ft: ~ {$In:[fields c:ft count:ft var:$ftN select:$subEntryN] $Out} /.*/ {$Wrt} ~ ftId: ~ {$In:[fields c:id] $Out} /.. *([A-Z0-9]+)/ {$Wrt:[s:"ID $1\_$subEntryN; parent: $1"]}~ h_ftId: ~ {$In:[ftId t:html]} /.*parent: */ /[A-Z0-9]+/ {$Rep:{$ParStr:emblIdR $Ct $Ct}} ~ t_ft: ~ {$In:ftClean $Out} /(]*>/ ~ h_links: ~ {$In:[fields c:link t:html] init{$hl={ 'SWISS-PROT': swissR DICTYDB: dictydbR GCRDB: gcrdbR MAIZEDB: maizedbR WORMPEP: wormpepR LISTA: listaR PIR: pirR YEPD: yepdR SGD: sgdR STYGENE: stygeneR HIV: hivR ECOGENE: ecogeneR ECO2DBASE: eco2dbaseR MIM: mimR SUBTILIST: subtilistR FLYBASE: flybaseR TRANSFAC: transfacR REBASE: rebaseR } } } (/DR/ dbName {$db=$Ct} ';' accno {$Rep:{$ParStr:$hl.$db $Ct $Ct}} ln)* ~ # other stuff tag: ~ /[A-Z][A-Z]/ ~ word: ~ /[^" ,;:()\/=\n.-]+/ ~ sp: ~ /[ ,;.:()\/=-]+/ ~ lnCode: ~ /\n[A-Z][A-Z]/ ~ ln: ~ /[^\n]*\n/ ~ accno: ~ /[A-Z0-9]+/ ~ num: ~ /(<|>)?[0-9?]+/ ~ name: ~ /[a-zA-Z0-9_-]+/ ~ dbName: ~ /[^;]+/ ~ } if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/gcg/gcgembl/em_ba.ref'] while:$JobHasInput:$job { $JobTokens:[$job name:acc print:0] $JobTokens:[$job name:t_ft print:1] $JobNext:$job #$print:"-------->entry\n" } } ~ /[^" ,;:()\/=\n.-]+/ ~ sp: ~ /[ ,;.:()\/=-]+/ ~ lnCode: ~ /\n[A-Z][A-Z]/ ~ ln: ~ /[^\n]*\n/ ~ accno: ~ /[A-Z0-9]+/ ~ num: ~ /(<|>)?[0-9?]+/ ~ name: ~ /[a-zA-Z0-9_-]+/ ~ dbName: ~ /[^;]+/ ~ } if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/gcg/gcgembl/em_ba.ref'] while:$JobHasInput:$job { $JobTokens:[$job name:acc print:0] $JobTokens:[$job name:t_ft print:1] $JobNext:$job #$srs/icarus/db/embl.it # # $RCSfile: embl.it,v $ # $Revision: 1.3 $ # $Date: 1996/10/10 16:47:04 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $dbInfo={ description: |The European Bioinformatics Institute (EBI) maintains and distributes |the EMBL Nucleotide Sequence database, Europe's primary nucleotide |sequence data resource. The EBI also maintains and distributes the |SWISS-PROT Protein Sequence database, in collaboration with Amos |Bairoch of the University of Geneva. Over fifty additional specialist |molecular biology databases, as well as software and documentation |of interest to molecular biologists are available. The EBI network |services include database searching and sequence similarity searching |facilities. www: |\ |http://www.ebi.ac.uk citation: |Patricia Rodriguez-Tom , Peter J. Stoehr , Graham N. Cameron and Tomas P. |Flores, "The European Bioinformatics Institute (EBI) databases", |Nucleic Acids Res. |24:(6-13), 1996 ftpSite:'' date: |25 Jul 1996 signature: |Anatoly Ulyanov } interest to molecular biologists are available. The EBI network |services include database searching and sequence similarity searching |facilities. www: |\ |http://www.ebi.ac.uk citation: |Patricia Rodriguez-Tom , Peter srs/icarus/db/emp.i # $RCSfile: emp.i,v $ # $Revision: 1.9 $ # $Date: 1997/03/17 23:21:02 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ EMP_DB:$library:[EMP group:@SEQRELATED_LIBS comment:"Metabolic pathways - Selkov." format:@EMP_FORMAT maxNameLen:30 ifiles:{"emp.i emp.is"} files:{ $file:8612 $file:8912 $file:9211 $file:8701 $file:9001 $file:9212 $file:8702 $file:9002 $file:9301 $file:8703 $file:9003 $file:9302 $file:8704 $file:9004 $file:9303 $file:8705 $file:9005 $file:9304 $file:8706 $file:9006 $file:9305 $file:8707 $file:9007 $file:9306 $file:8708 $file:9008 $file:9307 $file:8709 $file:9009 $file:9308 $file:8710 $file:9010 $file:9309 $file:8711 $file:9011 $file:9310 $file:8712 $file:9012 $file:9311 $file:8801 $file:9101 $file:9312 $file:8802 $file:9102 $file:9401 $file:8803 $file:9103 $file:9402 $file:8804 $file:9104 $file:9403 $file:8805 $file:9105 $file:9404 $file:8806 $file:9106 $file:9405 $file:8807 $file:9107 $file:9406 $file:8808 $file:9108 $file:9407 $file:8810 $file:9109 $file:9408 $file:8811 $file:9110 $file:9409 $file:8812 $file:9111 $file:9410 $file:8901 $file:9112 $file:9411 $file:8902 $file:9201 $file:9412 $file:8903 $file:9202 $file:9501 $file:8904 $file:9203 $file:9502 $file:8905 $file:9204 $file:9503 $file:8906 $file:9205 $file:9504 $file:8907 $file:9206 $file:9509 $file:8908 $file:9207 $file:8909 $file:9208 $file:8910 $file:9209 $file:8911 $file:9210 } ] $link:[@EMP_DB to:@?MPW_DB toField:@DF_Name token:'links|mpw'] $link:[@EMP_DB to:@?ENZYME_DB toField:@DF_ID token:'links|enzyme'] EMP_FORMAT:$libformat:[fileType:@EMP_FILE syntax:@EMP_SYNTAX tableFormat:left printFormat:topicList fields:{ $field:@DF_ALL $field:[@DF_LINK index:link indexToken:links] $field:[@DF_HeaderField name:'Entry Identification'] $field:[@DF_ID code: AN index:id indexToken:id] $field:[@DF_StaffFootnote code: '**'] $field:[@DF_AnnotatorsFootnote code: '***'] $field:[@DF_ReferenceNumber code: RN] $field:[@DF_HeaderField name:'Bibliographic Description'] $field:[@DF_Author code: AU] $field:[@DF_OrganizationalSource code:OS index:str indexToken:'words|OS'] # $field:[@DF_Title code: TI # index:str indexToken:'words|TI'] $field:[@DF_BibliographicSource code: SO] $field:[@DF_PublicationYear code: YR] $field:[@DF_SourceCode code: SC] $field:[@DF_DocumentType code: DT] $field:[@DF_Language code: LA] $field:[@DF_CategoryCode code: CC] $field:[@DF_IndexTerms code: IT] $field:[@DF_SupplementaryTerms code: ST] $field:[@DF_Abstract code: AB] $field:[@DF_AnnotatorsAbstract code: AAB] $field:[@DF_Reference code: REF] $field:[@DF_HeaderField name:'Biological Source'] $field:[@DF_CellLine code: CLI] $field:[@DF_CellType code: CTY] $field:[@DF_OrganismSystematicName code: OR index:str indexToken:'words|OR'] $field:[@DF_OrganismSubspecies code: SSP] $field:[@DF_OrganismCommonName code: OCN] $field:[@DF_TaxonomicGroup code: TG index:str indexToken:'words|TG'] $field:[@DF_CellSpeciesExtracellFluid code: CS] $field:[@DF_Strain code: STR] $field:[@DF_Genotype code: GET] $field:[@DF_Phenotype code: PHT] $field:[@DF_MetabolicType code: MET] $field:[@DF_Age code: AGE] $field:[@DF_Sex code: SEX] $field:[@DF_OrganismWeight code: WT] $field:[@DF_KeepingConditions code: KCO] $field:[@DF_OrganismTreatment code: OTR] $field:[@DF_PhysiologicalState code: PHS] $field:[@DF_DevelopmentalStage code: DEV] $field:[@DF_Pathology code: PAT] $field:[@DF_LightConditions code: LC] $field:[@DF_LightIntensity code: LI] $field:[@DF_WaveLength code: WL] $field:[@DF_TimeOftheDay code: TOD] $field:[@DF_CellCultureCategory code: CCC] $field:[@DF_HeaderField name:'Organism Phenotype'] $field:[@DF_SubspeciesName code: SSP] $field:[@DF_TypeSpecies code: TSP] $field:[@DF_TypeStrainName code: TSN] $field:[@DF_BactClassificationCode code: BC] # $field:[@DF_OrganismCommonName code: OCN] # $field:[@DF_TaxonomicGroup code: TG] $field:[@DF_CellCultureCategoryCode code: CCC] # $field:[@DF_CellType code: CTY] $field:[@DF_molGCContentInDNA code: GCC] $field:[@DF_GenomeSizeDaltons code: GSZ] $field:[@DF_ColonyMorphology code: CMO] $field:[@DF_CellMorphology code: MOR] $field:[@DF_PeptidoglycanComposition code: PGC] $field:[@DF_MembraneLipidComposition code: LIP] $field:[@DF_CytochromePresent code: CYT] $field:[@DF_MembrIsoprenoidQuinonesPresent code: QUI] $field:[@DF_FlagellarArrangement code: FLA] $field:[@DF_Physiology code: PHY] $field:[@DF_CellOrSporeMotility code: MOT] $field:[@DF_ConcentrationInCultivationMedium code: CON] $field:[@DF_AbsoluteRequirementForGrowth code: AR] $field:[@DF_GrowthInhibitor code: GRI] $field:[@DF_GrowthActivator code: GRA] $field:[@DF_CommonAntigeneName code: CAN] $field:[@DF_AlternativePathwayNames code: LAP] $field:[@DF_SystematicPathwayNames code: LSP] $field:[@DF_EnzymeProduced code: ENP] $field:[@DF_FermentationProduct code: FPR] $field:[@DF_ProductionOf code: PRD] $field:[@DF_AcidProducedFrom code: ACD] $field:[@DF_GasProducedFrom code: GAS] $field:[@DF_CarbonSourceUsed code: CSO] $field:[@DF_NitrogenSourceUsed code: NSO] $field:[@DF_Test code: TST] $field:[@DF_NaturalHost code: NHO] $field:[@DF_PathogenicityForHost code: PGY] $field:[@DF_HostPathologyDescription code: HPD] $field:[@DF_Habitat code: HAB] $field:[@DF_GeographicalDistribution code: GEO] $field:[@DF_CulturePreservationConditions code: CPC] $field:[@DF_HeaderField name:'Host'] $field:[@DF_LaboratoryHostSystematicName code: HST] $field:[@DF_HostAge code: HAG] $field:[@DF_HostCommonName code: HCN] $field:[@DF_HostTaxonomicGroup code: HTG] $field:[@DF_HostDevelopmentalStage code: HDS] $field:[@DF_HostStrainName code: HSN] $field:[@DF_HostSex code: HSX] $field:[@DF_HostGenotype code: HGT] $field:[@DF_HostPhenotype code: HPT] $field:[@DF_HostSubcellularFraction code: HSF] $field:[@DF_HostCellSpecies code: HCS] $field:[@DF_HostCellularLocation code: HSL] $field:[@DF_HostCellCultureCategory code: HCC] $field:[@DF_HostCellLine code: HCL] $field:[@DF_HostCellType code: HCT] $field:[@DF_HostTreatment code: HTR] $field:[@DF_NaturalHostSystematicName code: NHO] $field:[@DF_ClonedVector code: CLV] $field:[@DF_HeaderField name:'Biochemical Genetics'] $field:[@DF_GeneAcronym code: GN] $field:[@DF_AlternativeGeneAcronym code: AGA] $field:[@DF_GeneMnemonics code: GMN] $field:[@DF_GeneProduct code: GNP] $field:[@DF_GeneticMapPosition code: GMP] $field:[@DF_GeneLocation code: GL] $field:[@DF_CoordinatelyExpressedGenes code: CEG] $field:[@DF_NucleotideSequenceCrossref code: NS] $field:[@DF_TypeofSynthesis code: SYN] $field:[@DF_Inducer code: IND] $field:[@DF_InductionDegree code: IDE] $field:[@DF_Repressor code: REP] $field:[@DF_RepressionDegree code: RDE] $field:[@DF_DegradationActivator code: DAC] $field:[@DF_DegradationInhibitor code: DIN] $field:[@DF_EnzymeHalfLifeTime code: T05] $field:[@DF_HeaderField name:'Cell Cultivation Conditions'] $field:[@DF_CultivationConditions code: CUC] $field:[@DF_CultivationTemperature code: CUT] $field:[@DF_DilutionRate code: DR] $field:[@DF_CultivationMedium code: MED] $field:[@DF_NitrogenSource code: NSO] $field:[@DF_CarbonSource code: CSO] $field:[@DF_LimitingSubstrate code: LS] $field:[@DF_GrowthSubstrate code: GS] $field:[@DF_CultureDensity code: CD] $field:[@DF_CellCyclePhase code: CCP] $field:[@DF_GrowthPhase code: GP] $field:[@DF_GenerationTime code: GT] $field:[@DF_CellCyclePeriod code: CPE] $field:[@DF_GrowthRate code: GRR] $field:[@DF_SpecificGrowthRate code: SGR] $field:[@DF_GrowthMode code: GM] $field:[@DF_GrowthYield code: GY] $field:[@DF_ColonySize code: CSZ] $field:[@DF_HeaderField name:'Metabolism'] $field:[@DF_MetabolicPathwayName code: MPW] $field:[@DF_SystematicPathwayName code: SPN] $field:[@DF_AlternativePathwayName code: APN] $field:[@DF_OverallReaction code: OVR] $field:[@DF_OverallReactionVelocity code: VEL] $field:[@DF_MetabolicState code: MES] $field:[@DF_HeaderField name:'Enzyme and Reaction'] $field:[@DF_SubcellularLocation code: SL] $field:[@DF_SubcellularFraction code: SF] $field:[@DF_ActiveSiteLocation code: ASL] $field:[@DF_MultifunctionalEnzymeName code: MF] $field:[@DF_MultifunctionalEnzymeForm code: MFF] $field:[@DF_AltMultifunctionalEnzymeName code: AMF] $field:[@DF_MultifunctionalEnzymeCode code: MFC] $field:[@DF_RecommendedEnzymeName code: EN] $field:[@DF_SystematicEnzymeName code: SEN] $field:[@DF_OtherEnzymeName code: ON] $field:[@DF_EnzymeCode code: EC index:str indexToken:enzCode] $field:[@DF_EnzymeForm code: EF] $field:[@DF_ProteinName code: PN] $field:[@DF_NonCatalyticFunction code: NCF] $field:[@DF_ProteinForm code: PRF] # $field:[@DF_ProteinConcentration code: PCO] $field:[@DF_IsozymeNumber code: IZN] $field:[@DF_ReactionEquation code: RE index:str indexToken:'words|RE'] $field:[@DF_ReactionIdentifier code: RI] $field:[@DF_ReactionType code: RET] $field:[@DF_ElementaryStepEquation code: ESE] #was never found # $field:[@DF_Substrate code: SU # index:str indexToken:'words|SU'] $field:[@DF_SiteofEnzymeAction code: SEA] $field:[@DF_NonSubstrate code: NSU index:str indexToken:'words|NSU'] $field:[@DF_Coenzyme code: CO] $field:[@DF_NonCoenzyme code: NCO] $field:[@DF_Product code: PR] $field:[@DF_NonProduct code: NPR] $field:[@DF_AbsoluteRequirement code: AR] $field:[@DF_ReactionPhase code: RP] $field:[@DF_Reversibility code: REV] $field:[@DF_ReactionDirection code: RD] $field:[@DF_EnzymeApplication code: APP] $field:[@DF_HeaderField name:'Assay and Purification'] $field:[@DF_AssayConditions code: ASS] $field:[@DF_TissueActivity code: TA] $field:[@DF_PreparationSpecificActivity code: PA] $field:[@DF_SpecificActivity code: SA index:str indexToken:'words|SA'] $field:[@DF_PurificationSteps code: PS index:str indexToken:'words|PS'] $field:[@DF_PurifFactorAndPurityDegree code: PF] $field:[@DF_Yield code: YD] $field:[@DF_EnzymeConcentration code: ECO] $field:[@DF_ProteinConcentration code: PCO] $field:[@DF_TotalProteinContent code: TPC] $field:[@DF_PreparationSpecificBinding code: PB] $field:[@DF_SpecificBinding code: SB] $field:[@DF_StorageConditions code: STO] $field:[@DF_Buffer code: BUF] $field:[@DF_pHValue code: PH] $field:[@DF_Temperature code: TEM] $field:[@DF_IonicStrength code: IS] $field:[@DF_OptimalConditions code: OC] $field:[@DF_HeaderField name:'Enzyme Kinetics'] $field:[@DF_TypeofKineticsOrFunctDependence code: KT] $field:[@DF_MaxReactionVelocity code: VM] $field:[@DF_PreparationMaxVelocity code: PVM] $field:[@DF_RelativeMaxVelocity code: RVM] $field:[@DF_RelativeActivity code: RA] $field:[@DF_MolecularActivity code: MA] $field:[@DF_CatalyticConst code: KC] $field:[@DF_MichaelisConst code: KM index:str indexToken:'words|KM'] $field:[@DF_HalfSaturatingSubstrateConc code: S05] $field:[@DF_Conditions code: CND] $field:[@DF_CatalyticEfficiency code: CEF] $field:[@DF_ApparentCatalyticConst code: ACC] $field:[@DF_Ligand code: LIG] $field:[@DF_FixedLigand code: FL] $field:[@DF_VariableLigand code: VL] $field:[@DF_MaxSpecificBinding code: BM] $field:[@DF_HillsNumber code: NH] $field:[@DF_ReactionMechanism code: ME] $field:[@DF_RateLaw code: RL] $field:[@DF_RateConstDesignation code: RCD] $field:[@DF_RateConst code: RC] $field:[@DF_TimeConst code: TC] $field:[@DF_FunctionalDependence code: FUN] $field:[@DF_HeaderField name:'Enzyme Regulation'] $field:[@DF_Activator code: AC] $field:[@DF_ActivationType code: ACT] $field:[@DF_ActivationDegree code: AD] $field:[@DF_MaxActivationDegree code: MAD] $field:[@DF_ActivationConst code: KA] $field:[@DF_HalfActivatingConcentration code: A05] $field:[@DF_Inhibitor code: IN index:str indexToken:'words|IN'] $field:[@DF_InhibitionType code: INT] $field:[@DF_InhibitionDegree code: ID] $field:[@DF_MaxInhibitionDegree code: MID] $field:[@DF_InhibitionConst code: KI] $field:[@DF_HalfInhibitingConc code: I05] $field:[@DF_InterceptInhibitionConst code: KII] $field:[@DF_SlopeInhibitionConst code: KIS] $field:[@DF_NonInfluencingCompound code: NIC] $field:[@DF_HeaderField name:'Enzyme Modification'] $field:[@DF_EnzymeModificationProcess code: MP] $field:[@DF_EnzymeModifier code: MOD] $field:[@DF_EnzymeBindingPartner code: BPA] $field:[@DF_ModifyingEnzymeName code: MEN] $field:[@DF_ModifyingEnzymeCode code: MEC] $field:[@DF_ModifyingEnzymeForm code: MEF] $field:[@DF_ModificationResidual code: MRE] $field:[@DF_ModificationMechanism code: MME] $field:[@DF_ModificationPromotor code: MPR] $field:[@DF_ModificationAntagonist code: MAN] $field:[@DF_ModificationEffect code: MOE] $field:[@DF_EnzymeTreatment code: TR] $field:[@DF_TreatmentEffect code: EFF] $field:[@DF_HeaderField name:'Enzyme Structure'] $field:[@DF_MolecularMass code: MM index:str indexToken:'words|MM'] $field:[@DF_SedimentationConst code: ESC] $field:[@DF_SubunitMass code: SM] $field:[@DF_SubunitSedimentationConst code: SSC] $field:[@DF_SubunitName code: SUN] $field:[@DF_SubunitDesignation code: SUD] $field:[@DF_SubunitFunction code: SUF] $field:[@DF_SubunitNumber code: SN] $field:[@DF_SubunitComposition code: SUC] $field:[@DF_SubunitStructure code: SUS] $field:[@DF_SubunitBindingType code: SBT] $field:[@DF_MolecularSymmetry code: MS] $field:[@DF_PolypeptideChainNumber code: PCN] $field:[@DF_ProstheticGroup code: PRG] $field:[@DF_ProstheticGroupNumber code: PGN] $field:[@DF_BindingType code: BT] $field:[@DF_SHGroupNumber code: SHN] $field:[@DF_DisulfideBondNumber code: SSN] $field:[@DF_BindingSiteName code: SNA] $field:[@DF_BindingSiteNumber code: SNU] $field:[@DF_SiteAminoAcidSequence code: SSQ] $field:[@DF_BindingSiteResidual code: SRE] $field:[@DF_AminoAcids code: AA] $field:[@DF_Content code: CNT] $field:[@DF_AminoAcidSequenceOrCrossref code: AAS] $field:[@DF_EnzymeComposition code: ENC] $field:[@DF_TerminalAminoAcids code: TAA] $field:[@DF_SignalPeptide code: SP] $field:[@DF_SignalPeptideLength code: SPL] $field:[@DF_IntramolecularLocation code: LOC] $field:[@DF_PrimaryStructureHomology code: HOM] $field:[@DF_HeaderField name:'Equilibrium and Thermodynamics'] $field:[@DF_EquilibConst code: KEQ] $field:[@DF_EquilibConstFormula code: KEF] $field:[@DF_DissociationConstDesignation code: KDD] $field:[@DF_DissociationConst code: KD] $field:[@DF_AssociationConstDesignation code: KAD] $field:[@DF_AssociationConst code: KAS] $field:[@DF_EquilibConstDesignation code: KED] $field:[@DF_ElementaryStepEquilibConst code: KEE] $field:[@DF_MassActionRatio code: MAR] $field:[@DF_StandardFreeEnergyChange code: DG0] $field:[@DF_StandardEntropyChange code: DS0] $field:[@DF_StandardEnthalpyChange code: DH0] $field:[@DF_ActivationEnergy code: EA] $field:[@DF_ActivationFreeEnergyChange code: DGA] $field:[@DF_ActivationEnthalpyChange code: DHA] $field:[@DF_ActivationEntropyChange code: DSA] $field:[@DF_StandardRedoxPotential code: E0] $field:[@DF_ElectronTransferNumber code: ETN] $field:[@DF_HeatCapacityChange code: DCP] $field:[@DF_HeaderField name:'Physical Chemistry and Spectral Properties'] $field:[@DF_IsoelectricPoint code: IP] $field:[@DF_OptimalPH code: PHO] $field:[@DF_pHDependentParameter code: PHD] $field:[@DF_pHRange code: PHR] $field:[@DF_pKValues code: PKV] $field:[@DF_InactivationConst code: IC] $field:[@DF_OptimalTemperature code: TO] $field:[@DF_TempDependentParameter code: TD] $field:[@DF_TemperatureRange code: TER] $field:[@DF_TemperatureCoefficient code: Q10] $field:[@DF_NameofParameterorVariable code: PAR] $field:[@DF_ValueofParameterorVariable code: VAL] $field:[@DF_AbsorptionMaxWaveLength code: AM] $field:[@DF_AbsorptionCoefficient code: ABC] $field:[@DF_MolarAbsorptionCoefficient code: MAC] $field:[@DF_AbsorptionShoulder code: ASH] $field:[@DF_FluorescenceMax code: FM] $field:[@DF_CDSpectrumMax code: CMA] $field:[@DF_CDSpectrumMin code: CMI] $field:[@DF_CDSpectrumShoulder code: CSH] $field:[@DF_EPRSignals code: EPR] $field:[@DF_HeaderField name:'Immunochemistry'] $field:[@DF_Antigene code: AGN] $field:[@DF_Antibody code: ABD] $field:[@DF_CrossReactivity code: CRR] $field:[@DF_HeaderField name:'Common fields'] $field:[@DF_Abbreviation code: ABB] $field:[@DF_Addition code: ADD] $field:[@DF_BiologicalFunction code: BFN] $field:[@DF_Comments code: COM] $field:[@DF_Concentration code: CON] $field:[@DF_Designation code: DES] $field:[@DF_Formula code: FOR] $field:[@DF_Method code: MT] $field:[@DF_OscillationPeriod code: OP] $field:[@DF_PhaseDifference code: PDI] $field:[@DF_Process code: PRS] $field:[@DF_Property code: PRY] $field:[@DF_SubstanceComposition code: SCN] $field:[@DF_StandardDeviation code: SD] $field:[@DF_Substance code: SUB] $field:[@DF_Synonyms code: SYM] $field:[@DF_Time code: TIM] $field:[@DF_Type code: TYP] $field:[@DF_Unit code: UN] } ] DF_AccessionNumber: $srsfield:[AccessionNumber short: AN] DF_StaffFootnote: $srsfield:[StaffFootnote short: SF] DF_AnnotatorsFootnote: $srsfield:[AnnotatorsFootnote short: AF] DF_ReferenceNumber: $srsfield:[ReferenceNumber short: RN] DF_Author: $srsfield:[Author short: AU] DF_OrganizationalSource: $srsfield:[OrganizationalSource short: OS] DF_BibliographicSource: $srsfield:[BibliographicSource short: SO] DF_PublicationYear: $srsfield:[PublicationYear short: YR] DF_SourceCode: $srsfield:[SourceCode short: SC] DF_DocumentType: $srsfield:[DocumentType short: DT] DF_Language: $srsfield:[Language short: LA] DF_CategoryCode: $srsfield:[CategoryCode short: CC] DF_IndexTerms: $srsfield:[IndexTerms short: IT] DF_SupplementaryTerms: $srsfield:[SupplementaryTerms short: ST] DF_Abstract: $srsfield:[Abstract short: AB] DF_AnnotatorsAbstract: $srsfield:[AnnotatorsAbstract short: AAB] DF_CellLine: $srsfield:[CellLine short: CLI] DF_CellType: $srsfield:[CellType short: CTY] DF_OrganismSystematicName: $srsfield:[OrganismSystematicName short: OR] DF_OrganismSubspecies: $srsfield:[OrganismSubspecies short: SSP] DF_OrganismCommonName: $srsfield:[OrganismCommonName short: OCN] DF_TaxonomicGroup: $srsfield:[TaxonomicGroup short:TG group:@DF_ALL] DF_CellSpeciesExtracellFluid: $srsfield:[CellSpeciesExtracellFluid short: CS] DF_Strain: $srsfield:[Strain short: STR] DF_Genotype: $srsfield:[Genotype short: GET] DF_Phenotype: $srsfield:[Phenotype short: PHT] DF_MetabolicType: $srsfield:[MetabolicType short: MET] DF_Age: $srsfield:[Age short: AGE] DF_Sex: $srsfield:[Sex short: SEX] DF_OrganismWeight: $srsfield:[OrganismWeight short: WT] DF_KeepingConditions: $srsfield:[KeepingConditions short: KCO] DF_OrganismTreatment: $srsfield:[OrganismTreatment short: OTR] DF_PhysiologicalState: $srsfield:[PhysiologicalState short: PHS] DF_DevelopmentalStage: $srsfield:[DevelopmentalStage short: DEV] DF_Pathology: $srsfield:[Pathology short: PAT] DF_LightConditions: $srsfield:[LightConditions short: LC] DF_LightIntensity: $srsfield:[LightIntensity short: LI] DF_WaveLength: $srsfield:[WaveLength short: WL] DF_TimeOftheDay: $srsfield:[TimeOftheDay short: TOD] DF_CellCultureCategory: $srsfield:[CellCultureCategory short: CCC] DF_SubspeciesName: $srsfield:[SubspeciesName short: SSP] DF_TypeSpecies: $srsfield:[TypeSpecies short: TSP] DF_TypeStrainName: $srsfield:[TypeStrainName short: TSN] DF_BactClassificationCode: $srsfield:[BactClassificationCode short: BC] DF_CellCultureCategoryCode: $srsfield:[CellCultureCategoryCode short: CCC] DF_molGCContentInDNA: $srsfield:[molGCContentInDNA short: GCC] DF_GenomeSizeDaltons: $srsfield:[GenomeSizeDaltons short: GSZ] DF_ColonyMorphology: $srsfield:[ColonyMorphology short: CMO] DF_CellMorphology: $srsfield:[CellMorphology short: MOR] DF_PeptidoglycanComposition: $srsfield:[PeptidoglycanComposition short: PGC] DF_MembraneLipidComposition: $srsfield:[MembraneLipidComposition short: LIP] DF_CytochromePresent: $srsfield:[CytochromePresent short: CYT] DF_MembrIsoprenoidQuinonesPresent: $srsfield:[MembrIsoprenoidQuinonesPresent short: QUI] DF_FlagellarArrangement: $srsfield:[FlagellarArrangement short: FLA] DF_Physiology: $srsfield:[Physiology short: PHY] DF_CellOrSporeMotility: $srsfield:[CellOrSporeMotility short: MOT] DF_ConcentrationInCultivationMedium: $srsfield:[ConcentrationInCultivationMedium short: CON] DF_AbsoluteRequirementForGrowth: $srsfield:[AbsoluteRequirementForGrowth short: AR] DF_GrowthInhibitor: $srsfield:[GrowthInhibitor short: GRI] DF_GrowthActivator: $srsfield:[GrowthActivator short: GRA] DF_CommonAntigeneName: $srsfield:[CommonAntigeneName short: CAN] DF_AlternativePathwayNames: $srsfield:[AlternativePathwayNames short: LAP] DF_SystematicPathwayNames: $srsfield:[SystematicPathwayNames short: LSP] DF_EnzymeProduced: $srsfield:[EnzymeProduced short: ENP] DF_FermentationProduct: $srsfield:[FermentationProduct short: FPR] DF_ProductionOf: $srsfield:[ProductionOf short: PRD] DF_AcidProducedFrom: $srsfield:[AcidProducedFrom short: ACD] DF_GasProducedFrom: $srsfield:[GasProducedFrom short: GAS] DF_CarbonSourceUsed: $srsfield:[CarbonSourceUsed short: CSO] DF_NitrogenSourceUsed: $srsfield:[NitrogenSourceUsed short: NSO] DF_Test: $srsfield:[Test short: TST] DF_NaturalHost: $srsfield:[NaturalHost short: NHO] DF_PathogenicityForHost: $srsfield:[PathogenicityForHost short: PGY] DF_HostPathologyDescription: $srsfield:[HostPathologyDescription short: HPD] DF_Habitat: $srsfield:[Habitat short: HAB] DF_GeographicalDistribution: $srsfield:[GeographicalDistribution short: GEO] DF_CulturePreservationConditions: $srsfield:[CulturePreservationConditions short: CPC] DF_LaboratoryHostSystematicName: $srsfield:[LaboratoryHostSystematicName short: HST] DF_HostAge: $srsfield:[HostAge short: HAG] DF_HostCommonName: $srsfield:[HostCommonName short: HCN] DF_HostTaxonomicGroup: $srsfield:[HostTaxonomicGroup short: HTG] DF_HostDevelopmentalStage: $srsfield:[HostDevelopmentalStage short: HDS] DF_HostStrainName: $srsfield:[HostStrainName short: HSN] DF_HostSex: $srsfield:[HostSex short: HSX] DF_HostGenotype: $srsfield:[HostGenotype short: HGT] DF_HostPhenotype: $srsfield:[HostPhenotype short: HPT] DF_HostSubcellularFraction: $srsfield:[HostSubcellularFraction short: HSF] DF_HostCellSpecies: $srsfield:[HostCellSpecies short: HCS] DF_HostCellularLocation: $srsfield:[HostCellularLocation short: HSL] DF_HostCellCultureCategory: $srsfield:[HostCellCultureCategory short: HCC] DF_HostCellLine: $srsfield:[HostCellLine short: HCL] DF_HostCellType: $srsfield:[HostCellType short: HCT] DF_HostTreatment: $srsfield:[HostTreatment short: HTR] DF_NaturalHostSystematicName: $srsfield:[NaturalHostSystematicName short: NHO] DF_ClonedVector: $srsfield:[ClonedVector short: CLV] DF_GeneAcronym: $srsfield:[GeneAcronym short: GN] DF_AlternativeGeneAcronym: $srsfield:[AlternativeGeneAcronym short: AGA] DF_GeneMnemonics: $srsfield:[GeneMnemonics short: GMN] DF_GeneticMapPosition: $srsfield:[GeneticMapPosition short: GMP] DF_GeneLocation: $srsfield:[GeneLocation short: GL] DF_CoordinatelyExpressedGenes: $srsfield:[CoordinatelyExpressedGenes short: CEG] DF_NucleotideSequenceCrossref: $srsfield:[NucleotideSequenceCrossref short: NS] DF_TypeofSynthesis: $srsfield:[TypeofSynthesis short: SYN] DF_Inducer: $srsfield:[Inducer short: IND] DF_InductionDegree: $srsfield:[InductionDegree short: IDE] DF_Repressor: $srsfield:[Repressor short: REP] DF_RepressionDegree: $srsfield:[RepressionDegree short: RDE] DF_DegradationActivator: $srsfield:[DegradationActivator short: DAC] DF_DegradationInhibitor: $srsfield:[DegradationInhibitor short: DIN] DF_EnzymeHalfLifeTime: $srsfield:[EnzymeHalfLifeTime short: T05] DF_CultivationConditions: $srsfield:[CultivationConditions short: CUC] DF_CultivationTemperature: $srsfield:[CultivationTemperature short: CUT] DF_DilutionRate: $srsfield:[DilutionRate short: DR] DF_CultivationMedium: $srsfield:[CultivationMedium short: MED] DF_NitrogenSource: $srsfield:[NitrogenSource short: NSO] DF_CarbonSource: $srsfield:[CarbonSource short: CSO] DF_LimitingSubstrate: $srsfield:[LimitingSubstrate short: LS] DF_GrowthSubstrate: $srsfield:[GrowthSubstrate short: GS] DF_CultureDensity: $srsfield:[CultureDensity short: CD] DF_CellCyclePhase: $srsfield:[CellCyclePhase short: CCP] DF_GrowthPhase: $srsfield:[GrowthPhase short: GP] DF_GenerationTime: $srsfield:[GenerationTime short: GT] DF_CellCyclePeriod: $srsfield:[CellCyclePeriod short: CPE] DF_GrowthRate: $srsfield:[GrowthRate short: GRR] DF_SpecificGrowthRate: $srsfield:[SpecificGrowthRate short: SGR] DF_GrowthMode: $srsfield:[GrowthMode short: GM] DF_GrowthYield: $srsfield:[GrowthYield short: GY] DF_ColonySize: $srsfield:[ColonySize short: CSZ] DF_MetabolicPathwayName: $srsfield:[MetabolicPathwayName short: MPW group:@DF_ALL] DF_SystematicPathwayName: $srsfield:[SystematicPathwayName short: SPN group:@DF_ALL] DF_AlternativePathwayName: $srsfield:[AlternativePathwayName short: APN group:@DF_ALL] DF_OverallReaction: $srsfield:[OverallReaction short: OVR group:@DF_ALL] DF_OverallReactionVelocity: $srsfield:[OverallReactionVelocity short: VEL] DF_MetabolicState: $srsfield:[MetabolicState short: MES] DF_SubcellularLocation: $srsfield:[SubcellularLocation short: SL] DF_SubcellularFraction: $srsfield:[SubcellularFraction short: SF] DF_ActiveSiteLocation: $srsfield:[ActiveSiteLocation short: ASL] DF_MultifunctionalEnzymeName: $srsfield:[MultifunctionalEnzymeName short: MF] DF_MultifunctionalEnzymeForm: $srsfield:[MultifunctionalEnzymeForm short: MFF] DF_AltMultifunctionalEnzymeName: $srsfield:[AltMultifunctionalEnzymeName short: AMF] DF_MultifunctionalEnzymeCode: $srsfield:[MultifunctionalEnzymeCode short: MFC] DF_RecommendedEnzymeName: $srsfield:[RecommendedEnzymeName short: EN] DF_SystematicEnzymeName: $srsfield:[SystematicEnzymeName short: SEN] DF_OtherEnzymeName: $srsfield:[OtherEnzymeName short: ON] DF_EnzymeForm: $srsfield:[EnzymeForm short: EF] DF_ProteinName: $srsfield:[ProteinName short: PN] DF_NonCatalyticFunction: $srsfield:[NonCatalyticFunction short: NCF] DF_ProteinForm: $srsfield:[ProteinForm short: PRF] DF_ProteinConcentration: $srsfield:[ProteinConcentration short: PCO] DF_IsozymeNumber: $srsfield:[IsozymeNumber short: IZN] DF_ReactionEquation: $srsfield:[ReactionEquation short: RE] DF_ReactionIdentifier: $srsfield:[ReactionIdentifier short: RI] DF_ReactionType: $srsfield:[ReactionType short: RET] DF_ElementaryStepEquation: $srsfield:[ElementaryStepEquation short: ESE] DF_SiteofEnzymeAction: $srsfield:[SiteofEnzymeAction short: SEA] DF_NonSubstrate: $srsfield:[NonSubstrate short: NSU] DF_Coenzyme: $srsfield:[Coenzyme short: CO] DF_NonCoenzyme: $srsfield:[NonCoenzyme short: NCO] DF_Product: $srsfield:[Product short: PR] DF_NonProduct: $srsfield:[NonProduct short: NPR] DF_AbsoluteRequirement: $srsfield:[AbsoluteRequirement short: AR] DF_ReactionPhase: $srsfield:[ReactionPhase short: RP] DF_Reversibility: $srsfield:[Reversibility short: REV] DF_ReactionDirection: $srsfield:[ReactionDirection short: RD] DF_EnzymeApplication: $srsfield:[EnzymeApplication short: APP] DF_AssayConditions: $srsfield:[AssayConditions short: ASS] DF_TissueActivity: $srsfield:[TissueActivity short: TA] DF_PreparationSpecificActivity: $srsfield:[PreparationSpecificActivity short: PA] DF_SpecificActivity: $srsfield:[SpecificActivity short: SA] DF_PurificationSteps: $srsfield:[PurificationSteps short: PS] DF_PurifFactorAndPurityDegree: $srsfield:[PurifFactorAndPurityDegree short: PF] DF_Yield: $srsfield:[Yield short: YD] DF_EnzymeConcentration: $srsfield:[EnzymeConcentration short: ECO] DF_TotalProteinContent: $srsfield:[TotalProteinContent short: TPC] DF_PreparationSpecificBinding: $srsfield:[PreparationSpecificBinding short: PB] DF_SpecificBinding: $srsfield:[SpecificBinding short: SB] DF_StorageConditions: $srsfield:[StorageConditions short: STO] DF_Buffer: $srsfield:[Buffer short: BUF] DF_pHValue: $srsfield:[pHValue short: PH] DF_Temperature: $srsfield:[Temperature short: TEM] DF_IonicStrength: $srsfield:[IonicStrength short: IS] DF_OptimalConditions: $srsfield:[OptimalConditions short: OC] DF_TypeofKineticsOrFunctDependence: $srsfield:[TypeofKineticsOrFunctDependence short: KT] DF_MaxReactionVelocity: $srsfield:[MaxReactionVelocity short: VM] DF_PreparationMaxVelocity: $srsfield:[PreparationMaxVelocity short: PVM] DF_RelativeMaxVelocity: $srsfield:[RelativeMaxVelocity short: RVM] DF_RelativeActivity: $srsfield:[RelativeActivity short: RA] DF_MolecularActivity: $srsfield:[MolecularActivity short: MA] DF_CatalyticConst: $srsfield:[CatalyticConst short: KC] DF_MichaelisConst: $srsfield:[MichaelisConst short: KM] DF_HalfSaturatingSubstrateConc: $srsfield:[HalfSaturatingSubstrateConc short: S05] DF_Conditions: $srsfield:[Conditions short: CND] DF_CatalyticEfficiency: $srsfield:[CatalyticEfficiency short: CEF] DF_ApparentCatalyticConst: $srsfield:[ApparentCatalyticConst short: ACC] DF_Ligand: $srsfield:[Ligand short: LIG] DF_FixedLigand: $srsfield:[FixedLigand short: FL] DF_VariableLigand: $srsfield:[VariableLigand short: VL] DF_MaxSpecificBinding: $srsfield:[MaxSpecificBinding short: BM] DF_HillsNumber: $srsfield:[HillsNumber short: NH] DF_ReactionMechanism: $srsfield:[ReactionMechanism short: ME] DF_RateLaw: $srsfield:[RateLaw short: RL] DF_RateConstDesignation: $srsfield:[RateConstDesignation short: RCD] DF_RateConst: $srsfield:[RateConst short: RC] DF_TimeConst: $srsfield:[TimeConst short: TC] DF_FunctionalDependence: $srsfield:[FunctionalDependence short: FUN] DF_Activator: $srsfield:[Activator short: AC] DF_ActivationType: $srsfield:[ActivationType short: ACT] DF_ActivationDegree: $srsfield:[ActivationDegree short: AD] DF_MaxActivationDegree: $srsfield:[MaxActivationDegree short: MAD] DF_ActivationConst: $srsfield:[ActivationConst short: KA] DF_HalfActivatingConcentration: $srsfield:[HalfActivatingConcentration short: A05] DF_Inhibitor: $srsfield:[Inhibitor short: IN] DF_InhibitionType: $srsfield:[InhibitionType short: INT] DF_InhibitionDegree: $srsfield:[InhibitionDegree short: IND] DF_MaxInhibitionDegree: $srsfield:[MaxInhibitionDegree short: MID] DF_InhibitionConst: $srsfield:[InhibitionConst short: KI] DF_HalfInhibitingConc: $srsfield:[HalfInhibitingConc short: I05] DF_InterceptInhibitionConst: $srsfield:[InterceptInhibitionConst short: KII] DF_SlopeInhibitionConst: $srsfield:[SlopeInhibitionConst short: KIS] DF_NonInfluencingCompound: $srsfield:[NonInfluencingCompound short: NIC] DF_EnzymeModificationProcess: $srsfield:[EnzymeModificationProcess short: MP] DF_EnzymeModifier: $srsfield:[EnzymeModifier short: MOD] DF_EnzymeBindingPartner: $srsfield:[EnzymeBindingPartner short: BPA] DF_ModifyingEnzymeName: $srsfield:[ModifyingEnzymeName short: MEN] DF_ModifyingEnzymeCode: $srsfield:[ModifyingEnzymeCode short: MEC] DF_ModifyingEnzymeForm: $srsfield:[ModifyingEnzymeForm short: MEF] DF_ModificationResidual: $srsfield:[ModificationResidual short: MRE] DF_ModificationMechanism: $srsfield:[ModificationMechanism short: MME] DF_ModificationPromotor: $srsfield:[ModificationPromotor short: MPR] DF_ModificationAntagonist: $srsfield:[ModificationAntagonist short: MAN] DF_ModificationEffect: $srsfield:[ModificationEffect short: MOE] DF_EnzymeTreatment: $srsfield:[EnzymeTreatment short: TR] DF_TreatmentEffect: $srsfield:[TreatmentEffect short: EFF] DF_MolecularMass: $srsfield:[MolecularMass short: MM] DF_SedimentationConst: $srsfield:[SedimentationConst short: ESC] DF_SubunitMass: $srsfield:[SubunitMass short: SM] DF_SubunitSedimentationConst: $srsfield:[SubunitSedimentationConst short: SSC] DF_SubunitName: $srsfield:[SubunitName short: SUN] DF_SubunitDesignation: $srsfield:[SubunitDesignation short: SUD] DF_SubunitFunction: $srsfield:[SubunitFunction short: SUF] DF_SubunitNumber: $srsfield:[SubunitNumber short: SN] DF_SubunitComposition: $srsfield:[SubunitComposition short: SUC] DF_SubunitStructure: $srsfield:[SubunitStructure short: SUS] DF_SubunitBindingType: $srsfield:[SubunitBindingType short: SBT] DF_MolecularSymmetry: $srsfield:[MolecularSymmetry short: MS] DF_PolypeptideChainNumber: $srsfield:[PolypeptideChainNumber short: PCN] DF_ProstheticGroup: $srsfield:[ProstheticGroup short: PRG] DF_ProstheticGroupNumber: $srsfield:[ProstheticGroupNumber short: PGN] DF_BindingType: $srsfield:[BindingType short: BT] DF_SHGroupNumber: $srsfield:[SHGroupNumber short: SHN] DF_DisulfideBondNumber: $srsfield:[DisulfideBondNumber short: SSN] DF_BindingSiteName: $srsfield:[BindingSiteName short: SNA] DF_BindingSiteNumber: $srsfield:[BindingSiteNumber short: SNU] DF_SiteAminoAcidSequence: $srsfield:[SiteAminoAcidSequence short: SSQ] DF_BindingSiteResidual: $srsfield:[BindingSiteResidual short: SRE] DF_AminoAcids: $srsfield:[AminoAcids short: AA] DF_Content: $srsfield:[Content short: CNT] DF_AminoAcidSequenceOrCrossref: $srsfield:[AminoAcidSequenceOrCrossref short: AAS] DF_EnzymeComposition: $srsfield:[EnzymeComposition short: ENC] DF_TerminalAminoAcids: $srsfield:[TerminalAminoAcids short: TAA] DF_SignalPeptide: $srsfield:[SignalPeptide short: SP] DF_SignalPeptideLength: $srsfield:[SignalPeptideLength short: SPL] DF_IntramolecularLocation: $srsfield:[IntramolecularLocation short: LOC] DF_PrimaryStructureHomology: $srsfield:[PrimaryStructureHomology short: HOM] DF_EquilibConst: $srsfield:[EquilibConst short: KEQ] DF_EquilibConstFormula: $srsfield:[EquilibConstFormula short: KEF] DF_DissociationConstDesignation: $srsfield:[DissociationConstDesignation short: KDD] DF_DissociationConst: $srsfield:[DissociationConst short: KD] DF_AssociationConstDesignation: $srsfield:[AssociationConstDesignation short: KAD] DF_AssociationConst: $srsfield:[AssociationConst short: KAS] DF_EquilibConstDesignation: $srsfield:[EquilibConstDesignation short: KED] DF_ElementaryStepEquilibConst: $srsfield:[ElementaryStepEquilibConst short: KEE] DF_MassActionRatio: $srsfield:[MassActionRatio short: MAR] DF_StandardFreeEnergyChange: $srsfield:[StandardFreeEnergyChange short: DG0] DF_StandardEntropyChange: $srsfield:[StandardEntropyChange short: DS0] DF_StandardEnthalpyChange: $srsfield:[StandardEnthalpyChange short: DH0] DF_ActivationEnergy: $srsfield:[ActivationEnergy short: EA] DF_ActivationFreeEnergyChange: $srsfield:[ActivationFreeEnergyChange short: DGA] DF_ActivationEnthalpyChange: $srsfield:[ActivationEnthalpyChange short: DHA] DF_ActivationEntropyChange: $srsfield:[ActivationEntropyChange short: DSA] DF_StandardRedoxPotential: $srsfield:[StandardRedoxPotential short: E0] DF_ElectronTransferNumber: $srsfield:[ElectronTransferNumber short: ETN] DF_HeatCapacityChange: $srsfield:[HeatCapacityChange short: DCP] DF_OptimalPH: $srsfield:[OptimalPH short: PHO] DF_pHDependentParameter: $srsfield:[pHDependentParameter short: PHD] DF_pHRange: $srsfield:[pHRange short: PHR] DF_pKValues: $srsfield:[pKValues short: PKV] DF_InactivationConst: $srsfield:[InactivationConst short: IC] DF_OptimalTemperature: $srsfield:[OptimalTemperature short: TO] DF_TempDependentParameter: $srsfield:[TempDependentParameter short: TD] DF_TemperatureRange: $srsfield:[TemperatureRange short: TER] DF_TemperatureCoefficient: $srsfield:[TemperatureCoefficient short: Q10] DF_NameofParameterorVariable: $srsfield:[NameofParameterorVariable short: PAR] DF_ValueofParameterorVariable: $srsfield:[ValueofParameterorVariable short: VAL] DF_AbsorptionMaxWaveLength: $srsfield:[AbsorptionMaxWaveLength short: AM] DF_AbsorptionCoefficient: $srsfield:[AbsorptionCoefficient short: ABC] DF_MolarAbsorptionCoefficient: $srsfield:[MolarAbsorptionCoefficient short: MAC] DF_AbsorptionShoulder: $srsfield:[AbsorptionShoulder short: ASH] DF_FluorescenceMax: $srsfield:[FluorescenceMax short: FM] DF_CDSpectrumMax: $srsfield:[CDSpectrumMax short: CMA] DF_CDSpectrumMin: $srsfield:[CDSpectrumMin short: CMI] DF_CDSpectrumShoulder: $srsfield:[CDSpectrumShoulder short: CSH] DF_EPRSignals: $srsfield:[EPRSignals short: EPR] DF_Antigene: $srsfield:[Antigene short: AGN] DF_Antibody: $srsfield:[Antibody short: ABD] DF_CrossReactivity: $srsfield:[CrossReactivity short: CRR] DF_Abbreviation: $srsfield:[Abbreviation short: ABB] DF_Addition: $srsfield:[Addition short: ADD] DF_BiologicalFunction: $srsfield:[BiologicalFunction short: BFN] DF_Comments: $srsfield:[Comments short: COM] DF_Concentration: $srsfield:[Concentration short: CON] DF_Designation: $srsfield:[Designation short: DES] DF_Formula: $srsfield:[Formula short: FOR] DF_OscillationPeriod: $srsfield:[OscillationPeriod short: OP] DF_PhaseDifference: $srsfield:[PhaseDifference short: PDI] DF_Process: $srsfield:[Process short: PRS] DF_Property: $srsfield:[Property short: PRY] DF_SubstanceComposition: $srsfield:[SubstanceComposition short: SCN] DF_StandardDeviation: $srsfield:[StandardDeviation short: SD] DF_Substance: $srsfield:[Substance short: SUB] DF_Time: $srsfield:[Time short: TIM] DF_Type: $srsfield:[Type short: TYP] DF_Unit: $srsfield:[Unit short: UN] EMP_SYNTAX:$syntax:[file:"SRSDB:emp.is" ignore:" "] EMP_FILE:$filetype:[typename:bnk maxline:3000] eld:[PhaseDifference short: PDI] DF_Process: $srsfield:[Process short: PRS] DF_Property: $srsfield:[Property short: PRY] DF_SubstanceComposition: $srsfield:[SubstanceComposition short: SCN] DF_StandardDeviation: $srsfield:[StandardDeviation short: SD] DF_Substance: $srsfield:[Substance shorsrs/icarus/db/emp.is $tags= { '**': 'Staff Footnote' '***': 'Annotators Footnote' A05: 'Half-Activating Concentration' AAB: 'Annotators Abstract' AA: 'Amino Acids' AAS: 'Amino Acid Sequence or Crossreference' AB: 'Abstract' ABB: 'Abbreviation' ABC: 'Absorption Coefficient' ABD: 'Antibody' AC: 'Activator' ACC: 'Apparent Catalytic Constant' ACT: 'Activation Type' AD: 'Activation Degree' ADD: 'Addition' AGD: 'Alternative Gene Designation' AGE: 'Age' AGN: 'Antigene' ALG: 'Alternative gene name' AM: 'Absorption Maximum Wave Length' AMF: 'Alternative Multifunctional Enzyme Name' AN: 'Accession Number' APN: 'Alternative Pathway Name' APP: 'Enzyme Application' AR: 'Absolute Requirement' ASH: 'Absorption Shoulder' ASL: 'Active Site Location' ASS: 'Assay Conditions' AU: 'Author' BFN: 'Biological Function' BM: 'Maximum Specific Binding' BPA: 'Enzyme Binding Partner' BT: 'Binding Type' BUF: 'Buffer' CC: 'Category Code' CCC: 'Cell Culture Category' CD: 'Culture Density' CEF: 'Catalytic Efficiency' CEG: 'Coordinately Expressed Genes' CLI: 'Cell Line' CLV: 'Cloned Vector' CMA: 'CD Spectrum Maximum' CMI: 'CD Spectrum Minimum' CND: 'Conditions' CNT: 'Content' CO: 'Coenzyme' COL: 'Solution color' COM: 'Comments' CON: 'Concentration' CPE: 'Cell Cycle Period' CCP: 'Cell Cycle Phase' CRR: 'Cross-Reactivity' CS: 'Cell Species or Extracellular Fluid' CSH: 'CD Spectrum Shoulder' CSO: 'Carbon Source' CSZ: 'Colony Size' CTY: 'Cell Type' CUC: 'Cultivation Conditions' CUT: 'Cultivation Temperature' DAC: 'Degradation Activator' DCP: 'Heat Capacity Change' DES: 'Designation' DEV: 'Developmental Stage' DG0: 'Standard Free Energy Change' DGA: 'Activation Free Energy Change' DH0: 'Standard Enthalpy Change' DHA: 'Activation Enthalpy Change' DIN: 'Degradation Inhibitor' DR: 'Dilution Rate' DS0: 'Standard Entropy Change' DSA: 'Activation Entropy Change' DT: 'Document Type' E0: 'Standard Redox Potential' EA: 'Activation Energy' EC: 'Enzyme Code' ECO: 'Enzyme Concentration' EF: 'Enzyme Form' EFF: 'Treatment Effect' EN: 'Recommended Enzyme Name' ENC: 'Enzyme Composition' EPR: 'EPR Signals' ESC: 'Sedimentation Constant' ESE: 'Elementary Step Equation' ESR: 'unknown field-ESR' ETN: 'Electron Transfer Number' FL: 'Fixed Ligand' FM: 'Fluorescence Maximum' FOR: 'Formula' FUN: 'Functional Dependence' GCC: 'unknown field GCC' GEN: 'Gene Name' GET: 'Genotype' GL: 'Gene Location' GM: 'Growth Mode' GMP: 'Genetic Map Position' GN: 'Gene Designation' GNP: 'Gene Product' GP: 'Growth Phase' GRR: 'Growth Rate' GS: 'Growth Substrate' GT: 'Generation Time' GY: 'Growth Yield' HAB: 'unknown field-HAB' HAG: 'Host Age' HCC: 'Host Cell Culture Category' HCL: 'Host Cell Line' HCN: 'Host Common Name' HCS: 'Host Cell Species' HCT: 'Host Cell Type' HDS: 'Host Developmental Stage' HGT: 'Host Genotype' HMT: 'Host metabolic type' HOM: 'Primary Structure Homology' HPT: 'Host Phenotype' HSF: 'Host Subcellular Fraction' HSL: 'Host Cellular Location' HSN: 'Host Strain Name' HST: 'Laboratory Host Systematic Name' HSX: 'Host Sex' HTG: 'Host Taxonomic Group' HTR: 'Host Treatment' I05: 'Half-Inhibiting Concentration' IC: 'Inactivation Constant' ID: 'Inhibition Degree' IDE: 'Induction Degree' IN: 'Inhibitor' IND: 'Inducer' INT: 'Inhibition Type' IP: 'Isoelectric Point (pI)' IS: 'Ionic Strength' IT: 'Index Terms' IZN: 'Isozyme Number' KA: 'Activation Constant' KAD: 'Association Constant Designation' KAS: 'Association Constant' KC: 'Catalytic Constant' KCO: 'Keeping Conditions' KD: 'Dissociation Constant' KDD: 'Dissociation Constant Designation' KED: 'Equilibrium Constant Designation' KEE: 'Elementary Step Equilibrium Constant' KEF: 'Equilibrium Constant Formula' KEQ: 'Equilibrium Constant' KI: 'Inhibition Constant' KII: 'Intercept Inhibition Constant' KIS: 'Slope Inhibition Constant' KM: 'Michaelis Constant' KT: 'Type of Kinetics or Functional Dependence' LA: 'Language' LC: 'Light Conditions' LI: 'Light Intensity' LIG: 'Ligand' LOC: 'Intramolecular Location' LS: 'Limiting Substrate' LSO: 'Light source' MA: 'Molecular Activity' MAC: 'Molar Absorption Coefficient' MAD: 'Maximum Activation Degree' MAN: 'Modification Antagonist' MAR: 'Mass Action Ratio' MCC: 'Membrane carrier code' MCF: 'Membrane carrier form' MCN: 'Membrane carrier name' ME: 'Reaction Mechanism' MEC: 'Modifying Enzyme Code' MED: 'Cultivation Medium' MEF: 'Modifying Enzyme Form' MEN: 'Modifying Enzyme Name' MES: 'Metabolic State' MET: 'Metabolic Type' MF: 'Multifunctional Enzyme Name' MFC: 'Multifunctional Enzyme Code' MFF: 'Multifunctional Enzyme Form' MID: 'Maximum Inhibition Degree' MM: 'Molecular Mass' MME: 'Modification Mechanism' MOD: 'Enzyme Modifier' MOE: 'Modification Effect' MOR: 'unknown field-MOR' MOT: 'unknown field-MOT' MP: 'Enzyme Modification Process' MPR: 'Modification Promotor' MPW: 'Metabolic Pathway Name' MRE: 'Modification Residual' MS: 'Molecular Symmetry' MT: 'Method' NCF: 'Non-Catalytic Function' NCO: 'Non-Coenzyme' NH: 'Hills Number' NHO: 'Natural Host Systematic Name' NIC: 'Non-Influencing Compound' NPR: 'Non-Product' NS: 'Nucleotide Sequence Crossreference' NSO: 'Nitrogen Source' NSU: 'Non-Substrate' OC: 'Optimal Conditions' OCN: 'Organism Common Name' ON: 'Other Enzyme Name' OP: 'Oscillation Period' OPN: 'unknown field OPN' OR: 'Organism Systematic Name' OS: 'Organizational Source' OTR: 'Organism Treatment' OVR: 'Overall Reaction' PA: 'Preparation Specific Activity' PAR: 'Name of Parameter or Variable' PAT: 'Pathology' PB: 'Preparation Specific Binding' PCN: 'Polypeptide Chain Number' PCO: 'Protein Concentration' PDI: 'Phase Difference' PF: 'Purification Factor and Purity Degree' PGN: 'Prosthetic Group Number' PH: 'pH Value' PHD: 'pH-Dependent Parameter' PHO: 'Optimal pH' PHR: 'pH Range' PHS: 'Physiological State' PHT: 'Phenotype' PHY: 'unknown Field' PKV: 'pK Values' PLO: 'Ploidy' PN: 'Protein Name' PR: 'Product' PRF: 'Protein Form' PRG: 'Prosthetic Group' PRI: 'Primer/Template' PRS: 'Process' PRY: 'Property' PS: 'Purification Steps' PSL: 'Polypeptide synthesis Location' PVM: 'Preparation Maximum Velocity' Q10: 'Temperature Coefficient' RA: 'Relative Activity' RC: 'Rate Constant' RCD: 'Rate Constant Designation' RD: 'Reaction Direction' RDE: 'Repression Degree' RE: 'Reaction Equation' REF: 'Reference' REP: 'Repressor' RET: 'Reaction_Type' REV: 'Reversibility' RI: 'Reaction Identifier' RL: 'Rate Law' RN: 'Reference Number' RP: 'Reaction Phase' RVM: 'Relative Maximum Velocity' S05: 'Half-Saturating Substrate Concentration' SA: 'Specific Activity' SAA: 'Site amino acid sequence' SB: 'Specific Binding' SBT: 'Subunit Binding Type' SC: 'Source Code' SCN: 'Substance Composition' SD: 'Standard Deviation' SEA: 'Site of Enzyme Action' SEN: 'Systematic Enzyme Name' SEX: 'Sex' SF: 'Subcellular Fraction' SGR: 'Specific Growth Rate' SHN: 'SH-Group Number' SL: 'Subcellular Location' SM: 'Subunit Mass' SN: 'Subunit Number' SNA: 'Binding Site Name' SNU: 'Binding Site Number' SO: 'Bibliographic Source' SP: 'Signal Peptide' SPL: 'Signal Peptide Length' SPN: 'Systematic Pathway Name' SRE: 'Binding Site Residual' SSC: 'Subunit Sedimentation constant' SSN: 'Disulfide Bond Number' SSP: 'Organism Subspecies' SSQ: 'Site Sequence' ST: 'Supplementary Terms' STA: 'Stabilizer' STO: 'Storage Conditions' STR: 'Strain' SU: 'Substrate' SUB: 'Substance' SUC: 'Subunit Composition' SUD: 'Subunit Designation' SUF: 'Subunit Function' SUN: 'Subunit Name' SUS: 'Subunit Structure' SYM: 'Synonyms' SYN: 'Type of Synthesis' T05: 'Half-Life Time' TA: 'Tissue Activity' TAA: 'Terminal Amino Acids' TC: 'Time Constant' TD: 'Temperature-Dependent Parameter' TEM: 'Temperature' TER: 'Temperature Range' TG: 'Taxonomic Group' TI: 'Title' TIM: 'Time' TO: 'Optimal Temperature' TOD: 'Time Of the Day' TPC: 'Total Protein Content' TR: 'Enzyme Treatment' TRT: 'Transition temperature' TYP: 'Type' UN: 'Unit' VAL: 'Value of Parameter or Variable' VEL: 'Overall Reaction Velocity' VL: 'Variable Ligand' VM: 'Maximum Reaction Velocity' WL: 'Wave Length' WT: 'Organism Weight' YD: 'Yield' YR: 'Publication Year' } $rules={ entry: ~ {$In:[file:text] $Out pre $Skip:0} (/[A-Z][A-Z]/ {$Not} ln)* (tag {pre {$Skip:0 $entryFip = $Fip} $Wrt} appLn ('#'{$not} appLn)* '#' ln? )? ~ # fields fields: ~ {$In:entry $Out $Skip:1} (tag {$c=$Ct $Wrt:$Ct } appLn (/[A-Z]/ {$Not} appLn)* | annot)+ ~ annot: ~ {$Wrt} '**' appLn ~ # indexing i_id: ~ {$Out:id $In:[fields c:AN]} /../ name {$Wrt} ~ i_str: ~ /a-zA-Z_/ ~ i_enzCode:~ {$Out:enzCode $In:[fields c:EC]} /... +/ str? {$Wrt} ~ i_words: ~ {$In:fields $Out:words pre{$Skip:0} $Skip:1} tag? i_word* ~ i_word: ~ ( /[0-9-]+\\.[0-9-]+\\.[0-9-]+\\.[0-9-]+/ {$Wrt:$Itc} | /[a-zA-Z0-9]+/ {$Uniq:$Itc} | /./ )+ ~ i_links: ~ {$In:fields $Out:links pre{$Skip:1} $Skip:1} /[A-Z]+/ { if:($Ct==MFC || $Ct==EC) {$Prod:ecLink} elif:$Ct==MPW $Prod:mpwLink } ~ ecLink: ~ /[A-Z ]+/ ec {$Wrt:enzyme} (/[:\/ ]+/ ec {$Wrt:enzyme})* ~ ec: ~ /[0-9-]+\\.[0-9-]+\\.[0-9-]+\\.[0-9-]+/ ~ mpwLink: ~ /MPW G +/ /[A-Z0-9]+\\.[A-Z0-9]+/ {$Wrt:mpw} ~ # html display h_field: ~ {$In:[fields t:hl]} tag {$t=$tags.$Ct if:$ParInt:isTable $Rep:"" else $Rep:"
$t
" } (h_Ttable | h_Mtable | (h_word '\n')+) ~ h_Mtable: ~ 'M '{$Rep:"
"} h_tabhdr ('//'{$Rep:"
"} h_Mtabrow)* x{$Rep:[s:"
"]}~ h_Mtabrow:~ (/[^!\n]+/ ('!!' {$Rep:""})?)* '\n'{$Rep:"\n"}~ h_Ttabbeg:~ ('T ' | 'R ' | 'E ' | 'G ' | 'F ') ~ h_Ttable: ~ h_Ttabbeg {$Rep:"
"} h_tabhdr ('//'{$Rep:"
"} h_Ttabrow)* x{$Rep:[s:"
"]}~ h_Ttabrow:~ (h_word ('!!' {$Rep:""})?)* '\n'{$Rep:"\n"} ~ h_tabhdr: ~ (h_word ('!!' {$Rep:""})?)* '\n'{$Rep:"\n"} ~ h_word: ~ ( (/(EC_)?[0-9-]+\\.[0-9-]+\\.[0-9-]+\\.[0-9-]+/ {$Rep:{$ParStr:enzymeR $Ct $Ct}} (/([^0-9])([0-9-]+\\.[0-9-]+\\.[0-9-]+\\.[0-9-]+)/ {$Rep:{$ParStr:enzymeR $Ct $Ct}})*) | /(SWISS-PROT)_([A-Z0-9]+)/{$Rep:{"$1\:($ParStr:swissR)" $2 $2}}| /(PIR)_([A-Z0-9]+)/ {$Rep:{"$1\:($ParStr:pirR)" $2 $2}} | /(EMBL)_([A-Z0-9]+)/ {$Rep:{"$1\:($ParStr:emblR)" $2 $2}} | /(GenBank)_([A-Z0-9]+)/ {$Rep:{"$1\:($ParStr:genbankR)" $2 $2}}| /[^[(`' !<>\n_]+/ | /\\[(\\*[^]]*)\\]/ {$Rep:"$1"} | /`([a-zA-Z0-9]+)`/ {$Rep:"$1"} | /'([a-zA-Z0-9]+)'/ {$Rep:"$1"} | /\\(,([^)]+)\\)/ {$Rep:"$1"} | /\\('([^')]+)\\)/ {$Rep:"$1"} | '<' {$Rep:"<"} | '>' {$Rep:">"} | '_' {$Rep:' '} | /[[(`']/ )+ ~ h_head: ~ {$In:[fields c:head t:hl]} /.*/ {$Rep:"
\n"} ~ h_tail: ~ {$In:[fields c:tail t:hl]} /.*/ {$Rep:"\n
\n"} ~ h_pathway:~ {$In:[fields c:MPW t:hl]} /.* */ /[0-9A-Z]+\\.[0-9A-Z]+/ {$Rep:{$ParStr:mpwR $Ct $Ct}} ~ # other tag: ~ /[A-Z\*][0-9A-Z\*]+/ ~ appLn: ~ /[^\n]*\n/ {$App} ~ more: ~ (/ [^\n]*\n/)* ~ name: ~ /[A-Z0-9a-z-]+/ ~ str: ~ /[^\t \n]+/ ~ ln: ~ /[^\n]*\n/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/opt/srs/data/emp/9311.bnk'] while:$JobHasInput:$job { $JobTokens:[$job name:fields print:0] $JobNext:$job $print:"-------->entry\n" } } /[0-9A-Z]+\\.[0-9A-Z]+/ {$Rep:{$ParStr:mpwR $Ct $Ct}} ~ # other tag: ~ /[A-Z\*][0-9A-Z\*]+/ ~ appLn: ~srs/icarus/db/enzyme.i # $RCSfile: enzyme.i,v $ # $Revision: 1.5 $ # $Date: 1996/08/12 19:04:40 $ # # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ENZYME_DB:$library:[ENZYME group:@SEQRELATED_LIBS comment:" - A. Bairoch" format:@ENZYME_FORMAT maxNameLen:10 ifiles:{"enzyme.i" "enzyme.is"} files:{ $file:enzyme } ] ENZYME_FORMAT:$libformat:[fileType:@DAT_FILE syntax:@ENZYME_SYNTAX tableFormat:left fields:{ $field:@DF_ALL $field:[@DF_ID code:id index:id indexToken:id] $field:[@DF_AltName code:altnam index:str indexToken:i_altnam tableToken:t_altnam] $field:[@DF_Description code:des index:str indexToken:i_des tableToken:t_des] $field:[@DF_CatActivity code:i_catact tableToken:t_catact] $field:[@DF_COMMENT code:cc] $field:[@DF_LINK index:link code:link indexToken:links] } ] ENZYME_SYNTAX:$syntax:[file:"SRSDB:enzyme.is" ignore:" "] DF_CatActivity:$srsfield:[CatalyticActivity short:cat group:@DF_ALL] DF_AltName:$srsfield:[AltName short:alt group:@DF_ALL] #$link:[@ENZYME_DB to:@?SWISSPROT_DB token:'links|swiss' toField:@DF_ACCNO] $link:[@ENZYME_DB to:@?PROSITEDOC_DB token:'links|pr' toField:@DF_ID] s] $field:[@DF_CatActivity code:i_catact tableToken:t_catact] $field:[@DF_COMMENT code:cc] $field:[@DF_LINK index:link code:link indexToken:links] } ] ENZYME_SYNTAX:$syntax:[file:"SRSDB:enzyme.is" ignore:" "] DF_CatActivity:srs/icarus/db/enzyme.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: enzyme.is,v $ # $Revision: 1.7 $ # $Date: 1997/03/03 18:33:55 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $fn={ ID:id CA:catact DI:di '//':sep DE:des CF:cf DR:link AN:altnam CC:cc PR:link } $rules={ entry: ~ {$In:[file:text] $Out pre $Skip:0} ('ID' {$Not} ln)* ('ID ' {$entryFip=$fip $Wrt} ln {$App} ('ID' {$Not} ln {$App})*)? ~ # fields fields: ~ {$In:entry $Out $Skip:1} (/../ { if:$Ct==$prev $App else $Wrt:$fn.$Ct if:$fn.$Ct=="" $dp:"+++ unknown: $Ct +++" $prev=$Ct } ln {$App})+ ~ # indexing id: ~ {$In:[fields c:id] $Out:id} 'ID' /[0-9.]+/ {$Wrt} ~ i_des: ~ {$In:[fields c:des] $Out} ('DE' ( /[A-Za-z0-9_]+/ {$Wrt} | /[^A-Za-z0-9_]+/ )* )* ~ i_altnam: ~ {$In:[fields c:altnam] $Out} ('AN' ( /[A-Za-z0-9_]+/ {$Wrt} | /[^A-Za-z0-9_]+/ )* )* ~ i_catact: ~ {$In:[fields c:catact] $Out} 'CA' /[A-Z0-9_]+/ {$Wrt} ~ cf: ~ {$In:[fields c:cf] $Out:cf} 'CF' /[A-Z0-9_]+/ {$Wrt} ~ cc: ~ {$In:[fields c:cc] $Out:cc} 'CC' /[A-Z0-9_]+/ {$Wrt} ~ di: ~ {$In:[fields c:di] $Out:di} 'DI' /[A-Z0-9_]+/ {$Wrt} ~ links: ~ {$In:[fields c:link] $Out} (/DR/ (name {$Wrt:swiss} ',' name ';')*)* (/PR/ 'PROSITE;' name {$Wrt:pr} ';'?)* ~ # table display t_catact: ~ {$In:[fields c:catact] $Out} /../ ln {$Wrt} (/../ ln {$App})* ~ t_des: ~ {$In:[fields c:des] $Out} /../ ln {$Wrt} (/../ ln {$App})* ~ t_altnam: ~ {$In:[fields c:altnam] $Out} /../ ln {$Wrt} (/../ ln {$App})* ~ # html display hl_links: ~ {$In:[fields c:link t:hl]} ( (/DR/ (name {$Rep:{$ParStr:swissR $Ct $Ct}}',' name ';')* ln) | (/PR/ name ';' name {$Rep:{$ParStr:prositedocR $Ct $Ct}} ln) )* ~ # other name: ~ /[a-zA-Z0-9_]+/ ~ ln: ~ /[^\n]*\n/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/ftp/pub/databases/enzyme/enzyme.dat'] while:$JobHasInput:$job { $JobTokens:[$job name:fields print:1] $JobNext:$job $print:"-------->entry\n" } } (/DR/ (name {$Rep:{$ParStr:swissR $Ct $Ct}}',' name ';')* ln) | (/PR/ name ';' name {$Rep:{$ParStrsrs/icarus/db/enzyme.it # # $RCSfile: enzyme.it,v $ # $Revision: 1.3 $ # $Date: 1996/10/10 16:47:04 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $dbInfo={ description: |The ENZYME data bank contains the following data for each type of |characterized enzyme for which an EC number has been provided: EC number, |Recommended name, |Alternative names, Catalytic activity, Cofactors, Pointers to the SWISS-PROT |entrie(s) |that correspond to the enzyme, Pointers to disease(s) associated with a |deficiency of the enzyme. | |

www: |\ |http://www.gdb.org/Dan/proteins/ec-enzyme.html citation: |Bairoch A. (1993) The ENZYME data bank. Nucleic Acids Res, Jul |1;21(13):3155-6. fields:{ ID: |The ID (IDentification) line is always the first line of an entry. The |format of the ID line is: |

|ID EC NUMBER Description: | The DE (DEscription) line(s) contain the NC-IUB recommended name for an | enzyme. The format of the DE line is: |

| DE DESCRIPTION. |

| Important note: enzymes are sometimes deleted from the EC list, others | are renumbered; however the NC-IUBMB does not allocate the old numbers | to new enzymes. Obsolete EC numbers are indicated in this data bank by | the following DE line syntaxes. For deleted enzymes: |

| DE DELETED ENTRY. |

| and for renumbered enzymes: |

| DE TRANSFERRED ENTRY: x.x.x.x. |

| where x.x.x.x is the new, valid, EC number; as shown in the following | example: |

| DE TRANSFERRED ENTRY: 1.7.99.5. AltName: | The AN (Alternate Name) line(s) are used to indicate the different | name(s), other than the NC-IUBMB recommended name, that are used in the | literature to describe an enzyme. The format of the AN line is: |

| AN NAME. |

Reaction: | The CA (Catalytic Activity) line(s) are used to indicate the reaction(s) | catalyzed by an enzyme. The format of the CA line is: |

| CA REACTION. |

| Where the reaction is indicated following the recommendations of the NC- | IUBMB. The majority of the reactions are described using a standard | chemical reaction format: |

| CA SUBSTRATE_11 + SUBSTRATE_12 [+ SUBSTRATE_1N...] = SUBSTRATE_21 + | CA SUBSTRATE_22 [+ SUBSTRATE_2N]. |

| As shown in the following examples: |

| CA L-MALATE + NAD(+) = OXALOACETATE + NADH. |

| CA 2 ATP + GLUTAMINE + CO(2) + H(2)O = 2 ADP + ORTHOPHOSPHATE + | CA GLUTAMATE + CARBAMOYL PHOSPHATE. |

| In some cases free text is used to describe a reaction. As shown in the | following examples: |

| CA DEGRADES STARCH TO CYCLODEXTRINS BY FORMATION OF A 1,4-ALPHA-D- | CA GLUCOSIDIC BOND. |

| CA CLEAVES LEU-|-LEU BOND IN ANGIOTENSINOGEN TO GENERATE | CA ANGIOTENSIN I. |

| Notes |

| - Subscript and superscript are indicated between brackets: for example | NAD+ and NADP+ are indicated as NAD(+) and NADP(+), H2O as H(2)O, CO2 | as CO(2), etc. | - Greek letters are spelled out. |

Cofactor: | The CO (CoFactor) line(s) are used to indicate which cofactor(s) are | required by an enzyme. The format of the CF line is: |

| CF COFACTOR_1; COFACTOR_2 OR COFACTOR_3[; COFACTOR_N...]. |

Comments: | The CC lines are free text comments on the entry, and may be used to | convey any useful information. |

Disease: | The DI (DIsease) line(s) are used to indicate the known disases(s) | associated with a deficiency of the enzyme. Currently this information | is only given for human diseases listed in the MIM book [2]. |

| [2] McKusick V.A. | Mendelian Inheritance in Man | Catalogs of autosomal dominant, autosomal recessive, and X-linked | phenotypes | Tenth edition | Johns Hopkins University Press, Baltimore, (1991). |

| The format of the DI line is: |

| DI DISEASE_NAME; MIM:NUMBER. |

| Where 'NUMBER' is the MIM catalog number of the disease (or phenotype). |

Ref: | The DR (Data bank Reference) line(s) are used as pointers to the SWISS- | PROT entries that corresponds to the enzyme being described. The format | of the DR line is: |

| DR AC_NB, ENTRY_NAME; AC_NB, ENTRY_NAME; AC_NB, ENTRY_NAME; |

| where: |

| - 'AC_NB' is the SWISS-PROT primary accession number of the entry to | which reference is being made. | - 'ENTRY_NAME' is the SWISS-PROT entry name. |

} date: |25 Jul 1996 signature: |Anatoly Ulyanov } used as pointers to the SWISS- | PROT entries that corresponds to the enzyme being described. The format | of the DR line is: |

| DR AC_NB, ENTRY_NAME; AC_NB, ENTRY_NAME; AC_NB, ENTRY_NAME; |

| where: |

| - 'AC_NB' is the SWISS-PROT prsrs/icarus/db/epd.i # # $RCSfile: epd.i,v $ # $Revision: 1.5 $ # $Date: 1997/03/03 18:33:56 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ EPD_DB:$library:[EPD group:@SEQRELATED_LIBS comment:"Eukariotic Promoter Database - Philipp Bucher (1996)" format:@EPD_FORMAT cachesize:512 ifiles:{"epd.i" "epd.is"} files:{ $file:epd } ] EPD_FORMAT:$libformat:[fileType:@DAT_FILE syntax:@EPD_SYNTAX fields:{ $field:[@DF_ID code:id index:id indexToken:id] $field:[@DF_LINK code:link index:link indexToken:links] $field:[@DF_Organism code:source index:str indexToken:source tableToken:t_source tableFormat:left] $field:[@DF_GeneProduct code:prod index:str indexToken:product tableToken:t_product tableFormat:left] $field:[@DF_Protocol code:prtcl index:str indexToken:protocol tableToken:t_protocol tableFormat:center] $field:[@DF_Express code:exprs index:str indexToken:express tableToken:t_express tableFormat:center] } ] EPD_SYNTAX:$syntax:[file:"SRSDB:epd.is" ignore:" \t"] $link:[@EPD_DB to:@?EMBL_DB token:link toField:@DF_ID] DF_Protocol:$srsfield:[ExpProtocol short:ptc group:@DF_ALL] DF_Express: $srsfield:[ExpresRegul short:ess group:@DF_ALL] tableToken:t_product tableFormat:left] $field:[@DF_Protocol code:prtcl index:str indexToken:protocol tableToken:t_protocol tableFormat:center] srs/icarus/db/epd.is $abbrev={ specie: { # Code Scientific name (English name) # AAV2: 'Adeno-associated virus 2' Ac: 'Aplysia californica (gastropod mollusk)' AcNPV: 'Autographa californica nuclear polyhedrosis virus' Ad2: 'Human adenovirus type 2' Ad5: 'Human adenovirus type 5' Ad7: 'Human adenovirus type 7' Ad12: 'Human adenovirus type 12' Ag: 'Ateles geoffroyi (spider monkey)' ALV: 'Avian leukemia virus' Am: 'Antirrhinum majus (snapdragon)' 'A-MLV': 'Abelson murine leukemia virus' Apo: 'Antheraea polyphemus (silkmoth)' Ap: 'Anas platyrhynchos (mallard, domestic duck)' As: 'Avena sativa' At: 'Agrobacterium tumefaciens' Ath: 'Arabidopsis thaliana (fam. cruciferae)' Atr: 'Aotus trivirgatus (owl or night monkey)' Ay: 'Antheraea yamamai (Japanese oak silkmoth)' B19: 'Human parvovirus B19' Be: 'Bertholletia excelsa (Brazil nut)' BKV: '(Human) papovavirus BK' BLV: 'Bovine leukemia virus' Bm: 'Bombyx mori (silkmoth)' Bn: 'Brassica napus (rape)' BPV1: 'Bovine papilloma virus type 1' Bt: 'Bos taurus (cattle)' C4BP: 'Complement component C4b-binding protein' CaMV: 'Cauliflower mosaic virus' Cc: 'Cricetus cricetus (Chinese hamster)' Cco: 'Coturnix coturnix (Quail)' Ce: 'Caenorhabditis elegans (nematode)' Cg: 'Canavalia gladiata (Japanese jackbean)' Ch: 'Capra hircus (goat)' Cl: 'Canis lupus (dog)' Cm: 'Cairina moschata (muscovy duck)' Cp: 'Cavia porcellus (guinea pig)' Cpe: 'Cucurbita pepo (zucchini)' Ct: 'Chironomus thummi (midge)' Cte: 'Chironomus tentans (midge)' DAF: 'Decay-accelerating factor' Dc: 'Daucus carota (carrot)' Df: 'Drosophila funebris (fruit fly)' Dh: 'Drosophila hydei (fruit fly)' DHBV: 'Duck hepatitis virus' Dm: 'Drosophila melanogaster (fruit fly)' Dma: 'Drosophila mauritiana (fruit fly)' Dmo: 'Drosophila mojavensis (fruit fly)' Dmu: 'Drosophila mulleri (fruit fly)' Do: 'Drosophila orena (fruit fly)' Dp: 'Drosophila pseudoobscura (fruit fly)' Ds: 'Drosophila simulans (fruit fly)' Dse: 'Drosophila sechellia (fruit fly)' Dv: 'Drosophila virilis (fruit fly)' EBV: '(Human) Epstein-Barr virus' Ec: 'Equus caballus (horse)' 'FBJ-MSV': 'Finkel-Biskis-Jinkins murine osteosarcoma virus' 'FBR-MSV': 'Finkel-Biskis-Reilly murine osteosarcoma virus' 'F-MCF': '(Murine) Friend mink cell focus-inducing virus' Fs: 'Felis silvestris (cat)' 'F-SFFV': '(Murine) Friend spleen focus forming virus' Ft: 'Flaveria trinervia (dicot plant)' 'GA-FeLV': 'Gardner-Arnstein feline leukemia virus' GALV: 'Gibbon ape leukemia virus' Gg: 'Gallus gallus (chicken)' Ggo: 'Gorilla gorilla (gorilla)' Gm: 'Glycine max (soybean)' GSHV: 'Ground squirrel hepatitis virus' 'H-1': '(Murine) H-1 parvovirus' Ha: 'Helianthus annuus (sunflower)' Hb: 'Hevea brasiliensis (para rubber tree)' HBV: 'Human hepatitis B virus' HCMV: 'Human cytomegalovirus' Hg: 'Halichoerus grypus (grey seal)' 'HIV-1': 'Human immunodeficiency virus type 1' 'HIV-2': 'Human immunodeficiency virus type 2' HPV16: 'Human Pappilloma virus 16' HPV18: 'Human Pappilloma virus 18' Hs: 'Homo sapiens (man)' 'HSV-1': 'Human herpes simplex virus type 1' 'HSV-2': 'Human herpes simplex virus type 2' 'HTLV-I': 'Human T-cell leukemia virus type I' 'HTLV-II': 'Human T-cell leukemia virus type II' Hv: 'Hordeum vulgare (barley)' HVS: 'Herpesvirus saimiri' JCV: '(Human) papovavirus JC' Le: 'Lycopersicon esculentum (tomato)' Leu: 'Lepus europeaeus (hare)' Lm: 'Locusta migratoria' Lp: 'Lytechinus pictus (sea urchin)' Lpe: 'Lycopersicon peruvianum (wild tomato)' Lv: 'Lytechinus variegatus (sea urchin)' Ma: 'Mesocricetus aureus (golden hamster)' Mc: 'Macaca cynomolgus (macaque)' MCF: 'Mink cell focus-inducing virus' MCMV: 'Murine cytomegalovirus' MLV: 'Murine leukemia virus' Mm: 'Mus musculus (mouse)' 'M-MLV': 'Moloney murine leukemia virus' 'M-MSV': 'Moloney murine sarcoma virus' MMTV: 'Mouse mammary tumor virus' Ms: 'Medicago sativa (alfalfa)' MSV: 'Maize streak virus' Np: 'Nicotiana plumbaginifolia (leadwort-leaved tobacco)' Ns: 'Nicotiana silvestris (wood tobacco)' Nt: 'Nicotiana tabacum (tobacco)' Nto: 'Nicotiana tomentosiformis' Oa: 'Ovis aries (sheep)' Oc: 'Oryctolagus cuniculus (rabbit)' Os: 'Oryza sativa (rice)' Ph: 'Petunia hybrida (e.g. Petunia strain Mitchell)' Pa: 'Papio anubis (olive baboon)' Pc: 'Petroselinum crispum (parsley)' Pl: 'Paracentrotus lividus (sea urchin)' Pm: 'Psammechinus miliaris (sea urchin)' Polyoma: '(Murine) polyoma virus' Ppy: 'Photinus pyralis' Pp: 'Pongo pygmaeus (orangutan)' Ps: 'Pisum sativum (pea)' Pt: 'Pan troglodytes (chimpanzee)' Pth: 'Pinus thunbergii (Japanese black pine)' Pv: 'Phaseolus vulgaris (french bean, kidney bean)' RAV2: '(Avian) Rous associated virus type 2' Rc: 'Ricinus communis' 'R-MCF': '(Murine) Rauscher mink cell focus-inducing virus' Rn: 'Rattus norvegicus (rat)' RSV: '(Avian) Rous sarcoma virus' Sa: 'Sinapis alba (white mustard)' SA7P: 'Simian adenovirus 7P' Sd: 'Strongylocentrotus drobachiensis (sea urchin)' Se: 'Spalax ehrenbergi (blind mole rat)' Sg: 'Salmo gairdneri (rainbow trout)' 'SIV-III': 'Simian immunodeficiency virus type III' SNV: '(Avian) spleen necrosis virus' So: 'Spinacia oleracea (spinach)' Sp: 'Strongylocentrotus purpureatus (sea urchin)' Spe: 'Sarcophaga peregrina (flesh fly)' Sr: 'Sesbania rostrata' Ss: 'Sus scrofa (pig)' SSV: 'Simian sarcoma virus' St: 'Solanum tuberosum (potato)' Sv: 'Sorghum vulgare (sorghum)' SV40: 'Simian virus 40' Ta: 'Triticum aestivum (wheat)' Visna: 'Visna lentivirus' Xb: 'Xenopus borealis (Kenyan clawed frog)' Xl: 'Xenopus laevis (African clawed frog)' Xt: 'Xenopus tropicalis (western clawed frog)' Zm: 'Zea mays (maize)' } # iGene Product Abbreviations # product: { '1-25OH2D3': '1,25-(OH)_2 vitamin D_3' '20-OHE': '20-Hydroxyecdysone' 4CL: '4-coumarate coenzyme A ligase' a1: 'Gene locus 1 involved in anthocyanin biosynthesis' 'abd-g.': 'Abdominal ganglion' abl: 'Abelson murine leukemia virus oncogene' ACC: '1-aminocyclopropane-1-carboxylic acid' AChR: 'Acetylcholin receptor' ACP: 'b^-ketoacyl-acyl carrier protein of fatty acid synthase' ACTH: 'Adrenocorticotropic hormone' ADA: 'Adenosine deaminase' ADH: 'Alcohol dehydrogenase' 'ADPg-s': 'GT ADPglucose-starch glucosyltransferase' 'adult-HA': 'Adult hermaphrodite' AFW1: 'Adult fast-white (myosin heavy chain) 1' Ag: 'Antigen' '(AGM)': '"from african green monkey"' AGP: 'Acid glycoprotein' AGPP: 'ADP glucose pyrophosphorylase' AIRS: 'Aminoimidazole ribonucleotide synthase' 'ALA-synt.': '5-Aminolevulinate synthase' ALDH_2: 'Aldehyde dehydrogenase 2' AlkExo: 'Alkaline exonuclease' Amy: 'Amylase' antp: '"antennapedia" locus' aP2: 'Adipocyte homologue of myelin P2' 'apolipop.': 'Apolipoprotein' apoVLDLII: 'Very low densitiy apolipoprotein II' APRT: 'Adenine phosphoribosyltransferase' AR: 'Adrenergic receptor' ARF: 'ADP-ribosylation factor' arg: 'Arginine' AS: 'Argininosuccinate synthetase' 'AS-C': '"achaete-scute" complex locus' AspAT: 'Aspartate aminotransferase' 'ass.': 'Associated' AT: 'Antitrypsin' ATIII: 'Antithrombin III' ATCase: 'Aspartate transcarbamylase' ATP: 'Adenosinetriphosphate' awd: '"abnormal wing disk" locus' BB: 'Bowman-Birk (protease inhibitor)' BCKDHA: 'Branched-chain alpha-keto acid dehydrogenase complex' 'Bcl-2': 'B-cell leukemia/lymphoma 2 proto-oncogene' BPTI: 'Bovine pancreatic trypsin inhibitor' BSF: 'B-cell stimulating factor' bsg25D: 'Blastoderm specific locus 25D' 'c-': 'Cellular protooncogene ' c1: 'Regulatory locus of anthocyanin synthesis (maize)' CA: 'Carbonic anhydrase' cab: 'Chlorophyll a/b-binding protein' cAMP: 'Cyclic AMP (Adenosinemonophosphate)' 'card-m': 'Cardiac muscle' 'cc-ind.': 'Cell cycle-independent' CD3: 'T-cell differentiation antigen CD3' CD4: 'T-cell differentiation antigen CD4' CD8: 'T-cell differentiation antigen CD8' CEA: 'Carcinoembryonic antigen' CG: 'Chorionic gonadotropin' CNS: 'Central nervous system' CNTF: 'Ciliary neurotrophic factor' 'car.': 'Cartilage' 'col.': 'Collagen' 'conglyc.': 'Conglycinin' 'cor.': 'Cornea' 'cotyl.': 'Cotyledon' cp: 'Cytoplasm(ic)' CPS: 'Carbamyl-phosphate synthetase' CRF: 'Corticotropin-releasing factor' CRP: 'C-reactive protein' cs: 'Cytosol(ic)' CSF: 'Colony stimulating facter' cyt: 'Cytokinin gene (coding for isopentenyltransferase)' dbp: 'DNA binding protein' DDC: 'DOPA decarboxylase' 'dep.': 'dependent' 'dev.': 'Development(ally)' DHFR: 'Dihydrofolate reductase' 'diff.': 'differentiation, differentiated' 'DL/R': 'Left and right duplicated region' dUTPase: 'Deoxyuridinetriphosphatase' E: '1. Early, 2. Erythroid cell-specific' E8: 'Ethylene inducible gene during fruit ripening 8' EAS: '5-epi-aristolochene synthase (sesquiterpene cyclase)' EBNA: 'Epstein-Barr virus nuclear antigens' 'ecd-ind.': 'Ecdysone-inducible' EDF: 'Eosinophil differentiation factor' EFW1: 'Embryonic fast-white (myosin heavy chain) 1' EGF: 'Epidermal growth factor' EIa: 'Adenovirus early Ia region (transactivating element)' Eip: 'Ecdysone-induced protein' ELH: 'Egg-laying hormone' em: 'Embryo, embryonic' EPSP: '5-Enolpyruvylshikimate-3-phosphate' erbA: '(Avian) erythroblastosis virus oncogene A' erbB: '(Avian) erythroblastosis virus oncogene B' 'E-resp.': 'Estrogen-responsive' ERV3: 'Endogenous retrovirus 3' 'E.Tn': 'Early transposon' 'et-hypocot.': 'Etiolated hypocotyl' ev1: '(Avian) endogenous virus 1' eve: '"even-skipped" locus' 'exch.': 'Exchanger' 'f.': 'Factor' 'fibrob.': 'Fibroblasts' FMRFamide: 'Phe-Met-Arg-Phe-NH(2) neuropeptide' FNR: 'Ferredoxin-(NADP+)-oxidoreductase' fos: 'FBJ (Finkel-Biskis-Jinkins) osteosarcoma virus oncogene' FSH: 'Follicle stimulating hormone' ftz: '"fushi tarazu" locus' 'g.': 'Gene' G0S: 'G0/G1 switch regulatory gene ' G6PD: 'Glucose-6-phosphate dehydrogenase' GA: 'Gibberellic acid' GADPH: 'Glyceraldehyde-3-phosphate dehydrogenase' GARS: 'Glycinamide ribonucleotide synthase' Gart: '"Gart" locus (-> GARS, AIRS, GART)' GART: 'Glycinamide ribonucleotide transformylase' gC: 'Glycoprotein C' 'G-CSF': 'Granulocyte colony stimulating factor' gD: 'Glycoprotein D' GdX: 'X-linked gene downstream of G6PD gene' gE: 'Glycoprotein E' GFAP: 'Glial fibrillary acidic protein' gln: 'Glutamine' 'globul-12s': '12s globulin (oat seed storage protein)' glucc: 'Glucocorticoid' GLUT1: 'Glucose transporter type 1' 'GM-CSF': 'Granulocyte/Macrophage colony stimulating factor' GnRH: 'Gonadotropin-releasing hormone' gp: 'Glycoprotein' GPD: 'Glycerol-3-phosphate dehydrogenase' GRF: 'Growth hormone-releasing factor' GRP: 'Glycine-rich (cell wall) protein' GS17: 'Gastrula-specific transcript 17' GSHPx: 'Gluthathione peroxidase' 'G-spec.': 'Gastrula-specific' GST: 'Gutathione S-transferase' H: '1. Heavy chain, 2. Housekeeping-type promoter' 'Ha-ras': 'Rat-derived Harvey murine sarcoma virus oncogene' hb: '"hunchbank" locus' Hc: 'High-cysteine (chorion protein)' HGT: 'High-(glycine+tyrosine) keratin' 'hist.': 'Histone' 'HMG-': 'High mobility group chromosomal protein' 'HMG-CoA': '3-Hydroxy-3-methylglutaryl coenzyme A' HPRT: 'Hypoxanthine phosphoribosyltransferase' hs: 'Heatshock' hsc: 'Constitutive analogue of heatshock gene/protein' HSF: 'Hepatocyte-stimulating factor' hsp: 'Heatshock protein' HTF: 'Restriction endonuclease HpaII tiny fragments' 'I-FABP': 'Intestinal fatty-acid binding protein' IAA: 'Indolacetic acid' IAP: 'Intracisternal A-particles' ICP: 'Infected cell protein' IE: 'Immediate early (gene, RNA)' IF: 'Intermediate filament' IFI: 'Interferon-induced gene/protein' IFN: 'Interferon' Ig: 'Immunoglobulin' IGF: 'Insulin-like growth factor' IL: 'Interleukin' 'inf.': 'Infected' 'inh.': 'Inhibitor' ISG: 'Interferon-stimulated gene' 'k.': 'Kinase' 'Ki-ras': 'Rat-derived Kirsten murine sarcoma virus oncogene' L: '1. Light chain; 2. Late' larva: 'instar larva' LAT: 'Lycopersicon anther-specific gene ' LCAT: 'Lecithin-cholesterol acyltransferase' LDH: 'Lactate dehydrogenase' 'leghem.': 'Leghemoglobin' LeIF: 'Leukocyte interferon' LH: 'Luteinizing hormone' LHC: 'Light-harvesting complex' LHRH: 'Luteinizing hormone-releasing factor' LMW: 'Low molecular weight' LPH: 'Lipotropic hormone' LPS: 'Lipopolysaccharide' MBP: 'Myelin basic protein' '(MAC)': 'Macaque' MC: 'Methylcholanthrene' MCK: 'Muscle-specific creatine kinase' mGK: 'Submaxillary gland kallikrein' 'MHCI/MHCII': 'Class I/II transplantation antigens of major histocompatibility complex' MIF: 'Macrophage migration inhibitory factor' mit: 'Mitochondrial' 'mononuc-c.': 'Mononuclear cells' MOPC: 'Mineral oil-induced plasmacytoma' mos: 'Moloney murine sarcoma virus oncogene' MP: 'Macrophage' MPC: 'Mouse plasma cell tumor' MRP: 'MIF-related protein (see MIF)' MSF: 'Megakaryocyte stimulating factor' msp: 'Major sperm protein gene' MT: 'Metallothionein' mst: 'Male-specific transcript' MUP: 'Major urinary protein' myb: '(Avian) myeoloblastosis virus oncogene' myc: 'Myelocytomatosis virus 29 oncogene' NCA: 'nonspecific cross-reacting (with -> CEA) antigen' neu: 'Ethyl-nitrosurea-induced rat neuroblastoma oncogene' 'neuropep.': 'Neuropeptide' NGF: 'Nerve growth factor' ninaE: '"neither inactivation nor afterpotential" locus E' NMDH: 'NADP-malate dehydrogenase' nos: 'Nopaline synthetase' NR: 'Nitrate reductase' 'N-ras': 'Neuroblastoma ras-like (-> Ha-ras) oncogene' NS: 'Nervous system' OAT: 'Ornithine aminotransferase' ocs: 'Octopine synthetase' ODC: 'Ornithine decarboxylase' Ori: 'Origin of replication' OTC: 'Ornithine transcarbamylase' 'ovalb.': 'Ovalbumin' 'p.': 'Protein' 'P-450': 'Cytochrome P-450' p53: '53K phosphoprotein' 'panc.': 'pancreas, pancreatic' 'parath.': 'Parathyroid' PB: 'Phenobarbital' PBGD: 'Porphobilinogen deaminase' PCNA: 'Proliferating cell nuclear antigen' PDGF: 'Platelet-derived growth factor' PEPCase: 'Phosphoenolpyruvate carboxylase' PEPCK: 'Phosphoenolpyruvate carboxykinase' PG: 'Prostaglandin' PGK: '3-Phosphoglycerate kinase' PHA: 'Phytohemagglutinin' PK: 'Protein kinase' P_L: 'Late promoter' PLP: 'Proteolipid protein' POL: 'Polymerase' POMC: 'Proopiomelanocortin' pp: 'Phosphoprotein ' PR1a: 'Pathogenesis-related protein 1a' PRBP: 'Plasma retinol-binding protein' PRL: 'Prolactin' 'prog.': 'Progesterone' prolyl: '4-hydr. Prolyl 4-hydroxylase' PrP: 'Prion protein' PSG: 'Pregnancy-specific glycoproteins ' PSBP: 'Prostatic steroid binding protein' PSP: 'Parotid secretory protein' PTH: 'Parathyroid hormone' pTiN: 'Nopaline type tumor inducing plasmid' pTiO: 'Octopine type tumor inducing plasmid' r: '"rudimentary" locus' R: '1. Regulatory subunit, 2. Erythroid cell-specific' RAB: 'Gene responsive to ABA' ras: 'Homologue of -> Ha-ras, Ki-ras, etc.' 'rec.': 'Receptor' 'red.': 'Reductase' 'reg.': 'Regulated' 'rep-dep.': 'Replication-dependent' rig: 'Rat insulinoma gene' RnBP: 'Renin-binding protein' RNR2: 'Ribonucleotide reductase large, small subunit' rp: 'Ribosomal protein' rTn: 'Retrotransposon' RuBPCss: 'Ribulose-1,5-biphosphate carboxylase small subunit' RuBPCA: 'Ribulose-1,5-biphosphate carboxylase/oxygenase activase' 's.': 'Small' 'saliv-g.': 'Salivary gland' SBP: 'Spermine-binding protein' 'sem-v.': 'Seminal vesicle' 'ser.': 'Serum' sgs: 'Salivary gland secretion protein' sis: 'Simian sarcoma virus oncogene' 'sk-m.': 'Skeletal muscle' 'skel-m.': 'Skeletal muscle' 'smooth-m.': 'Smooth muscle' snRNA: 'Small nuclear RNA' snrp: 'Small nuclear ribonucleoprotein' SOD: 'Superoxide dismutase' som: 'Somatic' 'spat-reg.': 'Spatially regulated' Spec: 'Strongylocentrotus purpureatus ectoderm enriched RNA' sry: '"serendipity" locus' SV40T: 'Tumor antigen of simian virus 40 (SV40)' SVS: 'Seminal vesicle secretory protein' synt: '^Synthase^' T3d: 'T-cell antigen receptor-associated T3-complex delta chain' TAT: 'Tyrosine aminotransferase' TCDD: '2,3,7,8-Tetrachlorodibenzo-p-dioxin' TCGF: 'T-cell growth factor' TCR: 'T-cell receptor' TdT: 'Terminal deoxynucleotidyltransferase' 'test.': 'testis' TF: 'Transcription factor' TGA1a: 'TGACG-specific DNA-binding protein 1a' 'TGF-b': 'Transforming growth factor beta' TH: 'Tyrosin hydroxylase' 'thyr.': 'Thyroxine' 'Thy-1.2': 'Thy-1 (thymocyte) antigen/glycoprotein allotype 2' TIF: 'Trans-inducing factor' TIM: 'Triosephosphate isomerase' 'tis.': 'Tissue' TM: 'Tropomyosin' tmr: '"tumor morphology root" locus' TNF: 'Tumor necrosis factor' TnT: 'Troponin T (tropomyosin-binding subunit)' TO: 'Tryptophan oxygenase' TP1: 'Transition protein 1' TP2: 'Transition protein 2' TPA: '12-O-tetradecaonyl-phorbol-13-acetate' TPI: 'Triosephosphate isomerase' 'tr.': 'Transcript' 'tr-': 'Transcript' TRF: 'T-cell replacing factor' TRH: 'Thyrotropin-releasing hormone' TS: 'Thymidylate sythetase' TSH: 'Thyroid stimulating hormone' 'T/t': 'Large/small T(tumor) antigen' Ubx: '"ultrabithorax" locus' uPA: 'Urine plasminogen activator' 'URO-D': 'Uroporphyrinogen decarboxylase' Vg1: 'Vegetal hemisphere-specific mRNA 1' 'vir-inf.': 'Viral infection' VL30: 'Retrovirus-like 30s RNA' V_NP: '(Immunoglobulin heavy chain) variable region specific for 4-hydroxyl-3-nitrophenacetyl' VP5: 'Virion protein 5 (HSV-1/2: =major capsid protein)' VSP: 'Virion stimulatory protein' vWf: 'von Willebrand factor' Zen: '"zerknuellt" protein' } } $rules={ entry: ~ {$In:[file:text] $Out:entry} ('FP' {$Not} ln)* ('FP ' {pre {$entryFip = $Fip} $Wrt} ln {$App} ('//' {$Not} ln {$App})*)? ~ # fields fields: ~ {$In:entry $Out} f_id f_com? f_doc ~ f_id: ~ {$Wrt:id} 'FP ' ln ~ f_com: ~ {$Wrt:com} 'XX' ln ~ f_doc: ~ {$Wrt:doc} ('DO ' ln)* ~ # substitute abbreviations ab_spec: ~ {$In:[fields c:id] $Out} 'FP' /[A-Za-z0-9-]+/ {if:[$abbrev.specie.$Ct != ''] $Wrt:[s:$abbrev.specie.$Ct] else $Wrt:[s:$Ct]} ~ ab_prod: ~ {$In:[fields c:id] $Out} 'FP' /[^ ]+/ (/[^:][^ :]+/ { if:[$abbrev.product.$Ct != ''] $Wrt:[s:$abbrev.product.$Ct] else $Wrt:[s:$Ct]} /'/? )* ~ ab_proto: ~ '(' {$exp="related"} | '<' {$exp="low-precision"} | /[0-9]+/ {$exp=$Ct} | '*' {$exp="in_vitro"} | 'o' {$exp="oocyte"} | '#' {$exp="transfected"} | '!' {$exp="transgenic"} ~ # indexing id: ~ {$In:[fields c:id] $Out:id} x{$Mov:56} ' '? /[A-Z0-9_]+/ {$Wrt} ~ link: ~ {$In:[fields c:id] $Out} x{$Mov:34} /[A-Z0-9_]+/ {$Wrt} ~ source: ~ {$In:ab_spec $Out:source} ('('? /[^ )(,]+/ {$Wrt} /[)(,]/?)* ~ product: ~ {$In:ab_prod $Out:product} ('('? /[^ )(,]+/ {$Wrt} /[)(,]/?)* ~ protocol: ~ {$In:[fields c:doc] $Out} (('DO Experimental evidence:' (ab_proto {$Wrt:[s:$exp]} /[)>,\/]/?)*) | ln)* ~ express: ~ {$In:[fields c:doc] $Out} (('DO Expression/Regulation:' (/[\[(+-]+/? /[A-Za-z0-9_':-]+/ {$Wrt} /[\]);,.+-]+/?)* | ln) | ln)* ~ doc: ~ {$In:[fields c:doc] $Out} ('DO' ( ('Experimental evidence:' (ab_proto {$Wrt:[prot s:$exp]} /[)>,\/]/? )* ln ) | ('Expression/Regulation:' ( /[(+-]+/? /[A-Za-z0-9_':-]+/ {$Wrt:regul} /[);,.+-]+/? )* ln )))* ~ sequence: ~ {$In:[fields c:id] $Out:id} x{$Mov:34} /[A-Z0-9_]+/ {$accN=$Ct} /[01]/ {$type=$Ct} /[+-]/ {$dir=$st} /[0-9]+/ ~ # table display t_source: ~ {$Out $In:[fields c:id]} 'FP' /[A-Za-z0-9-]+/ {$Wrt} ~ t_product: ~ {$Out $In:[fields c:id]} 'FP' /[^ ]+/ /[^:]+/? {$Wrt} ~ t_protocol: ~ {$Out $In:[fields c:doc]} (('DO Experimental evidence:' /[^\n]*/ {$Wrt} ) | ln )* ~ t_express: ~ {$Out $In:[fields c:doc]} (('DO Expression/Regulation:' /[^\n]*/ {$Wrt} ) | ln )* ~ # HTML display hl_links: ~ {$In:[fields c:id t:hl]} x{$Mov:34} /[A-Z0-9_]+/ {$Rep:{$ParStr:epdR $Ct $Ct}} ~ # other ln: ~ /[^\n]*\n/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/epd/epd.dat'] while:$JobHasInput:$job { $JobTokens:[$job name:link print:1] $JobNext:$job $print:"-------->entry\n" } } $In:[fields c:doc]} (('DO Expression/Regulation:' /[^\n]*/ {$Wrt} ) | ln )* ~ # HTML display hl_links: ~ {$In:[fields c:id t:hl]} x{$Mov:34} /[A-Z0-9_]+/ {$Rep:{$ParStr:epdR $Ct $Ct}} ~ # other ln: ~ /[^\n]*\n/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/epd/epd.dsrs/icarus/db/epd.it # # $RCSfile: epd.it,v $ # $Revision: 1.2 $ # $Date: 1996/10/10 16:47:05 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $dbInfo={ description: |The Eukaryotic Promoter Database EPD was designed and developed at |the WeizmannInstitute of Science in Rehovot (Israel) and is currently |maintained at ISREC inEpalinges s/Lausanne (Switzerland). EPD is a |specialized annotation database ofthe EMBL Data Library. It provides |information about eukaryotic promoters avail-able in the EMBL Data |Library and is intended to assist experimental research-ers, as well as |computer analysts, in the investigation of eukaryotic transcrip-tion |signals. The present version originated from a previous compilation |pub-lished in an article (1) and is organized as a hierarchically |ordered and docu-mented "functional position set" (2) pointing to |transcription initiation sites. All information is directly abstracted |from scientific literature and is thusindependent of the EMBL sequence |entry descriptions. As a consequence, many ofthe initiation sites |referred to in EPD do not appear in corresponding EMBLfeature tables. |

A co-ordinated updating procedure has been set up by the two |laboratories thatwill ensure future compatibility between the position |references in EPD and thesequence data in the main data library. |Investigators who access EMBL via pub-licly available programs should |be aware of the fact that software producers oc-casionally modify the |sequence data in ways that render position referencesinaccurate. EPD is |generally not compatible with sequence data of anotherrelease because |EMBL sequence entries are not designed as stable data units.

The |completeness and accuracy of EPD greatly benefits from user-feedback. |Anyreport of mistakes or omissions would be very much appreciated. |Direct communi-cation of newly published transcript mapping or gene |expression data is alsowelcome. Please forward all correspondence |to the address given on top of thisdocument. Use electronic mail if |possible. more: '' citation: '' ftpSite:'' fields:{ ID: |The entry code is a five-digit number which is the only part of a |promoter entry that is stable from release to release. The first two |digits designate the release of initial appearance. Organism: |Species codes consist of the |initials of genus and species name. Occasionally, three characters |are required to generate unique codes. Standard abbreviations identify |viruses. The full names of the organisms can be used in a query. The |names are given in appendix B.1. Subspecies or strains are specified |in parentheses. |Chromosomal locations (genetic or cytogenetic loci, genomic map |units, etc.) appear in square brackets immediately following species |codes. GeneProduct: |Many gene products are listed in appendix B.3. Alternative initiation |sites are identified by right-justified P1,P2.., or E1,E2.., depending |on whether the corresponding 5'exons are 3'co-terminal or not. The |strongest initiation site is marked by trailing + if known. ExpProtocol: |Special characters appended to the number codes designate an |experimental geneexpression system where the RNA for the corresponding |experiments wassynthesized. A query may have next key words: |

    |
  • related |
  • low-precision |
  • in_vitro |
  • oocyte |
  • transfected |
  • transgenic |
|or the transcript mapping experiments number that define the promoter, |that gives information about expression and regulation. The varies |experimental techniques are identified by number codes: | |
codesexperiments |
1direct RNA sequencing |
2length measurement of an RNA product |
3length measurement of a nuclease-protected complementary |RNA or DNA fragment by comparison with homologous sequence ladder |
4same as 3 but with heterologous size markers |
5RNA sequencing by dideoxy-terminated primer extension |
6DNA Sequencing of an in vitro generated strong-stop cDNA or |a full-length cDNA clone |
7length measurement of a primer-extension product by |comparison with homologous sequence ladder |
8same as 7 but with heterologous size markers |
9DNA sequencing of a full-length processed pseudogene |
10length measurement of a reverse direction primer-extension |product (blocked by RNA 5'end) by comparison with homologous sequence |ladder |
ExpresRegul: |The information on expression/regulation may include indication of |developmentalstages, tissues, cell types, cell cycle stages, and |various regulatory features. |
|
;
delimits different types of specifications | (e.g. developmental stage and tissue). | |
,
delimits alternative keywords (e.g. liver, kidney) | |
+
means "induced by" or "strongly expressed in". | |
-
means "repressed by" or "weakly expressed in". | |
~
means "modulated by". | |
[...]
delimits cell cycle stages. |
} date: |25 Jul 1996 signature: |Anatoly Ulyanov } of specifications | (e.g. developmental stage and tissue). | |
,
delimsrs/icarus/db/esther.is $rules={ entry: ~ { $Out pre $Skip:0} (/[0-9]+ / {$Not} ln)* (/[0-9]+ / {$Wrt $entryFip=$Fip} ln {$App} (/[0-9]+ / {$Not} ln {$App})+)? ~ ln: ~ /[^\n]*\n/ ~ } if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:"/u/etzold/data/databases.data/Esther/shaff.txt"] while:$JobHasInput:$job { $JobTokens:[$job name:entry print:1] # $JobTokens:[$job name:nucPos print:1] # $JobTokens:[$job name:nucChange print:1] $JobNext:$job $print:"-------->entry\n" } } (/[0-9]+ / {$Not} ln)* (/[0-9]+ / {$Wrt $entryFip=$Fip} ln {$App} (/[0-9]+ / {$Not} ln {$App})+)? ~ ln: ~ /[^\n]*\n/ ~ } if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:"/u/etzold/data/databases.data/Esther/shaff.txt"] while:$JobHasInput:$job { $JobTokens:[$job name:entry print:1] # $JobTokens:[$job name:nucPos print:1] # $JobTokens:[$job name:nusrs/icarus/db/fasta.i # $RCSfile: fasta.i,v $ # $Revision: 1.4 $ # $Date: 1997/03/03 18:33:56 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FASTA_DB:$library:[FASTA group:@APPLICATION_LIBS comment:"" format:@FASTA_FORMAT maxNameLen:40 ifiles:{"fasta.i" "fasta.is"} type:user files:{ $file:tmp } ] FASTA_FORMAT:$libformat:[fileType:@FASTA_FILE syntax:@FASTA_SYNTAX fields:{ $field:[@DF_ID code:title index:id indexToken:id] $field:[@DF_Init1 code:scores1 index:int indexToken:init1 tableToken:init1 tableFormat:right] $field:[@DF_Initn code:scores1 index:int indexToken:initn tableToken:initn tableFormat:right] $field:[@DF_OptScore code:scores1 index:int indexToken:opt tableToken:opt tableFormat:right] $field:[@DF_PercentIdent code:scores2 index:int indexToken:percIdent tableToken:percIdent tableFormat:right] $field:[@DF_Alignment code:align tableToken:t_align tableFormat:left] # $field:[@DF_QueryBeg code:align index:int indexToken:queryBeg] # $field:[@DF_QueryEnd code:align index:int indexToken:queryEnd] # $field:[@DF_MatchLen code:align index:int indexToken:matchLen # tableToken:matchLen tableFormat:right] $field:[@DF_LINK code:title index:link indexToken:link] } ] DF_Init1:$srsfield:[Init1 short:in1] DF_Initn:$srsfield:[Initn short:inn ] DF_OptScore:$srsfield:[OptScore short:opt] DF_PercentIdent:$srsfield:[PercentIdentity short:pid] FASTA_SYNTAX:$syntax:[file:"SRSDB:fasta.is" ignore:" "] FASTA_FILE:$filetype:[typename:fasta maxline:500] # links $link:[@FASTA_DB to:@?SWISSPROT_DB token:'link|swiss' toField:@DF_Accession] $link:[@FASTA_DB to:@?SWISSNEW_DB token:'link|swissnew' toField:@DF_Accession] $link:[@FASTA_DB to:@?PIR_DB token:'link|pir' toField:@DF_Accession] $link:[@FASTA_DB to:@?TREMBL_DB token:'link|trembl' toField:@DF_Accession] $link:[@FASTA_DB to:@?TREMBLNEW_DB token:'link|tremblnew' toField:@DF_Accession] ty short:pid] FASTA_SYNTAX:$syntax:[file:"SRSDB:fasta.is" ignore:" "] FASTA_FILE:$filetype:[typename:fasta maxline:500] # links $link:[@FASTA_DB to:@?SWISSPROT_DB token:'link|swiss' toField:@DF_Accession] $link:[@FASTA_DB to:@?SWISSNEW_DB token:'link|swissnew' toField:@DF_Accession] $link:[@FASTA_DB to:@?PIR_DB token:'link|pir' toField:@DF_Accession] $link:[@FASTA_DB to:@?TREMBL_DB token:'link|trembl' toField:@DF_Accession] $link:[@FASTA_DB to:@?TREMBLNEW_DB token:'link|tremblnew' srs/icarus/db/fasta.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: fasta.is,v $ # $Revision: 1.7 $ # $Date: 1997/03/03 18:33:57 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $rules={ entry: ~ {$In:[file:text] $Out pre{$Skip:0} init{$count=0}} ('>>' {$Not} ln)* ('>>' {$Wrt $entryFip=$Fip $count+=1} appLn ('>>' {$Not} appLn)+ )? ~ # data fields fields: ~ {$In:entry $Out $Skip:1} /(.*)(initn:[^\n]+\n)/ {$Wrt:[title s:"$1\n"] $Wrt:[scores1 s:"$2"]} ln {$Wrt:scores2} /.+/ {$Wrt:align} ~ # indexing id: ~ {$In:[fields c:title] $Out} />>([^|]+)\\|[^|]+\\|([A-Z0-9a-z_]+)/ {$Wrt:[s:"$count\_$1_$2"]} ~ init1: ~ {$In:[fields c:scores1] $Out} /.*init1: *([0-9]+)/{$Wrt:[s:$1]}~ initn: ~ {$In:[fields c:scores1] $Out} /.*initn: *([0-9]+)/{$Wrt:[s:$1]}~ opt: ~ {$In:[fields c:scores1] $Out} /.*opt: *([0-9]+)/{$Wrt:[s:$1]} ~ percIdent:~ {$In:[fields c:scores2] $Out} /.+ ([0-9.]+)%/ {$Wrt:[s:$1]} ~ queryBeg: ~ {$In:[fields c:align] $Out} /[ \n]+([0-9]+)/ {$b=$1 $Wrt:[s:$1]} ~ queryEnd: ~ {$In:[fields c:align] $Out} /.* ([0-9]+) *\n *[a-zA-Z0-9]/ {$e=$1 $Wrt:[s:$1]} ~ matchLen: ~ {$Out pre{$Request:queryEnd $Request:queryBeg $Wrt:[s:($e-$b+1)]}} / /~ link: ~ {$Out $In:[fields c:title]} '>>'(/(sw|swiss|swissprot|sp)\\|/{$dp:$Ct} name {$Wrt:swiss})?~ # table display t_align: ~ {$Out $In:[fields c:align]} /.+/ {$Wrt:[s:""]} ~ # html display h_title: ~ {$In:[fields c:title t:html]} '>>' ('sp|' name {$Rep:{$ParStr:swissR $Ct $Ct}})? ~ # other name: ~ /[a-zA-Z0-9_]+/ ~ appLn: ~ /[^\n]*\n/ {$App} ~ ln: ~ /[^\n]*\n/ ~ } if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'u/etzold/tmp.fasta'] while:$JobHasInput:$job { $JobTokens:[$job name:fields print:1] $JobTokens:[$job name:id print:1] $JobNext:$job $print:"----------------------------------------------\n" } } splay h_title: ~ {$In:[fields c:title t:html]} '>>' ('sp|' name {$Rep:{$ParStr:swissR $Ct $Ct}})? ~ # other name: ~ /[a-zA-Z0-9_]+/ ~ appLn: ~ /[^\n]*\n/ {$App} ~ ln: ~ /[^\n]*\n/ ~ } if:$TestMode { $job srs/icarus/db/flygene.i # $RCSfile: flygene.i,v $ # $Revision: 1.4 $ # $Date: 1996/12/06 22:17:39 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FLYGENE_DB:$library:[FLYGENE group:@GENOME_LIBS format:@FLYGENE_FORMAT maxNameLen:15 ifiles:{"flygene.i" "flygene.is"} files:{ $file:genes } ] FLYGENE_FORMAT:$libformat:[fileType:@TXT_FILE syntax:@FLYGENE_SYNTAX printFormat:table2 tableFormat:left fields:{ $field:[@DF_ID code:id index:id indexToken:id tableToken:id] # $field:[@DF_FullName code:e index:str indexToken:e] # $field:[@DF_GenMapPos code:b index:str indexToken:b] $field:[@DF_MinCytologicLoc code:c index:str indexToken:'c|min'] $field:[@DF_MaxCytologicLoc code:c index:str indexToken:'c|max'] } ] FLYGENE_SYNTAX:$syntax:[file:"SRSDB:flygene.is" ignore:" "] DF_FullName:$srsfield:[FullName short:fnm group:@DF_ALL] DF_GenMapPos:$srsfield:[GeneticMapPosition short:gmp] DF_MinCytologicLoc:$srsfield:[MinCytologicLocation short:mcl] DF_MaxCytologicLoc:$srsfield:[MaxCytologicLocation short:xcl] #$link:[@FLYGENE_DB to:@?EMBL_DB toField:@DF_Accession token:'dr|embl'] $field:[@DF_MinCytologicLoc code:c index:str indexToken:'c|min'] $field:[@DF_MaxCytologicLoc code:c index:str indexToken:'c|max'] } ] FLYGENE_SYNTAX:$syntax:[file:"SRSDB:flygene.is" ignore:" "] DF_FullName:$srsfield:[FullName short:fnm group:@DF_ALL] DF_GenMapPos:$srsfield:[GeneticMasrs/icarus/db/flygene.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: flygene.is,v $ # $Revision: 1.3 $ # $Date: 1996/12/06 16:37:30 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $fn={ a: "Gene symbol" b: "Genetic map position" c: "Cytological map position" d: "Function(s) of product" e: "Full name" g: "D. mel. DNA/RNA AC no(s)" h: "D. spp. DNA/RNA AC no(s)" i: "Synonym(s)" j: "Non-Drosophila homologue" k: "Phenotypic information" l: "Length (type\\ends\\total)" m: "D. mel. protein AC no(s)" n: "D. spp. protein AC no(s)" o: "Origin/mutagen" p: "Phenotypic information" q: "Miscellaneous information on genes and alleles" r: "Copy number" s: "Molecular biology data" t: "Target site duplication" u: "Other information" w: "Discoverer(s)" x: "Genes References" y: "Secondary FlyBase id(s)" z: "FlyBase gene id number" A: "Allele" B: "Revised genetic map posn." C: "Associated cytology" D: "Revised cyto. map posn." E: "References" F: "Enzyme name/number(s)" H: "Last update" J: "Prosite protein domains" K: "RNA space/time distrib." N: "Cyto. location of clone" O: "Progenitor allele/chromosome" R: "Misc. allele information" S: "Open reading frame size" T: "cDNA clone length" U: "RNA in situ distribution" V: "Protein distribution" Y: "Transcript size(s)" Z: "Genomic length of clone" } $dbRef={SWP:swiss PIR:pir} $rules={ entry: ~ {$In:[file:text] $Out pre $Skip:0} ('*a' {$Not} ln)* ('*a' {$entryFip=$Fip $Wrt} ln {$App} ('*a' {$Not} ln {$App})+)? ~ fields: ~ {$In:entry $Out $Skip:1} (/\\*([a-zA-Z])/ {if:$1==$prev $App else $Wrt:$1 $prev=$1} ln {$App})+ ~ # indexing id: ~ {$In:[fields c:a] $Out} tag /[^ \n]+/ {$Wrt} ~ c: ~ {$In:[fields c:c] $Out} tag (/[A-Z0-9a-z]+/ {$Wrt:min} /-+([A-Z0-9a-z]+)/? {$Wrt:[max s:$1]})? ~ # html h_x: ~ {$In:[fields t:html c:x]} tag name {$Rep:{"
($ParStr:flyrefsR)" $Ct $Ct}} '==' {$Rep:"
"} ln (tag name {$Rep:{"
($ParStr:flyrefsR)" $Ct $Ct}} '==' {$Rep:"
"} ln)* x{$Rep:"
"} ~ h_E: ~ {$In:[fields t:html c:E]} tag name {$Rep:{$ParStr:flyrefsR $Ct $Ct}} ~ h_g: ~ {$In:[fields t:html c:g]} (tag name {$Rep:{$ParStr:emblR $Ct $Ct}} ln)+ ~ h_m: ~ {$In:[fields t:html c:m]} (tag name {$db=$Ct} '/' name {$Rep:{$ParStr:"($dbRef.$db)R" $Ct $Ct}} ln)+ ~ h_J: ~ {$In:[fields t:html c:J]} tag x{$Rep:"
  • "} name {$Rep:{$ParStr:prositeR $Ct $Ct}} ln (tag x{$Rep:"
  • "} name {$Rep:{$ParStr:prositeR $Ct $Ct}} ln)* x{$Rep:"
"} ~ h_fields: ~ {$In:[fields t:html]} /\\*([a-zA-Z])/ {$Rep:"($fn.$1)"} ln (tag {$Rep:""} ln)* x{$Rep:""} ~ h_A: ~ {$In:[fields t:html c:A]} /(.*)(.*)<\/B>/ {$Rep:"$1$2"} ~ # others name: ~ /[A-Z0-9a-z]+/ ~ ln: ~ /[^\n]*\n/ ~ tag: ~ /\\*[a-zA-Z]/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/opt/srs/data/flybase/genes.txt'] while:$JobHasInput:$job { $JobTokens:[$job name:fields code:c print:1] $JobTokens:[$job name:c print:1] $JobNext:$job $print:"-------->entry\n" } } } /(.*)(.*)<\/B>/ {$Rep:"$1$2"} ~ # others name: ~ /[A-Z0-9a-z]+/ ~ ln: ~ /[^\n]*\n/ ~ tag: ~ /\\*[a-zA-Z]/srs/icarus/db/flygene.it # # $RCSfile: flygene.it,v $ # $Revision: 1.1 $ # $Date: 1996/11/25 19:45:49 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $dbInfo={ description: | www: |\ |http://flybase.bio.indiana.edu:82/
|\ |http://www.embl-ebi.ac.uk/flybase/
|\ |http://www.angis.su.oz.au:7081/
|\ |http://shigen.lab.nig.ac.jp:7081/
|\ |http://cbbridges.harvard.edu:7081/
ftp: |\ |ftp://ftp.ebi.ac.uk/pub/databases/flybase/genes/ email: |Please send any communications about use of FlyBase services to: | flybase-help@morgan.harvard.edu |

|Please send any data corrections or updates to: | flybase-updates@morgan.harvard.edu | fax: | contact: | address: |FlyBase
|Biological Laboratories
|Harvard University
|16 Divinity Ave
|Cambridge, MA 02138 USA
literature: | updates: | fields:{ } } bi.ac.uk/pub/databases/flybase/genes/ email: |Please send any communications about use of FlyBase services to: srs/icarus/db/flyrefs.i # $RCSfile: flyrefs.i,v $ # $Revision: 1.2 $ # $Date: 1996/12/06 16:37:32 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FLYREFS_DB:$library:[FLYREFS group:@GENOME_LIBS format:@FLYREFS_FORMAT maxNameLen:15 ifiles:{"flyrefs.i" "flyrefs.is"} files:{ $file:genes } ] FLYREFS_FORMAT:$libformat:[fileType:@TXT_FILE syntax:@FLYREFS_SYNTAX printFormat:table2 tableFormat:left fields:{ $field:[@DF_ID code:id index:id indexToken:id tableToken:id] } ] FLYREFS_SYNTAX:$syntax:[file:"SRSDB:flyrefs.is" ignore:" "] $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FLYREFS_DB:$library:[FLYREFS group:@GENOME_LIBS format:@FLYREFS_FORMAT maxNameLen:15 ifiles:{"flyrefs.i" "flyrefs.is"} files:{ $file:genes } ] FLYREFS_FORMAT:$libformat:[fileType:@TXT_FILE syntax:@FLYREFS_SYNTAX printForsrs/icarus/db/flyrefs.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: flyrefs.is,v $ # $Revision: 1.2 $ # $Date: 1996/12/06 16:37:33 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $fn={ a: "Gene symbol" b: "Genetic map position" c: "Cytological map position" d: "Function(s) of product" e: "Full name" g: "D. mel. DNA/RNA AC no(s)" h: "D. spp. DNA/RNA AC no(s)" i: "Synonym(s)" j: "Non-Drosophila homologue" k: "Phenotypic information" l: "Length (type\\ends\\total)" m: "D. mel. protein AC no(s)" n: "D. spp. protein AC no(s)" o: "Origin/mutagen" p: "Phenotypic information" q: "Miscellaneous information on genes and alleles" r: "Copy number" s: "Molecular biology data" t: "Target site duplication" u: "Other information" w: "Discoverer(s)" x: "Genes References" y: "Secondary FlyBase id(s)" z: "FlyBase gene id number" A: "Allele" B: "Revised genetic map posn." C: "Associated cytology" D: "Revised cyto. map posn." E: "References" F: "Enzyme name/number(s)" H: "Last update" J: "Prosite protein domains" K: "RNA space/time distrib." N: "Cyto. location of clone" O: "Progenitor allele/chromosome" R: "Misc. allele information" S: "Open reading frame size" T: "cDNA clone length" U: "RNA in situ distribution" V: "Protein distribution" Y: "Transcript size(s)" Z: "Genomic length of clone" } $dbRef={SWP:swiss PIR:pir} $rules={ entry: ~ {$In:[file:text] $Out pre $Skip:0} ('*a' {$Not} ln)* ('*a' {$entryFip=$Fip $Wrt} ln {$App} ('*a' {$Not} ln {$App})+)? ~ fields: ~ {$In:entry $Out $Skip:1} (/\\*([a-zA-Z])/ {if:$1==$prev $App else $Wrt:$1 $prev=$1} ln {$App})+ ~ # indexing id: ~ {$In:[fields c:a] $Out} tag /[^ \n]+/ {$Wrt} ~ c: ~ {$In:[fields c:c] $Out} tag (/[A-Z0-9a-z]+/ {$Wrt:min} /-+([A-Z0-9a-z]+)/? {$Wrt:[max s:$1]})? ~ # html h_x: ~ {$In:[fields t:html c:x]} tag name {$Rep:{"

($ParStr:flyrefsR)" $Ct $Ct}} '==' {$Rep:"
"} ln (tag name {$Rep:{"
($ParStr:flyrefsR)" $Ct $Ct}} '==' {$Rep:"
"} ln)* x{$Rep:"
"} ~ h_E: ~ {$In:[fields t:html c:E]} tag name {$Rep:{$ParStr:flyrefsR $Ct $Ct}} ~ h_g: ~ {$In:[fields t:html c:g]} (tag name {$Rep:{$ParStr:emblR $Ct $Ct}} ln)+ ~ h_m: ~ {$In:[fields t:html c:m]} (tag name {$db=$Ct} '/' name {$Rep:{$ParStr:"($dbRef.$db)R" $Ct $Ct}} ln)+ ~ h_J: ~ {$In:[fields t:html c:J]} tag x{$Rep:"
  • "} name {$Rep:{$ParStr:prositeR $Ct $Ct}} ln (tag x{$Rep:"
  • "} name {$Rep:{$ParStr:prositeR $Ct $Ct}} ln)* x{$Rep:"
"} ~ h_fields: ~ {$In:[fields t:html]} /\\*([a-zA-Z])/ {$Rep:"($fn.$1)"} ln (tag {$Rep:""} ln)* x{$Rep:""} ~ h_A: ~ {$In:[fields t:html c:A]} /(.*)(.*)<\/B>/ {$Rep:"$1$2"} ~ # others name: ~ /[A-Z0-9a-z]+/ ~ ln: ~ /[^\n]*\n/ ~ tag: ~ /\\*[a-zA-Z]/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/opt/srs/data/flybase/genes.txt'] while:$JobHasInput:$job { $JobTokens:[$job name:fields code:c print:1] $JobTokens:[$job name:c print:1] $JobNext:$job $print:"-------->entry\n" } } } /(.*)(.*)<\/B>/ {$Rep:"$1$2"} ~ # others name: ~ /[A-Z0-9a-z]+/ ~ ln: ~ /[^\n]*\n/ ~ tag: ~ /\\*[a-zA-Z]/srs/icarus/db/fssp.i # $RCSfile: fssp.i,v $ # $Revision: 1.4 $ # $Date: 1997/03/03 18:33:58 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FSSP_DB:$library:[FSSP group:@PROTSTRUCT_LIBS format:@FSSP_FORMAT maxNameLen:10 ifiles:{"fssp.i" "fssp.is"} ] FSSP_FORMAT:$libformat:[fileType:@FSSP_FILE syntax:@FSSP_SYNTAX fields:{ $field:[@DF_ID code:pdbid keyConvert:none index:id indexToken:id] $field:[@DF_Header code:header index:str indexToken:hdr] $field:[@DF_Compound code:compnd index:str indexToken:comp] $field:[@DF_Source code:source index:str indexToken:src] $field:[@DF_Authors code:author index:str indexToken:authors] $field:[@DF_SeqLength code:seqlen index:int indexToken:seql] $field:[@DF_NAlign code:nalign index:int indexToken:nali] $field:[@DF_Summary code:summary] $field:[@DF_Alignment code:alignments] $field:[@DF_Equivalences code:equivalences] $field:[@DF_Matrices code:matrices] } ] DF_NAlign:$srsfield:[NAlign short:nal] DF_Summary:$srsfield:[Summary short:sum] DF_Equivalences:$srsfield:[Equivalences short:eqv] DF_Matrices:$srsfield:[Matrices short:mat] FSSP_SYNTAX:$syntax:[file:"SRSDB:fssp.is" ignore:" "] FSSP_FILE:$FileType:[typename:'fssp' singleEntry:y maxline:500] $link:[@FSSP_DB to:@?PDB_DB token:pdbLink fromField:@DF_ID toField:@DF_ID] ry] $field:[@DF_Alignment code:alignments] $field:[@DF_Equivalences code:equisrs/icarus/db/fssp.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: fssp.is,v $ # $Revision: 1.2 $ # $Date: 1996/12/06 16:37:34 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $rules={ # the entry entry: ~ {$In:[file:text] $Out pre $Skip:0} ln {$entryFip=$Fip $Wrt} appLn+ ~ # fields from text fields: ~ {$In:entry $Out $Skip:1} title pdbid header source compnd author seqlen nalign summary alignments matrices footer ~ title: ~ {$Wrt:title} ('PDBID'{$Not} ln)+ ~ pdbid: ~ {$Wrt:pdbid} ('PDBID' ln)+ ~ header: ~ {$Wrt:header} ('HEADER' ln)+ ~ compnd: ~ {$Wrt:compnd} ('COMPND' ln)+ ~ source: ~ {$Wrt:source} ('SOURCE' ln)+ ~ author: ~ {$Wrt:author} ('AUTHOR' ln)+ ~ seqlen: ~ {$Wrt:seqlen} ('SEQLENGTH' ln)+ ~ nalign: ~ {$Wrt:nalign} ('NALIGN' ln)+ ~ summary: ~ {$Wrt:summary} ln ln ('##' {$Not} ln)+ ~ alignments:~ {$Wrt:alignments} ('## EQUIV' {$Not} ln)+ ~ matrices: ~ {$Wrt:matrices} ln ('##' {$Not} ln)+ ~ footer: ~ {$Wrt:footer} ln+ ~ # indexing production id: ~ {$In:[fields c:pdbid] $Out pre $Skip:1} tag /([a-z0-9]+)(-([A-Z0-9]))?/ {$Wrt:[s:"$1$2"]} ~ hdr: ~ {$In:[fields c:header] $Out} (x{$Mov:10} words {$Len:50} ln)+ ~ comp: ~ {$In:[fields c:compnd] $Out} (x{$Mov:10} words {$Len:60} ln)+ ~ src: ~ {$In:[fields c:source] $Out} (x{$Mov:10} words {$Len:60} ln)+ ~ authors: ~ {$In:[fields c:author] $Out} (x{$Mov:10} auts {$Len:60} ln)+ ~ seql: ~ {$In:[fields c:seqlen] $Out} tag num {$Wrt} ~ nali: ~ {$In:[fields c:nalign] $Out} tag num {$Wrt} ~ auts: ~ aut (',' aut?)* ~ aut: ~ / *([^ ,]*\\.)([^ ,]*)/ {$Uniq:[s:"$2,$1"]} ~ words: ~ (/[A-Z0-9]+/ {$Uniq:$Itc} | /./)+ ~ pdbLink: ~ {$In:[fields c:pdbid] $Out} tag /([a-zA-Z0-9]+)/ {$Wrt} ~ # html display h_com: ~ {$In:[fields c:compnd t:html]} (/(E\\.C\\.|EC: *)([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)/ {$Rep:{"$1($ParStr:enzymeR)" $2 $2}} | /./)+ ~ h_pbd: ~ {$In:[fields c:pdbid t:html]} tag /[a-z0-9]+/ {$Rep:{$ParStr:pdbR $Ct $Ct}} ~ h_sum: ~ {$In:[fields c:summary t:html]} (/ *[0-9]+:/ /[^ ]+/ name {$Rep:{$ParStr:pdbR $Ct $Ct}} ln | ln)+ ~ # other productions tag: ~ /[A-Z]+/ ~ name: ~ /[a-zA-Z0-9_]+/ ~ num: ~ /[0-9.]+/ ~ word: ~ /[^ ]+/ ~ ln: ~ /[^\n]*\n/ ~ appLn: ~ /[^\n]*\n/ {$App} ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/fssp/1psdB.fssp'] $JobTokens:[$job name:fields print:1] $JobNext:$job } h_sum: ~ {$In:[fields c:summary t:html]} (/ *[0-9]+:/ /[^ ]+/ name {$Rep:{$ParStr:pdbR $Ct $Ct}} ln | ln)+ ~ # other productions tag: ~ /[A-Z]+/ ~ name: ~ /[a-zA-Z0-9_]+/ ~ nusrs/icarus/db/ftseq.is # # the feature location # # $origin = { $BEG:0 $BOTH:1 $END:2 } # a position is either known (a number) or a range $c={ unbounded:-1 sequenceLen:-2 singleBase:-3 optional:1 # chunk can be omitted left:2 # chunk varies left^right to right^right right:3 # chunk varies left^right to left^left } $rules={ #-- range to chunk converter ------------------------------------------- position: ~ /[0-9]+/ {$SdbChunk:[$seq to:$Ct+$offs]} | /\\(?([0-9]+) *\. *([0-9]+)\\)?/ {$SdbChunk:[$seq to:$1+$offs] $SdbChunk:[$seq to:$2+$offs uncertain:$dir]}| '>' /[0-9]+/ {$SdbChunk:[$seq to:$Ct+$offs] $SdbChunk:[$seq to:$c.unbounded uncertain:$dir]} | '<' /[0-9]+/ {$SdbChunk:[$seq to:$c.unbounded] $SdbChunk:[$seq to:$Ct+$offs uncertain:$dir]} | 'one-of' '(' /[0-9]+/ { $SdbChunk:[$seq to:$Ct+$offs]} (',' /[0-9]+/ { $SdbChunk:[$seq to:$Ct+$offs uncertain:$c.optional]} )* ')' ~ range: ~ {pre {$db="" $seq=$SdbRetrieve:["" db:""] $SdbPush $offs=-1 $dir=$c.left}} # get entry sequence # (/([A-Z]+[0-9]+)::/ {$db=$1} )? (/([A-Z]+[0-9]+)[ \n]*:/ {$seq=$SdbRetrieve:[$1 db:$db]} )? # get chunk (chunks if range uncertain) from sequence # position {$dir=$c.right} ( /(\\.\\.|\\. \\.)/ {$offs=0} position | '^' {$offs=-1} position | x{$SdbChunk:[$seq to:$c.singleBase]} ) ~ #---------------------------------------------------------------------- sequence: ~ literal|operator|range ~ operator: ~ join | complement | replace | order | group |one_of~ literal: ~ '\"' /[a-zA-Z]*/ { $seq=$Ct } ( /[a-zA-Z]+/ { $StrApp:[$seq s:$Ct] })* '\"' { $SdbPush $SdbChunk:$seq } ~ replace: ~ 'replace' '(' range ',' sequence { $SdbReplace } ')' ~ join: ~ 'join' '(' sequence (',' sequence {$SdbJoin} )* ')' ~ complement: ~ 'complement' '(' sequence {$SdbComplement} ')' ~ order: ~ 'order' '(' sequence (',' sequence)* ')' ~ group: ~ 'group' '(' sequence (',' sequence)* ')' ~ one_of: ~ /one-of *\\([^\\)]*(\\.\\.|\\^)/ {$Probe} 'one-of' '(' sequence (',' sequence )* ')' ~ # swissprot range swissrange: ~ {pre {$db="" $seq=$SdbRetrieve:["" db:""] $SdbPush $offs=-1 $dir=$c.left}} position {$dir=$c.right} position {$offs=0} ~ } quence (',' sequence {$SdbJoin} )* ')' ~ complement: ~ 'complement' '(' sequence {$SdbComplement} ')' ~srs/icarus/db/genbank.i # # $RCSfile: genbank.i,v $ # $Revision: 1.8 $ # $Date: 1997/03/03 18:33:59 $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GENBANK_DB:$library:[GENBANK group:@SEQUENCE_LIBS partSize:100000 subentries:@GenbankFeatures_DB format:@GENBANK_FORMAT cachesize:512 maxNameLen:10 files:{ $file:gbbct $file:gbest1 $file:gbest2 $file:gbest3 $file:gbest4 $file:gbest5 $file:gbest6 $file:gbest7 $file:gbest8 $file:gbest9 $file:gbest10 $file:gbhtg $file:gbgss $file:gbinv $file:gbmam $file:gbpat $file:gbphg $file:gbpln $file:gbpri $file:gbrna $file:gbrod $file:gbsyn $file:gbsts $file:gbuna $file:gbvrl $file:gbvrt } ] GENBANK_FORMAT:$libformat:[fileType:{@GBREF_FILE @GBSEQ_FILE} syntax:@GENBANK_SYNTAX tableFormat:left fields:{ $field:[@DF_ALL] $field:[@DF_ID code:id index:id indexToken:id] $field:[@DF_Division code:str index:str indexToken:div] $field:[@DF_SeqLength code:id index:int indexToken:seqlen] $field:[@DF_Molecule code:id index:str indexToken:mol] $field:[@DF_Date code:id index:int indexToken:date tableToken:t_date] $field:[@DF_Description index:str code:def indexToken:des tableToken:'t_field|def'] $field:[@DF_Accession code:acc index:str indexToken:acc] $field:[@DF_Nid code:nid index:str indexToken:nid] $field:[@DF_Keywords code:kwd index:str indexToken:keyw] $field:[@DF_Source code:src index:str indexToken:source] $field:[@DF_Organism code:srcorg index:str indexToken:org] $field:[@DF_Authors code:refaut index:str indexToken:authors] $field:[@DF_Title code:reftit index:str indexToken:title] $field:[@DF_Citation code:refjnl index:str indexToken:cit] # $field:[@DF_DNASequence token:gcgseq format:embl] #GCG format GenbankSeq:$field:[@DF_DNASequence token:sequence format:embl] #orig format $field:[@DF_HeaderField name:'Feature Table Fields'] $field:[@DF_FtKey code:ft index:str indexToken:ftKey indexId:@SUBENTRY_ID] $field:[@DF_FtQualifier code:ft index:str indexToken:ftQual indexId:@SUBENTRY_ID] $field:[@DF_PID code:ft index:str indexToken:pid indexId:@SUBENTRY_ID] $field:[@DF_FtDescription code:ft index:str indexToken:ftDes indexId:@SUBENTRY_ID] $field:[@DF_FtSource code:ft index:str indexToken:ftSrc indexId:@SUBENTRY_ID] $field:[@DF_ChrsNo code:ft index:str indexToken:chrsNo indexId:@SUBENTRY_ID] $field:[@DF_FtMap code:ft index:str indexToken:map indexId:@SUBENTRY_ID] $field:[@DF_FtLength index:int indexToken:ftLen code:ft indexId:@SUBENTRY_ID] } ] DF_Nid:$srsfield:[Nid short:nid] GENBANK_SYNTAX:$syntax:[file:"SRSDB:genbank.is"] GBREF_FILE:$filetype:[text typename:seq maxline:200 fieldTokens:fields fipVar:entryFip ] GBSEQ_FILE:$filetype:[seq typename:seq maxline:200 shareWith:@GBREF_FILE fieldTokens:sequence fipVar:seqFip ] GenbankFeatures_DB:$library:[GENBANK_features format:@GenbankFeature_Format] GenbankFeature_Format:$libformat:[syntax:@GENBANK_SYNTAX tableFormat:left fields:{ $field:[@DF_ID token:ftId] $field:[@DF_FtKey token:ft tableToken:'t_ft|key'] $field:[@DF_FtQualifier token:ft tableToken:'t_ft|qual'] $field:[@DF_PID token:ft tableToken:'t_ft|db_xref'] $field:[@DF_FtDescription token:ft tableToken:'t_ft|note'] $field:[@DF_FtGene token:ft tableToken:'t_ft|gene'] $field:[@DF_FtProduct token:ft tableToken:'t_ft|product'] $field:[@DF_FtPartial token:ft tableToken:'t_ft|partial'] $field:[@DF_FtPseudo token:ft tableToken:'t_ft|pseudo'] $field:[@DF_FtNumber token:ft tableToken:'t_ft|number'] $field:[@DF_FtSource token:ft tableToken:ftSrc] $field:[@DF_ChrsNo token:ft tableToken:'t_ft|chromosome'] $field:[@DF_FtMap token:ft tableToken:'t_ft|map'] $field:[@DF_DNALocation token:ftLocat parent:@GenbankSeq tableFormat:listing] } ] ] $field:[@DF_FtProduct token:ft tableToken:'t_ft|product'] $field:[@DF_FtPartial token:ft tableToken:'t_ft|partial'] $field:[@DF_FtPseudo token:ft tableToken:'t_ft|pseudo'] $field:[@DF_FtNumber token:ft tableToken:'t_ft|number'] $field:[@DF_FtSource token:ft tableToken:ftSrc] $field:[@DF_ChrsNo token:ft tableToken:'t_ft|chromosome'] $field:[@DF_FtMap token:ft tableToken:'t_ft|map'] $field:[@DF_DNALocation token:ftLocat parent:@GenbankSeq tableFormat:listing] } srs/icarus/db/genbank.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: genbank.is,v $ # $Revision: 1.10 $ # $Date: 1997/03/17 23:21:03 $ # # Author: Antoine Daruvar # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $fn={ LOCUS:id DEFINITION:def ACCESSION:acc NID:nid SEGMENT:seg SOURCE:src ORGANISM:srcorg REFERENCE:reftit AUTHORS:refaut TITLE:reftit KEYWORDS:kwd COMMENT:com JOURNAL:refjnl MEDLINE:refmed REMARK:refrem BASE:bct } $rules={ # entry and fields entry: ~ {$In:[file:text] pre{$Skip:0} $Out} ('LOCUS' {$Not} lnT)* ('LOCUS' {$Wrt $entryFip=$Fip} lnT {$App} ('ORIGIN' {$Not} lnT {$App})+)? ~ lnT: ~ /[^\n]+\n?/ ~ # line terminator may be missing if truncated fields: ~ {$In:entry $Out $Skip:1} (ftList | / *([A-Z]+)[^\n]*\n/ {if:$fn.$1=="" $dp:"+++ unknown: $1 in $entryName +++" $Wrt:$fn.$1} (/ [^\n]+\n/ {$App})*)+ ~ ftList: ~ /FEATURES[^\n]*\n/ {$Wrt:ftTitle} (/ [^ ][^\n]+\n/ {$Wrt:ft} / [^\n]+\n/* {$App})+ ~ # parsing the sequence part from separate stream gcgseq: ~ { $In:[file:seq] $Out pre $s=$SeqNew $SeqMake:$s $Wrt:[s:$entryName] } '>>>>' {$seqFip=$Fip} (/[A-Z0-9]+/ seq | /[A-Z0-9]+_0/ seq (/>>>>[A-Z0-9]+_[1-9]+/ {$SeqTrunc:[$s len:10000]} seq)+) ~ seq: ~ (/.*2BIT *Len:/ /[0-9]+/ {$len=$Ct} ln ln {$SeqGet2Bit:[$s file:$File len:$len]} ('>>>>'{$Not} ln)*| /.*ASCII/ ln ln ('>>>>' {$Not} /.*/ {$SeqApp:[$s s:$Ct]})+) ~ sequence: ~ {$In:[file:seq share:text] $Out pre {$s=$SeqNew $seqFip=$Fip} $Wrt:[s:$entryName] $SeqMake:$s} ln ('LOCUS' {$Not} ln {$SeqApp:[$s s:$Ct]})* ~ # indexing id: ~ {$In:[fields c:id] $Out} /LOCUS */ iword {$Wrt} ~ seqlen: ~ {$In:[fields c:id] $Out} /.+ ([0-9]+) *bp/ {$Wrt:[s:$1]} ~ mol: ~ {$In:[fields c:id] $Out} /.* bp +([a-zA-Z0-9-]+)/ {$Wrt:[s:$1]} ~ div: ~ {$In:[fields c:id] $Out} /.+([A-Z][A-Z][A-Z]) +[0-9]+-[A-Z][A-Z][A-Z]-[0-9]+/ {$Wrt:[s:$1]} ~ date: ~ {$In:[fields c:id] $Out} datenum {$Wrt:[s:$dateval]} ~ datenum: ~ {init {$month={JAN:1 FEB:2 MAR:3 APR:4 MAY:5 JUN:6 JUL:7 AUG:8 SEP:9 OCT:10 NOV:11 DEC:12}}} /.+ ([0-9]+)-([A-Z][A-Z][A-Z])-([0-9]+)/ {$dateval=$1 + $month.$2 * 100 + $3 * 10000} ~ des: ~ {$In:[fields c:def] $Out} tag (iword {$Uniq} | /./)* ~ acc: ~ {$In:[fields c:acc] $Out} tag (iword {$Uniq} | /./)* ~ nid: ~ {$In:[fields c:nid] $Out} tag (iword {$Uniq} | /./)* ~ keyw: ~ {$In:[fields c:kwd] $Out} tag (/[^;.\n]+/ {$Wrt} | /./)* ~ source: ~ {$In:[fields c:src] $Out} tag (iword {$Uniq} | /./)* ~ org: ~ {$In:[fields c:srcorg] $Out} tag ('Mitochondrion' | /[^;.\n]+/ {$Wrt} | /./)* ~ authors: ~ {$In:[fields c:refaut] $Out} tag ((/([^,\n]+),([^ ,\n]+)/ {$Uniq:[s:"$1,$2"]} (/, */ | /and */)?)+ ln)+ ~ title: ~ {$In:[fields c:reftit] $Out} tag (iword {$Uniq} | /./)* ~ cit: ~ {$In:[fields c:refjnl] $Out} /./ ~ medline: ~ {$In:[fields c:refmed] $Out:medline} tag iword {$Wrt} ~ i_ftsqua: ~ {$In:[fields c:fts count:fts var:$ftN] $Out:Features} /[^\/]+/ ('/' (/translation[^\/]+/ | /[a-zA-Z_]+/ (/[0-9a-zA-Z_]+/ {$Uniq:[n:$ftN]} | /[^0-9a-zA-Z\/]+/)+))* ~ # indexing features ftWord: ~ /[^" ,;:*()\n.-]+/ ~ #" ftSep: ~ /[ ,;.:*()\n-]+/ ~ ftKey: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} /[^ ]+/ {$Wrt:[n:$ftN]} ~ ftQual: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} /[^\/]+/ (/\/([a-zA-Z0-9_]+)/ {$Wrt:[s:$1 n:$ftN]} (/=[a-zA-Z0-9_]+/ | /="[^"]+"/)? /[^\/]+/)* ~ #" chrsNo: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} /.+\/chromosome="?/ (/[^\n\" ]+/ {$Uniq:[n:$ftN]} | /[ \n]+/)+ ~ #" ftSrc: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} (/[^\/]+\// ( /(tissue_type|cell_line|organism|strain|dev_stage|sex|clone_lib)="/ (ftWord {$Uniq:[n:$ftN]} | ftSep)+)?)+ ~ ftDes: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} (/[^\/]+\// (/(product|note|gene)="/ (/NCBI gi: *[0-9]+/ | ftWord {$Uniq:[n:$ftN]} | ftSep)+)?)* ~ map: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} /.+\/map="/ (/[^a-zA-Z0-9"]+/|/[a-zA-Z0-9]+/{$Wrt:[n:$ftN]})+ ~ ftLen: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} /[^ ]+/ (range {$Wrt:[n:$ftN s:$l]} | /.*join\\(/ {$ftl=0} (range{$ftl+=$l} ','?)* ')'? {$Wrt:[n:$ftN s:$ftl]})? ~ range: ~ /([A-Z0-9]+:)?([0-9]+)\\.\\.([0-9A-Z]+:)?([0-9]+)/ {$l=$4-$2+1} ~ pid: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} (/db_xref="?PID:([0-9a-zA-Z]+)/ {$Wrt:[n:$ftN s:$1]} | /[^\/]+\// )+ ~ #" # displaying features ft: ~ {$In:[fields c:ft count:ft var:$ftN select:$subEntryN] $Out pre $Skip:0 $Skip:1} /.*/ {$Wrt} ~ ftId: ~ {$In:[fields c:id] $Out} /LOCUS *([A-Z0-9]+)/ {$Wrt:[s:"LOCUS $1\_$subEntryN; parent: $1"]}~ h_ftId: ~ {$In:[ftId t:html]} /.*parent: */ /[A-Z0-9]+/ {$Rep:{$ParStr:genbankIdR $Ct $Ct}} ~ t_ft: ~ {$In:ft $Out} / *(entry\n" } } '/')+ ~ h_medline:~ {$In:[fields c:refmed t:html]} tag /[0-9]+/ {$Rep:{$ParStr:medlineR $Ct $Ct}} ~ # utilities iword: ~ /[a-zA-Z0-9_]+/ ~ ln: ~ /[^\n]*\n/ ~ tag: ~ / *[A-Z]+ */ ~ } if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/genbank/gbmam.seq'] while:$JobHasInput:$job { $JobTokens:[$job name:id print:1] $JobTokens:[$job name:fields print:1] $JobNext:$job #$print:"-------->entry\nsrs/icarus/db/genbank.it # # $RCSfile: genbank.it,v $ # $Revision: 1.4 $ # $Date: 1996/10/10 16:47:06 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $dbInfo={ description: |GenBank (1) is the NIH's database of all known nucleotide and protein |sequences including supporting bibliographic and biological |information. Since 1992 it has been based at the National Center for |Biotechnology Information (NCBI), a division of the National Library of |Medicine, located on the NIH campus. NCBI was created by Congress in |1988 and specifically charged with developing automated information |systems to support molecular biology and biotechnology. Its other |mission is to conduct basic research and as part of the NIH Intramural |Program, NCBI scientists pursue research in genome analysis, molecular |structure modeling and prediction, and mathematical methods for |sequence analysis. www: |\ |http://www.ncbi.nlm.nih.gov/Web/Genbank/index.html literature: |
    |
  1. Benson, D., Boguski, M., Lipman, D.J., and Ostell, J. (1994) |Nucleic Acids Research, 22, 3441-3444. |
  2. Boguski, M.S. (1995) Trends in Biochemical Sciences, 20, 295-296. |
  3. Boguski, M.S., Tolstoshev, C. M. and Bassett, D. E. (1994) Science, |265, 1993-1994. |
  4. Boguski, M.S. and Schuler, G.D. (1995) Nature Genetics, 10, 369-371. |
  5. Levy-Lahad, E., Wasco, W., Poorkaj, P., Romano, D.M., Oshima, J., |Pettingell, W.H., Yu, C.-E., Jondro, P.D., Schmidt, S.D., Wang, K., |Crowley, A.C., Fu, Y.-H., Guenette, S.Y., Galas, D., Nemens, E., |Wijsman, E.M., Bird, T.D., Schellenberg, G.D. and Tanzi, R.E. (1995) |Science, 269, 973-977. |
  6. Bassett, D.E., Boguski, M.S., Spencer, F., Reeves, R. Goebl, M., and |Hieter, P. (1995) Trends in Genetics, 11, 372-373. |
  7. Schuler, G.D., Epstein, J.A., Ohkawa, H., and Kans, J.A. Methods in |Enzymology, in press. |
  8. Altschul, S.F., Boguski, M.S., Gish, W., and Wootton, J.C. (1994) |Nature Genetics, 6, 119-129. |
  9. Madden, T.L., Tatusov, R.L. and Zhang, J. Methods in Enzymology, in |press. |
fields:{ ID: |The pieces of information contained in the LOCUS (ID) |record are always |found in fixed positions. The locus name (or entry name), which is |always ten characters or less, begins in position 13. The locus name |is designed to help group entries with similar sequences: the first |three characters usually designate the organism; the fourth and fifth |characters can be used to show other group designations, such as gene |product; for segmented entries the last character is one of a series |of sequential integers. AccNumber: |The ACCESSION number is assigned to a sequence and should |remain |linked with it for ever, whereas |entry names may change; also occasionally a few sequences may be |merged to a |single sequence |that will then inherit all accession numbers). |

|Corresponding sequences in EMBL and GenBank should to have the same |accession |numbers. In |all current sequence libraries the accession number consists of an |alphabetical character followed |by 5 digits, e.g "X12345". Description: |The DEFINITION record gives a brief description of the |sequence, |proceeding from general to specific. It starts with the common name of |the source organism, then gives the criteria by which this sequence is |distinguished from the remainder of the source genome, such as the |gene name and what it codes for, or the protein name and mRNA, or some |description of the sequence's function (if the sequence is |non-coding). Keywords: |Short phrases describing gene products and other |information about an entry. Mandatory keyword in all annotated |entries/one or more records. Organism: |Formal scientific name of the organism (first line) |and taxonomic classification levels (second and subsequent lines). |Mandatory subkeyword in all annotated entries/two or more records. |

|A taxon is either an organism name or the name of the family, |group etc.. |Usually latin names are best (e.g. "EUKARYOTA", or "HOMO SAP*") |but often |the english common name is also given in this data field. Title: |Full title of citation. Optional subkeyword (present |in all but unpublished citations)/one or more records. Reference: |Four items of the literature reference are indexed: |

    |
  • journal name (e.g., "EMBO JOURNAL"), |
  • volume number (e.g., "22"), |
  • first page (e.g., "1712-"), |
  • and publication year (e.g., "1987"). |
|

|Note: The journal names are not yet converted to standard |names; e.g., | the journal NAR might be called "Nucl. Acids Res." in one | library and "Nucl. Acids Research" in the other. |

|Note: When searching first page numbers a dash must be added |to the | number (e.g., 122-) which is necessary to make the page number | distinct from both volume number and publication year. Features: |Table containing information on portions of the |sequence that code for proteins and RNA molecules and information on |experimentally determined sites of biological significance. Optional |keyword/one or more records. } date: |25 Jul 1996 signature: |Anatoly Ulyanov } ers a dash must be added |to the | number (e.g., 122-) which is necessary to make the page number | distinct from both volume number and publication year. Features:srs/icarus/db/gene.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: gene.is,v $ # $Revision: 1.1 $ # $Date: 1997/03/03 18:36:24 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $fn={ ID: id DE:de BS:bs AC: ac OS:os DT: dt OC:oc '//':xln SD: sd BC:bc XX:xln } $rules={ entry: ~ {$In:[file:text] $Out pre $Skip:0} ('AC' {$Not} ln)* ('AC ' {$entryFip=$Fip $Wrt} ln {$App} ('AC' {$Not} ln {$App})+)? ~ # fields fields: ~ {$In:entry $Out $Skip:1} (/../ { if:$Ct==$prev $App else $Wrt:$fn.$Ct if:$fn.$Ct=="" $dp:"+++ unknown: $Ct +++" $prev=$Ct } ln {$App})+ ~ # indexing id: ~ {$In:[fields c:id] $Out $Break} tag /[0-9A-Za-z$_-]+/ {$Wrt} ~ wrd: ~ {$In:[fields c:{ac ty el se dt}] $Out} tag word {$Wrt:$Itc} ~ dt: ~ {$In:[fields c:dt] $Out} 'DT' /([0-9]+).([0-9]+).([0-9]+)/ {$Wrt:[s:($1+$2*100+"19$3"*10000)]} ~ words: ~ {$In:[fields c:{bf so cc de os me}] $Out} (tag (sep | /[a-zA-Z0-9+-]+/ {$Uniq:$Itc})* ln)+ ~ el: ~ {$In:[fields c:el] $Out} tag word {$Wrt} ~ se: ~ {$In:[fields c:se] $Out} tag word {$Wrt} ~ sf: ~ {$In:[fields c:sf] $Out} tag num {$Wrt} ~ st: ~ {$In:[fields c:st] $Out} tag num {$Wrt} ~ #links: bfRef: ~ {$In:[fields c:bf] $Out} (tag name {$Wrt} ln)+ ~ soRef: ~ {$In:[fields c:so] $Out} (tag name {$Wrt} ln)+ ~ dr: ~ {$In:[fields c:dr] $Out} (tag ('EMBL;' word {$Wrt:embl} | 'Flybase;' name {$Wrt:flybase}) ln)+ ~ # table display t_date: ~ {$In:[fields c:dt] $Out} tag /[0-9\.]+]/ {$Wrt} ~ # HTML display h_bf: ~ {$In:[fields c:bf t:html]} (tag name {$Rep:{$ParStr:tffactorR $Ct $Ct}} ln)+ ~ h_so: ~ {$In:[fields c:so t:html]} (tag /[0-9]+/ {$Rep:{$ParStr:tfcellR $Ct $Ct}} ln)+ ~ h_dr: ~ {$In:[fields c:dr t:html]} (tag ('EMBL;' word {$Rep:{$ParStr:emblR $Ct $Ct}} | 'Flybase;' word {$Rep:{$ParStr:flybaseR $Ct $Ct}} ) ln)+ ~ # others num: ~ /-?[0-9]+/ ~ tag: ~ /[A-Z][A-Z0-9]/ ~ ln: ~ /[^\n]*\n/ ~ name: ~ /[a-zA-Z0-9$_-]+/ ~ word: ~ /[a-zA-Z0-9_]+/ ~ sep: ~ /[^a-zA-Z0-9_\n]+/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/opt/srs/data/transfac/gene.dat'] while:$JobHasInput:$job { $JobTokens:[$job name:fields print:0] $JobNext:$job $print:"-------->entry\n" } } 'Flybase;' word {$Rep:{$ParStr:flybaseR $Ct $Ct}} ) ln)+ ~ # others num: ~ /-?[0-9]+/ ~ tag: ~ /[A-Z][A-Z0-9]/ ~ ln: ~ /[^\n]*\n/ ~ name: ~ /[a-zA-Z0-9$_-]+/ ~ word: ~ /[a-zA-Z0-9_]+/ ~ sep: ~ /[^a-zA-Z0-9_\n]+/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/opt/srs/data/transfac/gene.dat'] while:$JobHasInput:$job { $JobTokens:[$job name:fisrs/icarus/db/general.it # # $RCSfile: general.it,v $ # $Revision: 1.5 $ # $Date: 1997/03/03 18:34:00 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $main={ AccNumber: |The accession number is assigned to a sequence and should remain linked |with it for ever, whereas entry names may change; also occasionally a few |sequences may be merged to a single sequence that will then inherit all |accession numbers). |

|Corresponding sequences in EMBL and GenBank should to |have the same accession numbers. In all current sequence libraries the |accession number consists of an alphabetical character followed by 5 |digits, e.g "X12345". |

|Using Wildcards Description: |This is probably the best data field for searching an entry you don't know |very much about; however, you can't expect to find all entries of a |class, since often different conventions are used for naming enzymes, |organisms, genes, etc.. Organism: |A taxon is either an organism name or the name of the family, group etc.. |Usually latin names are best (e.g. "EUKARYOTA", or "HOMO SAP*") but often |the english common name is also given in this data field. |

|Using Wildcards Authors: |All author names of all libraries are converted to this format: surname |followed by a comma, followed by the initials (no blanks before or after |the "," or between initials!). |If you don't know the initials put a wildcard ("*") after the comma; e.g., |"SCHULZ,*"; if you place it after the surname you might get "SCHULZKI,.." |as well. |

|Using Wildcards SeqLength: |The sequence length is calculated by reading the sequence. Some libraries |(EMBL, SWISSPROT) have the length also in the first entry line so |to display the sequence length in these libraries, select the ID field. |

|Note that ranges can be combined: "300-!500 | !600-700" or "300-700 ! |500-600" retrieve the |same set of sequences, namely all sequences from 300 to 500, |excluding 500, plus sequences from 600 to |700 where the 600 is excluded. Date: |The date field contains in most cases the creation date of the entry and |is always stored in the index as an 8 digit number of the format |"yyyymmdd" where y=year, m=month and d=day, e.g., "19940117". |

|It is also possible to |type the date to be searched in a different, more intuitive, format: |"dd-mmm-yy" |or "dd-mmm-yyyy", e.g., "1-jan-97" or "01-jan-1997" Reference: |Four items of the literature reference are indexed: |

    |
  • journal name (e.g., "EMBO JOURNAL"), |
  • volume number (e.g., "22"), |
  • first page (e.g., "1712-"), |
  • and publication year (e.g., "1987"). |
|

|Note:The journal names are not yet converted to standard | names; e.g., | the journal NAR might be called "Nucl. Acids Res." in one | library and "Nucl. Acids Research" in the other. |

|Note:When searching first page numbers a dash must be added to the | number (e.g., 122-) which is necessary to make the page number | distinct from both volume number and publication year. |

|Using Wildcards Methods: |The ExpMethod field can contain one of the following: |

|
X |
X-ray structure |
NMR |
NMR structure |
FIBER |
Fiber diffraction study |
MODEL |
A model without explicit experimental data |
|The Exp-Method is derived from the EXPDTA field in |the PDB if present, otherwise it is derived from other sources. Resolution: |The Resolution is derived from REMARK 2 in the PDB |file. For NMR structures and models no resolution is given. RFactor: |The R-Factor for X-ray structures is derived from REMARK |3 and REMARK 4 if possible. For X-ray structures lacking |a valid R-factor in the PDB file, the R-factor field |is based on the original literature. A number of corrections to values |found in the PDB have also been applied. In some cases no |R-factor could be found, or the original literature does contain an |R-factor but the published coordinates are C-alpha only. In those |cases no R-Factor field is present. Also no R-factor is given |for NMR structures, because the calculation methods are too diverse. NoHSSPAlign: |The HSSP-N-Align field gives the number of aligned sequences in |the HSSP database, if a HSSP file for the structure |exists (Normally: if the structure is a protein structure). TotFractHelix: |Gives the fraction of the assigned |secondary structure that is helical: it is the total of the |Helix fields for all chains divided by the total of all |Sec-Struc fields. This field is only present if there is a |secondary structure. TotFractBeta: |Gives the fraction of the assigned |secondary structure that is Beta: it is the total of the Beta |fields for all chains divided by the total of all Sec-Struc |fields. This field is only present if there is a secondary structure. TotNResProt: |Gives the total number of amino acid residues |in the structure, if any. Non-standard amino-acids are included. TotWaterMols: |Gives the total number of water molecules in |the structure, if any. NoHetGroups: |The HET-Groups field gives the number of HET cards |in the PDB file, if any. The following items are repeated for |every HET-group, and are all derived from the PDB HET cards. } sent if there is a secondary structure. TotNResProt: |Gives the total number of amino acid residues |in the structure, if any. Non-standard amino-acids are included. TotWaterMols: |Gives the total number of water molecules in |the structure, if any. NoHetGroups: |The HET-Groups field gives the number of HET cards |in the PDB file, if any. The following items are repeated for srs/icarus/db/haema.i # $RCSfile: haema.i,v $ # $Revision: 1.1 $ # $Date: 1996/11/05 19:54:21 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ HAEMA_DB:$library:[HAEMA group:@MUTATION_LIBS format:@HAEMA_FORMAT maxNameLen:30 ifiles:{'haema.i' 'haema.is' 'haema.it'} files:{ $file:haema } ] HAEMA_FORMAT:$libformat:[syntax:@HAEMA_SYNTAX fileType:@TXT_FILE printFormat:table fields:{ $field:@DF_ALL $field:[@DF_ID indexToken:id index:id tableToken:id tableFormat:right] $field:[@DF_NuclChange code:dnaChange indexToken:'inx|dnaChange' index:str tableToken:'inx|dnaChange' tableFormat:left] $field:[@DF_DnaChangePos code:loc indexToken:'inx|loc' index:int tableToken:'inx|loc' tableFormat:right] $field:[@DF_AaChange code:aaChange indexToken:'inx|aaChange' index:str tableToken:'inx|aaChange' tableFormat:right] $field:[@DF_Reference code:ref] } ] HAEMA_SYNTAX:$syntax:[file:"SRSDB:haema.is" ignore:" "] id tableToken:id tableFormat:right] $field:[@DF_NuclChange code:dnaChange indexToken:'inx|dnaChange' index:str tableToken:'inx|dnaChange' tableFormat:left] $field:[@DF_DnaChangePos code:loc indexToken:'inx|loc' index:int tableToken:'inx|loc' tableFormat:right] $field:[@DF_AaChange code:aaChange indexToken:'inx|aaChange' index:str tableToken:'inx|aaChange' tableFormat:right] $field:[@DF_Reference codsrs/icarus/db/haema.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: haema.is,v $ # $Revision: 1.3 $ # $Date: 1997/03/17 23:21:04 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $field={ inex: {len:9 index:normal } loc: {len:7 index:normal } dnaChange: {len:14 index:dnaChange } aaChange: {len:18 index:aaChange } patient: {len:11 index:normal } fC: {len:9 index:normal } fAg: {len:11 index:normal } Severity: {len:16 index:normal } inhib: {len:15 index:normal } cmnt: {len:33 index:cmnt } ref: {len:50 index:ref } } $rules={ entry: ~ {$In:[file:text] $Out pre $Skip:0 init $count=0} (/ [0-9]/ {$Not} ln)* (/ [0-9]+/ {$entryFip=$Fip $Wrt $count+=1} ln {$App})? ~ # fields fields: ~ {$In:entry $Out} x{ for:{$k=1 $k<12 $k+=1} { $l=$field[$k].len $c=$Key:$field[$k] $Prod:cell } } ~ cell: ~ /.+/ {if:$Trim:$Ct!="" $Wrt:$c $Len:$l} ~ # indexing id: ~ {$In:entry $Out} x{$Wrt:[s:$count]} ~ inx: ~ {$In:fields $Out pre $Skip:1} x{$Prod:$field.($Itc).index} ~ normal: ~ /[^ ]+/ {$Wrt:$Itc} ~ dnaChange: ~ /([A-Z]+) +([A-Z]+)/ {$Wrt:[$Itc s:"$1>$2"]} ~ aaChange: ~ {init $aa={Ile:I Leu:L Met:M Ala:A Val:V Ser:S Thr:T Phe:F Tyr:Y Gly:G Pro:P Trp:W Cys:C Gln:Q Asn:N Arg:R Lys:K Asp:D Glu:E His:H Stop:Stop} } /([A-Za-z]+) +([A-Za-z]+)/ {$Wrt:[$Itc s:"($aa.$1)>($aa.$2)"]} ~ cmnt: ~ /./ ~ ref: ~ /./ ~ # others ln: ~ /[^\n]*\n/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/opt/srs/data/mutdb/haema/haema.txt'] while:$JobHasInput:$job { $JobTokens:[$job name:id print:1] $JobNext:$job $print:"-------->entry\n" } } srs/icarus/db/haema.it # # $RCSfile: haema.it,v $ # $Revision: 1.1 $ # $Date: 1996/11/05 19:54:29 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $dbInfo={ description: |Haemophilia A: Database of nucleotide substitutions, deletions, |insertions and rearrangements of the factor VIII gene. www: |\ |http://146.179.66.63/usr/WWW/WebPages/main.dir/main.htm ftp: |\ |ftp://www.ebi.ac.uk/pub/databases/haema email: |etuddenh@hgmp.mrc.ac.uk contact: |Professor E.G.D. Tuddenham,
|Haemostasis Research Group,
|MRC Clinical Sciences Centre,
|Royal Postgraduate Medical School,
|Hammersmith Hospital,
|Du Cane Road, London
|W12 ONN
|UK fax: |+44-0181-259-8319 literature: |
    |
  1. Tuddenham,E.G.D. and Cooper,D.N. (1994) The Molecular Genetics of |Haemostasis |and its Inherited Disorders. Oxford University Press, Oxford. |
  2. Tuddenham,E.G.D., Cooper,D.N., Gitschier,J., Higuchi,M., Hoyer,L.W., |Yoshioka,A., Peake,I.R., Schwaab,R., Olek,K., Kazazian,H.H., |Lavergne,J-M., |Giannelli,F. and |Antonarakis,S.E. Nucleic Acids Res. (1991) 19, 4821-4833. |
fields:{ } } > |UK fax: |+44-0181-259-8319 literaturesrs/icarus/db/haemb.i # $RCSfile: haemb.i,v $ # $Revision: 1.1 $ # $Date: 1996/11/05 19:54:20 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ HAEMB_DB:$library:[HAEMB group:@MUTATION_LIBS format:@HAEMB_FORMAT maxNameLen:30 ifiles:{'haemb.i' 'haemb.is' 'haemb.it'} files:{ $file:'haemb' } ] HAEMB_FORMAT:$libformat:[syntax:@HAEMB_SYNTAX fileType:@DAT_FILE fields:{ $field:@DF_ALL $field:[@DF_ID code:id indexToken:id index:id tableToken:id tableFormat:left] $field:[@DF_Date code:dt] $field:[@DF_Patient code:pt index:str indexToken:pt] $field:[@DF_NuclChange code:mu indexToken:'mu|mut' index:str tableToken:'mu|mut' tableFormat:left] $field:[@DF_DnaChangePos code:mu indexToken:'mu|pos' index:int tableToken:'mu|pos' tableFormat:right] $field:[@DF_AaChange code:ac indexToken:'ac|mut' index:str tableToken:'ac|mut' tableformat:left] $field:[@DF_ProtChangePos code:ac indexToken:'ac|pos' index:int tableToken:'ac|pos' tableFormat:right] $field:[@DF_ClottingAct code:ct] $field:[@DF_FactorIXAntigen code:ag] $field:[@DF_Coordinator code:co] $field:[@DF_Comment code:co] $field:[@DF_Authors code:rl] $field:[@DF_Reference code:rl] } ] DF_Patient:$srsfield:[Patient short:pat group:@DF_ALL] DF_ClottingAct:$srsfield:[ClottingActivity short:cla] DF_FactorIXAntigen:$srsfield:[FactorIXAntigen short:faa] DF_Coordinator:$srsfield:[Coordinator short:coo] HAEMB_SYNTAX:$syntax:[file:"SRSDB:haemb.is" ignore:" "] bleFormat:right] $field:[@DF_ClottingAct code:ct] $field:[@DF_FactorIXAntigen code:ag] $field:[@DF_Coordinator code:co] $field:[@DF_Comment code:co] $field:[@DF_Authors code:rl] $field:[@DF_Reference code:rl] } ] DF_Patient:$srsfield:[Patient short:pat group:@DF_ALL] DF_ClottingAct:$srsfield:[ClottingActivity short:cla] DF_FactorIXAntigen:$srsfield:[FactorIXAntigen short:faa] DF_Cosrs/icarus/db/haemb.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: haemb.is,v $ # $Revision: 1.2 $ # $Date: 1996/12/06 16:37:36 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $rules={ entry: ~ {$In:[file:text] $Out} ('ID' {$Not} ln)* ('ID ' {$entryFip=$Fip $Wrt} ln {$App} ('ID' {$Not} ln {$App})+)? ~ # fields fields: ~ {$In:entry $Out $Break} f_id f_pt? f_mu? f_ct? f_ag? f_ac? f_cc? (f_ra f_rl?)* f_co f_dt ~ f_id: ~ {$Wrt:id} 'ID ' ln ~ f_pt: ~ {$Wrt:pt} ('PT ' ln)+ ~ f_mu: ~ {$Wrt:mu} ('MU ' ln)+ ~ f_ct: ~ {$Wrt:ct} ('CT ' ln)+ ~ f_ag: ~ {$Wrt:ag} ('AG ' ln)+ ~ f_ac: ~ {$Wrt:ac} ('AC ' ln)+ ~ f_cc: ~ {$Wrt:cc} ('CC ' ln)+ ~ f_ra: ~ {$Wrt:ra} ('RA ' ln)+ ~ f_rl: ~ {$Wrt:rl} ('RL ' ln)+ ~ f_co: ~ {$Wrt:co} ('CO ' ln)+ ~ f_dt: ~ {$Wrt:dt} ('DT ' ln)+ ~ # indexing id: ~ {$In:[fields c:id] $Out} tag word {$Wrt} ~ pt: ~ {$In:[fields c:pt] $Out} tag (word {$Wrt} | sep)* ~ mu: ~ {$In:[fields c:mu] $Out} tag (num {$Wrt:pos} ':'? /([A-Z])->([A-Z])/? {$Wrt:[mut s:"$1>$2"]})? ~ ac: ~ {$In:[fields c:ac] $Out} tag (num {$Wrt:pos} ':'? /([A-Za-z]+)->([A-Za-z]+)/? {$Wrt:[mut s:"$1>$2"]})? ~ # HTML display # others tag: ~ /[A-Z][A-Z0-9]/ ~ num: ~ /-?[0-9]+/ ~ ln: ~ /[^\n]*\n/ ~ word: ~ /[a-zA-Z0-9_]+/ ~ sep: ~ /[^a-zA-Z0-9_\n]+/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/transfac/site.dat'] while:$JobHasInput:$job { $JobTokens:[$job name:id print:1] $JobNext:$job $print:"-------->entry\n" } } tag (num {$Wrt:pos} ':'? /([A-Za-z]+)->([A-Za-z]+)/? {$Wrt:[mut s:"$1>$2"]})? ~ # HTML display # others tag: ~ /[A-Z][A-Z0-9]/ ~ num: ~ /-?[0-9]+/ ~ ln: ~ srs/icarus/db/haemb.it # # $RCSfile: haemb.it,v $ # $Revision: 1.1 $ # $Date: 1996/11/05 19:54:27 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $dbInfo={ description: |Haemophilia B - A data base of point mutations and short additions and |deletions. | |

NOMENCLATURE

| |
    Some points may need clarifying: | |
  1. The nucleotide numbering system is from Yoshitake et.al. (1985). |2965 must be added to the number specified in MU in this data base to |correspond to the numbering in the EMBL file, Accession number K02402, |of the Yoshitake et.al., complete factor IX gene sequence. | |
  2. The amino acid numbering is according to Anson et.al. (1984) and |Yoshitake et.al. (1985). 46 must be added to the number specified in |AC in this data base, to correspond to the number quoted for factor |IX, code KFHU, in the NBRF protein data base. | |
  3. A `Gla' mutant is one affecting a gammacarboxyglutamyl residue. | |
  4. A Bm mutant has an extended prothrombin clotting time (Hougie and |Twomey, 1967) | |
  5. The a-h nomenclature of Anson et.al. (1984) is used for exons. |Donor and acceptor splice sites are named according to the exon they |flank. | |
  6. Where the mutation is an insertion, as in ID 17 (Recklinghausen), |the numbers in the MU field correspond to the position of the first of |the inserted nucleotides. Thus in this entry, `MU 114:insert AT', the |inserted dinucleotide, AT, occupies nucleotides 114 and 115, |displacing the residues there in the wild-type factor IX gene to 116 |and 117. | |
  7. In frameshift mutations, for example ID 17, the amino acid |encoded by the frameshifted nucleotide is listed, i.e. AC -18, stating |there is a premature stop afterwards. The extent of the short, |frameshifted, C-terminal sequence formed is not specified. | |
  8. Only deletions or additions shorter than 20 nucleotides are |included in this data base. Thompson (1990) has reviewed studies on |about 30 patients with longer deletions or more complex |rearrangements. | |
ftp: |\ |ftp://www.ebi.ac.uk/pub/databases/haemb/ email: |brownlee@molecular-biology.oxford.ac.uk contact: |by F. Giannelli (1), P.M. Green (1), K.A. High (2), S. Sommer (3), |M.C. Poon |(4), M. Ludwig (5), R. Schwaab (5), P.H. Reitsma (6), M. Goossens |(7), A. Yoshioka (8), and G.G. Brownlee (9). address: |(1) Paediatric Research Unit, Guy's Tower, London Bridge, |London SE1 9RT,UK; (2) Hematology Laboratory, Children's Hospital of |Philadelphia, 34th Street & Civic Center Boulevard, Philadelphia, PA |19104, USA; (3) Mayo Clinic, 200 Southwest First Street, Rochester, |Minnesota 55905, USA; (4) University of Calgary, Foothills Hospital, |Calgary, AB T2N, Canada (5) Institute of Clinical Biochemistry and |Institute of Experimental Haematology and Blood Transfusion, |Sigmund-Freud-Strasse 25, 5300 Bonn 1, W. Germany, and Institute of |Clinical Biochemistry, University of Bonn; (6) Hemostasis and |Thrombosis Research Unit, University Hospital, PO Box 9600, 2300 RC |Leiden, The Netherlands; (7) National Institute of Health and Medical |Research, 51 Av.du Marechal de Lattre de Tassigny, 94010 Creteil, |France; (8) Department of Pediatrics, Nara Medical College, Kashihara |City, Nara, Japan; and (9) Sir William Dunn School of Pathology, |University of Oxford, South Parks Road, Oxford, OX1 3RE, UK. literature: |
    |
  1. Anson D.S., Choo K.H., Rees D.J.G. et.al., EMBO J. 3: 1054-1064 |(1984) |
  2. Giannelli F., Green P.M., High K.A. et.al., Nucl. Acids Res. 21: |3075-3087 (1993) |
  3. Hougie C., Twomey J.J. Lancet i: 699 (1967) |
  4. Thompson A.R., Prog. Hemost. Thromb. 10: 175-214 (1990) |
  5. Yoshitake S., Schach B.G., Foster D.C., et.al., Biochemistry, 24: |3736-3750 (1985) |
  6. Giannelli F., Green P.M., Sommer S.S., et.al., Nucl. Acids Res. 22: |3534-3546 (1994) |
fields:{ Identifier: |Unique patient identity number, or accession number. Patient: |Original patient pseudonym, acronym, or location. ClottingActivity: |Clotting activity, if known, expressed as a percent of normal. FactorIXAntigen: |Factor IX antigen, if known, expressed as a percent of normal. Comment: |Comments, if any, with those of different types separated by a |semicolon. All CG->CA or TG mutations, and some of the known de |novo mutations are listed here. Coordinator: |coordinator reference. 1, prepared by Giannelli and Green |representing the UK, Sweden and Iceland; 2, by High and Sommer, |USA; 3, by Poon, Canada; 4, by Ludwig and Schwaab, Germany; 5, |by Reitsma, The Netherlands; 6, by Goossens, France; 7, by |Yoshioka, Japan; 8, by Brownlee, rest of the world. } } ith those of different types separated by a |semicolon. All CG->CA or TG mutations, and some of the known de |novo mutations are listed here. Coordinator: |coordinator reference. 1, prepared by Giannelli and Green |representing the UK, Sweden and Iceland; 2, by High and Sommer, |USA; 3, by Poon, Canada; 4, by Ludwig and Schwaab, Germany; 5, |by Reitsma, The Netherlands; 6, by Goossensrs/icarus/db/hssp.i # $RCSfile: hssp.i,v $ # $Revision: 1.2 $ # $Date: 1997/03/03 18:34:02 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ HSSP_DB:$library:[HSSP group:@PROTSTRUCT_LIBS format:@HSSP_FORMAT maxNameLen:30 ifiles:{"hssp.i" "hssp.is"} ] HSSP_FORMAT:$libformat:[fileType:@HSSP_FILE syntax:@HSSP_SYNTAX fields:{ $field:[@DF_ID code:pdbid index:id indexToken:id] $field:[@DF_Date code:date index:int indexToken:creDate] $field:[@DF_Header code:header index:str indexToken:'wrds|header'] $field:[@DF_Compound code:compnd index:str indexToken:'wrds|compnd' tableToken:'t_fields|com'] $field:[@DF_Source code:com index:str indexToken:src] $field:[@DF_EntryAuthors code:entryAut index:str indexToken:entryAut] $field:[@DF_NAlign code:nalign index:int indexToken:'nums|nalign'] $field:[@DF_NChain code:nchain index:int indexToken:'nums|nchain'] $field:[@DF_KChain code:kchain index:int indexToken:'nums|kchain'] $field:[@DF_SeqLength code:seqlen index:int indexToken:'nums|seqlen'] } ] DF_KChain:$srsfield:[KChain short:kch] DF_NChain:$srsfield:[NChain short:nch] HSSP_SYNTAX:$syntax:[file:"SRSDB:hssp.is" ignore:" "] HSSP_FILE:$FileType:[typename:'hssp' singleEntry:y maxline:500] $link:[@HSSP_DB to:@?SWISSPROT_DB token: 'link|swissprot' toField:@DF_ID] $link:[@HSSP_DB to:@?PDB_DB token:'link|pdb' toField:@DF_ID] indexToken:'nums|nchain'] srs/icarus/db/hssp.is $rules={ # the entry entry: ~ {$In:[file:text] $Out pre $Skip:0} 'HSSP' {pre {$entryFip=0} $Wrt} appLn appLn+ ~ # fields from text fields: ~ {$In:entry $Out $Skip:1} title pdbid f_date seqbase param info header compnd source f_author seqlen nchain? kchain? nalign? notation? proteins? alignments? profile? insList? ~ title: ~ {$Wrt:title} 'HSSP' ln ~ pdbid: ~ {$Wrt:pdbid} 'PDBID' ln ~ f_date: ~ {$Wrt:date} 'DATE' ln ~ seqbase: ~ {$Wrt:seqbase} ('SEQBASE' ln)+ ~ param: ~ {$Wrt:param} 'PARAMETER' ln ('REFERENCE' {$Not} ln)*~ info: ~ {$Wrt:info} ('HEADER' {$Not} ln)+ ~ header: ~ {$Wrt:header} ('HEADER' ln)+ ~ compnd: ~ {$Wrt:compnd} ('COMPND' ln)+ ~ source: ~ {$Wrt:source} ('SOURCE' ln)+ ~ f_author: ~ {$Wrt:author} ('AUTHOR' ln)+ ~ seqlen: ~ {$Wrt:seqlen} ('SEQLENGTH' ln)+ ~ nchain: ~ {$Wrt:nchain} ('NCHAIN' ln)+ ~ kchain: ~ {$Wrt:kchain} ('KCHAIN' ln)+ ~ nalign: ~ {$Wrt:nalign} ('NALIGN' ln)+ ~ notation: ~ {$Wrt:notation} ('##' {$Not} ln)+ ~ proteins: ~ {$Wrt:proteins} ('## ALIGNMENTS' {$Not} ln)+ ~ alignments:~ {$Wrt:alignments} ('## SEQUENCE PROFILE' {$Not} ln)+ ~ profile: ~ {$Wrt:profile} ('## INSERTION LIST' {$Not} ln)+ ~ insList: ~ {$Wrt:insList} ln+ ~ # indexing production id: ~ {$In:[fields c:pdbid] $Out} tag /[a-zA-Z0-9]+/ {$Wrt} ~ nums: ~ {$In:[fields c:{nalign nchain kchain seqlen}] $Out} x{$Mov:10} /[0-9]+/ {$Wrt:$Itc} ~ creDate: ~ {$In:[fields c:date] $Out} /.*generated on/ datenum {$Wrt:[s:$date]} ~ wrds: ~ {$In:[fields c:{compnd header}] $Out} (x{$Mov:10 $Break} words {$Len:60} ln)+ ~ src: ~ {$In:[fields c:src] $Out} (x{$Mov:10} words {$Len:60} ln)+ ~ entryAut: ~ {$In:[fields c:entryAut] $Out} (x{$Mov:10} authors {$Len:60} ln)+ ~ aut: ~ {$In:[fields c:aut] $Out} (x{$Mov:18} authors {$Len:52} ln)+ ~ tit: ~ {$In:[fields c:tit] $Out} (x{$Mov:18} words {$Len:52} ln)+ ~ ref: ~ {$In:[fields c:ref] $Out} (x{$Mov:18} words {$Len:52} ln)+ ~ authors: ~ author (',' author?)* ~ author: ~ / *([^ ,]*\\.)([^ ,]*)/ {$Uniq:[s:"$2,$1"]} ~ words: ~ (/[A-Z0-9_]+/ {$Uniq:$Itc} | /./)+ ~ datenum: ~ {init {$month={Jan:1 Feb:2 Mar:3 Apr:4 May:5 Jun:6 Jul:7 Aug:8 Sep:9 Oct:10 Nov:11 Dec:12}}} / *([0-9]+)-([A-Z][a-z][a-z])-([0-9]+)/ {$date=$1 + $month.$2 * 100 + $3 * 10000 + 19000000} ~ link: ~ {$In:[fields c:proteins] $Out} ln ln (/[0-9]+ *:/ name {$Wrt:swissprot} /[1-9][A-Z0-9]+/? {$Wrt:pdb} ln)+ ~ # reformat multiple alignment mali: ~ {$In:[fields c:alignments] $Out pre {$Skip:0 $ali={} for:{$k=0 $k<501 $k+=1} $ali+=""} for:{$k=1 $k<501 $k+=1} $dp:$ali[$k]} (/.. ALIGNMENTS *([0-9]+)[ -]+([0-9]+)/ {$from=$1 $to=$2+1 $dp:"$from - $to"} ln | (x{$Mov:51} x{for:{$k=$from $k<$to $k+=1} $Prod:aa}ln))+ ~ aa: ~ /[A-Z.]/{$StrApp:[$ali[$k] s:$Ct]} | / ?/{$StrApp:[$ali[$k] s:"~"]} ~ # table display t_fields: ~ {$In:fields $Out} (x{$Mov:9 $Getc:62 $Wrt:$Itc} ln)+ ~ # html display h_pdbid: ~ {$In:[fields c:pdbid t:html]} tag name {$Rep:{$ParStr:pdbR $Ct $Ct}} ~ h_proteins:~ {$In:[fields c:proteins t:html]} ln ln (/[0-9]+ *:/ name {$Rep:{$ParStr:swissidR $Ct $Ct}} /[1-9][A-Z0-9]+/? {$Rep:{$ParStr:pdbR $Ct $Ct}} ln)+ ~ # other productions tag: ~ /[A-Z0-9]+ */ ~ name: ~ /[a-zA-Z0-9_]+/ ~ word: ~ /[^ ]+/ ~ ln: ~ /[^\n]*\n/ ~ appLn: ~ /[^\n]*\n/ {$App} ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/hssp/1seb.hssp'] $JobTokens:[$job name:creDate print:1] } s:~ {$In:[fields c:proteins t:html]} srs/icarus/db/imgt.i # # $RCSfile: imgt.i,v $ # $Revision: 1.2 $ # $Date: 1997/03/19 20:30:35 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IMGT_DB:$library:[IMGT group:@SEQUENCE_LIBS partSize:100000 comment:"Immunoglobulin Database from the EBI" subentries:@ImgtFeatures_DB format:@IMGT_FORMAT cachesize:2048 maxNameLen:30 files:{ $file:imgt $file:imgt1 } ] IMGT_FORMAT:$libformat:[syntax:@IMGT_SYNTAX fileType:{@DAT_FILE} # fileType:{@GCGREF_FILE @GCGSEQ_FILE} fields:{ $field:@DF_ALL $field:[@DF_ID code:id index:id indexToken:id] $field:[@DF_Accession code:acc index:str indexToken:acc tableToken:acc tableFormat:left] $field:[@DF_Division code:id index:str indexToken:div tableToken:div tableFormat:left] $field:[@DF_Molecule code:id index:str indexToken:mol tableToken:mol tableFormat:left] # $field:[@DF_DBOrigin code:acc index:str indexToken:dbOri # tableToken:dbOri tableFormat:left] # $field:[@DF_AccessionKey code:acc index:str indexToken:accKey # tableToken:accKey tableFormat:center] $field:[@DF_Description code:des index:str indexToken:des tableToken:t_des tableFormat:left] $field:[@DF_Keywords code:key index:str indexToken:key tableToken:key tableFormat:left] $field:[@DF_Organism code:org index:str indexToken:org] $field:[@DF_Authors code:ra index:str indexToken:authors tableToken:authors tableFormat:left] $field:[@DF_Date code:date index:int indexToken:date tableToken:date tableFormat:center] $field:[@DF_SeqLength code:sq index:int indexToken:seqLen tableToken:seqLen tableFormat:right] $field:[@DF_LINK code:dr] $field:[@DF_DNASequence code:seq format:imgt] $field:[@DF_HeaderField name:'Feature Table Fields'] $field:[@DF_FtKey code:ft index:str indexToken:ftKey indexId:@SUBENTRY_ID tableToken:ftKey tableFormat:left] $field:[@DF_FtQualifier code:ft index:str indexToken:ftQual indexId:@SUBENTRY_ID] $field:[@DF_PID code:ft index:str indexToken:pid indexId:@SUBENTRY_ID] $field:[@DF_FtDescription code:ft index:str indexToken:ftDes indexId:@SUBENTRY_ID] $field:[@DF_FtSource code:ft index:str indexToken:ftSrc indexId:@SUBENTRY_ID] $field:[@DF_ChrsNo code:ft index:str indexToken:chrsNo indexId:@SUBENTRY_ID] $field:[@DF_FtMap code:ft index:str indexToken:map indexId:@SUBENTRY_ID] } ] IMGT_SYNTAX:$syntax:[file:"SRSDB:imgt.is" ignore:" \t"] $syntax:[name:ftseq file:"SRSDB:ftseq.is" ignore:" \t\n"] #$link:[@IMGT_DB to:@?GENBANK_DB toField:@DF_ACCNO] #$link:[@IMGT_DB to:@?PIR_DB toField:@DF_ACCNO] #$link:[@IMGT_DB to:@?REBASE_DB toField:@DF_ID] #$link:[@IMGT_DB to:@?OMIM_DB toField:@DF_ID] #$link:[@IMGT_DB to:@?MEDLINE_DB toField:@DF_ID] ImgtFeatures_DB:$library:[IMGT_features format:@ImgtFeature_Format] ImgtFeature_Format:$libformat:[syntax:@IMGT_SYNTAX #idType:@SUBENTRY_ID tableFormat:left fields:{ $field:[@DF_ID token:ftId] # $field:[@DF_Accession code:acc fromParent:y] # $field:[@DF_Description code:des fromParent:y] $field:[@DF_FtKey token:ft tableToken:'t_ft|key'] $field:[@DF_FtQualifier token:ft tableToken:'t_ft|qual'] $field:[@DF_PID token:ft tableToken:'t_ft|db_xref'] $field:[@DF_FtDescription token:ft tableToken:'t_ft|note'] $field:[@DF_FtGene token:ft tableToken:'t_ft|gene'] $field:[@DF_FtProduct token:ft tableToken:'t_ft|product'] $field:[@DF_FtPartial token:ft tableToken:'t_ft|partial'] $field:[@DF_FtPseudo token:ft tableToken:'t_ft|pseudo'] $field:[@DF_FtNumber token:ft tableToken:'t_ft|number'] $field:[@DF_FtSource token:ft tableToken:ftSrc] $field:[@DF_ChrsNo token:ft tableToken:'t_ft|chromosome'] $field:[@DF_FtMap token:ft tableToken:'t_ft|map'] $field:[@DF_DNALocation token:ftLocat tableFormat:listing] } ] n:ft tableToken:'t_ft|gene'] $field:[@DF_FtProduct token:ft tableTokesrs/icarus/db/imgt.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: imgt.is,v $ # $Revision: 1.2 $ # $Date: 1997/03/19 20:30:35 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $fn={ ID: id KW: key RP: refp RL: refln SQ: seqln AC: acc OS: org RX: refx DR: link XX: space DT: date OC: tax RA: refaut FH: fthead '//': space DE: des RN: refn RT: refttl CC: comment NI:ni RC: refc } $rules={ entry: ~ {$In:[file:text] $Out pre $Skip:0} ('ID ' {$not} ln)* ('ID '{$entryFip=$Fip $Wrt} ln {$App} (' ' {$Not} ln {$App})+ )? ~ # data-fields fields: ~ {$In:entry $Out $Skip:1} (ftln | /../ { if:$Ct==$prev $App else $Wrt:$fn.$Ct if:$fn.$Ct=="" $dp:"+++ unknown: $Ct in $entryName +++" $prev=$Ct } ln {$App})+ ~ ftln: ~ {$Wrt:ft} 'FT' ln ('FT ' ln)* ~ clFields: ~ {$In:fields $Out} (/.. */ ln {$Wrt:$Itc} (/.. */ ln {$App})*)? ~ sequence: ~ {pre {$seq=$SeqNew:$entryName $Wrt:[seq s:$entryName]} $SeqMake:$seq} (ln {$SeqApp:[$seq s:$Ct]})* ~ # parsing the sequence in a GCG formatted file seqFields: ~ { $In:[file:data] $Out pre $s=$SeqNew $SeqMake:$s $Wrt:[s:$entryName] } '>>>>' {$seqFip=$Fip} (/[A-Z0-9]+/ seq | /[A-Z0-9]+_0/ seq (/>>>>[A-Z0-9]+_[1-9]+/ {$SeqTrunc:[$s len:10000]} seq)+) ~ seq: ~ (/.*2BIT *Len:/ /[0-9]+/ {$len=$Ct} ln ln {$s=$SeqGet2Bit:[$s file:$File len:$len]} ('>>>>'{$Not} ln)*| /.*ASCII/ ln ln ('>>>>' {$Not} /.*/ {$SeqApp:[$s s:$Ct]})+) ~ # for indexing i_id: ~ {$In:[entry] $Out:id} /ID +/ name {$Wrt} ~ # indexing features ftWord: ~ /[^" ,;:()\n.-]+/ ~ #" ftSep: ~ /[ ,;.:()-]+/ ~ ftKey: ~ {$In:[clFields c:ft count:ft var:$ftN] $Out} ftK {$Wrt:[n:$ftN]} ~ ftK: ~ {pre $Skip:1} /[A-Za-z0-9_'-]+/ ~ chrsNo: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} /.+\/chromosome="?/ (/[^\n\" ]+/ {$Uniq:[n:$ftN]} | '\nFT' | ' ')+ ~ #" ftSrc: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} (/[^\/]+\// ( /(tissue_type|cell_line|organism|strain|dev_stage|sex|clone_lib)="/ ('\nFT' | ftWord {$Uniq:[n:$ftN]} | ftSep)+)?)* ~ ftDes: ~ {$In:[clFields c:ft count:ft var:$ftN] $Out} ftK num '..' num (/[A-Za-z0-9_]+/ {$Uniq:[n:$ftN]} | /[^A-Za-z0-9_]+/)* ~ ftQual: ~ {$In:[clFields c:ft count:ft var:$ftN] $Out} /[^\/]+/ (/\/([a-zA-Z0-9_]+)/ {$Wrt:[s:$1 n:$ftN]} (/=[a-zA-Z0-9_]+/ | /="[^"]+"/)? /[^\/]+/)* ~ #" # borrowed from embl.is instead # ftK ftLoc (ftQualNm {$Wrt:[n:$ftN s:$name]} ftQualVal?)* ~ ftQualNm: ~ /\/([a-zA-Z0-9_-]+)/ {$Break $name=$1} ~ ftQualVal: ~ '=' (/"([^"]+)"/ {$val=$1} | /[^ \n]+/ {$val=$Ct}) ~ #" # ftLoc: ~ pos {$b=$Ct} '..' pos {$e=$Ct} ~ pos: ~ /[0-9]+/ ~ ftLen: ~ {$In:[clFields c:ft count:ft var:$ftN] $Out} ftK ftLoc {$Wrt:[n:$ftN s:($e-$b+1)]} ~ i_div: ~ {$In:[fields c:id] $Out:div} /.+ ([A-Z]+); +[0-9]+ +BP/ {$Wrt:[s:$1]} ~ i_mol: ~ {$In:[fields c:id] $Out:mol} /[^;]+;[^;]+; +([A-Z]+)/ {$Wrt:[s:$1]} ~ i_acc: ~ {$In:[fields c:acc] $Out:acc} ('AC' (name {$Wrt} ';')+)+ ~ i_nid: ~ {$In:[fields c:nid] $Out:nid} 'NI' name {$Wrt} ~ i_dates: ~ { $In:[fields c:date] $Out:date init $month={JAN:1 FEB:2 MAR:3 APR:4 MAY:5 JUN:6 JUL:7 AUG:8 SEP:9 OCT:10 NOV:11 DEC:12} } /.* ([0-9]+)-([A-Z]+)-([0-9]+)[^\n]+Cre/ {$Wrt:[credate s:($1 + $month.$2*100 + $3*10000)]} ~ des: ~ {$In:[fields c:des] $Out} ('DE' (/\\(EC *([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)/ {$Wrt:[s:$1]}| word{$Wrt} | sp)+ ln)+ ~ org: ~ {$In:[fields c:org] $Out} ('OC' (/[^;.\n]+/ {$Wrt} | /[^\n]/)*)+ | 'OS' /[^(\n]+/ {$Wrt:[s:$Trim:$Ct]} ('(' (/[^ \n)]+/ | /[^)]/)+)? | 'OG' /[^\n;.]+/ {$Wrt} ~ key: ~ {$In:[fields c:key] $Out} ('KW' (/[^\n;.]+/ {$Wrt} | /[^\n]/)+)+ ~ i_authors: ~ {$In:[fields c:ra] $Out:authors} (/RA/ (/([^.,\n]+) +([^,;\n]+)/ {$Uniq:[s:"$1,$2"]} /[,;]/)* ln)* ~ i_seqLen: ~ {$In:[fields c:sq] $Out:seqLen} 'SQ Sequence' /[0-9]+/ {$Wrt} ~ # indexing features map: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} /.+\/map="/ (/[^a-zA-Z0-9"]+/|/[a-zA-Z0-9]+/{$Wrt:[n:$ftN]})+ #" ~ pid: ~ {$In:[fields c:ft count:ft var:$ftN select:$subEntryN] $Out} (/db_xref="?PID:([0-9a-zA-Z]+)/ {$Wrt:[n:$ftN s:$1]} | /[^\/]+\// )+ ~ # displaying features ftClean: ~ {$In:[fields c:ft count:ft var:$ftN select:$subEntryN] $Out } 'FT' ln {$Wrt} ('FT' ln {$App})* ~ ftLoc: ~ {$In:ftClean $Out} /[^ ]+/ /[^\/]+/ {$Wrt} ~ ft: ~ {$In:[fields c:ft count:ft var:$ftN select:$subEntryN] $Out} /.*/ {$Wrt} ~ ftId: ~ {$In:[fields c:id] $Out} /.. *([A-Z0-9]+)/ {$Wrt:[s:"ID $1\_$subEntryN; parent: $1"]}~ h_ftId: ~ {$In:[ftId t:html]} /.*parent: */ /[A-Z0-9]+/ {$Rep:{$ParStr:emblIdR $Ct $Ct}} ~ t_ft: ~ {$In:ftClean $Out} /(]*>/ ~ h_links: ~ {$In:[fields c:link t:html] init{$hl={ 'SWISS-PROT': swissR DICTYDB: dictydbR GCRDB: gcrdbR MAIZEDB: maizedbR WORMPEP: wormpepR LISTA: listaR PIR: pirR YEPD: yepdR SGD: sgdR STYGENE: stygeneR HIV: hivR ECOGENE: ecogeneR ECO2DBASE: eco2dbaseR MIM: mimR SUBTILIST: subtilistR FLYBASE: flybaseR TRANSFAC: transfacR REBASE: rebaseR } } } (/DR/ dbName {$db=$Ct} ';' accno {$Rep:{$ParStr:$hl.$db $Ct $Ct}} ln)* ~ # other stuff word: ~ /[^" ,;:()\/=\n.-]+/ ~ sp: ~ /[ ,;.:()\/=-]+/ ~ lnCode: ~ /\n[A-Z][A-Z]/ ~ ln: ~ /[^\n]*\n/ ~ accno: ~ /[A-Z0-9]+/ ~ num: ~ /(<|>)?[0-9?]+/ ~ name: ~ /[a-zA-Z0-9_-]+/ ~ dbName: ~ /[^;]+/ ~ } if:$TestMode { $job = $JobNew:[prod:$rules skip:" \n" fileName:'imgt.dat'] while:$JobHasInput:$job { # $JobTokens:[$job name:fields print:1] $JobTokens:[$job name:acc print:1] $JobNext:$job $print:"-------->entry\n" } } er stuff word: ~ /[^" ,;:()\/=\n.-]+/ ~ sp: ~ /[ ,;.:()\/=-]+/ ~ lnCode: ~ /\n[A-Z][A-Z]/ ~ ln: ~ /[^\n]*\n/ ~ accno: ~ /[A-Z0-9]+/ ~ srs/icarus/db/ldlr.i # $RCSfile: ldlr.i,v $ # $Revision: 1.1 $ # $Date: 1997/03/19 16:15:08 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ LDLR_DB:$library:[LDLR group:@MUTATION_LIBS format:@LDLR_FORMAT maxNameLen:30 ifiles:{"ldlr.i" "ldlr.is"} files:{ $file:csv } ] LDLR_FORMAT:$libformat:[fileType:@TXT_FILE syntax:@LDLR_SYNTAX printFormat:table tableFormat:left fields:{ $field:[@DF_ID code:id index:id indexToken:id tableToken:id] $field:[@DF_Code code:code index:str indexToken:code tableToken:code] # $field:[@DF_NuclPos code:nucl index:int indexToken:nucPos] $field:[@DF_NuclChange code:nuclChange index:str indexToken:nuclChange tableToken:nuclChange] $field:[@DF_DnaChangePos code:dnaPos index:int indexToken:dnaPos tableToken:dnaPos tableFormat:right] # $field:[@DF_TranslEffect code:feature index:str indexToken:translEff # tableToken:translEff] $field:[@DF_AaChange code:aaChange index:str indexToken:aaChange tableToken:aaChange] $field:[@DF_ProtChangePos code:aaPos index:int indexToken:aaPos tableToken:aaPos tableFormat:right] $field:[@DF_Population token:Pop index:str indexToken:Pop tableToken:Pop tableFormat:right] } ] LDLR_SYNTAX:$syntax:[file:"SRSDB:ldlr.is"] LDLR_FILE:$filetype:[typeName:dat maxline:300] DF_Population:$srsfield:[Population short:pop] #DF_Code:$srsfield:[Code short:cod] #DF_NuclPos:$srsfield:[NucleotidePosition short:nup] x:str indexToken:aaChange tableToken:aaChange] $field:[@DF_ProtChangePos code:aaPos index:int indexToken:aaPos tableToken:aaPos tableFormat:right] $field:[@DF_Population token:Pop index:str indexToken:Pop tableToken:Pop tableFormat:right] } ] LDLR_SYNTAX:$syntax:[file:"SRSDB:ldlr.is"] LDLR_FILE:$filetype:[typeName:dat maxline:300] DF_Population:$srsfield:[Population short:pop] #DF_Code:$srsfield:[Code short:cod] #Dsrs/icarus/db/ldlr.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: ldlr.is,v $ # $Revision: 1.1 $ # $Date: 1997/03/19 16:14:42 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $fn={ id population mutation result name authors comment reference } $rules={ entry: ~ {$In:[file:text] $Out} ln {$entryFip=$Fip $Wrt} ~ ln: ~ /[^\n]*\n/ ~ # parsing fields fields: ~ {$In:entry $Out pre $n=1} (/("[^"]*"|[^,\n]+)/ { $s=$Trim:[$Ct skip:'"'] if: $s!="" $Wrt:[c:$fn[$n] s:$s] $n+=1 } /,|\n/)+ ~ #indexing id: ~ {$In:[fields c:id] $Out} /.*/ {$Wrt} ~ code: ~ {$In:[fields c:name] $Out} /.*/ {$Wrt} ~ nuclChange: ~ {$In:[fields c:mutation] $Out} /([A-Za-z]>[A-Za-z]).*/ {$Wrt:[s:"$1"]}| /.*/ {$Wrt} ~ dnaPos: ~ {$In:[fields c:mutation] $Out} /[A-Za-z]>[A-Za-z] at ([0-9]+)/ {$Wrt:[s:"$1"]} ~ aaChange: ~ {$In:[fields c:result] $Out} /([A-Za-z])[0-9]+([A-Za-z])/ {$Wrt:[s:"$1>$2"]}| /.*/ {$Wrt} ~ aaPos: ~ {$In:[fields c:result] $Out} /[A-Za-z]([0-9]+)[A-Za-z].*/ {$Wrt:[s:"$1"]} ~ Pop: ~ {$In:[fields c:population] $Out} /.*/ {$Wrt} ~ authors: ~ {$In:[fields c:authors] $Out} (/[^;]+/ {$Wrt} /;/)+ ~ reference: ~ {$In:[fields c:reference] $Out} (/[^;]+/ {$Wrt} /;/)+ ~ comment: ~ {$In:[fields c:comment] $Out} (/[^;]+/ {$Wrt} /;/)+ ~ # for displaying HTML h_fields: ~ {$In:[fields t:html]} x{if:$ParInt:[isTable] == 1 $Fail} /.*/ {$Rep:"$Itc$Ct"} ~ #other # num: ~ /[0-9]+/ ~ # letter: ~ /[A-Za-z]/ ~ # word: ~ /[A-Za-z]+/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/u1/srs/data/mutdb/ldlr/csv.txt'] while:$JobHasInput:$job { $JobTokens:[$job name:aaPos print:1] $JobNext:$job $print:"-------->entry\n" } } s: ~ {$In:[fields t:html]} x{if:$ParInt:[isTable] == 1 $Fail} /.*/ {$Rep:"$Itc$Ct"} ~ #other # num: ~ /[0-9]+/ ~ # letter: ~ /[A-Za-z]/ ~ # word: ~ /[A-Za-z]+/ ~srs/icarus/db/ldlr.it # address: contact: |
|Ian Day
|Division of Cardiovascular Genetics
|Department of Medicine
|The Rayne Institute
|University College London Medical School
|London WC1E 6IJ, UK |

www: |\ |http://www.ucl.ac.uk/fh/ # telephone: '+358-0-708 59081' # telefax: '+358-0-708 59068' email: 'iday@hgmp.mrc.ac.uk' } # letter: ~ /[A-Za-z]/ ~ # word: b+/ ~srs/icarus/db/maketrembl.i #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: maketrembl.i,v $ # $Revision: 1.3 $ # $Date: 1996/12/14 18:18:59 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $rules={ entry: ~ {$In:[file:text] $Out pre {$Skip:0 $cdsN=0 $ft={} $ftN=0}} ('ID ' {$not} ln)* ('ID '{$entryFip=$Fip $Wrt} ln {$App} ('SQ' {$Not} ln {$App})+ )? ~ # fields fields: ~ {$In:entry $Out $Skip:1} id ('AC' {$Not} ln)* acc ('DE' {$Not} ln)* des ('OS' {$Not} ln)* src sep tax sep org? ('FT' {$Not} ln)* ft* x{$Break}~ id: ~ {$Wrt:id} 'ID' / *([A-Z0-9_]+)/ {$entryName=$1} ln ~ acc: ~ /AC +/ /[A-Z0-9]+/ {$accNo=$Ct} ('AC' ln)* ~ des: ~ {$des=$Ct} ('DE' ln)+ ~ src: ~ {$src=$Ct} ('OS' ln)+ ~ tax: ~ {$tax=$Ct} ('OC' ln)+ ~ org: ~ {$org=$Ct} ('OG' ln)+ ~ ft: ~ {$Wrt:ft $ft+=$Ct} 'FT' ln ('FT ' ln)* ~ sep: ~ ('XX' ln)* ~ #feature ftClean: ~ {$In:[fields c:ft] $Out} 'FT' ln {$Wrt} ('FT' ln {$App})* ~ cds: ~ {$In:ftClean $Out pre $ftN+=1 $Break:[cond:$entryName=='A12061']} ('CDS'{$cdsN+=1 $product="" $gene="" $note="" $t="" $s=$SeqNew} /[^\/]+/ (gene | product | translate | note | other)+ x{ if:$SeqLen:[$s]>0 { $Print: |ID ($entryName)_$cdsN standard; PRT; ($SeqLen:$s) AA. $Print:|AC $accNo; $Print:|DR EMBL; $accNo; $entryName. if:($gene=="" && $product=="" && $note=="") $Print:|DE unnamed ORF; else { if:$gene!="" $Print:["gene: \"$gene\"; " v:$t] if:$product!="" $Print:["product: \"$product\"; " v:$t] if:$t!="" $Print:"($StrFormat:[$StrTrans:[$t from:'\n' to:' '] label:'DE ' width:80])\n" } $Print:$des $Print:"$src$tax$org" $Print:$ft[$ftN] $SeqPrint:[format:embl] } } )? ~ gene: ~ '/gene=' value {$gene=$v} ~ product: ~ '/product=' value {$product=$v} ~ translate: ~ '/translation=' '"' /[^"]+/ {$SeqApp:[$s s:$Ct] $SeqMake:$s} '"' ~ note: ~ '/note=' value {$note=$v} ~ other: ~ /\/[^= \n]+/ ('=' value)? ~ value: ~ '"' /[^"]+/ {$v="$Ct"} '"' | /[^ \n]+/ {$v="$Ct"} ~ #other stuff ln: ~ /[^\n]*\n/ ~ } $files={ mam est1 est2 est3 est4 est5 est6 est7 fun gss hum1 hum2 inv org patent phg pln pro rod sts syn unc vrl vrt } foreach:[$name in:$files] { $job = $JobNew:[prod:$rules skip:" \n" fileName:"/data/embl_dna/$name.dat"] while:$JobTokens:[$job name:cds] { $JobNext:$job } } :$s} '"' ~ note: ~ '/note=' value {$note=$v} ~ other: ~ /\/[^= \n]+/ ('=' value)? ~ value: ~ '"' /[^"]+/ {$v="$Ct"} '"' | /[^ \n]+/ {$v="$Ctsrs/icarus/db/medline.i # $RCSfile: medline.i,v $ # $Revision: 1.1 $ # $Date: 1997/03/03 18:36:27 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MEDLINE_DB:$library:[MEDLINE group:@LITERATURE_LIBS partSize:200000 format:@MEDLINE_FORMAT maxNameLen:10 ifiles:{"medline.i" "medline.is"} files:{ $file:medlars001 $file:medlars002 $file:medlars003 $file:medlars004 $file:medlars005 $file:medlars006 $file:medlars007 $file:medlars008 $file:medlars009 $file:medlars010 $file:medlars011 $file:medlars012 $file:medlars013 $file:medlars014 $file:medlars015 } ] MEDLINE_FORMAT:$libformat:[fileType:@DAT_FILE syntax:@MEDLINE_SYNTAX tableFormat:left fields:{ $field:[@DF_UI code:ui index:id indexToken:ui] $field:[@DF_ALL] $field:[@DF_Authors code:au index:str indexToken:au] $field:[@DF_Title code:ti index:str indexToken:ti tableToken:'t_fd|ti'] $field:[@DF_Abstract code:ab index:str indexToken:ab tableToken:'t_fd|ab'] $field:[@DF_MeshTerm code:mh index:str indexToken:mh] $field:[@DF_Date code:dp index:int indexToken:dp] $field:[@DF_Journal code:ta index:str indexToken:ta] $field:[@DF_Citation code:so tableToken:'t_fd|so'] } ] MEDLINE_SYNTAX:$syntax:[file:"SRSDB:medline.is" ignore:" "] DF_UI:$srsfield:[UI short:ui] DF_MeshTerm:$srsfield:[MeshTerms short:mh] DF_Journal:$srsfield:[JournalName short:jnl] en:'t_fd|ti'] $field:[@DF_Abstract code:ab index:str indexToken:ab tableToken:'t_fd|ab'] $field:[@DF_MeshTerm code:mh index:str indexToken:mh] $field:[@DF_Date code:dp index:int indexToken:dp] $field:[@DF_Journal code:ta index:str indexToken:ta] $field:[@DF_Citation code:so tableToken:'t_fd|so'] } ] MEDLINE_SYNTAX:$syntax:[file:"SRSDB:medline.is" ignore:" "] DF_UI:$srsfield:[UI short:ui] DF_MeshTerm:$srsfield:[MeshTerms short:mh] DF_Journal:$srsfield:[JournalName short:jnl] srs/icarus/db/medline.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: medline.is,v $ # $Revision: 1.1 $ # $Date: 1997/03/03 18:36:28 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $fn={ 'UI -': ui 'TA -':ta 'SO -':so 'GS -':gs 'AU -': au 'DP -':dp 'AB -':ab 'AD -':ad 'MH -': mh 'PG -':pg 'IP -':ip 'SI -':si 'TI -': ti 'VI -':vi 'RN -':rn } $rules={ entry: ~ {$In:[file:text] $Out pre $Skip:0} ('UI' {$Not} ln)* ('UI' {$entryFip=$Fip $Wrt} ln {$App} ('UI' {$Not} ln {$App})+)? ~ # fields fields: ~ {$In:entry $Out $Skip:1} (tag { if:$Ct==$prev $App else $Wrt:$fn.$Ct if:$fn.$Ct=="" $dp:"+++ unknown: $Ct +++" $prev=$Ct } ln {$App} / [^\n]+\n/* {$App})+ ~ # indexing ui: ~ {$In:[fields c:ui] $Out} tag name {$Wrt} ~ au: ~ {$In:[fields c:au] $Out} (tag /([^\n]+) ([A-Z]+)( Jr| 2d| 3d)?\n/ {$Wrt:[s:"$1;$2"]})+ ~ mh: ~ {$In:[fields c:mh] $Out} (tag '*'? /[^\/,\n]+/ {$Uniq} (/[\/,]/ '*'?/[^\/,\n]+/ {$Uniq})* ln)+~ ab: ~ {$In:[fields c:ab] $Out} tag (word {$Uniq} | /./)+ ~ ti: ~ {$In:[fields c:ti] $Out} tag (word {$Uniq} | /./)+ ~ ta: ~ {$In:[fields c:ta] $Out} tag /[^\n]+/ {$Wrt} ~ dp: ~ {$In:[fields c:dp] $Out init $month={Jan:1 Feb:2 Mar:3 Apr:4 May:5 Jun:6 Jul:7 Aug:8 Sep:9 Oct:10 Nov:11 Dec:12} pre {$m=1 $d=1} $Wrt:[s:($y*10000 + $m*100 + $d)]} tag num {$y=$Ct} (/[A-Z][a-z]+/ {$m=$month.$Ct} num? {$d=$Ct})? ~ # table display t_fd: ~ {$In:[fields c:{ab ti so}] $Out} tag /.*/ {$Wrt:$Itc} ~ # HTML display # others num: ~ /-?[0-9]+/ ~ tag: ~ /[A-Z][A-Z] +-/ ~ ln: ~ /[^\n]*\n/ ~ name: ~ /[a-zA-Z0-9$_-]+/ ~ word: ~ /[a-zA-Z0-9_]+/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/medline1/medlars010.dat'] while:$JobHasInput:$job { $JobTokens:[$job name:dp print:1] $JobNext:$job $print:"-------->entry\n" } } # table display t_fd: ~ {$In:[fields c:{ab ti so}] $Out} tag /.*/ {$Wrt:$Itc} ~ # HTML display # others num: ~ /-?[0-9]+/ ~ tag: ~ /[A-Z][A-Z] +-/ ~ ln: ~ /[^\n]*\n/ ~ name: ~ /[a-zA-Z0-9$_-]+/ ~ word: ~ /[a-zA-Z0-9_]+/ ~ } # debugging if:$TestMode { $job = $JobNew:srs/icarus/db/mpw.i # $RCSfile: mpw.i,v $ # $Revision: 1.7 $ # $Date: 1997/03/03 18:34:03 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MPW_DB:$library:[MPW group:@SEQRELATED_LIBS comment:"Metabolic pathways - Selkov." format:@MPW_FORMAT maxNameLen:30 ifiles:{"prosite.i" "prosite.is"} files:{ $file:pathway_graphics # $file:aac # $file:aro # $file:car # $file:coe # $file:enz # $file:hal # $file:hyd # $file:lip # $file:mtr # $file:nit # $file:nuc # $file:oxy # $file:pho # $file:pro # $file:pur # $file:pyr # $file:sig # $file:sul } ] MPW_FORMAT:$libformat:[fileType:@MPW_FILE syntax:@MPW_SYNTAX tableFormat:left printFormat:topicList fields:{ $field:[@DF_ALL] $field:[@DF_ID index:id indexToken:id] $field:[@DF_Name code:MPW index:str indexToken:name] $field:[@DF_CellCultureCategoryCode code:CCC indexToken:'words|CCC'] $field:[@DF_AlternativePathwayNames code:APN index:str indexToken:'words|APN' tableToken:'fields|APN'] $field:[@DF_SystematicPathwayNames code:SPN index:str indexToken:'words|SPN' tableToken:'fields|SPN'] # $field:[@DF_SystematicPathwayNames code:SPW index:str # indexToken:'words|SPW'] $field:[@DF_MetabolicPathwayName code:MPW index:str indexToken:'name' tableToken:'fields|MPW'] $field:[@DF_TaxonomicGroup code:TG index:str indexToken:'words|TG'] $field:[@DF_Strain code:STR index:str indexToken:'words|STR'] $field:[@DF_OverallReaction code:OVR index:str indexToken:'words|OVR'] $field:[@DF_Diagram code:diag index:str indexToken:'words|diag' tableToken:'fields|diag'] $field:[@DF_EnzymeCode code:diag index:str indexToken:enzyme tableToken:enzyme] $field:[@DF_TransitionsN code:TRN index:int indexToken:'words|TRN'] } ] DF_Diagram:$srsfield:[Diagram short:dia group:@DF_ALL] DF_TransitionsN:$srsField:[TransitionsN short:trn] MPW_SYNTAX:$syntax:[file:"SRSDB:mpw.is" ignore:" "] MPW_FILE:$filetype:[typename:txt maxline:1000] $link:[@MPW_DB to:@?ENZYME_DB fromField:@DF_EnzymeCode toField:@DF_ID] exToken:'words|diag' tableToken:'fields|diag'] $field:[@DF_EnzymeCode code:diag index:str indexToken:enzyme tableToken:enzyme] $field:[@DF_TransitionsN code:TRN index:int indexToken:'words|TRN'] } ] DF_Diagram:$srsfield:[Diagram short:dia group:@DF_ALL] DF_Transitionssrs/icarus/db/mpw.is $tags= { UDP: 'UDP-Unknown data-field' COM: 'Comment' OVR: 'Overall Reaction' CCC: 'Cell Culture Category' STR: 'Strain' APN: 'Alternative Pathway Name' SPN: 'Systematic Pathway Name' SPW: 'Systematic Pathway Name' MPW: 'Metabolic Pathway Name' PN: 'Protein Name' GN: 'Gene Name' OR: 'Organism Name' TG: 'Taxonomic Group' } $rules={ entry: ~ {$In:[file:text] $Out init{$count=0} $count+=1 pre{$Skip:0}} ( /[A-Z][A-Z]/ {$Not} ln)* (tag {$entryFip=$Fip $Wrt} ln {$App} (/\12| *#/ {$Not} ln {$App})+ )? ~ # fields fields: ~ {$In:entry $Out $Skip:1} (trn | diag | id | date | field)+ ~ field: ~ {$Wrt:$code} /[A-Z]+/ {$code=$Ct} ln? more ~ date: ~ {$Wrt:date} '***' ln2 ~ id: ~ {$Wrt:name} 'MPW G' ln2 more ~ diag: ~ {$Wrt:diag} /\n+[^\n]+\n/ (/[A-Z][A-Z]/ {$Not} ln | '\n')+ ~ trn: ~ /\n*(TRN)/ {$Wrt:[TRN s:$1]} ln2 {$App} ~ # indexing i_id: ~ {$In:[file:text] $Out:id} x{$Wrt:[s:$count]}~ i_name: ~ {$Out:name $In:[fields c:name]} /MPW G */ /[0-9A-Z.]+/ {$Wrt} ~ i_enzyme:~ {$Out:enzyme $In:[fields c:diag]} (/[0-9-]+\\.[0-9]+\\.[0-9]+\\.[0-9]+/{$Wrt} | /[^0-9.]+/ | /./)* ~ i_words: ~ {$In:fields $Out:words pre{$Skip:0}} tag? i_word* ~ i_word: ~ ( /[0-9-]+\\.[0-9-]+\\.[0-9-]+\\.[0-9-]+/ {$Uniq:$Itc $InWord=0} | name {$Uniq:[$Itc s:$s]} | /./ {$inWord=0} )+ ~ name: ~ {pre $s="" $Skip:1} (/'([a-zA-Z0-9]+)'/ {$StrApp:[$s s:$1] $Skip:0} | /`([a-zA-Z0-9]+)`/ {$StrApp:[$s s:$1] $Skip:0} | /\\([,']([0-9+-]+)\\)/ {$StrApp:[$s s:$1] $Skip:0} | /[a-zA-Z0-9]+/ {$StrApp:[$s s:$Ct] $Skip:0})+ ~ # html display h_field: ~ {$In:[fields t:hl]} tag {if:$tags.$Ct=="" $t=$Ct else $t=$tags.$Ct if:$parInt:isTable $Rep:"" else $Rep:"

$t
" } /[ \n]*G +([A-Z0-9.]+) +!!/? {$Rep:"$1
"} (/[ \n|]+/ | h_word)* | x{if:$Itc==diag $Prod:h_diag} ~ h_diag: ~ {pre{$Skip:0} $Skip:1} ln x{$Rep:"

"} 
             (/[ \n|]+/ | h_word 
             {if:$n $Rep:
          "($HtmlSpace:[($n/2) l:3 s:2])$Ct($HtmlSpace:[($n-$n/2) l:3 s:2])"})+
             x{$Rep:"
"} ~ h_word: ~ {pre{$n=0}} ( /[0-9-]+\\.[0-9-]+\\.[0-9-]+\\.[0-9-]+/ {$Rep:{$ParStr:enzymeR $Ct $Ct}} | '_' {$Rep:' '} | /[^(`' \n]/ | /`([a-zA-Z0-9,]+)`/ {$Rep:"$1" $n=$n+6} | /'([a-zA-Z0-9,]+)'/ {$Rep:"$1" $n=$n+6} | /\\(,'([^')]+)'\\)/{$Rep:"$1" $n=$n+9+$Strlen:[$1]+6}| /\\(,`([^`)]+)`\\)/{$Rep:"$1" $n=$n+9+$Strlen:[$1]+6}| /\\(,([^)]+)\\)/ {$Rep:"$1" $n=$n+9+$Strlen:$1} | /\\(''([^')]+)'\\)/ {$Rep:"$1" $n=$n+9+$Strlen:[$1]+6} | /\\('([^')]+)\\)/ {$Rep:"$1" $n=$n+9+$Strlen:$1} | /[(`']/ )+ ~ # other appLn: ~ /[^\n]*\n/ {$App} ~ more: ~ (/ [^\n]*\n/)* ~ ln: ~ /[^\n]*\n/ ~ ln2: ~ /[^\n]+\n/ ~ tag: ~ /[A-Z][A-Z][A-Z]?/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" \n" fileName:'/u1/srs/data/emp/pathway_graphics.txt'] while:$JobHasInput:$job { $JobTokens:[$job name:fields print:1] $JobNext:$job $print:"-------->entry\n" } } #$fil = $fileOpen:"/data/mpw/aac.asc" #$job = $jobNew:[prod:$rules skip:" "] #$jobNext:[$job file:$fil] #while:$jobTokens:[$job name:fields print:1] { # $jobTokens:[$job name:words print:1] # $jobEnd:$job # $jobNext:[$job file:$fil] #} -Z][A-Z]?/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skipsrs/icarus/db/nrl3d.i # # $RCSfile: nrl3d.i,v $ # $Revision: 1.3 $ # $Date: 1996/12/06 22:17:40 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ NRL3D_DB:$library:[NRL3D group:@SEQUENCE_LIBS subentries:@Nrl3dFeatures_DB format:@NRL3D_FORMAT maxNameLen:12 files:{ $file:nrl_3d } ] NRL3D_FORMAT:$libformat:[fileType:{@PIRREF_FILE @PIRSEQ_FILE} syntax:@NRL3D_SYNTAX tableFormat:left fields:{ $field:[@DF_ID code:id index:id indexToken:id] $field:@DF_ALL $field:[@DF_Description code:des index:str indexToken:des tableToken:'clFields|des'] $field:[@DF_Keywords code:key index:str indexToken:key] $field:[@DF_Comment code:cmnt index:str indexToken:cmnt] $field:[@DF_Organism code:spec index:str indexToken:spec] $field:[@DF_Authors code:aut index:str indexToken:aut] $field:[@DF_Title code:ttl index:str indexToken:ttl] $field:[@DF_Resolution code:res index:real indextoken:res] $field:[@DF_EXP_METHOD code:det index:str indexToken:det] $field:[@DF_R_FACTOR code:rFactor index:real indexToken:rval indexToken:rval tableToken:rval] $field:[@DF_FtKey index:str indexToken:ftKey code:ft indexId:@SUBENTRY_ID] $field:[@DF_FtDescription index:str indexToken:ftDes code:ft indexId:@SUBENTRY_ID] $field:[@DF_FtLength index:int indexToken:ftLen code:ft indexId:@SUBENTRY_ID] $field:[@DF_ProtSequence token:sequence format:pir] } ] NRL3D_SYNTAX:$syntax:[file:"SRSDB:nrl3d.is" ignore:" \t"] DF_Determination:$srsfield:[Determination short:det] $link:[@NRL3D_DB to:@?PDB_DB token:pdblink toField:@DF_ID] Nrl3dFeatures_DB:$library:[Nrl3d_features format:@PirFeature_Format ] ndexId:@SUBENTRY_ID] $field:[@DF_FtDescription index:str indexToken:ftDes code:ft indexId:@SUBENTRY_ID] $field:[@DF_FtLength index:int indexToken:ftLen code:ft indexId:@SUBENTRY_ID] $field:[@DF_ProtSequence token:sequence format:srs/icarus/db/nrl3d.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: nrl3d.is,v $ # $Revision: 1.3 $ # $Date: 1996/12/06 22:17:40 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $fn={ 'C;Species:': spec 'A;Note:': note 'A;Reference number:': refn 'A;Title:': ttl 'C;Resolution:': res 'C;Keywords:': key 'C;Determination:': determ 'C;R-value:': rval 'C;Comment:': cmnt 'N;Contains:': cont 'N;Alternate names:': des 'R;': aut 'F;': ft } $rules={ entry: ~ {$In:[file:text] $Out pre $Skip:0} ('>' {$not} ln)* (/>[^;]+;([A-Z0-9]+)/ {$entryFip=$Fip $Wrt $entryName=$1} ln{$App} ('>' {$Not} ln {$App})+ )? ~ sequence: ~ {$In:[file:seq] $Out pre $s=$SeqNew $Wrt:[s:$entryName] $SeqMake:$s} ('>' {$Not} ln)* ln {pre $seqFip=$Fip} ln ('>' {$Not} ln {$SeqApp:[$s s:$Ct]})* ~ # extracting data fields fields: ~ {$In:entry $Out $Skip:1} ln {$Wrt:id} ln {$Wrt:des} (/[ACRFN];([a-zA-Z -]+:)?/ {$Wrt:$fn.$Ct if:$fn.$Ct=="" $dp:"+++ unknown: $Ct in $entryName +++"} ln {$App} | ln {$App})+ ~ # for indexing tag: ~ /[ACRFN];([a-zA-Z -]+:)?/ ~ id: ~ {$In:entry $Out} />[^;]+;([A-Z0-9]+)/ {$Wrt:[s:$1]} ~ aut: ~ {$In:[fields c:aut] $Out} 'R;' (author {$Uniq:[s:$author]} ';'?)+ ~ author: ~ /([^,\n]+,) *([^;\n]+)/ {$author="$1$2"} ~ key: ~ {$In:[fields c:key] $Out} tag (/[^\n;]+/ {$Wrt:[s:$Trim:$Ct]} ';'?)* ~ ttl: ~ {$In:[fields c:ttl] $Out} tag (/[a-zA-Z0-9]+/ {$Uniq} | /./)* ~ des: ~ {$In:[fields c:des] $Out} tag? (/[a-zA-Z0-9]+/ {$Uniq} | /./)* ~ cmnt: ~ {$In:[fields c:cmnt] $Out} tag? (/[a-zA-Z0-9]+/ {$Uniq} | /./)*~ spec: ~ {$In:[fields c:spec] $Out} tag /[^(]+/ {$Wrt:[s:$Trim:$Ct]} ('('/[^)]+/ {$Wrt} ')')? ~ res: ~ {$In:[fields c:res] $Out} tag /[0-9.]+/? {$Wrt} ~ rval: ~ {$In:[fields c:rval] $Out} tag /[0-9.]+/? {$Wrt} ~ det: ~ {$In:[fields c:determ] $Out} tag /[^\n]+/ {$Wrt} ~ pdblink: ~ {$In:entry $Out} />[^;]+;(....)/ {$Wrt:[s:$1]} ~ # indexing features ft: ~ {$In:[fields c:ft] $Out} 'F;'{$r={}} (/[^,\/]+/ {$r+=$Ct} ','?)+ ln {foreach:[$e in:$r] $Wrt:[ft s:"F;$e$Ct"]} ~ ftKey: ~ {$In:[ft count:ft var:$ftN] $Out} /[^\/]+\/([^:]+):/ {$Wrt:[n:$ftN s:$1]} ~ ftDes: ~ {$In:[ft count:ft var:$ftN] $Out} /[^:]+:/ (/[A-Za-z0-9_]+/ {$Uniq:[n:$ftN]} | /./)* ~ ftLen: ~ {$In:[ft c:ft count:ft var:$ftN] $Out} 'F;' /([0-9]+)(-([0-9]+))?/ {if:$3=="" $Wrt:[n:$ftN s:1] else $Wrt:[n:$ftN s:($3-$1+1)]} ~ # display features ftId: ~ {$In:[fields c:id] $Out} /(>[^;]+;)([A-Z0-9]+)/ {$Wrt:[s:"$1$2\_$subEntryN; parent: $2"]} ~ ftLine: ~ {$In:[ft c:ft count:ft var:$ftN select:$subEntryN] $Out} /.*/ {$Wrt} ~ t_ft: ~ {$In:ftLine $Out $Skip:1} 'F;' /([^\/]+)/ {$Wrt:[range s:$1]} /\/([^:]+):/ {$Wrt:[n:$ftN s:$1]} /.*/ {$Wrt:des} ~ h_ftId: ~ {$In:[ftId t:html]} /.*parent: */ /[A-Z0-9_]+/ {$Rep:{$ParStr:pirR $Ct $Ct}} ~ # printing in HTML format h_refn: ~ {$In:[fields c:refn t:html]} (/.*PDB:/ name {$Rep:{$ParStr:pdbR $Ct $Ct}})? ~ # other stuff ln: ~ /[^\n]*\n/ ~ accno: ~ /[A-Z0-9]+/ ~ num: ~ /(<|>)?[0-9?]+/ ~ name: ~ /[a-zA-Z0-9_-]+/ ~ dbName: ~ /[^;]+/ ~ } # debugging $subEntryN=3 if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/nrl3d/nrl_3d.ref'] while:$JobHasInput:$job { $JobTokens:[$job name:ft print:1] # $JobTokens:[$job name:aut print:1] $JobNext:$job $print:"-------->entry\n" } } (/.*PDB:/ name {$Rep:{$ParStr:pdbR $Ct $Ct}})? ~ # other stuff ln: ~ /[^\n]*\n/ ~ accno: ~ /[A-Z0-9]+/ ~ num: ~ /(<|>)?[0-9?]+/ ~ name: ~ /[a-zA-Z0-9_-]+/ ~ dbName: ~ /[^;]+/ ~ } # debugging $subEntryN=3 if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/nrl3d/nrl_3d.ref'] while:$JobHasInput:$job { $JobTokens:[$job name:ft print:1] # $JobTokens:[$job name:aut psrs/icarus/db/omim.i # $RCSfile: omim.i,v $ # $Revision: 1.1 $ # $Date: 1996/10/01 18:30:44 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ OMIM_DB:$library:[OMIM group:@MUTATION_LIBS format:@OMIM_FORMAT maxNameLen:8 ifiles:{"omim.i" "omim.is"} files:{ $file:omim } ] OMIM_FORMAT:$libformat:[fileType:@TXT_FILE syntax:@OMIM_SYNTAX printFormat:text fields:{ $field:[@DF_ID code:id index:id indexToken:id] $field:[@DF_Keywords code:title] $field:[@DF_MN code:mn] $field:[@DF_Text code:text index:str indexToken:text] $field:[@DF_AllelicVars code:allVar] $field:[@DF_SA code:date] $field:[@DF_Reference code:ref] $field:[@DF_ClinicalSymptoms code:clinSym] $field:[@DF_CN code:date] $field:[@DF_Date code:date] $field:[@DF_History code:history] } ] OMIM_SYNTAX:$syntax:[file:"SRSDB:omim.is" ignore:" "] DF_SA:$srsfield:[SA short:sa] DF_MN:$srsfield:[MN short:mn] DF_CN:$srsfield:[CN short:cn] DF_Text:$srsfield:[Text short:txt] DF_ClinicalSymptoms:$srsfield:[ClinicalSymptoms short:cls] DF_History:$srsfield:[History short:his] DF_AllelicVars:$srsfield:[AllelicVariants short:alv] ence code:ref] $field:[@DF_ClinicalSymptoms code:clinSym] $field:[@DF_CN code:date] $field:[@DF_Date code:date] $field:[@DF_History code:history] } ] OMIM_SYNTAX:$syntax:[file:"SRSDB:omim.is" ignore:" "] DF_SA:$srsfield:[SA short:sa] DF_Msrs/icarus/db/omim.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: omim.is,v $ # $Revision: 1.3 $ # $Date: 1996/12/18 19:44:45 $ # $Author: weare $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $rules={ entry: ~ {$In:[file:text] $Out pre $Skip:0} ('*RECORD*' {$Not} ln)* ('*RECORD*'{$entryFip=$Fip $Wrt} ln {$App} ('*RECORD*\n' {$Not} ln {$App})+ )? ~ # data fields fields: ~ {$In:entry $Out $Skip:1} ln id title mn? text? allVar? sa? ref? clinSyn? cn? date? history ~ id: ~ {$Wrt:id} '*FIELD* NO\n' ('*FIELD*' {$Not} ln)+ ~ title: ~ {$Wrt:title} '*FIELD* TI\n' ('*FIELD*' {$Not} ln)+ ~ mn: ~ {$Wrt:mn} '*FIELD* MN\n' ('*FIELD*' {$Not} ln)+ ~ text: ~ {$Wrt:text} '*FIELD* TX\n' ('*FIELD*' {$Not} ln)+ ~ allVar: ~ {$Wrt:allVar} '*FIELD* AV\n' ('*FIELD*' {$Not} ln)+ ~ sa: ~ {$Wrt:sa} '*FIELD* SA\n' ('*FIELD*' {$Not} ln)+ ~ ref: ~ {$Wrt:ref} '*FIELD* RF\n' ('*FIELD*' {$Not} ln)+ ~ clinSyn: ~ {$Wrt:clinSyn} '*FIELD* CS\n' ('*FIELD*' {$Not} ln)+ ~ cn: ~ {$Wrt:cn} '*FIELD* CN\n' ('*FIELD*' {$Not} ln)+ ~ date: ~ {$Wrt:date} '*FIELD* CD\n' ('*FIELD*' {$Not} ln)+ ~ history: ~ {$Wrt:history} '*FIELD* ED\n' ('*FIELD*' {$Not} ln)+ ~ # indexing i_id: ~ {$In:[fields c:id] $Out:id} ln '^'? /[0-9]+/ {$Wrt} ~ i_text: ~ {$In:[fields c:text] $Out:text} ln (word {$Uniq} | sep)+ ~ # html display t_toc: ~ {$In:[fields t:html] init $t={ text: "TEXT" ref: "REFERENCES" sa: "SEE ALSO" allVar: "ALLELIC VARIANTS" clinSyn: "CLINICAL SYNOPSIS" date: "CREATION DATE" history: "EDIT HISTORY" } } /./ { if:$t.$Itc!="" { if:$toc=="" $toc="

CONTENTS

    " $print:["
  • ($t.$Itc)\n" v:$toc] } } ~ t_id: ~ {$In:[fields c:id t:html]} /.+/ {$Rep:""} ~ t_title: ~ {$In:[fields c:title t:html]} ln {$Rep:""} ln {$Rep:"

    $Ct

    "} ~ t_text: ~ { $In:[fields c:text t:html]} ln {$Rep:"$toc

TEXT

" $toc="" } (/\n/ {$Rep:"

"} | textln)+ ~ textln: ~ ( # make references in various formats hypertext links /([a-zA-Z-]+)[ \n]+et[ \n]+al.[ \n]+\\(([0-9][0-9][0-9][0-9])\\)/ {$Rep:"$Ct"} | /([a-zA-Z-]+)[ \n]+and[ \n]+[a-zA-Z-]+[ \n]+\\(([0-9][0-9][0-9][0-9])\\)/ {$Rep:"$Ct"} | /([a-zA-Z-]+)[ \n]+\\(([0-9][0-9][0-9][0-9])\\)/ {$Rep:"$Ct"} | /\\(([a-zA-Z-]+),[ \n]+([0-9][0-9][0-9][0-9])\\)/ {$Rep:"$Ct"} | /[^0-9 \n]+/ | /([1-6][0-9][0-9][0-9][0-9][0-9])(\\.[0-9]+)?/ { if:$2!="" $Rep:{$ParStr:mimAllR $1 $2 $Ct} else $Rep:{$ParStr:mimR $Ct $Ct} } | /[0-9 ]+/)+ '\n'? ~ t_ref1: ~ {$In:[fields c:ref t:html]} ln t_snglref+ ~ t_snglref: ~ /[0-9]+\\. *([a-zA-Z-]+)([^\n]+\n)*[^\n]*([1-2][0-9][0-9][0-9])\\.\n\n/ {$Rep:"\n$Ct

"} | /([^\n]+\n)+\n/ {$Rep:"\n$Ct"} ~ t_ref2: ~ {$In:[fields c:ref t:html]} ln {$Rep:"

REFERENCES

"} (ln /[0-9]+\\.[^:]+:/ {$Rep:"
$Ct
"} /[^.]+./ {$Rep:"$Ct"} (/<\/DL>/{$Not} ln)*)+ ~ t_allVar: ~ {$In:[fields c:allVar t:html]} ln {$Rep:"

ALLELIC VARIANTS

"} (/(\\.[0-9]+)[^\n]*\n/ {$Rep:"

$1 "} mut {$Rep:"$Ct

"} | /\n/ {$Rep:"

"} | ln)+ ~ mut: ~ ln (/([^\n]* )([A-Z]+[0-9]+[A-Z]+)([\n]*\n)/ {$Rep:"$1$2$3"} | ln) ~ t_clinSyn: ~ {$In:[fields c:clinSyn t:html]} ln {$Rep:"

CLINICAL SYNOPSIS

"} (/\n/ {$Rep:"

"} | ln)+ ~ t_history: ~ {$In:[fields c:history t:html]} ln {$Rep:"

EDIT HISTORY

"} ln+ {$Rep:"$Ct
"} ~ t_date: ~ {$In:[fields c:date t:html]} ln {$Rep:"

CREATION DATE

"} (/\n/ {$Rep:"

"} | ln)+ ~ # other stuff ln: ~ /[^\n]*\n/ ~ word: ~ /[a-zA-Z0-9_]+/ ~ sep: ~ /[^a-zA-Z0-9_]+/ ~ } NICAL SYNOPSIS"} (/\n/ {$Rep:"

"} | ln)+ ~ t_history: ~ {$In:[fields c:history t:html]} ln {$Rep:"

EDIT HISTORY

"} ln+ {$Rep:"$Ct
"} ~ t_date: ~ {$In:[fields c:date t:html]} ln {$Rep:"

CREATION DATE

"} srs/icarus/db/p53.i # File: p53 .i | # Version: 1.0 | # Date: 11-Sep-1996 | # Author: Benny Shomer | # bshomer@ebi.ac.uk | #-------------------------------------- P53_DB:$library:[P53 group:@MUTATION_LIBS format:@P53_FORMAT maxNameLen:10 files:{ $file:p53 } ] P53_FORMAT:$libformat:[syntax:@P53_SYNTAX fileType:@P53_FILE tableFormat:left fields:{ $field:[@DF_ID code:id indexToken:id index:id] $field:[@DF_NuclChange code:bc indexToken:'dnaChange|mut' index:str] $field:[@DF_DnaChangePos code:bc indexToken:'dnaChange|pos' index:int tableFormat:right] $field:[@DF_TranslEffect code:cd index:str indexToken:'aaChange|eff'] $field:[@DF_AaChange code:cd indexToken:'aaChange|mut' index:str] $field:[@DF_ProtChangePos code:cd indexToken:'aaChange|pos' index:int tableFormat:right] $field:[@DF_CT code:ct indexToken:ct index:str] $field:[@DF_TS code:ts indexToken:ts index:str tableToken:t_ts] $field:[@DF_Comment code:cc indexToken:cc index:str] $field:[@DF_RP code:rp indexToken:rp index:str] } ] #data field types DF_CD:$srsfield:[Codon_Change short:CD group:@DF_ALL] DF_BC:$srsfield:[Base_Change short:BC group:@DF_ALL] DF_CT:$srsfield:[CpG_Transition short:CT group:@DF_ALL] DF_TS:$srsfield:[Tumor_Specific short:TS group:@DF_ALL] DF_RP:$srsfield:[Reference short:RP group:@DF_ALL] #links $link:[@P53_DB to:@?P53REF_DB fromField:@DF_RP toField:@DF_ID token:rp] P53_SYNTAX:$syntax:[file:"SRSDB:p53.is" ignore:" \t"] P53_FILE:$filetype:[typeName:dat maxline:200] :rp indexToken:rp index:str] } ] #data field types DF_CD:$srsfield:[Codon_Change short:CD group:@DF_ALL] DF_BC:$srsfield:[Base_Change short:BC group:@DF_ALL] DF_CT:$srsfield:[CpG_Transition short:CT group:@DF_ALL] DF_TS:$srsfield:[Tumor_Specific short:TS group:@DF_ALL] DF_RP:$srsfield:[Reference short:RP group:@DF_ALL] #links $link:[@P53_DB to:@?P53REF_DB fromField:@DF_RP toField:@DF_ID toksrs/icarus/db/p53.is #-------------------------------------- # File: p53.is | # Version: 1.0 | # Date: 11-Sep-1996 | # Author: Benny Shomer | # bshomer@ebi.ac.uk | #-------------------------------------- $rules={ #data record entry: ~ {$In:[file:text] $Out} ('ID ' {$entryFip=$Fip $Wrt} ln {$App} ('ID ' {$Not} ln {$App})*)? ~ ln: ~ /[^\n]*\n/ ~ # Data fields fields: ~ {$In:entry $Out} f_id f_cd f_bc f_ct f_ts f_cc f_rp ~ f_id: ~ {$Wrt:id} 'ID' ln ~ f_cd: ~ {$Wrt:cd} ('CD' ln)* ~ f_bc: ~ {$Wrt:bc} ('BC' ln)* ~ f_ct: ~ {$Wrt:ct} ('CT' ln)* ~ f_ts: ~ {$Wrt:ts} ('TS' ln)* ~ f_cc: ~ {$Wrt:cc} ('CC' ln)* ~ f_rp: ~ {$Wrt:rp} ('RP' ln)* ~ # Indexing word: ~ /[A-Za-z0-9_-]+/ ~ int: ~ /[-]?[0-9]+/ ~ real: ~ /[-]?[0-9]+([\.]?[0-9]+)?/~ i_id: ~ {$In:[fields c:id] $Out:id} 'ID' int {$Wrt} ~ aaChange: ~ {$In:[fields c:cd] $Out init $aa={Ile:I Leu:L Met:M Ala:A Val:V Ser:S Thr:T Phe:F Tyr:Y Gly:G Pro:P Trp:W Cys:C Gln:Q Asn:N Arg:R Lys:K Asp:D Glu:E His:H Stop:'*'} } ('CD' (int {$Wrt:pos} ('-' int)? ';' | /[^;]+;/) /[^;]+;/ (/([a-zA-Z?]+)-.?([a-zA-Z?]+)/ {$Wrt:[mut s:"($aa.$1)>($aa.$2)"] $Wrt:[eff s:substitution]}| /[a-zA-Z?_-]+/ {$Wrt:eff}))* ~ dnaChange: ~ {$In:[fields c:bc] $Out} ('BC' (int {$Wrt:pos} ';'| /[^;]+;/) /([A-Z]+) *-> *([A-Z]+)/? {$Wrt:[mut s:"$1>$2"]})* ~ ct: ~ {$In:[fields c:ct] $Out} ('CT' /[yesYES]+/ {$Wrt}|ln)+ ~ ts: ~ {$In:[fields c:ts] $Out} ('TS' (/[^;>.? \'\/\n-]+/ {$Wrt}| /[;>.? \'\/\n-]+/)* )* ~ cc: ~ {$In:[fields c:cc] $Out} ('CC' (/[^;>.? -]+/ {$Wrt}| /[;>.? -]*/)*)* ~ rp: ~ {$In:[fields c:rp] $Out} 'RP' /[0-9]+/? {$Wrt} ~ # table t_ts: ~ {$In:[fields c:ts] $Out} (tag ln {$Wrt})* ~ # printing in HTML format h_rp: ~ {$In:[fields c:rp t:html]} ('RP' /[ ]*/ /[0-9]+/ {$Rep:{$ParStr:p53refR $Ct $Ct}} ln) ~ # other stuff tag: ~ /../ ~ } >.? \'\/\n-]+/ {$Wrt}| /[;>.? \'\/\n-]+/)* )* ~ cc: ~ {$In:[fields c:cc] $Out} ('CC' (/[^;>.? -]+/ {$Wrt}| /[;>.? -]*/)*)* ~ rp: ~ {$In:[fields c:rp] $Out} 'RP' /[0-9]+/? {$Wrtsrs/icarus/db/p53.it # # $RCSfile: p53.it,v $ # $Revision: 1.1 $ # $Date: 1996/11/05 19:54:19 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $dbInfo={ description: |This database is a compilation of p53 mutations in human tumor cells and cell |lines from a systematic search of reports published before 1 January 1994. These |mutations were identified by DNA sequencing of PCR-amplified material or cloned |PCR products. Preliminary screening for mutations by techniques such as those |employing SSCP or DGGE/CDGE (reviewed in Rossiter & Caskey, 1990; Grompe, 1993) |were often performed. Most analyses were confined to exons 5-8, since early |studies noted that mutations occurred primarily in this evolutionarily conserved |midregion. A bias against identification of DNA sequence alterations outside |this mutation cluster region can thus be expected. If the same mutations were |published in more than one article, only one report is referenced, either the |first or the most complete report, and the data are only entered once in the |database. If the identical mutation was found in two separate samples from the |same patient, for example in the primary tumor and in the metastatic tissue, the |mutation is considered to be a single event and is entered only once. Tandem |mutations, i.e. two adjacent base substitutions, are also considered as one |mutation event and are entered together; therefore there will be only one |identification number (see below) for this mutation pair. Discrepancies in |published reports that are clearly due to typographical errors or that can be |explained by other information in the publication have been corrected. In this |case, or if there are uncorrected errors or ambiguities regarding a mutation |record, the letter 'e' appears in column M (see below). Information that does |not permit us to identify the nature and location of the mutation has not been |entered. Mutations found by digestion of DNA with a restriction enzyme and |demonstration of an RFLP are not entered; however, publications reporting such |data will be cited in the electronic version as second appendix. Mutations |identified in tumors are presumed to be somatic unless 1) analysis of normal |tissue from the same patient demonstrated that the mutation was constitutional |in that individual, or 2) the mutation corresponded to one of the known |constitutional polymorphisms of the human p53 gene (at codons 21, 31, 47, 72, |and 213), as these are unlikely to be mutations that arose in the tumors. |Germline mutations, including those identified in families with the Li-Fraumeni |cancer syndrom are not in this database. literature: |
    |
  • Caron de Fromentel, C. and Soussi, T. (1992) Genes Chromosomes Cancer 4, 1-15. |
  • Donehower, L.A. and Bradley, A. (1993) Biochim. Biophys. Acta 1155, 181-207. |
  • Greenblatt, M.S., Bennet, W.P., Hollstein, M.C. and Harris, C.C. (1994) Cancer | Res. (in press). |
  • Grompe, M. (1993) Nature genetics 5, 111-117. |
  • Harris, C.C. and Hollstein, M. (1993) New Engl. J. Med. 329, 1318-1327. |
  • Hollstein, M.C, Sidranskym D., Vogelstein, B. and Harris, C.C. (1991) Science | 253, 49-53. |
  • Jones, P.A., Buckley, J.D., Henderson, B.E., Ross, R.K. and Pike M.C. (1991) | Cancer Res. 51, 3617-3620. |
  • Kunkel, T.A. (1990) Biochemistry 29, 8003-8011. |
  • Kunkel, T.A. (1993) Nature 365, 207-208. |
  • Levine, A.J. (1993) Annu. Rev. Biochem. 62, 623-651. |
  • Lindahl, T. (1993) Nature 362, 709-715. |
  • Mellon & Hanawalt (1989) Nature 342, 95-998. |
  • Rice, C., Fuchs, R., Higgins, D.G., Stoehr, P.S. and Cameron, G.N. (1993) Nucl. | Acids Res. 21, 2967-2971. |
  • Rossiter, B.J.F. and Caskey, C.T. (1990) J. Biol. Chem. 265, 12753-12756. |
  • Selby & Sancar (1993) Science 260, 53-58. |
  • Takeshima, S., Seyama, T., Bennett, W.P. et al. (1991) Lancet 342, 1520-2521. |
ftp: |ftp.ebi.ac.uk/pub/databases/p53 www: |Through the WWW server at: http://www.ebi.ac.uk/ email: |netserv@ebi.ac.uk and include the line "help p53" updates: |This compilation of p53 mutations is to provide the scientific community with a |database of rapidly accumulating data that can be useful to various disciplines |in cancer research, including epidemiology, medicine and basic science. Future |versions of the database may include separate sections on germline mutations, |mutations detected by RFLP, anamnestic data on patients, and standardization of |terminology with the International Classification of Diseases for Oncology |(ICD-O). Notifications of omissions and errors of the current version would be |gratefully received by the authors. When individual records in the present |version require correction they will be revised and the date of revision will be |noted in a new column, column N. Data published in th first six months of 1994 |will be added at regular intervals during the second half of the year. } standardization of |terminology with the International Classification of Diseases for Oncology |(ICD-O). Notifications of omissions and errors of the current version would be |gratefully received by the authors. When individual records in the present |version resrs/icarus/db/p53apc.i # $RCSfile: p53apc.i,v $ # $Revision: 1.3 $ # $Date: 1997/03/03 18:34:06 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #-------------------------------------- # File: p53.i | # Version: 1.0 | # Date: 17-Sep-1996 | # Author: Benny Shomer | # bshomer@ebi.ac.uk | #-------------------------------------- P53APC_DB:$library:[P53APC group:@MUTATION_LIBS format:@P53APC_FORMAT maxNameLen:20 files:{ $file:p53apc } ] P53APC_FORMAT:$libformat:[syntax:@P53APC_SYNTAX fileType:@P53APC_FILE fields:{ $field:[@DF_ID code:id indexToken:id index:id] $field:[@DF_GN code:gn indexToken:gn index:str] $field:[@DF_CG code:cg indexToken:cg index:str] $field:[@DF_DnaChangePos code:nn indexToken:nn index:int tableToken:nn tableFormat:right] $field:[@DF_NuclChange code:nc indexToken:nc index:str tableToken:nc tableFormat:left] $field:[@DF_ProtChangePos code:cn indexToken:cn index:int tableToken:cn tableFormat:right] $field:[@DF_CB code:cb indexToken:cb index:str] $field:[@DF_AaChange code:cc indexToken:cc index:str tableToken:cc tableFormat:left] $field:[@DF_LO code:lo indexToken:lo index:str] $field:[@DF_LE code:le indexToken:le index:str] $field:[@DF_EN code:en indexToken:en index:str] $field:[@DF_MT code:mt indexToken:mt index:str] $field:[@DF_MM code:mm indexToken:mm index:str] $field:[@DF_SP code:sp indexToken:sp index:str] $field:[@DF_GS code:gs indexToken:gs index:str] $field:[@DF_AS code:as indexToken:as index:str] $field:[@DF_TT code:tt indexToken:tt index:str] $field:[@DF_CI code:ci indexToken:ci index:str] $field:[@DF_CL code:cl indexToken:cl index:str] $field:[@DF_IM code:im indexToken:im index:str] $field:[@DF_DS code:ds indexToken:ds index:str] $field:[@DF_PT code:pt indexToken:pt index:str] $field:[@DF_RE code:re indexToken:re index:str] $field:[@DF_MR code:mr indexToken:mr index:str] $field:[@DF_UP code:up indexToken:up index:str] $field:[@DF_RM code:rm indexToken:rm index:str] } ] #data field types DF_GN:$srsfield:[Gene_Name short:GN group:@DF_ALL] DF_CG:$srsfield:[CpG_Site short:CG group:@DF_ALL] DF_NN:$srsfield:[Nucl_Number short:NN group:@DF_ALL] DF_NC:$srsfield:[Nucl_Change short:NC group:@DF_ALL] DF_CB:$srsfield:[Codon_Base short:CB group:@DF_ALL] DF_LO:$srsfield:[Location short:LO group:@DF_ALL] DF_LE:$srsfield:[Length short:LE group:@DF_ALL] DF_EN:$srsfield:[Exon_Number short:EN group:@DF_ALL] DF_MT:$srsfield:[Mutation_Type short:MT group:@DF_ALL] DF_MM:$srsfield:[Multiple_Mutant short:MM group:@DF_ALL] DF_SP:$srsfield:[Splicing short:SP group:@DF_ALL] DF_GS:$srsfield:[Germline_Somatic short:GS group:@DF_ALL] DF_AS:$srsfield:[Allelic_Status short:AS group:@DF_ALL] DF_TT:$srsfield:[Tumor_Type short:TT group:@DF_ALL] DF_CI:$srsfield:[Clinical_Info short:CI group:@DF_ALL] DF_CL:$srsfield:[Cell_Line short:CL group:@DF_ALL] DF_IM:$srsfield:[Immuno_Stain short:IM group:@DF_ALL] DF_DS:$srsfield:[DNA_Source short:DS group:@DF_ALL] DF_PT:$srsfield:[Patient short:PT group:@DF_ALL] DF_RE:$srsfield:[Reference short:RE group:@DF_ALL] DF_MR:$srsfield:[Method_Reference short:MR group:@DF_ALL] DF_UP:$srsfield:[Update_Reference short:UP group:@DF_ALL] DF_RM:$srsfield:[Remarks short:RM group:@DF_ALL] #links $link:[@P53APC_DB to:@?P53APCREF_DB fromField:@DF_RE toField:@DF_ID token:re] $link:[@P53APC_DB to:@?P53APCMET_DB fromField:@DF_MR toField:@DF_ID token:mr] $link:[@P53APC_DB to:@?P53APC_DB fromField:@DF_UP toField:@DF_ID token:up] P53APC_SYNTAX:$syntax:[file:"SRSDB:p53apc.is" ignore:" \t"] P53APC_FILE:$filetype:[typeName:dat maxline:200] ethod_Reference short:MR group:@DF_ALL] DF_UP:$srsfield:[Update_Reference short:UP group:@DFsrs/icarus/db/p53apc.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: p53apc.is,v $ # $Revision: 1.3 $ # $Date: 1996/12/06 16:37:40 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #-------------------------------------- # File: p53apc.is | # Version: 1.0 | # Date: 17-Sep-1996 | # Author: Benny Shomer | # bshomer@ebi.ac.uk | #-------------------------------------- $rules={ #data record entry: ~ {$In:[file:text] $Out} ('Identifier ' {$entryFip=$Fip $Wrt} ln {$App} ('Identifier ' {$Not} ln {$App})*)? ~ ln: ~ /[^\n]*\n/ ~ # Data fields fields: ~ {$In:entry $Out} id gn cg nn nc cn cb cc lo le en mt mm sp gs as tt ci cl im ds pt re mr up rm ~ id: ~ {$Wrt:id} 'Identifier ' ln~ gn: ~ {$Wrt:gn} ('Gene_Name ' ln)* ~ cg: ~ {$Wrt:cg} ('CpG_Site ' ln)* ~ nn: ~ {$Wrt:nn} ('Nucl_Number ' ln)* ~ nc: ~ {$Wrt:nc} ('Nucl_Change ' ln)* ~ cn: ~ {$Wrt:cn} ('Codon_Number ' ln)* ~ cb: ~ {$Wrt:cb} ('Codon_Base ' ln)* ~ cc: ~ {$Wrt:cc} ('Codon_Change ' ln)* ~ lo: ~ {$Wrt:lo} ('Location ' ln)* ~ le: ~ {$Wrt:le} ('Length ' ln)* ~ en: ~ {$Wrt:en} ('Exon_Number ' ln)* ~ mt: ~ {$Wrt:mt} ('Mutation_Type ' ln)* ~ mm: ~ {$Wrt:mm} ('Multiple_Mutant ' ln)* ~ sp: ~ {$Wrt:sp} ('Splicing ' ln)* ~ gs: ~ {$Wrt:gs} ('Germline_Somatic' ln)* ~ as: ~ {$Wrt:as} ('Allelic_Status ' ln)* ~ tt: ~ {$Wrt:tt} ('Tumor_Type ' ln)* ~ ci: ~ {$Wrt:ci} ('Clinical_Info ' ln)* ~ cl: ~ {$Wrt:cl} ('Cell_Line ' ln)* ~ im: ~ {$Wrt:im} ('Immuno_Stain ' ln)* ~ ds: ~ {$Wrt:ds} ('DNA_Source ' ln)* ~ pt: ~ {$Wrt:pt} ('Patient ' ln)* ~ re: ~ {$Wrt:re} ('Reference ' ln)* ~ mr: ~ {$Wrt:mr} ('Method_Reference' ln)* ~ up: ~ {$Wrt:up} ('Update_Reference' ln)* ~ rm: ~ {$Wrt:rm} ('Remarks ' ln)* ~ # Indexing word: ~ /[A-Za-z0-9_-]+/ ~ int: ~ /[-]?[0-9]+/ ~ real: ~ /[-]?[0-9]+([\.]?[0-9]+)?/~ i_id: ~ {$In:[fields c:id] $out:id} 'Identifier' int {$Wrt} ~ i_gn: ~ {$In:[fields c:gn] $out:gn} ('Gene_Name' ( word {$Wrt} )* )* ~ i_cg: ~ {$In:[fields c:cg] $out:cg} ('CpG_Site' ( word {$Wrt} )* )* ~ i_nn: ~ {$In:[fields c:nn] $out:nn} ('Nucl_Number' (word {$Wrt}/[;->.? ]*/ )* )* ~ i_nc: ~ {$In:[fields c:nc] $out:nc} 'Nucl_Change' /([A-Z]) *-> *([A-Z])/? {$Wrt:[s:"$1>$2"]} ~ i_cn: ~ {$In:[fields c:cn] $out:cn} ('Codon_Number' (int {$Wrt} )* )* ~ i_cb: ~ {$In:[fields c:cb] $out:cb} ('Codon_Base' (/[^;->.? ]+/ {$Wrt} )* )* ~ i_cc: ~ {$In:[fields c:cc] $out:cc} 'Codon_Change ' /([A-Z]) *-> *([A-Z*])/? {if:$2=='*' $to=Stop else $to=$2 $Wrt:[s:"$1>$to"]} ~ i_lo: ~ {$In:[fields c:lo] $out:lo} ('Location' (/[^;->? ]+/ {$Wrt} /[;->? ]*/ )* )* ~ i_le: ~ {$In:[fields c:le] $out:le} ('Length' (word {$Wrt} )* )* ~ i_en: ~ {$In:[fields c:en] $out:en} ('Exon_Number' (int {$Wrt} )* )* ~ i_mt: ~ {$In:[fields c:mt] $out:mt} ('Mutation_Type' /[";]?/ ( /[^;->.? ]+/ {$Wrt} /[;->.? ]*/)* )* ~ i_mm: ~ {$In:[fields c:mm] $out:mm} ('Multiple_Mutant' (int {$Wrt} )* )* ~ i_sp: ~ {$In:[fields c:sp] $out:sp} ('Splicing' (word {$Wrt} )* )* ~ i_gs: ~ {$In:[fields c:gs] $out:gs} ('Germline_Somatic' (word {$Wrt} )* )* ~ i_as: ~ {$In:[fields c:as] $out:as} ('Allelic_Status' (int {$Wrt} )* )* ~ i_tt: ~ {$In:[fields c:tt] $out:tt} ('Tumor_Type' /[";]?/ ( /[^;->.? ]+/ {$Wrt} /[;->.? ]*/)* )* ~ i_ci: ~ {$In:[fields c:ci] $out:ci} ('Clinical_Info' (word {$Wrt} )* )* ~ i_cl: ~ {$In:[fields c:cl] $out:cl} ('Cell_Line' (/[^"; ]+/ {$Wrt} )* )* ~ i_im: ~ {$In:[fields c:im] $out:im} ('Immuno_Stain' (/[^"; ]+/ {$Wrt}/["; ]*/ )* )* ~ i_ds: ~ {$In:[fields c:ds] $out:ds} ('DNA_Source' ( /[^"; ]+/ {$Wrt}/["; ]*/ )* )* ~ i_pt: ~ {$In:[fields c:pt] $out:pt} ('Patient' /[";]?/ ( /[^"; ]+/ {$Wrt}/["; ]*/ )* )* ~ i_re: ~ {$In:[fields c:re] $out:re} ('Reference ' (int {$Wrt} /["; ]*/)* )* ~ i_mr: ~ {$In:[fields c:mr] $out:mr} ('Method_Reference' (int {$Wrt}/["; ]*/ )* )* ~ i_up: ~ {$In:[fields c:up] $out:up} ('Update_Reference' ( int {$Wrt} /["; ]*/)* )* ~ i_rm: ~ {$In:[fields c:rm] $out:rm} ('Remarks' (/[^"; ]+/ {$Wrt} /["; ]*/)* )* ~ # # printing in HTML format } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/opt/srs/data/mutdb/p53apc/p53apc.dat'] while:$JobHasInput:$job { $JobTokens:[$job name:id print:1] $JobNext:$job $print:"-------->entry\n" } } ]*/ )* )* ~ i_up: ~ {$In:[fields c:up] $out:up} ('Update_Reference' srs/icarus/db/p53apc.it description: |This is a database of mutations in the p53 |and APC tumor suppressor genes designed to facilitate molecular epidemiological |analyses. |

Sources

|Mutations in this database are from journals published in the |English language before September 1, 1993. The sources of |references include the laboratory's collection of papers, Dr. |Soussi's database, and searches of Medline, Cancerline, Chemical |Abstracts, Biological Abstracts, Excerpta Medica, and Current |Contents. While every effort has been made to be comprehensive, |inadvertent omissions are unavoidable. Authors are encouraged to |supply information updates in the future. |

Design

|The database is organized into three "relational" database |tables that are interrelated through common key numbers. |Explanations for each field of the relational database tables |are described below. # literature:'' address: |
    |Guggenheim 1501B
    |Department of Biochemistry & Molecular Biology
    |Mayo Clinic/Foundation
    |Rochester, MN 55905
    |
ftp: |\ |ftp.ebi.ac.uk/pub/databases/p53APC # www:'' email: |liaod@Mayo.EDU # updates:'' } l" database |tables that are interrelated through common key numbers. |Explanations for each field of the relational database tables |are described below. # literature:'' address: |
    |Guggenheim 150srs/icarus/db/p53apcref.i
#    File:		p53apcref.i            |
#    Version: 	1.0                    |
#    Date:		11-Sep-1996            |
#    Author:	Benny Shomer           |
# 				bshomer@ebi.ac.uk      |
#--------------------------------------    


P53APCREF_DB:$library:[P53APCREF group:@MUTATION_LIBS
	format:@P53APCREF_FORMAT maxNameLen:10 files:{
		$file:p53apc
	}
]

P53APCREF_FORMAT:$libformat:[syntax:@P53APCREF_SYNTAX fileType:@P53APCREF_FILE  
fields:{
    $field:[@DF_ID code:id indexToken:id index:id]
    $field:[@DF_Authors code:ra indexToken:ra index:str]
    $field:[@DF_Title code:rt indexToken:rt index:str]
    $field:[@DF_Reference code:rl indexToken:rl index:str]
    $field:[@DF_JR2 code:jr indexToken:jr index:str]
  }
]


#data field types
DF_JR2:$srsfield:[Cross_Ref short:XR group:@DF_ALL]



#links
$link:[@P53APCREF_DB to:@?MEDLINE_DB fromField:@DF_JR toField:@DF_ID token:jr]


P53APCREF_SYNTAX:$syntax:[file:"SRSDB:p53apcref.is" ignore:" \t"]
P53APCREF_FILE:$filetype:[typeName:ref maxline:200]


   $field:[@DF_Authors code:ra indexToken:ra index:str]
    $field:[@DF_Title code:rt indexToken:rt index:str]
    $field:[@DF_Reference code:rl indexToken:rl index:str]
    $field:[@DF_JR2 code:jr indexToken:jr index:str]
  }
]


#data field types
DF_JR2:$srsfield:[Cross_Ref short:XR group:@DF_ALL]



#links
$link:[@P53APCREF_DB to:@?MEDLINE_DB fromField:@DF_JR toField:@DF_ID token:jr]


P53APCREF_SYNTAX:$syntax:[file:"SRSDB:p53apcref.is" ignore:" \t"]
P53APCREF_FILE:$filetype:[typeNasrs/icarus/db/p53apcref.is
#--------------------------------------
#    File:		p53apcref.is           |
#    Version: 	1.0                    |
#    Date:		11-Sep-1996            |
#    Author:	Benny Shomer           |
# 				bshomer@ebi.ac.uk      |
#--------------------------------------    

$rules={

	#data record
	entry:	~ {$In:[file:text] $Out}
	          ('ID  ' {$entryFip=$Fip $Wrt} ln {$App}
                  ('ID  ' {$Not} ln {$App})*)?
		~
			
	ln:		~  /[^\n]*\n/ ~
	
	
	# Data fields
	fields:	~ {$In:entry $Out} id  ra rt rl jr ~
	id:		~ {$Wrt:id}    'ID'  ln  ~
        ra:             ~ {$Wrt:ra}             ('RA' ln)*   ~
        rt:             ~ {$Wrt:rt}             ('RT' ln)*   ~
        rl:             ~ {$Wrt:rl}             ('RL' ln)*   ~
        jr:             ~ {$Wrt:jr}             ('XR' ln)*   ~

	# Indexing
	word:	~ /[A-Za-z0-9_-]+/ ~
	name:	~ /[A-Za-z0-9_'-\?^]+/ ~
	int:    ~ /[-]?[0-9]+/ ~
	real:    ~ /[-]?[0-9]+([\.]?[0-9]+)?/~
	author:  ~ name /[^,;]+/ ~
	
	i_id:	~ {$In:[fields c:id]  $out:id} 
                 'ID' /[0-9.]+/ {$Wrt} ~
    i_ra:   ~ {$In:[fields c:ra]  $out:ra}
                 ( 'RA' (/[^ .,;:"\n]+/ {$Wrt} (/[. ,;]*/|'et al'
                 /[.,;]?/))*)* ~
    i_rt:   ~ {$In:[fields c:rt]  $out:rt}
                 ( 'RT' (/[^ .,;:"\n]+/ {$Wrt}/[ .,;:"\n]*/)* ln)* ~
    i_rl:   ~ {$In:[fields c:rl]  $out:rl}
                 'RL' /[^0-9]+/ {$Wrt:jrn} 
                 /([0-9]+), ([0-9]+)-([0-9]+), ([0-9]+)[.]?/
                 {$Wrt:[vol s:$1] $Wrt:[pg1 s:$2] $Wrt:[pg2 s:$3] 
                 $Wrt:[year s:$4]} ~
    i_jr:   ~ {$In:[fields c:jr]  $out:jr}
                  'XR  MEDLINE:' int {$Wrt} ~


	# printing in HTML format
	h_jr:     ~ {$In:[fields c:jr t:html]}
				('XR  MEDLINE:' /[0-9]+/
				{$Rep:{$ParStr:medlineR $Ct $Ct}} ln)
			  ~


}
	


"\n]*/)* ln)* ~
    i_rl:   ~ {$In:[fields c:rl]  $out:rl}
                 'RL' /[^0-9]+/ {$Wrt:jrn} 
                 /([0-9]+), ([0-9]+)-([0-9]+), ([0-9]+)[.]?/
                 {$Wrt:[vol s:$1] $Wrt:[pg1 s:$2] $Wrt:[pg2 s:$3srs/icarus/db/p53ref.i
#    File:		p53ref.i               |
#    Version: 	1.0                    |
#    Date:		11-Sep-1996            |
#    Author:	Benny Shomer           |
# 				bshomer@ebi.ac.uk      |
#--------------------------------------    


P53REF_DB:$library:[P53REF group:@MUTATION_LIBS
	format:@P53REF_FORMAT maxNameLen:10 files:{
		$file:p53
	}
]

P53REF_FORMAT:$libformat:[syntax:@P53REF_SYNTAX fileType:@P53REF_FILE  
fields:{
    $field:[@DF_ID code:id indexToken:id index:id]
    $field:[@DF_RA code:ra indexToken:ra index:str]
    $field:[@DF_RT code:rt indexToken:rt index:str]
    $field:[@DF_RL code:rl indexToken:rl index:str]
    $field:[@DF_JR code:jr indexToken:jr index:str]
  }
]


#data field types
DF_RA:$srsfield:[Authors short:AU group:@DF_ALL]
DF_RT:$srsfield:[Title short:TI group:@DF_ALL]
DF_RL:$srsfield:[Source short:SO group:@DF_ALL]
DF_JR:$srsfield:[Cross_Ref short:XR group:@DF_ALL]



#links
$link:[@P53REF_DB to:@?MEDLINE_DB fromField:@DF_JR toField:@DF_ID token:jr]


P53REF_SYNTAX:$syntax:[file:"SRSDB:p53ref.is" ignore:" \t"]
P53REF_FILE:$filetype:[typeName:ref maxline:200]


@DF_RL code:rl indexToken:rl index:str]
    $field:[@DF_JR code:jr indexToken:jr index:str]
  }
]


#data field types
DF_RA:$srsfield:[Authors short:AU group:@DF_ALL]
DF_RT:$srsfield:[Title short:TI group:@DF_ALL]
DF_RL:$srsfield:[Source short:SO group:@DF_ALL]
DF_JR:$srsfield:[Cross_Ref short:XR group:@DF_ALL]



#links
$link:[@P53REF_DB to:@?MEDLINE_DB fromField:@DF_JR toField:@DF_ID token:jsrs/icarus/db/p53ref.is
#--------------------------------------
#    File:		p53ref.is              |
#    Version: 	1.0                    |
#    Date:		11-Sep-1996            |
#    Author:	Benny Shomer           |
# 				bshomer@ebi.ac.uk      |
#--------------------------------------    

$rules={

  #data record
  entry:    ~ {$In:[file:text] $Out}
              ('ID  ' {$entryFip=$Fip $Wrt} ln {$App}
              ('ID  ' {$Not} ln {$App})*)?
	     ~
  ln:        ~  /[^\n]*\n/ ~
	
  # Data fields
  fields:   ~ {$In:entry $Out} id  ra rt rl jr ~
  id:	    ~ {$Wrt:id}    'ID'  ln  ~
  ra:       ~ {$Wrt:ra}             ('RA' ln)*   ~
  rt:       ~ {$Wrt:rt}             ('RT' ln)*   ~
  rl:       ~ {$Wrt:rl}             ('RL' ln)*   ~
  jr:       ~ {$Wrt:jr}             ('XR' ln)*   ~

  # Indexing
  word:	    ~ /[A-Za-z0-9_-]+/ ~
  name:	    ~ /[A-Za-z0-9_'-\?^]+/ ~
  int:      ~ /[-]?[0-9]+/ ~
  real:     ~ /[-]?[0-9]+([\.]?[0-9]+)?/~
  author:   ~ name /[^,;]+/ ~
  
  i_id:	    ~ {$In:[fields c:id]  $out:id} 
              'ID' int  {$Wrt} ~
  i_ra:     ~ {$In:[fields c:ra]  $out:ra}
              ( 'RA' (/[^ .,;:"\n]+/ {$Wrt} (/[. ,;]*/|'et al'
              /[.,;]?/))*)* ~
  i_rt:     ~ {$In:[fields c:rt]  $out:rt}
               ( 'RT' (/[^ .,;:"\n]+/ {$Wrt}/[ .,;:"\n]*/)* ln)* ~
  i_rl:     ~ {$In:[fields c:rl]  $out:rl}
              'RL' /[^0-9]+/ {$Wrt:jrn} 
              /([0-9]+), ([0-9]+)-([0-9]+), ([0-9]+)[.]?/
              {$Wrt:[vol s:$1] $Wrt:[pg1 s:$2] $Wrt:[pg2 s:$3] 
              $Wrt:[year s:$4]} ~
  i_jr:     ~ {$In:[fields c:jr]  $out:jr}
                  'XR  MEDLINE:' int {$Wrt} ~

  # printing in HTML format
  h_jr:     ~ {$In:[fields c:jr t:html]}
              ('XR  MEDLINE:' /[0-9]+/
              {$Rep:{$ParStr:medlineR $Ct $Ct}} ln)
            ~
}
	


~
  i_rl:     ~ {$In:[fields c:rl]  $out:rl}
              'RL' /[^0-9]+/ {$Wrt:jrn} 
              /([0-9]+), ([0-9]+)-([0-9]+), ([0-9]+)[.]?/
              {$Wrt:[vol s:$1] $Wrt:[pg1 s:$2] $Wrt:[pg2 s:$3] 
              $Wrt:[year s:$4srs/icarus/db/pah.i
#    $RCSfile: pah.i,v $
#    $Revision: 1.2 $
#    $Date: 1997/03/03 18:34:08 $
#    $Author: srs $
#
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

PAH_DB:$library:[PAH group:@MUTATION_LIBS
  format:@PAH_FORMAT maxNameLen:30 ifiles:{'pah.i' 'pah.is' 'pah.it'}
  files:{
    $file:'CFmutations96-1'
  }
]

PAH_FORMAT:$libformat:[syntax:@PAH_SYNTAX fileType:@TXT_FILE  
  printFormat:table
  fields:{
    $field:[@DF_ID indexToken:id index:id
      tableToken:id tableFormat:right]
    $field:@DF_ALL
#    $field:[@DF_DnaSubst code:mut indexToken:'dnaMut|subst' index:str
#      tableToken:'dnaMut|subst' tableFormat:left]
    $field:[@DF_NuclChange code:mut indexToken:'nuclChange|mut' index:str
      tableToken:'nuclChange|mut' tableFormat:left]
 #   $field:[@DF_MutConseq code:aaSubst indexToken:mutConseq index:str
 #     tableToken:'aaSubst|subst' tableformat:left]
    $field:[@DF_DnaChangePos code:dnaSubst indexToken:dnaMutPos index:int
      tableToken:dnaMutPos tableFormat:right]
    $field:[@DF_ProtChangePos code:aaSubst indexToken:aaMutPos index:int
      tableToken:aaMutPos tableFormat:right]
    $field:[@DF_Reference code:ref]
  }
]


PAH_SYNTAX:$syntax:[file:"SRSDB:pah.is" ignore:" "]
tr
      tableToken:'nuclChange|mut' tableFormat:left]
 #   $field:[@DF_MutConseq code:aaSubst indexToken:mutConseq index:str
 #     tableToken:'aaSubst|subst' tableformat:left]
    $field:[@DF_DnaChangePos code:dnaSsrs/icarus/db/pah.is
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#    $RCSfile: pah.is,v $
#    $Revision: 1.2 $
#    $Date: 1996/12/06 16:37:42 $
#    $Author: etzold $
#
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


$field={
  inex:       {len:9  index:normal }
  loc:        {len:7  index:normal }
  dnaChange:  {len:14 index:dnaChange }
  aaChange:   {len:18 index:aaChange }
  patient:    {len:11 index:normal }
  fC:         {len:9  index:normal }
  fAg:        {len:11 index:normal }
  Severity:   {len:16 index:normal }
  inhib:      {len:15 index:normal }
  cmnt:       {len:33 index:cmnt }
  ref:        {len:50 index:ref }
}

$rules={
  entry:   ~ {$In:[file:text] $Out pre $Skip:0 init $count=0}
             (/ [0-9]/ {$Not} ln)*
             (/ [0-9]+/ {$entryFip=$Fip $Wrt $count+=1} ln {$App})?
           ~
  # fields
   fields:  ~ {$In:entry $Out}
             x{ for:{$k=1 $k<12 $k+=1} {
                  $l=$field[$k].len 
                  $c=$Key:$field[$k]
                  $Prod:cell
                }
              } ~
  cell:    ~ /.+/ {if:$Trim:[$Ct]!="" $Wrt:$c $Len:$l} ~

  # indexing
  id:        ~ {$In:entry $Out} x{$Wrt:[s:$count]} ~
  inx:       ~ {$In:fields $Out pre $Skip:1} x{$Prod:$field.($Itc).index} ~
  normal:    ~ /[^ ]+/ {$Wrt:$Itc} ~
  dnaChange: ~ /([A-Z]+) +([A-Z]+)/ {$Wrt:[$Itc s:"$1>$2"]} ~
  aaChange:  ~ {init $aa={Ile:I Leu:L Met:M Ala:A Val:V Ser:S Thr:T Phe:F 
                          Tyr:Y Gly:G Pro:P Trp:W Cys:C Gln:Q 
                          Asn:N Arg:R Lys:K Asp:D Glu:E His:H Stop:Stop}
               } /([A-Za-z]+) +([A-Za-z]+)/ 
               {$Wrt:[$Itc s:"($aa.$1)>($aa.$2)"]} ~
  cmnt:      ~ /./ ~
  ref:       ~ /./ ~

  # others
  ln:      ~ /[^\n]*\n/ ~
}

# debugging 
if:$TestMode {
  $job = $JobNew:[prod:$rules skip:" " 
    fileName:'/opt/srs/data/mutdb/haema/haema.txt']
  while:$JobHasInput:$job {
    $JobTokens:[$job name:id print:1] 
    $JobNext:$job
    $print:"-------->entry\n" 
  }
}



Cys:C Gln:Q 
                          Asn:N Arg:R Lys:K Asp:D Glu:E His:H Stop:Stop}
               } /([A-Za-z]+) +([A-Za-z]+)/ 
               {$Wrt:[$Itc s:"($aa.$1)>($aa.$2)"]} ~
  cmnt:      ~ /./ ~
  ref:       ~ /./ ~

  # others
  ln:      ~ /[^\n]*\n/ ~
}

# debugging 
if:$TestMode {
  $job = $JobNew:[prod:$rules skip:" " 
    fileName:'/opt/srs/data/mutdb/haema/haema.txt']
  while:$JobHasInput:$job {
    $JobTokens:[$job name:id print:1] 
    $JobNext:$job
    $print:"-------->entry\n" 
  }
}
srs/icarus/db/pah.it
#    
#    $RCSfile: pah.it,v $
#    $Revision: 1.1 $
#    $Date: 1996/11/05 19:54:13 $
#    $Author: etzold $
#
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

$dbInfo={
  description:
    |Mutations in the phenylalanine hydroxylase (PAH) gene, the majority of
    |which result in deficient enzyme activity and cause
    |hyperphenylalaninemia, occur in all 13 exons of the gene and flanking
    |sequence; Some in phenylketonuria, others cause non-PKU
    |hyperphenylalaninemia, while still others are silent polymorphisms
    |present on both normal and mutant chromosomes. Some PAH alleles are
    |present at elevated frequencies, 5 account for approximately 60%% of
    |European mutations and they tend to cluster in regions or are on only
    |one of a few haplotypes. Several hundred mutations and three-fold
    |greater mutation associations have been recorded. The majority of
    |changes are missense mutations, although splice ,nonsense and silent
    |mutations, as well as single base-pair frameshifts, and larger
    |deletions and insertions have been found.
    |
    |

PAH Mutations Database

| |Mutation data were collated from both published articles and personal |communications of 80 investigators from the PAH Mutation Analysis |Consortium in 26 countries. The curator has developed a database and |software package (WINPAHDB) which is stand-alone executable on an |IBM-compatible computer with Microsoft Windows. This enables us to |maintain and centralize mutation data on the PAH gene, while providing |fast and easy access for users. Searchable fields of the database |available to users are: mutation name, polymorphic haplotype, |population, geographic location, gene region, codon number, mutation |type, substitution, phenotype, and author's name. The complete |information provided for each mutation is regularly updated from both |published data and personal communications. This database occupies a |WWW site on the internet and is a resource for the Human Genetic |Diversity Project (HUGO). www: |\ |http://blizzard.cc.mcgill.ca/pahdb email: |mc77@musica.mcgill.ca phone: |+1 514 934 4417 fax: |+1 514 934 4329 contact: |Charles R. Scriver address: |McGill University-Montreal, |Children's Hospital Research Institute, |Debelle Laboratory for Biochemical Genetics, |2300 Tupper St., Montreal, Quebec H3H 1P3, Canada. literature: |Nucleic Acids Research 24, 129-131, (1996) fields:{ } } www: |\ |http://blizzard.cc.mcgill.ca/pahdb email: |mc77@musica.mcgill.ca phone: |+1 514 934 4417 fax: |+1 514 934 4329 contact: |Charles R. Scriver address: |McGill University-Montreal, |Children's Hospital Research Institute, |Debelle Laboratory fsrs/icarus/db/pdb.i # $RCSfile: pdb.i,v $ # $Revision: 1.6 $ # $Date: 1997/03/19 20:30:37 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PDB_DB:$library:[PDB group:@PROTSTRUCT_LIBS format:@PDB_FORMAT maxNameLen:30 ifiles:{"pdb.i" "pdb.is"} ] PDB_FORMAT:$libformat:[fileType:{@PDB_FILE} syntax:@PDB_SYNTAX fields:{ $field:[@DF_HeaderField name:'Title Section'] $field:[@DF_ID code:header index:id indexToken:id] $field:[@DF_Date code:header index:int indexToken:date] $field:[@DF_Supersedes code:sprsde index:str indexToken:sprsde] $field:[@DF_Compound code:compnd index:str indexToken:'wordX|compnd' tableToken:'t_fields|compnd'] $field:[@DF_Source code:source index:str indexToken:'wordX|source' tableToken:'t_fields|source'] $field:[@DF_EntryAuthors code:author index:str indexToken:author] $field:[@DF_Authors code:auth index:str indexToken:auth] $field:[@DF_Title code:titl index:str indexToken:'wordX|compnd'] $field:[@DF_Remark code:remark index:str indexToken:'wordX|remark'] $field:[@DF_HeaderField name:'Primary Structure Section'] $field:[@DF_HeaderField name:'Annotation Section'] $field:[@DF_HeaderField name:'Crystallographic Section'] $field:[@DF_CRYST1 code:CRYST1 tableToken:'t_fields|CRYST1'] $field:[@DF_ORIGXn code:ORIGX tableToken:'t_fields|ORIGX'] $field:[@DF_SCALEn code:SCALE tableToken:'t_fields|SCALE'] $field:[@DF_MTRIXn code:MTRIX tableToken:'t_fields|MTRIX'] $field:[@DF_TVECT code:TVECT tableToken:'t_fields|TVECT'] $field:[@DF_MODEL code:MODEL tableToken:'t_fields|MODEL'] # $field:[@DF_Atoms token:'dfields|atom'] # $field:[@DF_Master token:'dfields|master'] # $field:[@DF_HeaderField name:'Coordinate Section'] # $field:[@DF_SIGATM token:'fields2|SIGATM' tableToken:'t_fields2|SIGATM'] # $field:[@DF_ANISOU token:'fields2|ANISOU' tableToken:'t_fields2|ANISOU'] # $field:[@DF_SIGUJ token:'fields2|SIGUJ' tableToken:'t_fields2|SIGUJ'] # $field:[@DF_TER token:'fields2|TER' tableToken:'t_fields2|TER'] # $field:[@DF_HETATM token:'fields2|HETATM' tableToken:'t_fields2|HETATM'] } ] DF_EntryAuthors:$srsfield:[EntryAuthors short:eat] DF_CRYST1:$srsfield:[CRYST1 short:cr1] DF_ORIGXn:$srsfield:[ORIGXn short:ori] DF_SCALEn:$srsfield:[SCALEn short:sca] DF_MTRIXn:$srsfield:[MTRIXn short:mtr] DF_TVECT:$srsfield:[TVECT short:tve] DF_MODEL:$srsfield:[MODEL short:mod] DF_Supersedes:$srsfield:[Supersedes short:spr] DF_Atoms:$srsfield:[ATOM short:atm] DF_SIGATM:$srsfield:[SIGATM short:sig] DF_ANISOU:$srsfield:[ANISOU short:ani] DF_SIGUJ:$srsfield:[SIGUJ short:sgu] DF_TER:$srsfield:[TER short:ter] DF_HETATM:$srsfield:[HETATM short:htm] DF_ENDMDL:$srsfield:[ENDMDL short:end] DF_Remark:$srsfield:[Remark short:rem] DF_Master:$srsfield:[Master short:mas] PDB_SYNTAX:$syntax:[file:"SRSDB:pdb.is" ignore:" "] # compressed files named pdbXXX.ent.Z #PDB_FILE:$FileType:[text singleEntry:y maxline:100 # saveName:file saveNameLength:20 pipe:"uncompress -c \%s" # searchName:'pdb*.ent.Z' #] PDB_FILE:$FileType:[text singleEntry:y maxline:100 saveName:file saveNameLength:20 searchName:'3*.brk*' ] #PDBDATA_FILE:$FileType:[data maxline:100 shareWith:@PDB_FILE # fieldTokens:dfields fipVar:dataFip #] emark short:rem] DF_Master:$srsfield:[Master short:mas] PDB_SYNTAX:$syntax:[file:"SRSDB:pdb.is" ignore:" "] # compressed files named pdbXXX.ent.Z #PDB_FILE:$FileType:[text singleEntry:y maxlinsrs/icarus/db/pdb.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: pdb.is,v $ # $Revision: 1.8 $ # $Date: 1997/03/19 20:30:37 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $fn={ HEADER: header HETNAM: hetnam TVECT: tvect TITLE: title HETSYN: hetsym MODEL: model SOURCE: source HETSIT: hetsit KEY: key FORMUL: formul ATOM: atom EXPDTA: expdta HELIX: helix SIGATM: sigatm AUTHOR: author SHEET: sheet ANISOU: anisou REVDAT: revdat TURN: turn SIGUIJ: siguij SPRSDE: sprsde SSBOND: ssbond TER: ter COMPND: compnd SITE: site HETATM: hetatm MODRES: modres CRYST1: cryst ENDMDL: endmdl DBREF: dbref ORIGX1: origx CONECT: conect SEQADV: seqadv ORIGX2: origx MASTER: master SEQRES: seqres ORIGX3: origx END: end FTNOTE: ftnote SCALE1: scale KEYWDS: keywds HET: het SCALE2: scale LINK: link JRNL: jrnl SCALE3: scale CISPEP: cispep REMARK: remark MTRIX2: mtrix MTRIX1: mtrix MTRIX3: mtrix 'JRNL AUTH': auth 'REMARK 1': head 'JRNL TITL': titl 'REMARK 1 REFERENCE': head 'JRNL REF': ref 'REMARK 1 AUTH': auth 'JRNL REFN': refn 'REMARK 1 TITL': titl 'JRNL EDIT': edit 'REMARK 1 REF': ref 'JRNL PUBL': publ 'REMARK 1 REFN': refn 'REMARK 1 EDIT': edit 'REMARK 1 PUBL': publ 'REMARK 1 RENF': publ } $rules={ # the entry entry: ~ {$In:[file:text] $Out init{$Skip:0}} 'HEADER ' {pre {$entryFip=0} $Wrt} appLn ('END ' {$Not} appLn)* ~ data: ~ {$In:[file:data share:text] $Out} ln {$Wrt $dataFip=$Fip} appLn+ ~ # fields from text and data fields: ~ {$In:entry $Out} (tag { $t=$Ct if:$fn.$t!="" {if:$fn.$t!=$fPrev $Wrt:$fn.$t else $App $fPrev = $fn.$t} } ln {$App})+ ~ dfields: ~ {$In:data $Out} (tag { $t=$Ct if:$fn.$t!="" {if:$fn.$t!=$fPrev $Wrt:$fn.$t else $App $fPrev = $fn.$t} } ln {$App})+ ~ tag: ~ /JRNL +[A-Z]+/ | /REMARK +1 +[A-Z]+/ | /[A-Z0-9]+/ ~ #indexing productions id: ~ {$In:[fields c:header] $Out $Mov:62} /[A-Z0-9]+/ {$Wrt} ~ date: ~ {$In:[fields c:header] $Out $Mov:50} datenum {$Wrt:[s:$date]} ~ wordX: ~ {$In:[fields c:{compnd source remark het}] $Out} (x{$Mov:10} words {$Len:60} ln)+ ~ author: ~ {$In:[fields c:author] $Out} (x{$Mov:10} authors {$Len:60} ln)+ ~ auth: ~ {$In:[fields c:auth] $Out} (x{$Mov:18} authors {$Len:52} ln)+ ~ titl: ~ {$In:[fields c:titl] $Out} (x{$Mov:18} words {$Len:52} ln)+ ~ ref: ~ {$In:[fields c:ref] $Out} (x{$Mov:18} words {$Len:52} ln)+ ~ master: ~ {$In:[dfields c:master] $Out} tag / */ word {$Wrt} ~ authors: ~ sauthor (',' sauthor?)* ~ sauthor: ~ / *([^ ,]*\\.)([^ ,]*)/ {$Uniq:[s:"$2,$1"]} ~ words: ~ (/[A-Z0-9]+/ {$Uniq:$Itc} | /[^A-Z0-9]+/)+ ~ datenum: ~ {init {$month={JAN:1 FEB:2 MAR:3 APR:4 MAY:5 JUN:6 JUL:7 AUG:8 SEP:9 OCT:10 NOV:11 DEC:12}}} / *([0-9]+)-([A-Z][A-Z][A-Z])-([0-9]+)/ {$date=$1 + $month.$2 * 100 + $3 * 10000 + 19000000} ~ sprsde: ~ {$In:[fields c:sprsde] $Out $Mov:10} / *[^ \n]+/ / *[^ \n]+ */ /[^ \n]+/ {$Wrt} ~ # table display t_fields: ~ {$In:[fields c:{source compnd}] $Out} (x{$Mov:9 $Getc:62 $Wrt:$Itc} ln)+ ~ # html display h_com: ~ {$In:[t_fields c:com t:html]} (/(E\\.C\\.|EC: *)([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)/ {$Rep:{"$1($ParStr:enzymeR)" $2 $2}} | /./)+ ~ # other productions word: ~ /[^ ]+/ ~ ln: ~ /[^\n]*\n/ ~ appLn: ~ /[^\n]*\n/ {$App} ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/research/pdb/2hya.brk'] $JobTokens:[$job name:fields print:0] $JobTokens:[$job name:id print:1] $JobTokens:[$job name:date print:1] $JobTokens:[$job name:wordX print:1] $JobTokens:[$job name:author print:1] $JobTokens:[$job name:auth print:1] } /./)+ ~ # othersrs/icarus/db/pdb.it # # $RCSfile: pdb.it,v $ # $Revision: 1.4 $ # $Date: 1996/10/30 10:20:21 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $dbInfo={ description: |The Protein Data Bank (PDB) is an archive of experimentally determined |three-dimensional structures of biological macromolecules, serving a |global community of researchers, educators, and students. The archives |contain atomic coordinates, bibliographic citations, primary and |secondary structure information, as well as crystallographic structure |factors and NMR experimental data. The PDB Newsletter and CD ROM are |published quarterly.

The PDB is supported by a combination of |Federal Government Agency funds and user fees. Support is provided |by the U.S. National Science Foundation, the U.S. Public Health |Service, National Institutes of Health, National Center for Research |Resources, National Institutes of General Medical Sciences, National |Library of Medicine, and the U.S. Department of Energy under contract |DE-AC02-76CH00016 and user fees. www: |http://www.pdb.bnl.gov/ literature: |PDB |Quarterly Newsletter date: |25 Jul 1996 signature: |Anatoly Ulyanov } lth |Service, National Institutes of Health, National Center for Resrs/icarus/db/pdbfinder.i # $RCSfile: pdbfinder.i,v $ # $Revision: 1.9 $ # $Date: 1997/03/03 18:34:10 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PDBFINDER_DB:$library:[PDBFINDER group:@PROTSTRUCT_LIBS comment:"Directory for the Brookhaven Protein Data Bank" format:@PDBFINDER_FORMAT ifiles:{'pdbfinder.i' 'pdbfinder.is'} subentries:@PdbfinderChains_DB files:{ $file:pdbfinder } ] PDBFINDER_FORMAT:$libformat:[fileType:@PDBFINDER_FILE syntax:@PDBFINDER_SYNTAX tableFormat:left fields:{ $field:[@DF_ALL] $field:[@DF_ID code:id index:id indexToken:id] $field:[@DF_Header code:header index:str indexToken:'wordX|header' tableToken:'fields|header'] $field:[@DF_Compound code:compound index:str indexToken:'wordX|compound' tableToken:'fields|compound'] $field:[@DF_EnzymeCode code:enzyme index:str indexToken:enzyme] $field:[@DF_Source code:source index:str indexToken:'wordX|source' tableToken:'fields|source'] $field:[@DF_Authors code:author index:str indexToken:author] $field:[@DF_Date code:date index:int indexToken:date] $field:[@DF_Resolution code:resolution index:real indexToken:'realX|resolution'] $field:[@DF_R_FACTOR code:rFactor index:real indexToken:'numX|rFactor'] $field:[@DF_N_HSSP_ALIGN code:hsspNAlign index:int indexToken:'numX|hsspNAlign'] $field:[@DF_N_HET_GROUPS code:nHetGroups index:int indexToken:'numX|nHetGroups'] $field:[@DF_EXP_METHOD code:expMethod index:str indexToken:'wordX|expMethod'] $field:[@DF_tFracHelix code:tFracHelix index:int indexToken:'realX|tFracHelix'] $field:[@DF_T_NRES_PROT code:tNresProt index:int indexToken:'numX|tNresProt'] $field:[@DF_TWaterMols code:tWaterMols index:int indexToken:'numX|tWaterMols'] # chain subentry $field:[@DF_HeaderField name:'Chain Subentry Fields'] $field:[@DF_ChainName code:chain index:str indexToken:chnName indexId:@SUBENTRY_ID] $field:[@DF_N_NUCLACIDS code:nuc index:int indexToken:nuc indexId:@SUBENTRY_ID] $field:[@DF_N_AMINOACIDS code:aa index:int indexToken:aa indexId:@SUBENTRY_ID] $field:[@DF_SecStruc code:secStruc] $field:[@DF_Helix code:helix index:int indexToken:helix] $field:[@DF_II3 code:ii3] $field:[@DF_II5 code:ii5] $field:[@DF_Beta code:beta] $field:[@DF_BBridge code:bBridge] $field:[@DF_ParaHb code:paraHn] $field:[@DF_AntiHb code:antiHB] $field:[@DF_MissBB code:missBB] $field:[@DF_MissSC code:missSC] $field:[@DF_Break code:break] $field:[@DF_Substrate code:substrate] $field:[@DF_WaterMols code:waterMols index:int indexToken:waterMols indexId:@SUBENTRY_ID tableToken:waterMols tableFormat:right] $field:[@DF_Sequence code:sequence tableToken:t_sequence] } ] PdbfinderChains_DB:$library:[PDBFINDER_chains format:@PdbfinderChains_Format] PdbfinderChains_Format:$libformat:[syntax:@PDBFINDER_SYNTAX tableFormat:left fields:{ $field:[@DF_ID token:chainId] $field:[@DF_ChainName token:'chain|chain'] $field:[@DF_N_NUCLACIDS token:'chain|nuc' tableFormat:right] $field:[@DF_N_AMINOACIDS token:'chain|aa' tableFormat:right] $field:[@DF_SecStruc token:'chain|secStruc'] $field:[@DF_Helix token:'chain|helix'] $field:[@DF_II3 token:'chain|ii3'] $field:[@DF_II5 token:'chain|ii5'] $field:[@DF_Beta token:'chain|beta'] $field:[@DF_BBridge token:'chain|bBridge'] $field:[@DF_ParaHb token:'chain|paraHb'] $field:[@DF_MissBB token:'chain|missBB'] $field:[@DF_WaterMols token:'chain|waterMols'] $field:[@DF_ProtSequence token:chnSequence tableFormat:listing] } ] DF_EXP_METHOD:$srsfield:[ExpMethod short:exp group:@DF_ALL] DF_N_HET_GROUPS:$srsfield:[NoHetGroups short:het group:@DF_ALL] DF_N_HSSP_ALIGN:$srsfield:[NoHSSPAlign short:nha] DF_tFracHelix:$srsfield:[TotFractHelix short:tfh group:@DF_ALL] DF_T_FRAC_BETA:$srsfield:[TotFractBeta short:tfb group:@DF_ALL] DF_T_NRES_PROT:$srsfield:[TotNResProt short:tnp group:@DF_ALL] DF_TWaterMols:$srsfield:[TotWaterMols short:twm group:@DF_ALL] DF_Resolution:$srsfield:[Resolution short:res group:@DF_ALL] DF_R_FACTOR:$srsfield:[RFactor short:rfa group:@DF_ALL] DF_ChainName:$srsfield:[ChainName short:chn group:@DF_ALL] DF_N_NUCLACIDS:$srsfield:[NucleicAcids short:nuc] DF_N_AMINOACIDS:$srsfield:[AminoAcids short:aa] DF_SecStruc:$srsfield:[SecStruc short:ss] DF_Helix:$srsfield:[Helix short:hel] DF_II3:$srsfield:[II3 short:ii3] DF_II5:$srsfield:[II5 short:ii5] DF_Beta:$srsfield:[Beta short:bet] DF_BBridge:$srsfield:[BetaBridge short:bbr] DF_ParaHb:$srsfield:[ParaHb short:phb] DF_AntiHb:$srsfield:[AntiHb short:ahb] DF_MissBB:$srsfield:[MissBB short:mbb] DF_MissSC:$srsfield:[MissSC short:msc] DF_Break:$srsfield:[Break short:bre] DF_NWaterMols:$srsfield:[NWaterMols short:nwm] PDBFINDER_SYNTAX:$syntax:[file:"SRSDB:pdbfinder.is" ignore:" \t"] PDBFINDER_FILE:$filetype:[typename:dat maxline:5000] $link:[@PDBFINDER_DB to:@?PDB_DB fromField:@DF_ID toField:@DF_ID] ii5] DF_Beta:$srsfield:[Beta short:bet] DF_BBridge:$srsfield:[BetaBridge short:bbr] DF_ParaHb:$srsfield:[ParaHb short:phb] DF_AntiHb:$srsfield:[AntiHb short:ahb] DF_MissBB:$srsfield:[MissBB short:mbb] DF_MissSC:$srsfield:[MissSC short:msc] DF_Break:$srsfield:[Break short:bre] DF_NWaterMols:$srsfield:[NWaterMols short:nwm] PDBFINDER_SYNTAX:$syntax:[file:"SRSDB:pdbfinder.is" ignore:" \t"] PDBFINDsrs/icarus/db/pdbfinder.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: pdbfinder.is,v $ # $Revision: 1.7 $ # $Date: 1996/12/18 19:44:50 $ # $Author: weare $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $fn={ 'ID': id 'Name': hetName 'Header': header 'Chain': chain 'Date': date 'Sec-Struc': secStruc 'Compound': compound 'Helix': helix 'Enzyme-Code': enzyme 'i,i+3': ii3 'Source': source 'i,i+5': ii5 'Author': author 'Beta': beta 'Exp-Method': expMethod 'B-Bridge': bBridge 'Resolution': resolution 'E-Beta': missSC 'R-Factor': rFactor 'Para-Hb': paraHb 'Free-R': appLn 'Anti-Hb': antiHb 'Ref-Prog': refProg 'Amino-Acids': aa 'N-Models': nModels 'non-Std': missSC 'HSSP-N-Align': hsspNAlign 'Miss-BB': missBB 'T-Frac-Helix': tFracHelix 'Miss-SC': missSC 'T-Frac-Beta': tFracBeta 'only-Ca': missSC 'T-Nres-Prot': tNresProt 'CYSS': missSC 'T-non-Std': appLn 'Break': break 'T-Nres-Nucl': appLn 'Nucl-Acids': nuc 'T-Water-Mols': tWaterMols 'Substrate': substrate 'HET-Groups': nHetGroups 'Water-Mols': waterMols 'Het-Id': hetId 'Sequence': sequence 'Natom': hetNAtom 'UNK': unc 'SF-Type': unknown 'N-refl': unknown 'H-max': unknown 'H-min': unknown 'K-max': unknown 'K-min': unknown 'L-max': unknown 'L-min': unknown } $rules={ entry: ~ {$In:[file:text] $Out pre $Skip:0} ('ID' {$Not} ln)* 'ID' {$entryFip = $Fip $Wrt} appLn ('ID' {$Not} appLn)+ ~ # data fields fields: ~ {$In:entry $Out $Skip:1} (/ *([^ ]+) *:/ { if:$1==$prev $App else { if:$ParInt:isTable $Wrt:[s:"" c:$fn.$1] else $Wrt:$fn.$1 } if:$fn.$1=="" $dp:"+++ unknown: $1 +++" $prev=$1 } ln {$App})+ ~ # indexing id: ~ {$Out $In:[fields c:id]} tag /..../ {$Wrt} ~ enzyme: ~ {$Out $In:[fields c:enzyme]} tag /[0-9.-]+/ {$Wrt} ~ author: ~ {$Out $In:[fields c:author]} tag /([A-Za-z.-]+\\.)([a-zA-Z ]+)/ {$Wrt:[s:"$2,$1"]} ~ date: ~ {$Out $In:[fields c:date]} tag /([0-9]+)-([0-9]+)-([0-9]+)/ {$Wrt:[s:"$1$2$3"]} ~ wordX: ~ {$In:[fields c:{header compound source expMethod}] $Out} tag (word {$Uniq:$Itc} | sep)* ~ realX: ~ {$In:[fields c:{resolution rFactor tFracHelix}] $Out} tag real {$Wrt:$Itc} ~ numX: ~ {$In:[fields c:{nHetGroups hsspNAlign tNresProt tWaterMods}] $Out} tag int {$Wrt:$Itc} ~ chnName: ~ {$Out $In:[fields c:chain count:chain var:$chN]} tag str {$Wrt:[n:$chN]} ~ nuc: ~ {$Out $In:[fields c:nuc count:chain var:$chN]} tag int {$Wrt:[n:$chN]} ~ aa: ~ {$Out $In:[fields c:aa count:chain var:$chN]} tag int {$Wrt:[n:$chN]} ~ helix: ~ {$Out $In:[fields c:sequence]} ln {$Wrt:[s:'77777']} ~ waterMols: ~ {$Out $In:[fields c:waterMols count:chain var:$chN]} tag int {$Wrt:[n:$chN]} ~ # display chain subentries chainId: ~ {$In:[fields c:id] $Out pre $Skip:0} tag {$Wrt} / *([^ \n]+)/ {$entryName="$1\_$subEntryN" $App:[s:" $entryName ; parent: $1"]} ~ chain: ~ {$In:[fields count:chain var:$chN select:$subEntryN c:{chain nuc aa secStruc helix ii3 ii5 beta bBridge paraHb missBB waterMols}] $Out pre $Skip:0} tag {if:$ParInt:isTable $Wrt:[$Itc s:""] else $Wrt:$Itc} /.+/ {$App} ~ chnSequence: ~ {$In:[fields count:chain var:$chN select:$subEntryN c:sequence] $Out} tag /.+/ { pre $seq=$SeqNew:$entryName $SeqApp:[$seq s:$Ct] $SeqMake:$seq $Wrt:[s:$entryName] } ~ # table display t_sequence: ~ {$Out $In:[fields c:sequence]} tag ln {$Wrt:[s:""]} ~ # HTML display th_enzyme: ~ {$In:[enzyme t:hl]} /.*/ {$Rep:{$parStr:enzymeR $Ct $Ct}} ~ # other wrtField: ~ tag ln {$Wrt} ~ appLn: ~ /[^\n]*\n/ {$App} ~ ln: ~ /[^\n]*\n/ ~ tag: ~ /[^:]+:/? ~ int: ~ /[0-9]+/ ~ real: ~ /[0-9.]+/ ~ str: ~ /[0-9a-zA-Z_]+/ ~ word: ~ /[0-9a-zA-Z_]+/ ~ sep: ~ /[^0-9a-zA-Z_]+/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/pdbfinder/pdbfinder.dat'] while:$JobHasInput:$job { $JobTokens:[$job name:chainId print:1] $JobTokens:[$job name:chain print:1] # $JobTokens:[$job name:numInx print:1] # $JobTokens:[$job name:wordInx print:1] $JobNext:$job $print:"-------->entry\n" } } / ~ real: ~ /[0-9.]+/ ~ str: ~ /[0-9a-zA-Z_]+/ ~ word: ~ /[0-9a-zA-Z_]+/ ~ sep: ~ /[^0-9a-zA-Z_]+/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/pdbfinder/pdbfinder.dat'] while:$JobHasInput:$job { $JobTokens:[$job name:chainId print:1] $JobTokens:[$job name:chain print:1] # $JobTokens:[$job name:numInx psrs/icarus/db/pdbfinder.it # # $RCSfile: pdbfinder.it,v $ # $Revision: 1.4 $ # $Date: 1996/10/10 16:47:08 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $dbInfo={ description: |The PDBFINDER database is constructed using a PERL |script from the PDB, DSSP and HSSP databases. Many of the fields |contained in the PDBFINDER database are difficult to access from the |original databases. Some Information is retrieved from the original |literature. more: |

| |More on PDBFINDER |

citation:'' ftpSite:'' fields:{ ID: |The ID field contains the 4-letter PDB code of the |entry. It is always present. Header: |The Header field contains the information from the |HEADER records in the PDB file. It is always |present. Date: |from the HEADER records in the PDB file. |It contains the |date in the form "YYYY-MM-DD". It is always present. Compound: |The Compound field contains the information from the |COMPND records in the PDB file. EnzymeCode: |The Enzyme-Code fields contain E.C. numbers |extracted from the COMPND records in the PDB |file. Wildcards for the last numbers may be present as "-" characters. Source: |The Source field contains the information from the |SOURCE records in the PDB file. ExprSys: |The Expr-Sys field contains the expression system |extracted from the SOURCE records in the PDB |file. Author: |Each of the Author fields contains an author name from the |PDB record AUTHOR. ExpMethod: |The Exp-Method field can contain one of the following: |
|
X |
X-ray structure |
NMR |
NMR structure |
FIBER |
Fiber diffraction study |
MODEL |
A model without explicit experimental data |
NEUTRON |
Neutron diffraction study |
OTHER |
Currently Fluorescence Transfer and Electron Diffraction are | uncategorized. |
| |The Exp-Method is derived from the EXPDTA field in |the PDB if present, otherwise it is derived from other sources. | Resolution: |The Resolution is derived from REMARK 2 in the |PDB file. For NMR structures and models no resolution is given. | RFactor: |The R-Factor for X-ray structures is derived from REMARK |3 and REMARK 4 if possible. For X-ray structures lacking |a valid R-factor in the PDB file, the R-factor field |is based on the original literature. A number of corrections to values |found in the PDB have also been applied. In some cases no |R-factor could be found, or the original literature does contain an |R-factor but the published coordinates are C-alpha only. In those |cases no R-Factor field is present. Also no R-factor is given |for NMR structures, because the calculation methods are too diverse. | FreeR: |The Free-R for X-ray structures is derived from REMARK |3. It is only given for some modern PDB files. NModels: |The N-Models field gives the number of models preceded by |MODEL cards in the PDB file, if any. RefProg: |The Ref-Prog field contains any recognized names of |refinement programs, separated by slashes. Currently the following |program names are recognized: | |'AMBER', |'AMORE', |'ARP', |'ATOM', |'CALIBA', |'CEDAR', |'CHARMM', |'CORELS', |'CORMA', |'CRLS', |'CRYLSQ', |'DERIV', |'DGII', |'DIAMOND', |'DIANA', |'DINOSAUR', |'DISCOVER', |'DISGEO', |'DISMAN', |'DSPACE', |'ECEPP', |'EMBOSS', |'EREF', |'FANTOM', |'FREF', |'FRODO', |'GENERATE', |'GPRLSA', |'GRINCH', |'GROMOS', |'GROMOS-MDX', |'HABAS', |'HAFFIX', |'HKSCAT', |'INSIGHTII', |'IRMA', |'JACK-LEVITT', |'LOOP', |'MANOSK', |'MARDIGRAS', |'MIDGE', |'MM', |'MODELFIT', |'MUMOD', |'NCS', |'NOEMOL', |'NUCLIN', |'NUCLSQ', |'OMIT', |'OPAL', |'PIKSOL', |'PRESTO', |'PROFFT', |'PROLSQ', |'PROTEIN', |'PROTIN', |'PSFRODO', |'QUANTA', |'RESLSQ', |'RESTRAIN', |'ROTLSQ', |'RSREF', |'SCATT', |'SFALL', |'SFRK', |'SHELX', |'SHELXL', |'STEREOSEARCH', |'TNT', |'TOM', |'ULTIMA', |'VEMBED', |'X-PLOR', |'XEASY', |'YASAP'. | NoHSSPAlign: |The HSSP-N-Align field gives the number of |different aligned sequences in the HSSP |database, if a HSSP file for the structure exists (Normally: |if the structure is a protein structure). TotFracHelix: |The T-Frac-Helix field gives the fraction of the assigned |secondary structure that is helical: it is the total of the |Helix fields for all chains divided by the total of all |Sec-Struc fields. This field is only present if there is a |secondary structure. TotFracBeta: |The T-Frac-Beta field gives the fraction of the assigned |secondary structure that is Beta: it is the total of the Beta |fields for all chains divided by the total of all Sec-Struc |fields. This field is only present if there is a secondary structure. TotNresProt: |The T-Nres-Prot field gives the total number of amino acid |residues in the structure, if any. Non-standard amino-acids are |included. TotNonStd: |The T-non-Std field gives the total number of non-standard |amino acid residues in the structure, if any. TotNresNucl: |The T-Nres-Nucl field gives the total number of nucleic acid |residues in the structure, if any. TotWaterMols: |The T-Water-Mols field gives the total number of water |molecules in the structure, if any. NoHetGroups: |The HET-Groups field gives the number of HET cards |in the PDB file, if any. The following items are repeated for |every HET-group, and are all derived from the PDB HET cards. HetId: |Het-Id gives the residue ID for each HET group. NAtom: |Natom gives the number of atoms in each HET group. Name: |Name gives the full name for each HET group. ChainName: |The Chain field and the subfields below are repeated once for |each polymer chain (DNA, RNA, Protein) in the structure. |The Chain |field contains the chain-identifier for the chain, if any. If there is |no chain identifier, the Chain field contains "_". SecStruc: |The Sec-Struc field contains the number of residues in the |chain of which a secondary structure could be derived by the |DSSP program. Helix: |The Helix field contains the number of residues in the chain |for which the secondary structure is helical (either alpha helical, |pi-helical or 3/10 helical). 'i,i+3': |The i,i+3 field contains the number of residues in the chain |for which the assigned secondary structure is "3/10 helix". | |

Chain, Sec-Struc, Helix, i,i+5

| |The i,i+5 field contains the number of residues in the chain |for which the assigned secondary structure is "pi helix". | |

Chain, Sec-Struc, Beta

| |The Beta field contains the number of residues in the chain |for which the secondary structure is "beta". | |

Chain, Sec-Struc, Beta, B-Bridge

| |The B-Bridge field contains the number of residues in the chain |for which the assigned secondary structure is "beta bridge" | |

Chain, Sec-Struc, Beta, E-Beta

| |The E-Beta field contains the number of residues in the chain |for which the assigned secondary structure is "extended beta" | ParaHb: |The Para-Hb field contains the number of "parallel strand" |hydrogen bonds found in the chain. AntiHb: |The Anti-Hb field contains the number of "antiparallel |strand" hydrogen bonds found in the chain. AminoAcids: |The Amino-Acids field contains the number of amino-acid |residues in the chain, including non-standard amino acids. Only |present if non-zero. NonStd: |The non-Std field contains the number of non-standard amino |acids in the chain, if any. | MissBB: |The Miss-BB field contains the number of amino acids in the |chain for which part of the backbone coordinates are missing from the |PDB file. MissSC: |The Miss-SC field contains the number of amino acids in the |chain for which at least part of the side-chain coordinates are |missing from the PDB file. OnlyCa: |The only-Ca field contains the number of amino acids in the |chain |for which only the alpha-carbon coordinates are given. Unk: |The UNK field contains the number of amino acids in the chain |for which the amino acid type is unknown. Cyss: |The CYSS field contains the number of Cysteine |residues in the chain that are involved in Cysteine bridges. Break: |The Break field contains the number of chain |breaks in the chain. A chain break is counted whenever two |successive C-alpha atoms have a distance larger than 4.5 Angstrom. NuclAcids: |The Nucl-Acids field contains the number of nucleic acid |residues in the chain. Substrate: |The Substrate field contains the number of substrate atoms in |the chain. NwaterMols: |The Water-Mols field contains the number of water molecules in |the chain. Sequence: |The Sequence field contains the nucleic acid or protein |sequence derived from the PDB file. | | } } Acids: |The Nsrs/icarus/db/pir.i # # $RCSfile: pir.i,v $ # $Revision: 1.4 $ # $Date: 1997/03/17 23:21:06 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PIR_DB:$library:[PIR group:@SEQUENCE_LIBS subentries:@PirFeatures_DB format:@PIR_FORMAT maxNameLen:20 files:{ $file:pir1 $file:pir2 $file:pir3 $file:pir4 } ] PIR_FORMAT:$libformat:[fileType:{@PIRREF_FILE @PIRSEQ_FILE} contains:@PROTSEQ_DATA syntax:@PIR_SYNTAX tableFormat:left fields:{ $field:@DF_ALL $field:[@DF_ID code:id index:id indexToken:id] $field:[@DF_Accession code:acc index:str indexToken:acc] $field:[@DF_Description code:des index:str indexToken:des tableToken:'clFields|des'] $field:[@DF_Keywords code:key index:str indexToken:key] $field:[@DF_SuperFamily code:sfam index:str indexToken:sfam] $field:[@DF_MoleculeType code:moltyp index:str indexToken:moltyp] $field:[@DF_Date code:date index:int indexToken:date tableToken:t_date] $field:[@DF_Organism code:spec index:str indexToken:spec] $field:[@DF_Authors code:aut index:str indexToken:aut] $field:[@DF_Title code:ttl index:str indexToken:ttl tableToken:'clFields|ttl'] # $field:[@DF_SeqLength token:sequence index:int indexToken:seqlen] $field:[@DF_FtKey index:str indexToken:ftKey code:ft indexId:@SUBENTRY_ID] $field:[@DF_FtDescription index:str indexToken:ftDes code:ft indexId:@SUBENTRY_ID] $field:[@DF_FtLength index:int indexToken:ftLen code:ft indexId:@SUBENTRY_ID] $field:[@DF_ProtSequence token:sequence format:pir] } ] PIR_SYNTAX:$syntax:[file:"SRSDB:pir.is" ignore:" \t"] DF_SuperFamily:$srsfield:[SuperFamily short:sfa group:@DF_ALL] DF_MoleculeType:$srsfield:[MoleculeType short:mot group:@DF_ALL] PirFeatures_DB:$library:[PIR_features format:@PirFeature_Format ] PirFeature_Format:$libformat:[syntax:@PIR_SYNTAX contains:@PROTSEQ_DATA tableFormat:left fields:{ $field:[@DF_ID token:ftId] $field:[@DF_FtKey token:ft tableToken:'t_ft|key'] $field:[@DF_FtLength token:ft tableToken:'t_ft|len'] $field:[@DF_FtDescription token:ft tableToken:'t_ft|des'] $field:[@DF_FtLocation token:ft tableToken:'t_ft|loc' tableFormat:listing] } ] ld:[MoleculeType short:mot group:@DF_ALL] PirFeatures_DB:$library:[PIR_features format:@PirFeature_Format ] PirFeature_Format:$libformat:[syntax:@PIR_SYNTAX contains:@PROTSEQ_DATA tableFormat:left fields:{ srs/icarus/db/pir.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: pir.is,v $ # $Revision: 1.4 $ # $Date: 1997/03/17 23:21:06 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $fn={ 'C;Species:': spec 'C;Date:': date 'C;Accession:': acc 'A;Status:': status 'A;Description:': des 'A;Title:': ttl 'A;Reference number:': refn 'A;Contents:': cont 'A;Authors:': aut 'A;Variety:': var 'A;Accession:': acc 'A;Molecule type:': moltyp 'A;Residues:': res 'A;Mobile element:': mobel 'A;Cross-references:': link 'A;Introns:': intron 'A;Note:': note 'A;Gene:': gene 'A;Genome:': genome 'A;Pathway:': pathway 'A;Genetic code:': genecode 'A;Experimental source:': exp 'A;Start codon:': start 'A;Map position:': map 'A;Genetics:': genet 'R;': aut 'C;Genetics:': genet 'C;Superfamily:': sfam 'C;Keywords:': key 'C;Comment:': comment 'C;Complex:': complex 'C;Function:': fun 'F;': ft 'N;Alternate names:': alt 'N;Contains:': cont } $rules={ entry: ~ {$In:[file:text] $Out pre $Skip:0} ('>' {$not} ln)* (/>[^;]+;([A-Z0-9]+)/ {$entryFip=$Fip $Wrt $entryName=$1} ln{$App} ('>' {$Not} ln {$App})+ )? ~ sequence: ~ {$In:[file:seq] $Out $SeqMake:$s} ('>' {$Not} ln)* />[^;]+;([^ \n]+)/ {$s=$SeqNew:$1 $Wrt:[s:$1]} ln {pre $seqFip=$Fip} ln ('>' {$Not} ln {$SeqApp:[$s s:$Ct]})* ~ # extracting data fields fields: ~ {$In:entry $Out $Skip:1} ln {$Wrt:id} ln {$Wrt:des} (/[ACRFN];([a-zA-Z -]+:)?/ {$Wrt:$fn.$Ct if:$fn.$Ct=="" $dp:"+++ unknown: $Ct in $entryName +++"} ln {$App} | ln {$App})+ ~ # for indexing tag: ~ /[ACRFN];([a-zA-Z -]+:)?/ ~ id: ~ {$In:entry $Out} />[^;]+;([A-Z0-9]+)/ {$Wrt:[s:$1]} ~ aut: ~ {$In:[fields c:aut] $Out} 'R;' (author {$Uniq:[s:$author]} ';'?)+ ~ author: ~ /([^,\n]+,) *([^;\n]+)/ {$author="$1$2"} ~ acc: ~ {$In:[fields c:acc] $Out} tag (/[A-Z0-9]+/ {$Uniq} ';'?)* ~ sfam: ~ {$In:[fields c:sfam] $Out} tag (/[^\n;]+/ {$Wrt:[s:$Trim:$Ct]} ';'?)* ~ moltyp: ~ {$In:[fields c:moltyp] $Out} tag (/[^\n;]+/ {$Uniq:[s:$Trim:$Ct]} ';'?)* ~ key: ~ {$In:[fields c:key] $Out} tag (/[^\n;]+/ {$Wrt:[s:$Trim:$Ct]} ';'?)* ~ ttl: ~ {$In:[fields c:ttl] $Out} tag (/[a-zA-Z0-9]+/ {$Uniq} | /./)* ~ des: ~ {$In:[fields c:des] $Out} tag? (/[a-zA-Z0-9]+/ {$Uniq} | /./)* ~ date: ~ {$In:[fields c:date] $Out init $month={Jan:1 Feb:2 Mar:3 Apr:4 May:5 Jun:6 Jul:7 Aug:8 Sep:9 Oct:10 Nov:11 Dec:12}} tag /([0-9]+)-([a-zA-Z]+)-([0-9]+)/? {$Wrt:[s:($month.$2*100 + $1 + $3*10000)]} ~ spec: ~ {$In:[fields c:spec] $Out} tag /[^(]+/ {$Wrt:[s:$Trim:$Ct]} ('('/[^)]+/ {$Wrt} ')')? ~ # indexing features ft: ~ {$In:[fields c:ft] $Out} 'F;'{$r={}} (/[^,\/]+/ {$r+=$Ct} ','?)+ ln {foreach:[$e in:$r] {$Wrt:[ft s:"F;$e$Ct"]}} ~ ftKey: ~ {$In:[ft count:ft var:$ftN] $Out} /[^\/]+\/([^:]+):/ {$Wrt:[n:$ftN s:$1]} ~ ftDes: ~ {$In:[ft count:ft var:$ftN] $Out} /[^:]+:/ (/[A-Za-z0-9_]+/ {$Uniq:[n:$ftN]} | /./)* ~ ftLen: ~ {$In:[ft c:ft count:ft var:$ftN] $Out} 'F;' /([0-9]+)(-([0-9]+))?/ {if:$3=="" $Wrt:[n:$ftN s:1] else $Wrt:[n:$ftN s:($3-$1+1)]} ~ # display features ftId: ~ {$In:[fields c:id] $Out} /(>[^;]+;)([A-Z0-9]+)/ {$Wrt:[s:"$1$2\_$subEntryN; parent: $2"]} ~ ftLine: ~ {$In:[ft c:ft count:ft var:$ftN select:$subEntryN] $Out} /.*/ {$Wrt} ~ t_ft: ~ {$In:ftLine $Out $Skip:1} 'F;' /([^\/]+)/ {$Wrt:[range s:$1]} /\/([^:]+):/ {$Wrt:[n:$ftN s:$1]} /.*/ {$Wrt:des} ~ h_ftId: ~ {$In:[ftId t:html]} /.*parent: */ /[A-Z0-9_]+/ {$Rep:{$ParStr:pirR $Ct $Ct}} ~ # table display clFields: ~ {$In:[fields c:{ttl des}] $Out} tag? ln {$Wrt:$Itc} ~ t_date: ~ {$In:[fields c:date] $Out} tag /[0-9a-zA-Z-]+/? {$Wrt} ~ # printing in HTML format h_ref: ~ {$In:[fields c:refn t:html]} /.*MUID:/ num {$Rep:{$ParStr:medlineR $Ct $Ct}} ~ h_des: ~ {$In:[fields c:des t:html]} /.*\\(EC/ /[0-9.-]+/ {$Rep:{$ParStr:enzymeR $Ct $Ct}} ~ h_link: ~ {$In:[fields c:link t:html] init $l={GB:genbankR EMBL:emblR NCBIN:genbankR GDB:gdbR}} /.*nces:/ /[A-Za-z]+/ {$db=$Ct}':' /[^ \n]+/ {$Rep:{$ParStr:$l.$db $Ct $Ct}} ~ # other stuff num: ~ /[0-9]+/ ~ ln: ~ /[^\n]*\n/ ~ } # debugging $subEntryN=3 if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/pir/pir1.ref'] while:$JobHasInput:$job { $JobTokens:[$job name:fields print:1] $JobNext:$job $print:"-------->entry\n" } } ~ {$In:[fields c:link t:html] init $l={GB:genbankR EMBL:emblR NCBIN:genbankR GDB:gdbR}} /.*nces:/ /[A-Za-z]+/ {$db=$Ct}':' srs/icarus/db/pmd.is # # pmd.is # # Ramu C # $rules={ entry: ~ {init{$count=0} $out:entry $count=$count+1} ('ENTRY' {$not} ln)* ('ENTRY ' {pre {$entryFip = $fip} $wrt} ln {$app} ('///' {$not} ln {$app})* '///' {$app $fip:on})* ~ # fields fields: ~ {$in:entry $out} f_entry f_authors f_journal f_title f_crosref f_protein f_source f_nterm f_expsys(f_change | f_function | f_structure | f_stability | f_expr | f_trans | f_mut | f_var | f_cmnt) ~ f_ac: ~ {$wrt:ac} 'AC ' ln ~ f_dt: ~ {$wrt:dt} ('DT ' ln)* ~ f_so: ~ {$wrt:so} ('SO ' ln)* ~ f_os: ~ {$wrt:os} ('OS ' ln)* ~ f_cd: ~ {$wrt:cd} ('CD ' ln)* ~ f_xx: ~ ('XX' ln)? ~ # indexing ac: ~ {$in:[fields c:ac] $out:ac} 'AC' /[0-9A-Za-z]+/ {$wrt} ~ dt: ~ {$in:[fields c:dt] $out:dt} 'DT' /([0-9]+).([0-9]+).([0-9]+)/ {$wrt:[s:($1+$2*100+"19$3"*10000)]} ~ so: ~ {$in:[fields c:so] $out:so} 'SO' (sep | word {$wrt})* ~ os: ~ {$in:[fields c:os] $out:os} 'OS' (sep | word {$wrt})* ~ oc: ~ {$in:[fields c:cd] $out:cd} 'CD' (sep | word {$wrt})* ~ # extra ... ln: ~ /[^\n]*\n/ ~ word: ~ /[a-zA-Z0-9_]+/ ~ sep: ~ /[^a-zA-Z0-9_]+/ ~ } #$fil = $fileOpen:"/data/pmd/pmd.dat" #$job = $jobNew:[prod:$rules skip:" "] #$jobNext:[$job file:$fil] #for:{1 $jobTokens:[$job name:dt print:1 ] 1} { # $jobEnd:$job # $jobNext:[$job file:$fil] #} #$jobEnd:$job {$in:[fields c:so] $out:so} 'SO' (sep | word {$wrt})* ~ os: ~ {$in:[fields c:os] $out:os} 'OS' (sep | word {$wrt})* ~ oc: ~ {$in:[fields c:cd] $out:cd} 'CD' (sep | word {$wrt})* ~ # extra ... ln: ~ /[^\n]*\n/ ~ word: ~ /[a-zA-Z0-9_]+/ ~ sep: ~ /[^a-zA-Z0-9_]+/ ~ } #$fil = $fileOpen:"/data/pmd/pmd.dat" #$job = $jobNew:[prod:$rules skip:" "] #$jobNext:[$job file:$fil] #for:{1 $jobTokens:[$job name:dt print:1 ] 1} { # $jobEnd:$job # $jobNext:[$job file:$fil] #} #$jobEnd:$job srs/icarus/db/primers.i # The PCR Primers Database - 19 Jan 1996. # # Last modified - 14 Feb 1996. # # Author: Benny Shomer (bshomer@ebi.ac.uk) # # # # Many thanks to Jack Leunissen from CAOS/CAMM Center in the # # Netherlands for introducing independently a first working version # # and for introducing many important corrections into this file. # # # # Conversion to Icarus language by Thure Etzold # # # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# PRIMERS_DB:$library:[PRIMERS group:@MISC_LIBS format:@PRIMERS_FORMAT ifiles:{"primers.i" "primers.is"} files:{ $file:primers } ] PRIMERS_FORMAT:$libformat:[syntax:@PRIMERS_SYNTAX fileType:@PRIMERS_FILE fields:{ $field:[@DF_ID code:id indexToken:id index:str] $field:[@DF_Date code:date indexToken:date index:int] $field:[@DF_TARGET code:target index:str indexToken:target] $field:[@DF_NUMREF code:numref index:str indexToken:numref] $field:[@DF_Organism code:ospecs index:str indexToken:ospecs] $field:[@DF_SPAPLL code:spapll index:str indexToken:spapll] $field:[@DF_PNAME code:pname index:str indexToken:pname] $field:[@DF_PSEQN code:pseqn index:str indexToken:pseqn] $field:[@DF_RESTR code:restr index:str indexToken:restr] $field:[@DF_MUTAT code:mutat index:str indexToken:mutat] $field:[@DF_POLYMR code:polymr index:str indexToken:polymr] $field:[@DF_ADITIV code:aditiv index:str indexToken:aditiv] $field:[@DF_SOURCE code:source index:str indexToken:source] $field:[@DF_LINK code:{dbxref refxrf}] $field:[@DF_CONTRIBUTOR code:contrib index:str indexToken:contrib] $field:[@DF_Authors code:refaut index:str indexToken:refaut] $field:[@DF_REFTTL code:refttl index:str indexToken:refttl] $field:[@DF_REF code:refsrc index:str indexToken:refsrc] $field:[@DF_COMMENT code:comment index:str indexToken:comment] $field:[@DF_LINK code:link index:str indexToken:links] } ] #data field types DF_ATARGET:$srsfield:[Target short:TRG group:@DF_ALL] DF_NUMREF:$srsfield:[Number_ref short:NRF group:@DF_ALL] DF_SPAPLL:$srsfield:[Application short:APP group:@DF_ALL] DF_PNAME:$srsfield:[Primer_Name short:PNM group:@DF_ALL] DF_PSEQN:$srsfield:[Primer_Sequence short:PSQ group:@DF_ALL] DF_RESTR:$srsfield:[Restrict_Site short:RST group:@DF_ALL] DF_MUTAT:$srsfield:[Mutation short:MUT group:@DF_ALL] DF_POLYMR:$srsfield:[Polymerase short:POL group:@DF_ALL] DF_ADITIV:$srsfield:[Additive short:ADD group:@DF_ALL] DF_PSOURCE:$srsfield:[DNA_Source short:SRC group:@DF_ALL] DF_CONTRIBUTOR:$srsfield:[Contributor short:CNT group:@DF_ALL] DF_TARGET:$srsfield:[TargetSequence short:tsq group:@DF_ALL] DF_REFTTL:$srsfield:[ReferenceTitle short:rtl group:@DF_ALL] DF_SOURCE:$srsfield:[Source short:src group:@DF_ALL] #links to other databanks $link:[@PRIMERS_DB to:@?EMBL_DB token:'link:embl' toField:@DF_ID] $link:[@PRIMERS_DB to:@?EMNEW_DB token:'link:emnew' toField:@DF_ID] $link:[@PRIMERS_DB to:@?SWISSPROT_DB token:'link:swissprot' toField:@DF_ID] $link:[@PRIMERS_DB to:@?SWISSNEW_DB token:'link:swissnew' toField:@DF_ID] $link:[@PRIMERS_DB to:@?MEDLINE_DB token:'link:medline' toField:@DF_ID] $link:[@PRIMERS_DB to:@?IMGT_DB token:'link:imgt' toField:@DF_ACCNO] $link:[@PRIMERS_DB to:@?TFSITE_DB token:'link:tfsite' toField:@DF_ID] $link:[@PRIMERS_DB to:@?PIR_DB token:'link:pir' toField:@DF_ID] PRIMERS_SYNTAX:$syntax:[file:"SRSDB:primers.is" ignore:" "] PRIMERS_FILE:$filetype:[typeName:dat maxline:200] ISSPROT_DB token:'link:swissprot' toField:@DF_ID] $link:[@PRIMERS_DB to:@?SWISSNEW_DB token:'link:swissnew' toField:@DF_ID] $link:[@PRIMERS_DB to:@?MEDLINE_DB token:'link:medline' toField:@DF_ID]srs/icarus/db/primers.is $rules={ # the entry # the data fields fields: ~ id s date s target s (numref)? ospecs s spapll lncdna s lngnda (pname s pseqn s (restr s)? (mutat s)? flank s restr)* tcycle s probin s hotstr s idenat s denatr s anneal s tchdwn extend s prgrss s finext s cycles s rxnvol s polymr s buffer dntpcn s primcn s mgconc s aditiv s source s dbxref s cntnam contrib s refaut s refttl refxrf s remark ~ id: ~ {$wrt:id} 'ACCESS' ln ~ s: ~ {$wrt:s} ('XXXXXX' ln)* ~ # line spacer date: ~ {$wrt:} 'DATEIN' ln ~ target: ~ {$wrt:target} 'TARGET' ln ~ numref: ~ {$wrt:numref} 'NUMREF' ln ~ ospecs: ~ {$wrt:ospecs} 'OSPECS' ln ~ spapll: ~ {$wrt:spapll} 'SPAPPL' ln ~ lncdna: ~ {$wrt:lncdna} 'LNCDNA' ln ~ lngdna: ~ {$wrt:lngdna} 'LNGNDA' ln ~ pname: ~ {$wrt:pname} /FPNAME|RPNAME/ ln ~ pseqn: ~ {$wrt:pseqn} /FPSEQN|RPSEQN/ ln ~ flank: ~ {$wrt:flank} /FFLANK|RFLANK/ ln ~ restr: ~ {$wrt:restr} /FRESTR|RRESTR/ ln ~ mutat: ~ {$wrt:mutat} /FMUTAT|RMUTAT/ ln ~ tcycle: ~ {$wrt:tcycle} 'TCYCLE' ln ~ probin: ~ {$wrt:probin} 'PROBIN' ln ~ hotstr: ~ {$wrt:hotstr} 'HOTSTR' ln ~ idenat: ~ {$wrt:idenat} 'IDENAT' ln ~ denatr: ~ {$wrt:denatr} 'DENATR' ln ~ anneal: ~ {$wrt:anneal} 'ANNEAL' ln ~ tchdwn: ~ {$wrt:tchdwn} 'TCHDWN' ln ~ extend: ~ {$wrt:extend} 'EXTEND' ln ~ prgrss: ~ {$wrt:prgrss} 'PRGRSS' ln ~ finext: ~ {$wrt:finext} 'FINEXT' ln ~ cycles: ~ {$wrt:cycles} 'CYCLES' ln ~ rxnvol: ~ {$wrt:rxnvol} 'RXNVOL' ln ~ polymr: ~ {$wrt:polymr} 'POLYMR' ln ~ aditiv: ~ {$wrt:aditiv} 'ADITIV' ln ~ source: ~ {$wrt:source} 'SOURCE' ln ~ contrib: ~ {$wrt:contrib}/CNTNAM|CNTINS|CNTADR|CNTEML|CNTTEL|CNTFAX/ ln ~ refaut: ~ {$wrt:refaut} ('REFAUT' ln)+ ~ refttl: ~ {$wrt:refttl} 'REFTTL' ln ~ refsrc: ~ {$wrt:refsrc} 'REFSRC' ln ~ remark: ~ {$wrt:remark} ('REMARK' ln)+ ~ # indexing i_id: ~ {$in:[fields c:id] $out:id} tag name {$wrt} ~ i_target: ~ {$in:[fields c:target] $out:id} (tag (word {$wrt} sep)* ln)* ~ i_remark: ~ {$in:[fields c:remark] $out:id} (tag (word {$wrt} sep)* ln)* ~ i_link: ~ (tag refdb ':' (name {$wrt:$c} ';')* ln)* ~ # display HTML h_link: ~ {$in:[fields c:dbxref] $out:link} (tag refdb ':' (name {$rep:$parStr:{"$db_hl" $ct $ct}} ';')* ln)* ~ # other stuff refdb: ~ 'EMBL/GENBANK/DDBJ' {$db=embl $c=$embl} | 'MEDLINE' {$db=medline $c=$medline} | 'IMGT/LIGM' {$db=imgt $c=$imgt} | 'SWISS-PROT' {$db=swissprot $c=$swissprot} | 'TRANSFAC' {$db=transfac $c=$transfac} | 'PIR' {$db=pir $c=pir} ~ ln: ~ /[^\n]\n/ ~ word: ~ /[a-zA-Z0-9_]+/ ~ sep: ~ /[^a-zA-Z0-9_]+/ ~ name: ~ /[a-zA-Z][a-zA-Z0-9_]*/ ~ tag: ~ /....../ ~ } db: ~ 'EMBL/GENBANK/DDBJ' {$db=embl $c=$embl} | 'MEDLINE' {$db=medline $c=$medline} | 'IMGT/LIGM' {$db=imgt $c=$imgt} | 'SWISS-PROT' {$db=swissprot $c=$swissprot} | 'TRANSFAC' {$db=transfac $c=$transfac} | 'PIR' {$db=pir $c=pir} ~ ln: ~srs/icarus/db/prints.i # Description: icarus/srs structure description for PRINTS # Author: Martin Hilbers # Date: 3-9-1996 # Note: # PRINTS_DB:$library:[PRINTS group:@SEQRELATED_LIBS comment:"PRINTS PROTEIN MOTIF FINGERPRINT DATABASE" format:@PRINTS_FORMAT maxNameLen:30 ifiles:{"prints.i" "prints.is"} files:{ $file:prints5_0 } ] PRINTS_FORMAT:$libformat:[fileType:@DAT_FILE syntax:@PRINTS_SYNTAX fields:{ $field:[@DF_ALL] $field:[@DF_ID code:id index:id indexToken:id] $field:[@DF_Accession code:acc index:str indexToken:acc] $field:[@DF_Description code:def index:str indexToken:def] $field:[@DF_LINK code:link indexToken:link] $field:[@DF_Date code:date index:int indexToken:date] $field:[@DF_COMMENT code:cc index:str indexToken:cc] $field:[@DF_Authors code:refaut index:str indexToken:refaut] $field:[@DF_Title code:reftit index:str indexToken:reftit] $field:[@DF_Citation code:journal index:str indexToken:journal] } ] PRINTS_SYNTAX:$syntax:[file:"SRSDB:prints.is" ignore:" "] $link:[@PRINTS_DB to:@?OWL_DB token:'link|owl' toField:@DF_ID] $link:[@PRINTS_DB to:@?PDB_DB token:'link|pdb' toField:@DF_ID] $link:[@PRINTS_DB to:@?PROSITE_DB token:'link|prosite' toField:@DF_Accession] $link:[@PRINTS_DB to:@?BLOCKS_DB token:'link|blocks' toField:@DF_Shortaccession] # # PRODOM links in PRINTS 12 are not correct for PRODOM 33 #$link:[@PRINTS_DB to:@?PRODOM_DB token:'link|prodom' toField:@DF_ID] # $link:[@PRINTS_DB to:@?SBASE_DB token:'link|sbase' toField:@DF_ID] $link:[@PRINTS_DB to:@?GCRDB_DB token:'link|gcrdb' toField:@DF_ID] $link:[@PRINTS_DB to:@?NRL_DB token:'link|nrl' toField:@DF_ID] $link:[@PRINTS_DB to:@PRINTS_DB token:'link|prints' toName:PRINTS_IN toField:@DF_Accession] $href:[swissIR link:"%s"] $href:[owlR link:"%s"] $href:[printsR link:"%s"] $href:[blocksR link:"%s"] $href:[prodomR link:"%s"] $href:[sbaseR link:"%s"] $href:[nrlR link:"%s"] $href:[enzymeR link:"%s"] $href:[scopR link:"%s"] $href:[swiss3DR link:"%s"] sR link:"' {$Not} ln)* '>' {$entryFip=$fip $Wrt} ln {$App} ('>' {$Not} ln {$App})* ~ # fields fields: ~ {$In:entry $Out} f_des f_ali* ~ f_des: ~ {$Wrt:idln} '>' ln ~ f_ali: ~ {$Wrt:link} ln ~ # indexing i_des: ~ {$In:[fields c:idln] $Out} '>' /[0-9]+/ {$Wrt:id} /[p0-9]+/ '('/[0-9]+/ {$Wrt:seqs} ')' ((/[A-Z0-9_]+/ {$Wrt:des}) (/[()0-9]+/)? )* '//' ( /[A-Za-z0-9_]+/{$Wrt:des} | /[^A-Za-z0-9_]+/ )* ~ id: ~ {$In:[i_des c:id] $Out} /.+/ {$Wrt} ~ des: ~ {$In:[i_des c:des] $Out} /.+/ {$Wrt} ~ seqs: ~ {$In:[i_des c:seqs] $Out} /.+/ {$Wrt} ~ links: ~ {$In:[fields c:link] $Out} name {$Wrt:swiss} ~ # html display hl_links: ~ {$In:[fields c:link t:hl]} (name {$Rep:{$ParStr:swissIR $Ct $Ct}} ln)* ~ # other name: ~ /[a-zA-Z0-9_]+/ ~ ln: ~ /[^\n]*\n/ ~ } ( /[A-Za-z0-9_]+/{$Wrt:des} | /[^A-Za-z0-9_]+/ )* ~ id: ~ {$In:[i_des c:id] $Out} /.+/ {$Wrt} ~ des: ~ {$In:[i_des c:des] $Out} /.+/ {$Wrt} ~ seqs: ~ {$In:[i_des c:seqs] $Out} /.+/ {$Wrt} ~ links: ~ {$In:[fields c:link] $Out} name {$Wrt:swiss} ~ # html display hl_linsrs/icarus/db/prosite.i # $RCSfile: prosite.i,v $ # $Revision: 1.9 $ # $Date: 1997/03/03 18:34:13 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PROSITE_DB:$library:[PROSITE group:@SEQRELATED_LIBS comment:"A Dictionary of Protein Sites and Patterns - A. Bairoch" format:@PROSITE_FORMAT maxNameLen:30 ifiles:{"prosite.i" "prosite.is"} files:{ $file:prosite } ] PROSITE_FORMAT:$libformat:[fileType:@DAT_FILE syntax:@PROSITE_SYNTAX fields:{ $field:[@DF_ID code:id index:id indexToken:id] $field:[@DF_PATTERN code:patt tableToken:t_patt tableFormat:left] $field:[@DF_Accession code:acc index:str indexToken:acc tableToken:acc tableFormat:left] $field:[@DF_Description code:def index:str indexToken:def tableToken:t_descr tableFormat:left] $field:[@DF_LINK code:link] $field:[@DF_Date code:date index:int indexToken:date tableToken:t_date tableFormat:center] # $field:[@DF_TaxoRange index:str indexToken:taxrange] # $field:[@DF_MaxRepeat index:int indexToken:maxrep] # $field:[@DF_Site index:str indexToken:site] # $field:[@DF_SkipFlag index:str indexToken:skipflag] $field:[@DF_ALLPOS code:rule index:int indexToken:allpos tableToken:allpos tableFormat:right] } ] PROSITE_SYNTAX:$syntax:[file:"SRSDB:prosite.is" ignore:" "] DF_PATTERN:$srsfield:[Patterns short:pat] DF_ALLPOS:$srsfield:[AllPositive short:alp] DF_TaxoRange:$srsfield:[TaxoRange short:tax] DF_MaxRepeat:$srsfield:[MaxRepeat short:max] DF_SkipFlag:$srsfield:[SkipFlag short:skf] DF_Site:$srsfield:[Site short:sit] $link:[@PROSITE_DB to:@?SWISSPROT_DB token:'link|swiss' toField:@DF_Accession] $link:[@PROSITE_DB to:@?PDB_DB token:'link|pdb' toField:@DF_ID] $link:[@PROSITE_DB to:@?PROSITEDOC_DB token:'link|pd' toField:@DF_ID] ile:"SRSDB:prosite.is" ignore:" "] DF_PATTERN:$srsfield:[Patterns short:pat] DF_ALLPOS:$srsfield:[AllPositive short:alp] DF_TaxoRange:$srsfiesrs/icarus/db/prosite.is $rules={ entry: ~ { $In:[file:text] $Out:entry} ('ID' {$Not} ln)* ('ID ' {$entryFip=$Fip $Wrt} ln {$App} ('ID' {$Not} ln {$App})*)? ~ # fields fields: ~ {$In:entry $Out} f_id f_acc f_date f_def (f_mat)? f_patt f_rule f_cc f_links ~ f_id: ~ {$Wrt:id} 'ID ' ln ~ f_acc: ~ {$Wrt:acc} ('AC ' ln)* ~ f_date: ~ {$Wrt:date} ('DT ' ln)* ~ f_def: ~ {$Wrt:def} ('DE ' ln)* ~ f_mat: ~ {$Wrt:mat} ('MA ' ln)* ~ f_patt: ~ {$Wrt:patt} ('PA ' ln)* ~ f_rule: ~ {$Wrt:rule} (/(NR|RU) / ln)* ~ f_cc: ~ {$Wrt:cc} ('CC ' ln)* ~ f_links: ~ {$Wrt:link} (/(DR|3D|DO) / ln)* ~ # indexing id: ~ {$In:[fields c:id] $Out:id} 'ID' /[A-Z0-9_]+/ {$Wrt} ~ acc: ~ {$In:[fields c:acc] $Out:acc} 'AC' /[A-Z0-9_]+/ {$Wrt} ~ def: ~ {$In:[fields c:def] $Out} ( 'DE' ( /[A-Za-z0-9_]+/ {$Wrt} | /[^A-Za-z0-9_]+/ )* )* ~ date: ~ {$In:[fields c:date] $Out} 'DT' datenum {$Wrt:[s:$date c:cre]} '(CREATED);' datenum {$Wrt:[s:$date c:dupd]} '(DATA UPDATE);' datenum {$Wrt:[s:$date c:iupd]} '(INFO UPDATE).' ~ allpos: ~ {$In:[fields c:rule] $Out} (/.*POSITIVE=([0-9]+)/ {$Wrt:[s:$1]})? ~ datenum: ~ {init {$month={JAN:1 FEB:2 MAR:3 APR:4 MAY:5 JUN:6 JUL:7 AUG:8 SEP:9 OCT:10 NOV:11 DEC:12}}} /([A-Z][A-Z][A-Z])-([0-9]+)/ {$date=$month.$1 * 100 + $2 * 10000} ~ link: ~ {$In:[fields c:link] $Out} (/DR/ (name {$Wrt:swiss} ',' name ',' /[A-Z?]/ ';')* ln)* (/3D/ (name {$Wrt:pdb} (';'|'.'))* ln)* /DO/ name {$Wrt:pd} ~ # table display t_date: ~ {$In:[fields c:date] $Out} /.* ([A-Z0-9-]+) *\\(CREATED/ {$Wrt:[s:$1]} ~ t_patt: ~ {$In:[fields c:patt] $Out} /../ ln {$Wrt} (/../ ln {$App})* ~ t_descr: ~ {$In:[fields c:def] $Out} /../ ln {$Wrt} ~ # html display hl_links:~ {$In:[fields c:link t:hl]} (/DR/(name {$Rep:{$ParStr:swissR $Ct $Ct}} ','name',' /[A-Z?]/ ';')* ln)* (/3D/ (name {$Rep:{$ParStr:pdbR $Ct $Ct}} (';'|'.') )* ln)* /DO/ name {$Rep:{$ParStr:prositedocR $Ct $Ct}} ~ # other name: ~ /[a-zA-Z0-9_]+/ ~ ln: ~ /[^\n]*\n/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/prosite/prosite.dat'] while:$JobHasInput:$job { $JobTokens:[$job name:id print:1] $JobTokens:[$job name:date print:1] $JobNext:$job $print:"-------->entry\n" } } [A-Z?]/ ';')* ln)* (/3D/ (name {$Rep:{$ParStr:pdbR $Ct $Ct}} (';'|'.') )* ln)* /DO/ name {$Rep:{$ParStr:prositedocR $Ct $Ct}} ~ # other name: ~ /[a-zA-Z0-9_]+/ ~ ln: ~ /[^\n]*\n/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/prosite/prosite.dat'] while:$JobHasInput:$job { $JobTokesrs/icarus/db/prosite.it # # $RCSfile: prosite.it,v $ # $Revision: 1.3 $ # $Date: 1996/10/10 16:47:08 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $dbInfo={ description: |The PROSITE data bank is composed of two ASCII (text) files. The first |file (PROSITE.DAT) is a computer readable file that contains all the |information necessary to programs that will scan sequence(s) with patterns |and/or matrices. The second file (PROSITE.DOC) contains textual |information that fully documents each pattern and profile. We must point |out that we strongly urge software developers to build software tools that |make use of both files. A list of patterns or profiles present in a |sequence is not very useful to biologists without the relevant |documentation. |

www: |\ |http://expasy.hcuge.ch/sprot/prosite.html literature: |Bairoch A., Bucher P., PROSITE: recent developments. |Nucleic Acids Res. 22:3583-3589(1994). fields:{ ID: |The ID (IDentification) line is always the first line of an |entry. The general form of the ID line is: |

|ID ENTRY_NAME; ENTRY_TYPE. |

|The first item on the ID line is the entry name. This name is a useful |means of identifying an entry. The entry name consists of from 2 to 21 |uppercase alphanumeric characters. The characters that are allowed in an |entry name are: A-Z, 0-9, and the underscore character "_". |

AccNumber: |The AC (ACcession number) line lists the accession number |associated with an entry. It is always the second line of an entry. |Accession numbers provide a stable way of identifying entries |from release to release. It is sometimes necessary for reasons of |consistency to change the names of the entries between releases.

|An accession number, however, never change. Accession numbers allow |unambiguous citation of database entries. Researchers who wish to cite |a PROSITE entry in their publications should always cite the accession |number of that entry in order to ensure that readers can find the |relevant data in a subsequent release.

The format of the AC line |is:

AC PSnnnnn;

Where `PS' stands for PROSITE and `nnnnn' is a |five digit number.

Patterns: |The PA (PAttern) lines contains the definition of a PROSITE |pattern. The patterns are described using the following conventions: |

    |
  • The standard IUPAC one-letter codes for the amino acids are used. |
  • The symbol `x' is used for a position where any amino acid is |accepted. |
  • Ambiguities are indicated by listing the acceptable amino acids for |a given position, between square parentheses `[ ]'. For example: [ALT] |stands for Ala or Leu or Thr. |
Matrix: |The MA (MAtrix) lines contain the definition of a PROSITE |profile (or matrix) entry. The exact format content of this line is |fully described in a specific document (PROFILE.TXT) which is part of |the PROSITE distribution files.

Rule: |The RU (RUle) lines contain the definition of a PROSITE rule |entry. The format of the RU line is:

|

|DE Rule_Description. |

|The rule is described in ordinary English and is free-format. |

Result: |The NR (Numerical Results) lines contain information relevant |to the results of the scan with a pattern on the complete SWISS-PROT |data bank. Comment: |The CC (Comments) lines contains various types of comments. The |format of the CC line is: |

|CC /QUALIFIER=data; /QUALIFIER=data; ....... |

|The qualifiers that are currently defined are: |

|/TAXO-RANGE Taxonomic range. |/MAX-REPEAT Maximum known number of repetitions of the pattern in a | single protein. |/SITE Indication of an `interesting' site in the pattern. |/SKIP-FLAG Indication of an entry that can be, in some cases, ignored | by a program (because it is too unspecific). |

Ref: | The DR (Data bank Reference) line(s) are used as pointers to | the SWISS- PROT entries that corresponds to the enzyme being described. | The format | of the DR line is: |

| DR AC_NB, ENTRY_NAME; AC_NB, ENTRY_NAME; AC_NB, ENTRY_NAME; |

| where: |

| - 'AC_NB' is the SWISS-PROT primary accession number of the entry to | which reference is being made. | - 'ENTRY_NAME' is the SWISS-PROT entry name. |

3D: |

|The 3D (3D-structure) line is used to list the code(s) of X-ray |crystallography Protein Data Bank (PDB) entries that contain structural |data corresponding the sequence region described in a PROSITE entry. The |format of the 3D line is: |

|3D name; [name2;...] |

Doc: |The DO (DOcumentation) line contains a pointer to the entry in |the PROSITE documentation file that describes the entry. The format of |the DO line is:

DO PDOCnnnnn;

Where `PDOC' stands for PROSITE |DOCumentation and `nnnnn' is a five digit number.

} date: |25 Jul 1996 signature: |Anatoly Ulyanov } ng the sequence region described in a PROSITE entry. The |format of the 3D line is: |

|3D name; [name2;...] |

Doc: |The DO (DOcumentation) line contains a pointer to the entry in |the PROSITE documentation file that describes the entry. The format of |the DO line is:

DO PDOCnnnnn;

Where `PDOC' stands for PROSIsrs/icarus/db/prositedoc.i # $RCSfile: prositedoc.i,v $ # $Revision: 1.4 $ # $Date: 1996/08/11 22:51:53 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PROSITEDOC_DB:$library:[PROSITEDOC group:@SEQRELATED_LIBS comment:"A Dictionary of Protein Sites and Patterns - A. Bairoch" format:@PROSITEDOC_FORMAT maxNameLen:10 ifiles:{"prositedoc.i" "prositedoc.is"} files:{ $file:prosite } ] PROSITEDOC_FORMAT:$libformat:[fileType:@PDOC_FILE syntax:@PROSITEDOC_SYNTAX fields:{ $field:[@DF_ID code:id index:id indexToken:id] $field:[@DF_Description code:des] $field:[@DF_Authors index:str code:litref indexToken:authors] $field:[@DF_LINK index:link code:proslink indexToken:links] } ] PROSITEDOC_SYNTAX:$syntax:[file:"SRSDB:prositedoc.is" ignore:" "] PDOC_FILE:$filetype:[typename:doc maxline:200] #$link:[@PROSITEDOC_DB to:@?PROSITE_DB token:'link' toField:@DF_Accession] ROSITEDOC_FORMAT:$libformat:[fileType:@PDOC_FILE syntax:@PROSITEDOC_SYNTAX fields:{ $field:[@DF_ID code:id index:id indexToken:id] $field:[@DF_Description code:des] $field:[@DF_Authors index:str code:litref indexToken:authors] $field:[@DF_LINK index:link code:proslink indexToken:links] } ] PROSITEDOC_SYNTAX:$syntax:[file:"SRSDB:prositedoc.is" ignore:" "] PDOC_FILE:$filetype:[typename:doc maxline:200] #$link:[@PROSITEDOC_DB to:@?PROSITE_DB token:'link' toField:@DF_Accessionsrs/icarus/db/prositedoc.is $rules={ entry: ~ {$In:[file:text] $Out pre{$Skip:0}} ('{PDOC' {$Not} ln)* ('{PDOC' {$entryFip=$Fip $Wrt} appLn ('{END' {$Not} appLn)* appLn)? ~ # fields fields: ~ {$In:entry $Out $Skip:1} f_id f_proslink f_title f_des (f_litref)* ~ f_id: ~ {$Wrt:id} '{PDOC' ln ~ f_proslink: ~ {$Wrt:proslink} ('{PS' ln)* ~ f_title: ~ {$Wrt:title} '{BEGIN}' ln ln ln ln ~ f_des: ~ {$Wrt:des} ('[' {$Not} ln)* ~ f_litref: ~ {$Wrt:litref} /\\[[0-9 ][0-9 ]\\] / ln (/(\\[|{END})/ {$Not} ln)* ~ # indexing id: ~ {$In:[fields c:id] $Out:id} '{' /[^}]+/ {$Wrt} ~ authors: ~ {$In:[fields c:litref] $Out} /[^a-zA-Z]+/ author (',' author)* ~ link: ~ {$In:[fields c:proslink] $Out} '{' name {$Wrt} ~ # html display hl_links: ~ {$In:[fields c:proslink t:hl]} ('{' /[^;]+/ {$Rep:{$parStr:prositeR $ct $ct}} ln)+ ~ h_des: ~ {$In:[fields c:des t:hl]} (/PDOC[0-9]+/ {$Rep:{$parStr:prositedocR $ct $ct}} | /(EC +)([0-9]\\.[0-9.]+)/{$Rep:{"$1($parStr:enzymeR)" $2 $2}} | /[a-zA-Z0-9]+/ | /[^a-zA-Z0-9]+/ )* ~ # other name: ~ /[a-zA-Z0-9_]+/ ~ ln: ~ /[^\n]*\n/ ~ appLn: ~ /[^\n]*\n/ {$App} ~ author: ~ /([^.,\n]+) +([^,;\n]+)/ {$Wrt:[s:"$1,$2"]} ~ } ('{' /[^;]+/ {$Rep:{$parStr:prositeR $ct $ct}} ln)+ ~ h_des: ~ {$Isrs/icarus/db/prositedoc.it # # $RCSfile: prositedoc.it,v $ # $Revision: 1.3 $ # $Date: 1996/10/10 16:47:09 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $dbInfo={ description: |The PROSITE data bank is composed of two ASCII (text) files. The first |file (PROSITE.DAT) is a computer readable file that contains all the |information necessary to programs that will scan sequence(s) with patterns |and/or matrices. The second file (PROSITE.DOC) contains textual |information that fully documents each pattern and profile. We must point |out that we strongly urge software developers to build software tools that |make use of both files. A list of patterns or profiles present in a |sequence is not very useful to biologists without the relevant |documentation. www: |\ |http://expasy.hcuge.ch/sprot/prosite.html">More on PROSITE literature: |Bairoch A., Bucher P., PROSITE: recent developments. |Nucleic Acids Res. 22:3583-3589(1994). date: |25 Jul 1996 signature: |Anatoly Ulyanov } software tools that |make use of both files. A list of patterns or profiles present in a |sequence is not very useful to biologists without the relevant |documentation. www: |$Ct } ~ h_up: ~ {$In:[fields c:up t:html]} tag /[^ \n]+/ {$Rep:{$ParStr:reptaxR $Ct $Ct}} ~ h_field: ~ {$In:[fields t:html]} tag {if:$ParInt:isTable $Rep:"" else $Rep:"

$Ct
" } ~ # others word: ~ /[a-zA-Z0-9]+/ ~ sep: ~ /[^a-zA-Z0-9]+/ ~ specName: ~ / *([^ ]+ +[^ \n\t]+)/ {$name=$1} ~ data: ~ ' ' ln | / *\n/ ~ ln: ~ /[^\n]*\n/ ~ tag: ~ /[^:]+:\n/ ~ } if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:"/opt/srs/data/reptilia/taxonomy.dat"] while:$JobHasInput:$job { $JobTokens:[$job name:id print:1] $JobTokens:[$job name:taxon print:1] $JobTokens:[$job name:up print:1] $JobNext:$job } } } ~ # others word: ~ /[a-zA-Z0-9]+/ ~ sep: ~ /[^a-zA-Z0-9]+/ ~ specName: ~ / *([^ ]+ +[^ \n\t]+)/ {$name=$1} ~ data: ~ ' ' ln | / *\n/ ~ ln: ~ /[^\n]*\n/ ~ tag: ~ /[^:]+:\n/ ~ } if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:"srs/icarus/db/reptilia.i # $RCSfile: reptilia.i,v $ # $Revision: 1.6 $ # $Date: 1997/03/03 18:34:14 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ REPTILIA_DB:$library:[REPTILIA group:@MISC_LIBS format:@REPTILIA_FORMAT maxNameLen:50 ifiles:{"reptilia.i" "reptilia.is"} files:{ $file:agamidae $file:amphisbaenia $file:atractaspididae $file:chamaeleonidae $file:colubridae $file:cordylidae $file:crocodylidae $file:dibamidae $file:diploglossa $file:elapidae $file:gekkonidae $file:henophidia $file:hydrophiidae $file:iguanidae $file:lacertidae $file:platynota $file:pygopodidae $file:scincidae $file:sphenodontidae $file:teiidae $file:testudines $file:typhlopoidea $file:viperidae $file:xantusiidae } ] REPTILIA_FORMAT:$libformat:[fileType:@REPTILIA_FILE syntax:@REPTILIA_SYNTAX tableFormat:left printFormat:topicList fields:{ $field:[@DF_Species code:spec index:id indexToken:id] $field:[@DF_Synonyms code:syn index:str indexToken:syn tableToken:'fields|syn'] $field:[@DF_Family code:fam index:str indexToken:fam tabletoken:'fields|fam'] $field:[@DF_Distribution code:distrib index:str indexToken:distrib tableToken:'fields|distrib'] $field:[@DF_Comment code:distrib tableToken:'fields|comment'] $field:[@DF_Reference code:reference index:str indexToken:ref tableToken:'fields|reference'] } ] REPTILIA_SYNTAX:$syntax:[file:"SRSDB:reptilia.is"] DF_Species:$srsfield:[Species short:spc] DF_Distribution:$srsfield:[Distribution short:dis] DF_Family:$srsfield:[Family short:fam] REPTILIA_FILE:$filetype:[typename:dat maxline:5000] $link:[@REPTILIA_DB to:@GENBANK_DB fromField:@DF_ID toField:@DF_Organism] $link:[@REPTILIA_DB to:@REPTAX_DB token:taxl fromField:@DF_ID toField:@DF_Taxon] ] $field:[@DF_Reference code:reference index:str indexToken:ref tableToken:'fields|reference'] } ] REPTILIA_SYNTAX:$syntax:[file:"SRSDB:reptilia.is"] DF_Species:$srsfield:[Species short:spc] DF_Distribution:$srsfield:[Distribution short:dis] DF_Family:$srsfield:[Family short:fam] REPTILIA_FILE:$filetype:[typename:dat maxline:5000] $link:[@REPTILIA_DB to:@GENBANK_DB fromField:@DF_ID toField:@DF_Organism] $link:[@REPTILIA_DB to:@srs/icarus/db/reptilia.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: reptilia.is,v $ # $Revision: 1.6 $ # $Date: 1997/03/03 18:34:15 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $rules={ entry: ~ {$In:[file:text] $Out pre $Skip:0} ('Species:'{$Not} ln)* (ln {pre{$entryFip=$Fip} $Wrt} ('Species:'{$Not} ln {$App})+)? ~ fields: ~ {$In:entry $Out} spec syn subSpec family distrib comment reference tail ~ spec: ~ {$Wrt:spec} 'Species:\n' data ~ syn: ~ {$Wrt:syn} 'Synonyms:\n' data* ~ subSpec: ~ {$Wrt:subspecies} 'Subspecies:\n' data* ~ family: ~ {$Wrt:fam} 'Family:\n' data* ~ distrib: ~ {$Wrt:distrib} 'Distribution:\n' data* ~ comment: ~ {$Wrt:comment} 'Comment:\n' data* ~ reference: ~ {$Wrt:reference} 'References:\n' data* ~ tail: ~ {$Wrt:tail} '//\n' ~ # indexing i_species: ~ {$In:[entry] $Out:id} tag specName {$Wrt:[s:$name]} ~ i_syn: ~ {$In:[fields c:syn] $Out:syn} tag (specName {$Uniq:[s:$name]} (/[ \t\n],[ \t\n]/ specName {$Uniq:[s:$name]})*)? ~ i_distrib: ~ {$In:[fields c:distrib] $Out:distrib} tag (word {$Uniq} | sep) * ~ fam: ~ {$In:[fields c:fam] $Out} tag (word {$Wrt} | /[: ]+/) * ~ i_ref: ~ {$In:[fields c:reference] $Out:ref} tag (word {$Uniq} | sep) * ~ taxl: ~ {$In:[fields c:spec] $Out} tag / */ word {$Wrt} ~ # html h_field: ~ {$In:[fields t:html]} tag {if:$ParInt:isTable $Rep:"" else $Rep:"
$Ct
" } ln* {$Rep:"$Ct
"}~ # others word: ~ /[a-zA-Z0-9]+/ ~ sep: ~ /[^a-zA-Z0-9]+/ ~ specName: ~ / *([^ ]+ +[^ \n\t]+)/ {$name=$1} ~ data: ~ ' ' ln | / *\n/ ~ ln: ~ /[^\n]*\n/ ~ tag: ~ /[^:]+:\n/ | ln ~ } if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:"/opt/srs/data/reptilia/reptilia.dat"] while:$JobHasInput:$job { $JobTokens:[$job name:syn print:1] $JobNext:$job } } else $Rep:"
$Ct
" } ln* {$Rep:"$Ct
"}~ # others word: ~ /[a-zA-Z0-9]+/ ~ sep: ~ /[^a-zA-Z0-9]+/ ~ specName: ~ / *([^ ]+ +[^ \n\t]+)/ {$name=$1} ~ data: ~ ' ' ln | / *\n/ ~ ln: ~ /[^\n]*\n/ ~ tag: ~ /[srs/icarus/db/sptrembl.i # # $RCSfile: sptrembl.i,v $ # $Revision: 1.2 $ # $Date: 1996/12/06 16:38:08 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SPTREMBL_DB:$library:[SPTREMBL group:@SEQUENCE_LIBS subentries:@SptremblFeatures_DB format:@SPTREMBL_FORMAT maxNameLen:14 files:{ $file:fun $file:hum $file:inv $file:mam $file:mhc $file:org $file:phg $file:pln $file:pro $file:rod $file:vrl $file:vrt } ] REMTREMBL_DB:$library:[REMTREMBL group:@SEQUENCE_LIBS format:@?SPTREMBL_FORMAT maxNameLen:14 files:{ $file:immuno $file:patent $file:pseudo $file:smalls } ] SPTREMBL_FORMAT:$libformat:[fileType:{@DAT_FILE @SEQ_FILE} syntax:@SPTREMBL_SYNTAX tableFormat:left fields:{ $field:[@DF_ID code:id index:id indexToken:id] $field:@DF_ALL $field:[@DF_Accession code:acc index:str indexToken:acc] $field:[@DF_Description code:des index:str indexToken:des tableToken:'clFields|des'] $field:[@DF_GeneName code:gene index:str indexToken:gene] $field:[@DF_Date code:date index:int indexToken:date] $field:[@DF_Organism code:{org tax} index:str indexToken:org] $field:[@DF_Organelle code:organ index:str indexToken:organ] $field:[@DF_Authors code:refaut index:str indexToken:authors] $field:[@DF_LINK index:link code:link indexToken:link] $field:[@DF_SeqLength index:int indexToken:seqlen code:seqln] $field:[@DF_MolWeight index:int indexToken:molweight code:seqln] $field:[@DF_CommentType index:str indexToken:'cc|ttl' code:cc] $field:[@DF_Comment index:str indexToken:'cc|word' code:cc tableToken:'clFields|cc'] $field:[@DF_FtKey index:str indexToken:ftKey code:ft indexId:@SUBENTRY_ID] $field:[@DF_FtDescription index:str indexToken:ftDes code:ft indexId:@SUBENTRY_ID] $field:[@DF_FtLength index:int indexToken:ftLen code:ft indexId:@SUBENTRY_ID] $field:[@DF_ProtSequence token:'sequence' format:swiss] } ] SPTREMBL_SYNTAX:$syntax:[file:"SRSDB:swissprot.is" ignore:" \t"] REMTREMBL_SYNTAX:$syntax:[file:"SRSDB:swissprot.is" ignore:" \t"] $link:[@SPTREMBL_DB to:@?GENBANK_DB token: 'link|EMBL' toField:@DF_Accession] $link:[@SPTREMBL_DB to:@?EMBL_DB token:'link|EMBL' toField:@DF_Accession] $link:[@SPTREMBL_DB to:@?PIR_DB token:'link|PIR' toField:@DF_Accession] $link:[@SPTREMBL_DB to:@?PDB_DB token:'link|PDB'toField:@DF_ID] $link:[@SPTREMBL_DB to:@?REBASE_DB toField:@DF_ID] $link:[@SPTREMBL_DB to:@?OMIM_DB token:'link|MIM' toField:@DF_ID] $link:[@SPTREMBL_DB to:@?MEDLINE_DB toField:@DF_ID] $link:[@SPTREMBL_DB to:@?ENZYME_DB fromField:@DF_Description toField:@DF_ID] SptremblFeatures_DB:$library:[SPTREMBL_features format:@SptremblFeature_Format ] SptremblFeature_Format:$libformat:[syntax:@SPTREMBL_SYNTAX tableFormat:left fields:{ $field:[@DF_ID token:ftId] $field:[@DF_FtKey token:ft tableToken:'t_ft|key'] $field:[@DF_FtLength token:ft tableToken:'t_ft|len'] $field:[@DF_FtDescription token:ft tableToken:'t_ft|des'] $field:[@DF_FtLocation token:ft tableToken:'t_ft|loc' tableFormat:listing] } ] fromField:@DF_Description toField:@DF_ID] SptremblFeatures_DB:$library:[SPTREMBL_features format:@SptremblFeature_Format ] SptremblFeature_Format:$libformat:[syntax:@SPTREMBL_SYNTAX tableFormat:left fields:{ $field:[@DF_ID token:ftId] $field:[@DF_FtKey token:ft tableToken:'t_ft|key'] $field:[@DF_FtLength token:ft tableTokensrs/icarus/db/srsdb.i # # $RCSfile: srsdb.i,v $ # $Revision: 1.32 $ # $Date: 1997/03/19 20:39:16 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ file:"SRSDB:swissprot.i" file:"SRSDB:pir.i" file:"SRSDB:nrl3d.i" file:"SRSDB:embl.i" file:"SRSDB:subtilist.i" file:"SRSDB:sptrembl.i" file:"SRSDB:trembl.i" file:"SRSDB:imgt.i" file:"SRSDB:prosite.i" file:"SRSDB:prositedoc.i" file:"SRSDB:blocks.i" file:"SRSDB:prints.i" file:"SRSDB:enzyme.i" file:"SRSDB:pdbfinder.i" file:"SRSDB:mpw.i" file:"SRSDB:emp.i" file:"SRSDB:clustalw.i" file:"SRSDB:blast.i" file:"SRSDB:fasta.i" file:"SRSDB:sw.i" file:"SRSDB:primers.i" file:"SRSDB:tfcell.i" file:"SRSDB:tffactor.i" file:"SRSDB:tfsite.i" file:"SRSDB:tfclass.i" file:"SRSDB:tfmatrix.i" file:"SRSDB:tfgene.i" file:"SRSDB:genbank.i" file:"SRSDB:epd.i" file:"SRSDB:ypd.i" file:"SRSDB:pdb.i" file:"SRSDB:dssp.i" file:"SRSDB:hssp.i" file:"SRSDB:fssp.i" file:"SRSDB:reptilia.i" file:"SRSDB:reptax.i" file:"SRSDB:medline.i" file:"SRSDB:taxonomy.i" file:"SRSDB:flygene.i" file:"SRSDB:flyrefs.i" file:"SRSDB:omim.i" file:"SRSDB:p53.i" file:"SRSDB:p53apc.i" file:"SRSDB:p53ref.i" file:"SRSDB:p53apcref.i" file:"SRSDB:btkbase.i" file:"SRSDB:vwf.i" file:"SRSDB:cftr.i" file:"SRSDB:pah.i" file:"SRSDB:haema.i" file:"SRSDB:haemb.i" file:"SRSDB:ldlr.i" file:"SRSDB:views.i" file:"SRSDB:appl.i" $dataRoot = '/data' $dataRoot2 = '/u1/srs/data' $dataRoot3 = '/data/research' $dataRoot4 = '/data/ftp/pub/databases' $dataRoot5 = '/ebi/services/data' # for the demo in the "Guided Tour" file:"SRSDEMO:genes.i" file:"SRSDEMO:reflist.i" $site:[name:demo libs:{ $libloc:[@GENES_DB dir:"SRSDEMO:"] $libloc:[@REFLIST_DB dir:"SRSDEMO:"] } ] $site:[name:unix libs:{ $libloc:[@SWISSPROT_DB dir:"$dataRoot/gcg/gcgswissprot/"] # $libloc:[@SWISSNEW_DB dir:"$dataRoot/gcg/gcgswissnew/"] # $libloc:[@PIR_DB dir:"$dataRoot/gcg/gcgpir/"] # $libloc:[@NRL3D_DB dir:"$dataRoot/gcg/gcgnrl_3d/"] # $libloc:[@TREMBL_DB dir:"$dataRoot/trembl/"] # $libloc:[@TREMBLNEW_DB dir:"$dataRoot/trembl/"] # $libloc:[@GENBANK_DB dir:"$dataRoot/genbank/"] # $libloc:[@EMBL_DB dir:"$dataRoot/gcg/gcgembl/"] # $libloc:[@EMBLNEW_DB dir:"$dataRoot/gcg/gcgembl/"] # $libloc:[@SPTREMBL_DB dir:"$dataRoot/sptrembl/"] # $libloc:[@REMTREMBL_DB dir:"$dataRoot/remtrembl/"] # $libloc:[@IMGT_DB dir:"$dataRoot/imgt"] # $libloc:[@EMBL_DB dir:"/data/gcg/gcgembl/"] # $libLoc:[@SUBTILIST_DB dir:"$dataRoot/subtilis/"] # $libloc:[@PROSITE_DB dir:"$dataRoot3/prosite/"] # $libloc:[@PROSITEDOC_DB dir:"$dataRoot3/prosite/"] # $libloc:[@BLOCKS_DB dir:"$dataRoot3/blocks/"] # $libloc:[@ENZYME_DB dir:"$dataRoot4/enzyme/"] # $libloc:[@PRINTS_DB dir:"$dataRoot/prints/"] # $libloc:[@PDBFINDER_DB dir:"$dataRoot3/pdbfinder/"] # $libloc:[@BLAST_DB dir:"" indexDir:""] # $libloc:[@FASTA_DB dir:"" indexDir:""] # $libloc:[@SW_DB dir:"" indexDir:""] # $libloc:[@CLUSTALW_DB dir:"" indexDir:""] # $libloc:[@PRIMERS_DB dir:"/data/primers/"] # $libloc:[@YPD_DB dir:"$dataRoot/ypd/"] # $libloc:[@TFCELL_DB dir:"$dataRoot2/transfac/"] # $libloc:[@TFFACTOR_DB dir:"$dataRoot2/transfac/"] # $libloc:[@TFSITE_DB dir:"$dataRoot2/transfac/"] # $libloc:[@TFCLASS_DB dir:"$dataRoot2/transfac/"] # $libloc:[@TFMATRIX_DB dir:"$dataRoot2/transfac/"] # $libloc:[@TFGENE_DB dir:"$dataRoot2/transfac/"] # $libloc:[@FLYGENE_DB dir:"$dataRoot2/flybase/"] # $libloc:[@FLYREFS_DB dir:"$dataRoot2/flybase/"] # $libloc:[@MEDLINE_DB dir:"$dataRoot/medline1"] # $libloc:[@EMP_DB dir:"$dataRoot2/emp/"] # $libloc:[@MPW_DB dir:"$dataRoot2/emp/"] # $libloc:[@OMIM_DB dir:"$dataRoot2/omim/"] # $libloc:[@EPD_DB dir:"$dataRoot/epd/"] # $libloc:[@PDB_DB # dir:"/data/research/pdb/"] # $libloc:[@DSSP_DB dir:"$dataRoot3/dssp/"] # $libloc:[@HSSP_DB dir:"$dataRoot3/hssp/"] # $libloc:[@FSSP_DB dir:"$dataRoot3/fssp/"] # $libloc:[@REPTILIA_DB dir:"$dataRoot2/reptilia/"] # $libloc:[@REPTAX_DB dir:"$dataRoot2/reptilia/"] # $libloc:[@TAXONOMY_DB dir:"$dataRoot2/taxonomy/"] # $libloc:[@P53APC_DB dir:"$dataRoot2/mutdb/p53apc/"] # $libloc:[@P53APCREF_DB dir:"$dataRoot2/mutdb/p53apc/"] # $libloc:[@P53_DB dir:"$dataRoot2/mutdb/p53/"] # $libloc:[@P53REF_DB dir:"$dataRoot2/mutdb/p53/"] # $libloc:[@BTKBASE_DB dir:"$dataRoot2/mutdb/btkbase/"] # $libloc:[@VWF_DB dir:"$dataRoot2/mutdb/vwf/"] # $libloc:[@CFTR_DB dir:"$dataRoot2/mutdb/cftr/"] # $libloc:[@PAH_DB dir:"$dataRoot2/mutdb/pah/"] # $libloc:[@HAEMA_DB dir:"$dataRoot2/mutdb/haema/"] # $libloc:[@HAEMB_DB dir:"$dataRoot2/mutdb/haemb/"] # $libloc:[@LDLR_DB dir:"$dataRoot2/mutdb/ldlr/"] } ] # hypertext links to be inserted into entries before display $href:[medlineR link: |%s\ ] $href:[mpwR link:"%s"] $href:[swissR link:"%s"] $href:[swissidR link:"%s"] $href:[swissprotFtR link:"%s"] $href:[sptremblFtR link:"%s"] $href:[remtremblFtR link:"%s"] $href:[pidR link:"%s"] $href:[pdbR link:"%s"] $href:[prositedocR link:"%s"] $href:[prositeR link:"%s"] $href:[enzymeR link:"%s"] $href:[pirR link:"%s"] $href:[emblR link:"%s"] $href:[emblIdR link:"%s"] $href:[emblFeatR link:"%s"] $href:[subtilistFeatR link:"%s"] $href:[genbankR link:"%s"] $href:[genbankIdR link:"%s"] $href:[hsspR link:"%s"] $href:[ecogeneR link:"%s"] $href:[mimR link:"%s"] $href:[mimAllR link:"%s"] $href:[pdbR link:"%s"] $href:[epdR link:"%s"] $href:[transfacR link:"%s"] $href:[tffactorR link:"%s"] $href:[tfsiteR link:"%s"] $href:[tfcellR link:"%s"] $href:[tfmatrixR link:"%s"] $href:[tfclassR link:"%s"] $href:[listaR link:"%s"] $href:[yepdR link:"%s"] $href:[ypdrefR link:"%s"] $href:[sgdR link:"%s"] $href:[stygeneR link:"%s"] $href:[hivR link:"%s"] $href:[eco2dbaseR link:"%s"] $href:[subtilistR link:"%s"] $href:[flybaseR link:"%s"] $href:[flygeneR link:"%s"] $href:[flyrefsR link:"%s"] $href:[aarhusR link:"%s"] $href:[gcrdbR link:"%s"] $href:[wormpepR link:"%s"] $href:[swiss2dpageR link:"%s"] $href:[swissFeatR link:"%s"] $href:[gdbR link:"%s"] $href:[reptaxR link:"%s"] $href:[emblFtQualR link: "%s"] $href:[emblFtKeyR link: "%s"] # added ramu, useful for any database which has accno $href:[dbaseR link:"%s"] $href:[dbase_idR link:"%s"] $href:[headR link:| ] $srsdb:[ libIds:{ $libid:[1 lib:@?SWISSPROT_DB] $libid:[8 lib:@?SWISSNEW_DB] $libid:[2 lib:@?PIR_DB] $libid:[3 lib:@?EMBL_DB] $libid:[4 lib:@?EMBLNEW_DB] $libid:[5 lib:@?GENBANK_DB] $libid:[6 lib:@?NRL3D_DB] $libid:[7 lib:@?TREMBL_DB] $libid:[9 lib:@?TREMBLNEW_DB] $libid:[10 lib:@?REMTREMBL_DB] $libid:[11 lib:@?SPTREMBL_DB] $libid:[12 lib:@?IMGT_DB] $libid:[13 lib:@?SUBTILIST_DB] $libid:[21 lib:@?PDB_DB] $libid:[22 lib:@?PDBNEW_DB] $libid:[24 lib:@?DSSP_DB] $libid:[23 lib:@?HSSP_DB] $libid:[25 lib:@?ALI_DB] $libid:[26 lib:@?FSSP_DB] $libid:[27 lib:@?PDBFINDER_DB] $libid:[41 lib:@?PROSITE_DB] $libid:[42 lib:@?PROSITEDOC_DB] $libid:[43 lib:@?BLOCKS_DB] $libid:[44 lib:@?EPD_DB] $libid:[46 lib:@?ECDC_DB] $libid:[47 lib:@?MIM_DB] $libid:[48 lib:@?MIMMAP_DB] $libid:[49 lib:@?ENZYME_DB] $libid:[50 lib:@?REBASE_DB] $libid:[51 lib:@?CPGISLE_DB] $libid:[52 lib:@?MOLPROBE_DB] $libid:[53 lib:@?PRODOM_DB] $libid:[54 lib:@?PMD_DB] $libid:[55 lib:@?FLYGENE_DB] $libid:[56 lib:@?FLYREFS_DB] $libid:[65 lib:@?PIRALN_DB] $libid:[66 lib:@?YPD_DB] $libid:[67 lib:@?MPW_DB] $libid:[68 lib:@?PRIMERS_DB] $libid:[69 lib:@?EMP_DB] $libid:[70 lib:@?TAXONOMY_DB] $libid:[71 lib:@?PRINTS_DB] $libid:[72 lib:@?OMIM_DB] $libid:[81 lib:@?SEQANALREF_DB] $libid:[82 lib:@?SEQANALRABS_DB] $libid:[83 lib:@?PROTSTRUCTLIT_DB] $libid:[90 lib:@?MEDLINE_DB] $libid:[91 lib:@?YPDREF_DB] $libid:[101 lib:@?NAKAI_DB] $libid:[102 lib:@?LIMB_DB] $libid:[110 lib:@?TFSITE_DB] $libid:[111 lib:@?TFFACTOR_DB] $libid:[112 lib:@?TFCELL_DB] $libid:[113 lib:@?TFCLASS_DB] $libid:[114 lib:@?TFMATRIX_DB] $libid:[115 lib:@?TFGENE_DB] # databanks for mutations and aberrations $libid:[130 lib:@?P53_DB] $libid:[131 lib:@?P53APC_DB] $libid:[132 lib:@?P53REF_DB] $libid:[133 lib:@?P53APCREF_DB] $libid:[134 lib:@?BTKBASE_DB] $libid:[135 lib:@?VWF_DB] $libid:[136 lib:@?CFTR_DB] $libid:[137 lib:@?PAH_DB] $libid:[138 lib:@?HAEMA_DB] $libid:[139 lib:@?HAEMB_DB] $libid:[140 lib:@?LDLR_DB] $libid:[201 lib:@?FASTA_DB] $libid:[202 lib:@?BLAST_DB] $libid:[203 lib:@?PROFILE_DB] $libid:[204 lib:@?BLITZ_DB] $libid:[204 lib:@?SW_DB] $libid:[205 lib:@?CLUSTALW_DB] $libid:[230 lib:@?REPTILIA_DB] $libid:[231 lib:@?REPTAX_DB] $libid:[232 lib:@?MEDIA_DB] # the two demo databanks $libid:[254 lib:@?GENES_DB] $libid:[255 lib:@?REFLIST_DB] } ] lib:@?PAH_DB] $libid:[138 lib:@?HAEMA_DB] $libid:[139 lib:@?HAEMB_DB] $libid:[140 lib:@?LDLR_DB] $libid:[201 lib:@?FASTA_DB] $libid:[202 lib:@?BLAST_DB] $libid:[203 lib:@?PROFILE_DB] $libid:[204 lib:@?BLITZ_DB] $libid:[204 lib:@?SW_DB] $libidsrs/icarus/db/srsgen.i # $RCSfile: srsgen.i,v $ # $Revision: 1.7 $ # $Date: 1997/03/18 18:48:25 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # syntaxes SRSQUERY_SYNTAX:$syntax:[file:"SRSICA:srsquery.i" name:srsquery ignore:" \r\t\n"] MakeWild_Syntax:$syntax:[file:"SRSICA:makewild.i" name:makeWild] ICARUS_SYNTAX:$syntax:[file:"SRSICA:icarus.i" level3:0 comment:"^#[^\n]*\n" commandsyntax:@COMMAND_SYNTAX name:icarus ignore:" \t\n"] CABI_SYNTAX:$syntax:[file:"SRSICA:cabi.i" commandsyntax:@COMMAND_SYNTAX name:cabi] COMMAND_SYNTAX:$syntax:[file:"SRSICA:command.i" level3:0] BOOTCOMMAND_SYNTAX:$syntax:[file:"SRSICA:bootcommand.i" level3:0] # data bank groups SEQUENCE_LIBS:$libgroup:[Sequence short:SQ search:all] SEQRELATED_LIBS:$libgroup:[SeqRelated] MISC_LIBS:$libgroup:[Others] LITERATURE_LIBS:$libgroup:[Literature short:lit] PROTSTRUCT_LIBS:$libgroup:[Protein3DStruct short:'3d'] GENOME_LIBS:$libgroup:[Genome short:gen] TRANSFAC_LIBS:$libgroup:[TransFac short:'tf'] MUTATION_LIBS:$libgroup:['Human Mutations' short:'mut'] APPLICATION_LIBS:$libgroup:[Application short:app] # data field types DF_Class: $srsfield:[Class short:cla] DF_Synonyms: $srsfield:[Synonyms short: SYM] DF_HeaderField:$srsfield:[HeaderField type:header] DF_ID:$srsfield:[ID short:id group:@DF_ALL] DF_ALL:$srsfield:[AllText short:all isGroup:yes type:str] DF_ACCNO:$srsfield:[AccNumber short:acc group:@DF_ALL] DF_Accession:$srsfield:[AccNumber short:acc group:@DF_ALL] DF_SeqLength:$srsfield:[SeqLength short:sl] DF_Date:$srsfield:[Date short:dat] DF_Description:$srsfield:[Description short:des group:@DF_ALL] DF_Keywords:$srsfield:[Keywords short:key group:@DF_ALL] DF_Organism:$srsfield:[Organism short:org group:@DF_ALL] DF_Organelle:$srsfield:[Organelle short:ogn group:@DF_ALL] DF_GeneName:$srsfield:[GeneName short:gen group:@DF_ALL] DF_Molecule:$srsfield:[Molecule short:mol group:@DF_ALL] DF_Authors:$srsfield:[Authors short:aut group:@DF_ALL] DF_Title:$srsfield:[Title short:tit group:@DF_ALL] DF_Features:$srsfield:[Features short:fts group:@DF_ALL] DF_Citation:$srsfield:[Citation short:cit] DF_Division:$srsfield:[Division short:div] DF_LINK:$srsfield:[Link short:lnk] DF_COMMENT:$srsfield:[Comment short:cc group:@DF_ALL] DF_Comment:$srsfield:[Comment short:cc group:@DF_ALL] DF_CommentType:$srsfield:[CommentType short:cct group:@DF_ALL] DF_REF:$srsfield:[Reference short:ref] DF_Reference:$srsfield:[Reference short:ref] DF_EnzymeCode:$srsfield:[EnzymeCode short:enz group:@DF_ALL] DF_AccessionKey:$srsfield:[AccessionKey short:ack] DF_DBOrigin:$srsfield:[DBOrigin short:dbo] DF_Compound:$srsfield:[Compound short:com] DF_Header:$srsfield:[Header short:hdr] DF_Source:$srsfield:[Source short:src] DF_Substrate:$srsfield:[Substrate short:sub] DF_WaterMols:$srsfield:[WaterMols short:wat] DF_Method:$srsfield:[Method short:met] DF_GeneProduct: $srsfield:[GeneProduct short:pro group:@DF_ALL] DF_IsoelectricPoint:$srsfield:[IsoelectricPoint short:iep] # for sequence features DF_FtKey:$srsfield:[FeatureKey short:ftk] DF_FtQualifier:$srsfield:[FeatureQualifier short:ftq] DF_FtSource:$srsfield:[FeatureSource short:fts] DF_FtDescription:$srsfield:[FeatureDescription short:ftd] DF_FtLength:$srsfield:[FeatureLength short:ftl] DF_FtLocation:$srsfield:[FeatureLocation short:flo] DF_PID:$srsfield:[PID short:pid] DF_ChrsNo:$srsfield:[ChromosomeNo short:chn] DF_FtMap:$srsfield:[MapLocation short:mpl] DF_DNASequence:$srsfield:[Sequence short:seq format:{ $fieldFormat:[fasta eval:'$SeqPrint:[name:$field format:fasta]'] $fieldFormat:[gcg eval:'$SeqPrint:[format:gcg width:60]'] $fieldFormat:[pir eval:'$SeqPrint:[format:pir width:60]'] $fieldFormat:[embl eval:'$SeqPrint:[format:embl width:60]'] $fieldFormat:[plain eval:'$SeqPrint:[format:plain width:70]'] } ] DF_DNALocation:$srsfield:[Sequence short:seq format:{ $fieldFormat:[gcg eval:'$SeqPrint:[format:gcg s:$SeqGetFt:[$token db:embl]]' ] $fieldFormat:[location eval:'$Print:$token' ] $fieldFormat:[fasta eval:'$SeqPrint:[format:fasta s:$SeqGetFt:[$token db:embl]]' ] $fieldFormat:[plain eval:'$SeqPrint:[format:plain s:$SeqGetFt:[$token db:embl]]' ] $fieldFormat:[pir eval:'$SeqPrint:[format:pir s:$SeqGetFt:[$token db:embl]]' ] $fieldFormat:[embl eval:'$SeqPrint:[format:pir s:$SeqGetFt:[$token db:embl]]' ] } ] DF_ProtLocation:$srsfield:[Sequence short:seq format:{ $fieldFormat:[gcg eval:'$SeqPrint:[format:gcg s:$SeqGetFt:[$token db:swissprot]]' ] $fieldFormat:[location eval:'$Print:$token' ] $fieldFormat:[fasta eval:'$SeqPrint:[format:fasta s:$SeqGetFt:[$token db:swissprot]]' ] $fieldFormat:[plain eval:'$SeqPrint:[format:plain s:$SeqGetFt:[$token db:swissprot]]' ] $fieldFormat:[pir eval:'$SeqPrint:[format:pir s:$SeqGetFt:[$token db:swissprot]]' ] $fieldFormat:[swissprot eval:'$SeqPrint:[format:swissprot s:$SeqGetFt:[$token db:swissprot]]' ] } ] DF_Sequence:$srsfield:[Sequence short:seq] DF_Name:$srsfield:[Name short:nam group:@DF_ALL] DF_ProtSequence:$srsfield:[Sequence short:seq format:{ $fieldFormat:[fasta eval:'$SeqPrint:[name:$field format:fasta]'] $fieldFormat:[gcg eval:'$SeqPrint:[format:gcg width:60]'] $fieldFormat:[pir eval:'$SeqPrint:[format:pir width:60]'] $fieldFormat:[swiss eval:'$SeqPrint:[format:swiss width:60]'] $fieldFormat:[plain eval:'$SeqPrint:[format:plain width:70]'] $fieldFormat:[ProteinChart eval:'$SeqPrint:[format:msf width:50]'] # eval:'$AppletPrint:[proteinChart]' } ] DF_ALIGNMENT:$srsfield:[Alignment short:ali format:{ $fieldFormat:[msf eval:'$SeqPrint:[$SeqGet:$field format:msf width:50]'] $fieldFormat:[fasta eval:'$SeqPrint:[$SeqGet:$field format:fasta width:60]'] $fieldFormat:[pir eval:'$SeqPrint:[$SeqGet:$field format:pir width:70]'] $fieldFormat:[swiss eval:'$SeqPrint:[$SeqGet:$field format:swiss width:60]'] $fieldFormat:[clustal eval:'$SeqPrint:[$SeqGet:$field format:clustal width:80]'] } ] DF_Alignment:$srsfield:[Alignment short:ali] # for hum mut dbs DF_ProtChangePos:$srsfield:[ProteinChangePos short:acp] DF_DnaChangePos:$srsfield:[DnaChangePos short:dcp] DF_AaChange:$srsfield:[AaChange short:aac] DF_NuclChange:$srsfield:[NucleotideChange short:nuc] DF_CodonChange:$srsfield:[CodonChange short:coc] DF_CodonNo:$srsfield:[CodonNo short:cdn] DF_TranslEffect:$srsfield:[TranslationEffect short:tre] DF_LabName:$srsfield:[LabName short:lan group:@DF_ALL] DF_FuncStudies:$srsfield:[FunctionalStudies short:fst] DF_AlleleN:$srsfield:[NAlleles short:nal] DF_FamilyN:$srsfield:[NFamilies short:nfa] DF_PatientN:$srsfield:[NPatients short:npa] DF_PatientOrig:$srsfield:[PatientOrigin short:por group:@DF_ALL] # ID types SRSxSEQID:$idtype:['Seq-ID' size:4 fipBeg:0 fipLen:3 libIdBeg:3 libIdLen:1] ENTRY_ID:$idtype:['Entry-ID' size:4 fipBeg:0 fipLen:3 libIdBeg:3 libIdLen:1] STRUCTENT_ID:$idtype:['3D-ID' size:4 fipBeg:0 fipLen:3 libIdBeg:3 libIdLen:1] SUBENTRY_ID:$idtype:['SubEntry-ID' size:6 subNBeg:0 subNLen:2 fipBeg:2 fipLen:3 libIdBeg:5 libIdLen:1] SRSxLINKID:$idtype:["Link-ID" size:8 fipBeg:0 fipLen:3 libIdBeg:3 libIdLen:1] # file types GCGREF_FILE:$filetype:[text typename:ref maxline:512 fieldTokens:fields fipVar:entryFip] GCGSEQ_FILE:$filetype:[seq typename:seq maxline:10000 fieldTokens:gcgseq fipVar:seqFip] REF_FILE:$filetype:[text typename:ref maxline:2000 fipVar:entryFip] DAT_FILE:$filetype:[text typename:dat maxline:1000 fipVar:entryFip] SEQ_FILE:$filetype:[seq shareWith:@DAT_FILE fieldTokens:sequence fipVar:seqFip] TXT_FILE:$filetype:[text typename:txt maxline:500] TXTSEQ_FILE:$filetype:[seq shareWith:@TXT_FILE fieldTokens:sequence fipVar:seqFip] PIRREF_FILE:$filetype:[text typename:ref maxline:10000 fipVar:entryFip] PIRSEQ_FILE:$filetype:[seq typename:seq maxline:10000 fieldTokens:sequence fipVar:seqFip] # links $link:[fromName:subentry toName:entry type:parent idtype1:@ENTRY_ID idtype2:@SUBENTRY_ID] $link:[fromName:subentry toName:parent type:parent idtype1:@ENTRY_ID idtype2:@SUBENTRY_ID] # subentry types #Feature_SubEntry:$subentry:[fields:{@DF_ID @DF_ACCNO @DF_FEATURE}] #Chain_SubEntry:$subentry:[fields:{@DF_ID @DF_HEADER @DF_SEQUENCE}] # data types and applications DNASEQ_DATA:$dataType:[DNASequence] PROTSEQ_DATA:$dataType:[ProteinSequence applications:{@BLAST_APP @SW_APP @FASTA_APP @CLUSTALW_APP} ] fromName:subentry toName:ensrs/icarus/db/subtilist.i # # $RCSfile: subtilist.i,v $ # $Revision: 1.1 $ # $Date: 1997/03/03 18:36:31 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SUBTILIST_DB:$library:[SUBTILIST group:@SEQUENCE_LIBS subentries:@SubtilistFeatures_DB format:@SUBTILIST_FORMAT cachesize:2000 maxNameLen:12 files:{ $file:SLR12_embl } ] SUBTILIST_FORMAT:$libformat:[syntax:@SUBTILIST_SYNTAX contains:@DNASEQ_DATA tableFormat:left fileType:{@TXT_FILE @TXTSEQ_FILE} fields:{ $field:[@DF_ID code:id index:id indexToken:id] $field:@DF_ALL $field:[@DF_Accession code:acc index:str indexToken:acc tableToken:acc] $field:[@DF_Division code:id index:str indexToken:div tableToken:div] $field:[@DF_Molecule code:id index:str indexToken:mol tableToken:mol] $field:[@DF_Description code:des index:str indexToken:des tableToken:'clFields|des' tableFormat:listing] $field:[@DF_Keywords code:key index:str indexToken:key] $field:[@DF_Organism code:org index:str indexToken:org] $field:[@DF_Authors code:ra index:str indexToken:authors] $field:[@DF_Title code:rt index:str indexToken:ttl tableToken:'clFields|rt'] $field:[@DF_Citation code:rl index:str indexToken:cit tableToken:'clFields|rl'] $field:[@DF_Date code:date index:int indexToken:date tableToken:t_date] $field:[@DF_SeqLength code:sq index:int indexToken:seqLen tableToken:seqLen tableFormat:right] $field:[@DF_LINK code:dr] SUBTILISTSeq:$field:[@DF_DNASequence token:sequence format:embl] $field:[@DF_HeaderField name:'Feature Table Fields'] $field:[@DF_FtKey code:ft index:str indexToken:ftKey indexId:@SUBENTRY_ID tableToken:ftKey tableFormat:left] $field:[@DF_FtQualifier code:ft index:str indexToken:ftQual indexId:@SUBENTRY_ID] $field:[@DF_FtAccession code:ft index:str indexToken:acnum indexId:@SUBENTRY_ID] $field:[@DF_FtDescription code:ft index:str indexToken:ftDes indexId:@SUBENTRY_ID] $field:[@DF_FtGenetMapPos code:ft index:int indexToken:genetmap indexId:@SUBENTRY_ID] $field:[@DF_FtPhysMapPos code:ft index:int indexToken:physmap indexId:@SUBENTRY_ID] } ] DF_FtGenetMapPos:$srsfield:[GeneticMapPos short:gmp] DF_FtPhysMapPos:$srsfield:[PhysicalMapPos short:pmp] DF_FtAccession:$srsfield:[FtAccession short:fac] SUBTILIST_SYNTAX:$syntax:[file:"SRSDB:subtilist.is" ignore:" \t"] $syntax:[name:ftseq file:"SRSDB:ftseq.is" ignore:" \t\n"] $link:[@SUBTILIST_DB to:@?EMBL_DB toField:@DF_Accession token:embl] $link:[@SUBTILIST_DB to:@?SWISSPROT_DB toField:@DF_Accession token:'link|swiss'] SubtilistFeatures_DB:$library:[SUBTILIST_features format:@SubtilistFeature_Format] SubtilistFeature_Format:$libformat:[syntax:@SUBTILIST_SYNTAX tableFormat:left fields:{ $field:[@DF_ID token:ftId] $field:[@DF_FtKey token:ft tableToken:'t_ft|key'] $field:[@DF_FtQualifier token:ft tableToken:'t_ft|qual'] $field:[@DF_PID token:ft tableToken:'t_ft|db_xref'] $field:[@DF_FtDescription token:ft tableToken:'t_ft|note'] $field:[@DF_FtGene token:ft tableToken:'t_ft|gene'] $field:[@DF_FtProduct token:ft tableToken:'t_ft|product'] $field:[@DF_FtPhysMapPos token:ft tableToken:'t_ft|physmap'] $field:[@DF_FtGenetMapPos token:ft tableToken:'t_ft|genetmap'] $field:[@DF_DNALocation token:ftLocat parent:@SUBTILISTSeq tableFormat:listing] } ] _FtQualifier token:ft tableToken:'t_ft|qual'] $fsrs/icarus/db/subtilist.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: subtilist.is,v $ # $Revision: 1.1 $ # $Date: 1997/03/03 18:36:32 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $fn={ ID:id OG:org KW:key RN:rn '//':sep AC:acc OC:org RP:rp RT:rt FH: fh DT:date OS:org SQ:sq RC:rc PK: pk DE:des CC:cmnt RL:rl RA:ra DB: db DR:link RX:rx XX:sep PG: pg } $rules={ entry: ~ {$In:[file:text] $Out pre $Skip:0} ('ID ' {$not} ln?)* (/ID +([A-Z0-9_]+)/{$entryFip=$Fip $Wrt $entryName=$1} ln {$App} (/( |ID|>>)/ {$Not} ln {$App})+ )? ~ # extracting data fields fields: ~ {$In:entry $Out $Skip:1} (ftln | /../ { if:$Ct==$prev $App else $Wrt:$fn.$Ct if:$fn.$Ct=="" $dp:"+++ unknown: $Ct in $entryName +++" $prev=$Ct } ln {$App})+ ~ ftln: ~ {$Wrt:ft} 'FT' ln ('FT ' ln)* ~ clFields: ~ {$In:fields $Out $Skip:1} /.. */ ln {$Wrt:$Itc} (/.. */ ln {$App})* ~ # parsing the sequence part from separate stream gcgseq: ~ { $In:[file:seq] $Out $SeqMake:$s} '>>>>' {$seqFip=$Fip} (/[A-Z0-9]+/ {$Wrt:[s:$Ct] $s=$SeqNew:$Ct} seq | /[A-Z0-9]+_0/ seq (/>>>>[A-Z0-9]+_[1-9]+/ {$SeqTrunc:[$s len:10000]} seq)+) ~ seq: ~ (/.*2BIT *Len:/ /[0-9]+/ {$len=$Ct} ln ln {$SeqGet2Bit:[$s file:$File len:$len]} ('>>>>'{$Not} ln)*| /.*ASCII/ ln ln ('>>>>' {$Not} /.*/ {$SeqApp:[$s s:$Ct]})+) ~ sequence: ~ {$In:[file:seq share:text] $Out pre {$s=$SeqNew:$entryName $seqFip=$Fip} $Wrt:[s:$entryName] $SeqMake:$s} ('ID' {$Not} ln {$SeqApp:[$s s:$Ct]})* ~ # for indexing i_id: ~ {$In:[entry] $Out:id} /ID +/ name {$Wrt} ~ i_div: ~ {$In:[fields c:id] $Out:div} /ID +/ name /[^;]+/ ';' /[^;]+/ ';' name {$Wrt} ~ i_mol: ~ {$In:[fields c:id] $Out:mol} /ID +/ name /[^;]+/ ';' /[^;]+/ {$Wrt} ~ i_acc: ~ {$In:[fields c:acc] $Out:acc} ('AC' (name {$Wrt} ';')+)+ ~ i_dates: ~ { $In:[fields c:date] $Out:date init $month={JAN:1 FEB:2 MAR:3 APR:4 MAY:5 JUN:6 JUL:7 AUG:8 SEP:9 OCT:10 NOV:11 DEC:12} } /.* ([0-9]+)-([A-Z]+)-([0-9]+)[^\n]+Cre/ {$Wrt:[credate s:($1 + $month.$2*100 + $3*10000)]} ~ des: ~ {$In:[fields c:des] $Out} ('DE' (/\\(EC *([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)/ {$Wrt:[s:$1]}| word{$Wrt} | sp)+ ln)+ ~ org: ~ {$In:[fields c:org] $Out} ('OC' (/[^;.\n]+/ {$Wrt} | /[^\n]/)*)+ | 'OS' /[^(\n]+/ {$Wrt:[s:$Trim:$Ct]} ('(' (/[^ \n)]+/ | /[^)]/)+)? | 'OG' /[^\n;.]+/ {$Wrt} ~ key: ~ {$In:[fields c:key] $Out} ('KW' (/[^\n;.]+/ {$Wrt} | /[^\n]/)+)+ ~ authors: ~ {$In:[fields c:ra] $Out} (/RA/ (/([^.,\n]+) +([^,;\n]+)/ {$Uniq:[s:"$1,$2"]} /[,;]/)* ln)* ~ ttl: ~ {$In:[fields c:rt] $Out} (tag (word {$Wrt} | sp)* ln)+ ~ cit: ~ {$In:[fields c:rl] $Out} tag / *([^\n]+) ([0-9]+):([0-9]+)-[0-9]+\\(([0-9]+)\\)/? {$Uniq:[jnl s:$Trim:$1] $Uniq:[vol s:$2] $Uniq:[page s:"$3-"] $Uniq:[year s:$4]} ~ accKey: ~ {$In:[fields c:acc] $Out} 'AC' /[A-Z]+/ {$Wrt} ~ dbOri: ~ {$In:[fields c:acc] $Out init { $dbOriN={ A:1 F:1 V:1 X:1 Y:1 Z:1 AA:2 AC:2 AD:2 B:2 G:2 H:2 I:2 J:2 K:2 L:2 M:2 N:2 R:2 S:2 T:2 U:2 W:2 AB:3 C:3 D:3 E:3} $dbName={1:EMBL 2:GenBank 3:DDBJ} } } 'AC' /[A-Z]+/ {$Wrt:[s:$dbName.$dbOriN.$Ct]} ~ i_seqLen: ~ {$In:[fields c:sq] $Out:seqLen} 'SQ Sequence' /[0-9]+/ {$Wrt} ~ embl: ~ {$In:[fields c:des] $Out} (/.. +[A-Z0-9]+ +\\(/ name {$Wrt} ln | ln)+ ~ link: ~ {$In:[fields c:link] $Out} (/.. +SWISS-PROT;/ name {$Wrt:swiss} ln)+ ~ # indexing features ftWord: ~ /[^" ,;:()\n.-]+/ ~ #" ftSep: ~ /[ ,;.:()-]+/ ~ ftKey: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} 'FT' /[^ ]+/ {$Wrt:[n:$ftN]} ~ ftQual: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} /[^\/]+/ (/\/([a-zA-Z0-9_]+)/ {$Wrt:[s:$1 n:$ftN]} (/=[a-zA-Z0-9_]+/ | /="[^"]+"/)? /[^\/]+/)* ~ #" ftDes: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} (/[^\/]+\// (/[^\/]+\/(product|note|gene|alt_name|description)="/ ('\nFT' | /NCBI gi: *[0-9]+/ | ftWord {$Uniq:[n:$ftN]} | ftSep)+)?)* ~ acnum: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} /.+\/acnum="([0-9A-Z]+)"/ {$Wrt:[n:$ftN s:$1]} ~ physmap: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} /.+\/physical_map=([0-9]+)/ {$Wrt:[n:$ftN s:$1]} ~ genetmap: ~ {$In:[fields c:ft count:ft var:$ftN] $Out} /.+\/genetic_map=([0-9]+)/ {$Wrt:[n:$ftN s:$1]} ~ # displaying features ftClean: ~ {$In:[fields c:ft count:ft var:$ftN select:$subEntryN] $Out } 'FT' ln {$Wrt} ('FT' ln {$App})* ~ ftLoc: ~ {$In:ftClean $Out} /[^ ]+/ /[^\/]+/ {$Wrt} ~ ft: ~ {$In:[fields c:ft count:ft var:$ftN select:$subEntryN] $Out} /.*/ {$Wrt} ~ ftId: ~ {$In:[fields c:id] $Out} /.. *([A-Z0-9_]+)/{$Wrt:[s:"ID $1\_$subEntryN; parent: $1"]}~ h_ftId: ~ {$In:[ftId t:html]} /.*parent: */ /[A-Z0-9_]+/ {$Rep:{$ParStr:subtilistR $Ct $Ct}} ~ t_ft: ~ {$In:ftClean $Out} /(]*>/ ~ h_links: ~ {$In:[fields c:link t:html] init{$hl={ 'SWISS-PROT': swissR DICTYDB: dictydbR GCRDB: gcrdbR MAIZEDB: maizedbR WORMPEP: wormpepR LISTA: listaR PIR: pirR YEPD: yepdR SGD: sgdR STYGENE: stygeneR HIV: hivR ECOGENE: ecogeneR ECO2DBASE: eco2dbaseR MIM: mimR SUBTILIST: subtilistR FLYBASE: flybaseR TRANSFAC: transfacR REBASE: rebaseR } } } (/DR/ dbName {$db=$Ct} ';' accno {$Rep:{$ParStr:$hl.$db $Ct $Ct}} ln)* ~ # other stuff tag: ~ /[A-Z][A-Z]/ ~ word: ~ /[^" ,;:()\/=\n.-]+/ ~ sp: ~ /[ ,;.:()\/=-]+/ ~ lnCode: ~ /\n[A-Z][A-Z]/ ~ ln: ~ /[^\n]*\n/ ~ accno: ~ /[A-Z0-9]+/ ~ num: ~ /(<|>)?[0-9?]+/ ~ name: ~ /[a-zA-Z0-9_-]+/ ~ dbName: ~ /[^;]+/ ~ } if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/embl_dna/mam.dat'] while:$JobHasInput:$job { $JobTokens:[$job name:acc print:0] $JobTokens:[$job name:t_ft print:1] $JobNext:$job #$print:"-------->entry\n" } } word: ~ /[^" ,;:()\/=\n.-]+/ ~ sp: ~ /[ ,;.:()\/=-]+/ ~ lnCode: ~ /\n[A-Z][A-Z]/ ~ ln: ~ /[^\n]*\n/ ~ accno: ~ /[A-Z0-9]+/ ~ num: ~ /(<|>)?[0-9?]+/ ~ name: ~ /[a-zA-Z0-9_-]+/ ~ dbName: ~ /[^;]+/ ~ } if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/embl_dna/mam.dat'] while:$JobHasInput:$job { $JobTokens:[$job name:acc print:0] $JobTokens:[$job namsrs/icarus/db/sw.i # $RCSfile: sw.i,v $ # $Revision: 1.3 $ # $Date: 1997/03/03 18:34:17 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SW_DB:$library:[SW group:@APPLICATION_LIBS comment:"" format:@SW_FORMAT maxNameLen:40 ifiles:{"sw.i" "sw.is"} type:user files:{ $file:tmp } ] SW_FORMAT:$libformat:[fileType:@SW_FILE syntax:@SW_SYNTAX fields:{ $field:[@DF_ID code:title index:id indexToken:id] $field:[@DF_PercIdent code:scores index:real indexToken:percIdent tableToken:percIdent tableFormat:right] $field:[@DF_PercSim code:scores index:real indexToken:percSim tableToken:percIdent tableFormat:right] # $field:[@DF_QueryBeg code:tmatch # tableToken:queryBeg tableFormat:right] # $field:[@DF_QueryEnd code:tmatch # tableToken:queryEnd tableFormat:right] $field:[@DF_MatchLen code:tmatch index:int indexToken:length] $field:[@DF_Alignment code:tmatch tableToken:t_ali tableFormat:left] $field:[@DF_LINK index:link code:link indexToken:link] } ] DF_PercSim:$srsfield:[PercentSimilarity short:psi] SW_SYNTAX:$syntax:[file:"SRSDB:sw.is" ignore:" "] SW_FILE:$filetype:[typename:sw maxline:500] $link:[@SW_DB to:@?SWISSPROT_DB token:'link|swiss' toField:@DF_ID] t] # $field:[@DF_QueryEnd code:tmatch # tableToken:queryEnd tableFormat:right] $field:[@DF_MatchLen code:tmatch index:int indexToken:length] $field:[@srs/icarus/db/sw.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: sw.is,v $ # $Revision: 1.4 $ # $Date: 1997/03/03 18:34:18 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $rules={ entry: ~ {$In:[file:text] init{$count=0} $Out $count+=1 pre $Skip:0} (' to:' {$Not} ln)* ln {$entryFip=$Fip $Wrt} (' to:' {$Not} appLn)+ ~ # data fields fields: ~ {$In:entry $Out $Skip:0} title comment scores ali ~ title: ~ {$Wrt:title} ln ~ comment: ~ {$Wrt:comment} (/ *Quality/ {$Not} ln)+ ~ scores: ~ {$Wrt:scores} ln ln ln ~ ali: ~ {$Wrt:ali} ln+ ~ # indexing id: ~ {$In:[fields c:title] $Out} / *to: *([^ \n]+)/ {$Wrt:[s:"$count\_$1"]} ~ quality: ~ {$In:[fields c:scores] $Out} /.*Quality: *([0-9.]+)/{$Wrt:[s:$1]} ~ percSim: ~ {$In:[fields c:scores] $Out} /.*Similarity: *([0-9.]+)/{$Wrt:[s:$1]}~ percIdent:~ {$In:[fields c:scores] $Out} /.*Identity: *([0-9.]+)/{$Wrt:[s:$1]} ~ length: ~ {$In:[fields c:scores] $Out} /.*Length: *([0-9]+)/{$Wrt:[s:$1]} ~ gaps: ~ {$In:[fields c:scores] $Out} /.*Gaps: *([0-9]+)/{$Wrt:[s:$1]} ~ link: ~ {$Out $In:[fields c:title]} / *to: *([^ \n]+)/ {$Wrt:[swiss s:$1]} ~ # table display t_ali: ~ {$Out $In:[fields c:ali]} /.+/ {$Wrt:[s:""]} ~ # html h_link: ~ {$In:[fields c:title t:html]} / *to: */ /[^ \n]+/ {$Rep:{$ParStr:swissidR $Ct $Ct}} ~ # other appLn: ~ /[^\n]*\n/ {$App} ~ ln: ~ /[^\n]*\n/ ~ name: ~ /[a-zA-Z][a-zA-Z0-9]+/~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/opt/srs/srs5/tmp/1ujxx15V2BF/tmp.sw'] while:$JobHasInput:$job { $JobTokens:[$job name:fields code:ali print:0] $JobTokens:[$job name:link print:1] $JobNext:$job $print:"-------->entry\n" } } :[fields c:title t:html]} / *to: */ /[^ \n]+/ {$Rep:{$ParStr:swissidR $Ct $Ct}} ~ # other appLn: ~ /[^\n]*\n/ {$App} ~ ln: ~ /[^\n]*\n/ ~ name: ~ /[a-zA-Z][a-zA-Z0-9]+/~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/opt/srs/srs5/tmp/1ujxx15V2BF/tmp.sw'] while:$JobHasInput:$job { $JobTokens:[$job name:fields code:ali print:0] $JobTokens:[$job name:lisrs/icarus/db/swissprot.i # # $RCSfile: swissprot.i,v $ # $Revision: 1.16 $ # $Date: 1997/03/12 19:06:41 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SWISSPROT_DB:$library:[SWISSPROT group:@SEQUENCE_LIBS subentries:@SwissprotFeatures_DB format:@SWISSPROT_FORMAT maxNameLen:20 files:{ $file:swissprot #GCG format # $file:seq #orig format } ] SWISSNEW_DB:$library:[SWISSNEW group:@SEQUENCE_LIBS subentries:@?SwissnewFeatures_DB format:@SWISSPROT_FORMAT maxNameLen:20 files:{ $file:swissnew } ] SWISSPROT_FORMAT:$libformat:[contains:@PROTSEQ_DATA fileType:{@GCGREF_FILE @GCGSEQ_FILE} #GCG format # fileType:{@DAT_FILE @SEQ_FILE} #orig format syntax:@SWISSPROT_SYNTAX tableFormat:left fields:{ $field:[@DF_ID code:id index:id indexToken:id] $field:@DF_ALL $field:[@DF_Accession code:acc index:str indexToken:acc] $field:[@DF_Description code:des index:str indexToken:des tableToken:'clFields|des'] $field:[@DF_GeneName code:gene index:str indexToken:gene] $field:[@DF_Date code:date index:int indexToken:date tableToken:t_date] $field:[@DF_Organism code:{org tax} index:str indexToken:org] $field:[@DF_Organelle code:organ index:str indexToken:organ] $field:[@DF_Authors code:refaut index:str indexToken:authors] $field:[@DF_Citation code:rl index:str indexToken:cit tableToken:'clFields|rl'] $field:[@DF_LINK index:link code:link indexToken:link] $field:[@DF_SeqLength index:int indexToken:seqlen code:seqln] $field:[@DF_MolWeight index:int indexToken:molweight code:seqln] $field:[@DF_CommentType index:str indexToken:'cc|ttl' code:cc] $field:[@DF_Comment index:str indexToken:'cc|word' code:cc tableToken:'t_comment'] $field:[@DF_FtKey index:str indexToken:ftKey code:ft indexId:@SUBENTRY_ID] $field:[@DF_FtDescription index:str indexToken:ftDes code:ft indexId:@SUBENTRY_ID] $field:[@DF_FtLength index:int indexToken:ftLen code:ft indexId:@SUBENTRY_ID] # SwissSeq:$field:[@DF_ProtSequence token:'sequence' format:swiss] #orig format SwissSeq:$field:[@DF_ProtSequence token:gcgseq format:swiss tableFormat:left] #GCG format } ] SWISSPROT_SYNTAX:$syntax:[file:"SRSDB:swissprot.is" ignore:" \t"] $link:[@SWISSPROT_DB to:@?GENBANK_DB token: 'link|EMBL' toField:@DF_Accession] $link:[@SWISSPROT_DB to:@?EMBL_DB token:'link|EMBL' toField:@DF_Accession] $link:[@SWISSPROT_DB to:@?PIR_DB token:'link|PIR' toField:@DF_Accession] $link:[@SWISSPROT_DB to:@?PDB_DB token:'link|PDB'toField:@DF_ID] $link:[@SWISSPROT_DB to:@?REBASE_DB toField:@DF_ID] $link:[@SWISSPROT_DB to:@?OMIM_DB token:'link|MIM' toField:@DF_ID] $link:[@SWISSPROT_DB to:@?MEDLINE_DB toField:@DF_ID] $link:[@SWISSPROT_DB to:@?ENZYME_DB fromField:@DF_Description toField:@DF_ID] SwissprotFeatures_DB:$library:[SWISSPROT_features format:@SwissprotFeature_Format ] SwissprotFeature_Format:$libformat:[syntax:@SWISSPROT_SYNTAX contains:@PROTSEQ_DATA tableFormat:left fields:{ $field:[@DF_ID token:ftId] $field:[@DF_FtKey token:ft tableToken:'t_ft|key'] $field:[@DF_FtLength token:ft tableToken:'t_ft|len'] $field:[@DF_FtDescription token:ft tableToken:'t_ft|des'] $field:[@DF_ProtLocation token:ftLoc parent:@SwissSeq] } ] omField:@DF_Description toField:@DF_ID] SwissprotFeatures_DB:$library:[SWISSPROT_features format:@SwissprotFeature_Format ] SwissprotFeature_Format:$libformat:[syntax:@SWISSPROT_SYNTAX csrs/icarus/db/swissprot.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: swissprot.is,v $ # $Revision: 1.16 $ # $Date: 1997/03/13 19:39:52 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $fn={ ID:id OG:organ KW:key RN:refn AC:acc OC:tax RP:refp DT:date OS:org SQ:seqln RC:refc DE:des CC:cc RL:rl RA:refaut GN:gene DR:link RM:refm RX:refx } $rules={ entry: ~ {$In:[file:text] $Out pre $Skip:0} ('ID ' {$not} lnT)* (/ID +([A-Z0-9_]+)/ {$entryFip=$Fip $Wrt $entryName=$1} lnT {$App} (/( |ID|>>)/ {$Not} lnT {$App})+ )? ~ lnT: ~ /[^\n]+\n?/ ~ # line terminator may be missing if truncated sequence: ~ {$In:[file:seq share:text] $Out pre {$s=$SeqNew:$entryName $seqFip=$Fip} $Wrt:[s:$entryName] $SeqMake:$s} ('ID' {$Not} ln {$SeqApp:[$s s:$Ct]})* ~ gcgseq: ~ {$In:[file:seq] $Out pre {$seqFip=$Fip} $SeqMake:$s} '>>>>' name {$Wrt:[s:$Ct] $s=$SeqNew:$Ct} ln ln ('>>>>' {$Not} ln {$SeqApp:[$s s:$Ct]})+ ~ # extracting data fields fields: ~ {$In:entry $Out $Skip:1} (ftln | /../ { $t=$Ct if:$t==$prev $App else $Wrt:$fn.$t if:$fn.$t=="" $dp:"+++ unknown: $t in $entryName +++" $prev=$t } ln {$App})+ ~ ftln: ~ {$Wrt:ft} 'FT' ln ('FT ' ln)* ~ clFields: ~ {$In:fields $Out $Skip:1} /.. */ ln {$Wrt:$Itc} (/.. */ ln {$App})* ~ # for indexing date: ~ {$In:[fields c:date] $Out init $month={JAN:1 FEB:2 MAR:3 APR:4 MAY:5 JUN:6 JUL:7 AUG:8 SEP:9 OCT:10 NOV:11 DEC:12}} /.* ([0-9]+)-([A-Z]+)-([0-9]+).+CRE/ {$Wrt:[credate s:($1 + $month.$2*100 + $3*10000)]} ~ id: ~ {$In:[entry] $Out} /ID +([a-zA-Z0-9_]+)/ {$Wrt:[s:$1]} ~ acc: ~ {$In:[clFields c:acc] $Out} (/[a-zA-Z0-9_]+/ {$Wrt} | ';')+ ~ des: ~ {$In:[clFields c:des] $Out} (/[a-zA-Z0-9_]+/ {$Uniq} | /\\(EC *([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)/ {$Uniq:[s:$1]}| /[^a-aA-Z0-9(_\n]+/ | /[^\n]/)* ~ gene: ~ {$In:[clFields c:gene] $Out} (/[^ .\n]+/ {$Wrt} ('AND' | 'OR')?)* ~ authors: ~ {$In:[clFields c:refaut] $Out} (/([^.,\n]+) +([^,;\n]+)/ {$Uniq:[s:"$1,$2"]} /[,;]/)* ~ seqlen: ~ {$In:[fields c:seqln] $Out} /.* ([0-9]+) * AA/ {$Wrt:[s:$1]}~ molweight: ~ {$In:[fields c:seqln] $Out} /.* ([0-9]+) * MW/ {$Wrt:[s:$1]}~ keywords: ~ {$In:[clFields c:key] $Out} (/[^;.]+/ {$Wrt} | /[.;]+/)* ~ org: ~ {$In:[clFields c:{org tax}] $Out} (/(AND *)?([^;,.\n(]+[^ (;,.\n])/ {$Wrt:[s:$2]} | /\\(([^)]+)\\)/ {$Wrt:[s:$1]} | /[,;.]/)* ~ organ: ~ {$In:[clFields c:organ] $Out} (/(AND *)?([^,.\n]+)/ {$Wrt:[s:$2]} | /,./)* ~ link: ~ {$In:[clFields c:link] $Out} (dbName {$db=$Ct} ';' accno {$Wrt:$db} ln )* ~ cit: ~ {$In:[fields c:rl] $Out} /.. *([^\n]+) ([0-9]+):([0-9]+)-[0-9]+\\(([0-9]+)\\)/? {$Uniq:[jnl s:$Trim:$1] $Uniq:[vol s:$2] $Uniq:[page s:"$3-"] $Uniq:[year s:$4]} ~ cc: ~ {$In:[clFields c:cc] $Out} (/-!- *([^: \n]+( [^: \n]+)?):/ {$Wrt:[ttl s:$1]} | /[A-Z0-9_]+/{$Uniq:word} | /./)* ~ # indexing features ftKey: ~ {$In:[clFields c:ft count:ft var:$ftN] $Out} ftK {$Wrt:[n:$ftN]} ~ ftK: ~ /[A-Z0-9_]+/ ~ ftDes: ~ {$In:[clFields c:ft count:ft var:$ftN] $Out} ftK num num (/[A-Za-z0-9_]+/ {$Uniq:[n:$ftN]} | /[^A-Za-z0-9_]+/)* ~ ftLen: ~ {$In:[clFields c:ft count:ft var:$ftN] $Out} ftK ftl {if:$ftN>0 $Wrt:[n:$ftN s:$len]} ~ ftl: ~ /([0-9]+) +([0-9]+)/ {$len = $2-$1+1} | num {$len=0} num ~ # display features ftId: ~ {$In:[fields c:id] $Out} /.. *([A-Z0-9_]+)/{$Wrt:[s:"ID $1\_$subEntryN; parent: $1"]}~ ft: ~ {$In:[fields c:ft count:ft var:$ftN select:$subEntryN] $Out} /.*/ {$Wrt} ~ ftLoc: ~ {$In:ft $Out $Skip:1 init $SdbFunctions} 'FT' /[^ \n]+/ ftl {$Wrt} ~ t_ft: ~ {$In:ft $Out $Skip:1} 'FT' /[^ \n]+/ {$Wrt:key} ftl {$Wrt:loc if:$len>0 $Wrt:[len s:$len]} ln? {$Wrt:des} ('FT' ln {$App})* ~ h_ftId: ~ {$In:[ftId t:html]} /.*parent: */ /[A-Z0-9_]+/ {$Rep:{$ParStr:swissidR $Ct $Ct}} ~ # table view t_date: ~ {$In:[fields c:date] $Out} /.* ([0-9]+-[A-Z]+-[0-9]+).+CRE/ {$Wrt:[s:$1]} ~ t_comment: ~ {$In:[clFields c:cc] $Out} /.+/ {$Wrt} ~ # printing in HTML format # h_head: ~ {$In:[fields c:_head t:html] pre $Print:$ParStr:headR} /./ ~ h_id: ~ {$In:[fields c:id t:html]} /../ name {$entryName=$Ct} ~ h_refx: ~ {$In:[fields c:refx t:html]} /../ 'MEDLINE;' /[0-9]+/ {$Rep:{$ParStr:medlineR $Ct $Ct}} ~ h_des: ~ {$In:[fields c:des t:html]} (/(\\(EC )([0-9.-]+)/ {$Rep:{"$1($ParStr:enzymeR)" $2 $2}} | /[^ ]+/ )* ~ # h_features:~ {$In:[fields c:ft t:html count:ft var:$ftN]} # ('FT ' /[A-Z0-9_]+/ # {$Rep:{$ParStr:"($libName)FtR" $entryName $ftN $Ct}} )? ~ htmlTag: ~ /<[^<>]*>/ ~ h_links: ~ {$In:[fields c:link t:html] init $hl={ 'AARHUS/GHENT-2DPAGE': aarhusR 'SWISS-2DPAGE': swiss2dpageR DICTYDB: dictydbR GCRDB: gcrdbR MAIZEDB: maizedbR WORMPEP: ormpepR ENZYME: enzymeR LISTA: listaR PIR: pirR YEPD: yepdR EMBL: emblR SGD: sgdR HSSP: hsspR STYGENE: stygeneR PROSITE: prositeR HIV: hivR ECOGENE: ecogeneR ECO2DBASE: eco2dbaseR MIM: mimR SUBTILIST: subtilistR PDB: pdbR FLYBASE: flybaseR TRANSFAC: transfacR REBASE: rebaseR }} (/DR/ dbName {$db=$Ct} ';' accno {$Rep:{$ParStr:$hl.$db $Ct $Ct}} ln)* ~ h_comment: ~ {$In:[t_comment t:html]} x{$Rep:'
'} (/-!- *([^: \n]+( [^: \n]+)?):/ {$Rep:"
$1
"} | /[A-Z0-9_]+/ | /./)* x{$Rep:'
'} ~ # other stuff ln: ~ /[^\n]*\n/ ~ accno: ~ /[A-Z0-9]+/ ~ num: ~ /(<|>)?[0-9?]+/ ~ name: ~ /[a-zA-Z0-9_-]+/ ~ dbName: ~ /[^;]+/ ~ } # debugging $subEntryN=3 if:$TestMode { $job = $JobNew:[prod:$rules skip:" \n" fileName:'/data/gcg/gcgswissprot/swissprot.ref'] while:$JobHasInput:$job { $JobTokens:[$job name:fields print:1] $JobNext:$job $print:"-------->entry\n" } } srs/icarus/db/swissprot.it # # $RCSfile: swissprot.it,v $ # $Revision: 1.4 $ # $Date: 1997/03/19 20:30:39 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $dbInfo={ description: |The SWISS-PROT Protein Sequence Database is a database of protein |sequences produced collaboratively by Amos Bairoch (University of |Geneva) and the EMBL Data Library. The data in Swiss-Prot are derived |from translations of DNA sequences from the EMBL Nucleotide Sequence |Database, adapted from the Protein Identification Resource (PIR) |collection, extracted from the literature and directly submitted by |researchers. It contains high-quality annotation,is non-redundant, |and cross-referenced to several other databases, notably the EMBL |nucleotide sequence database, PROSITE pattern database and PDB. |SWISS-PROT is a curated protein sequence database which strives to |provide a high level of annotation (such as the description of the |function of a protein, its domain structure, post-translational |modifications, variants, etc), a minimal level of redundancy and a |high level of integration with other databases. Recent developments |of the database include: an increase in the number and scope of model |organisms; cross-references to seven additional databases; a variety |of new documentation files; the creation of TREMBL, an unannotated |supplement to SWISS-PROT. This supplement consists of entries in |SWISS-PROT-like format derived from the translation of all coding |sequences (CDS) in the EMBL nucleotide sequence database, except CDS |already included in SWISS-PROT. www: |
\ |http://expasy.hcuge.ch/sprot/sprot-top.html citation: |Amos Bairoch and Rolf Apweiler "The SWISS-PROT protein sequence |data bank and its new supplement TREMBL", Nucleic Acids Res. |24:(21-25), 1996 ftp:'ftp.ebi.ac.uk' fields: { Features: |The FT (Feature Table) lines provide a precise but simple means for |the annotation of the sequence data. The table describes regions |or sites of interest in the sequence. In general the feature table |lists post- translational modifications, binding sites, enzyme active |sites, local secondary structure or other characteristics reported in |the cited references. Sequence conflicts between references are also |included in the feature table. The feature table is updated when more |becomes known about a given sequence. FeatureLength: |Length of an amino acid sequence corresponed to some feature. The |length are defined by `FROM' and `TO' endpoint specifications. in |the Feature Table. entry.

Note: Ranges can be combined: |"300-!500 | !600-700" or "300-700 ! 500-600" retrieve the same set |of entries, namely all entries with feature lengths from 300 to 500, |excluding 500, plus lengths from 600 to 700 where the 600 is excluded. MolWeight: |Molecular Weight (MW) is rounded to the nearest gram. } date: |25 Jul 1996 signature: |Anatoly Ulyanov } are defined by `FROM' and `TO' endpoint specifications. in |the Feature Table. entry.

Note: Ranges can be combined: |"300-!500 | !600-700" or "300-700 ! 500-600" retrieve the same srs/icarus/db/taxonomy.i # $RCSfile: taxonomy.i,v $ # $Revision: 1.2 $ # $Date: 1997/03/03 18:34:21 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TAXONOMY_DB:$library:[TAXONOMY group:@SEQRELATED_LIBS format:@TAXONOMY_FORMAT maxNameLen:10 files:{ $file:tax } ] TAXONOMY_FORMAT:$libformat:[fileType:@DAT_FILE syntax:@TAXONOMY_SYNTAX fields:{ $field:[@DF_ID code:id index:id indexToken:id] $field:[@DF_ParentId code:parentId index:link indexToken:'parentId|ga'] $field:[@DF_Name code:name index:str indexToken:name] } ] TAXONOMY_SYNTAX:$syntax:[file:"SRSDB:taxonomy.is"] DF_ParentId:$srsfield:[ParentId short:pid] TAX_LINK:$link:[@TAXONOMY_DB to:@TAXONOMY_DB token:'parentId|ga' toField:@DF_ID fromField:@DF_ParentId fromName:TAX_DOWN toName:TAX_UP] $link:[@TAXONOMY_DB to:@TAXONOMY_DB toName:TAX_UP use:@TAX_LINK] $link:[@TAXONOMY_DB to:@TAXONOMY_DB fromName:TAX_DOWN use:@TAX_LINK] field:[@DF_ParentId code:parentId index:link indexToken:'parentId|ga'] $field:[@DF_Name code:name index:str indexToken:name] } ] TAXONOMY_SYNTAX:$syntax:[file:"SRSDB:taxonomy.is"] DF_ParentId:$srsfield:[ParentId short:pid] TAX_LINK:$link:[@TAXONOMY_DB to:@TAXONOMY_DB token:'parentId|ga' toField:@DF_ID fromField:@DF_ParentId fromName:TAX_DOWN toName:TAX_UP] $link:[@TAXONOMY_DB to:@TAXONOMY_DB toName:TAX_UP use:@TAX_LINK] $link:[@TAXONOMY_DB to:@TAXONOMY_DB fromName:TAX_DOWN srs/icarus/db/taxonomy.is $rules={ entry: ~ {$In:[file:text] $Out} ('ID' {$Not} ln)* ('ID ' {$entryFip=$Fip $Wrt} ln {$App} ('ID' {$Not} ln {$App})*)? ~ fields: ~ {$In:entry $Out} f_id f_parentId f_taxLevel f_tlInd f_name ~ f_id: ~ {$Wrt:id} /ID.[^:]+:/ ln ~ f_parentId: ~ {$Wrt:parentId} /Parent ID[^:]+:/ ln ~ f_taxLevel: ~ {$Wrt:taxLevel} /Taxonom.[^:]+:/ ln ~ f_tlInd: ~ {$Wrt:tlInd} /TlInd[^:]+:/ ln ~ f_name: ~ {$Wrt:name} /Name[^:]+:/ ln ~ # indexing id: ~ {$In:[fields c:id] $Out} tag num {$Wrt} ~ parentId: ~ {$In:[fields c:parentId] $Out} tag num {$Wrt:ga} ~ name: ~ {$In:[fields c:name] $Out} tag str {$Wrt} ~ tag: ~ /[^:]+: */ ~ ln: ~ /[^\n]*\n/ ~ num: ~ /[-0-9]*/ ~ str: ~ /[^\n]+/ ~ } Id: ~ {$Wrt:parentId} /Parent ID[^:]+:/ ln ~ f_taxLevel: ~ {$Wrt:taxLevel} /Taxonom.[^:]+:/ ln ~ f_tlInd: ~ {$Wrt:tlInd} /TlInd[^:]+:/ lnsrs/icarus/db/template.it # # $RCSfile: template.it,v $ # $Revision: 1.2 $ # $Date: 1996/10/30 10:20:22 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $dbInfo={ description: | www: | ftp: | email: | fax: | contact: | address: | literature: | updates: | fields:{ } } [^:]+:/ ln ~ f_tlInd: ~ {$Wrt:tlInd} / lnsrs/icarus/db/tfcell.i # $RCSfile: tfcell.i,v $ # $Revision: 1.4 $ # $Date 1996/02/28 # # Author: Chenna Ramu # TFCELL_DB:$library:[TFCELL group:@TRANSFAC_LIBS comment:"The TRANSFAC Database by Edgar Wingender and Rainer Knueppel" format:@TFCELL_FORMAT maxNameLen:10 ifiles:{"tfcell.i" "tfcell.is"} files:{ $file:cell } ] TFCELL_FORMAT:$libformat:[fileType:@DAT_FILE syntax:@TFCELL_SYNTAX tableFormat:left fields:{ $field:[@DF_ID code:ac index:id indexToken:ac] $field:[@DF_Date code:dt index:int indexToken:dt] $field:[@DF_Source code:so index:str indexToken:so] $field:[@DF_Organism code:os index:str indexToken:os] $field:[@DF_Description code:cd index:str indexToken:cd tableToken:'t_field|cd'] } ] TFCELL_SYNTAX:$syntax:[file:"SRSDB:tfcell.is" ignore:" "] "} files:{ $file:cell } ] TFCELL_FORMAT:$libformat:[fileType:@DAT_FILE syntax:@TFCELL_SYNTAX tableFormat:left fields:{ $field:[@DF_ID code:ac index:id indexToken:ac] $field:[@DF_Date code:dt insrs/icarus/db/tfcell.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: tfcell.is,v $ # $Revision: 1.4 $ # $Date: 1997/03/03 18:34:22 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $rules={ entry: ~ {$In:[file:text] $Out} ('AC' {$Not} ln)* ('AC ' {pre {$entryFip=$Fip} $Wrt} ln {$App} ('AC' {$Not} ln {$App})*)? ~ # fields fields: ~ {$In:entry $Out} f_ac f_xx f_dt f_xx f_so f_xx f_os f_xx f_cd f_xx f_xx ~ f_ac: ~ {$Wrt:ac} 'AC ' ln ~ f_dt: ~ {$Wrt:dt} ('DT ' ln)* ~ f_so: ~ {$Wrt:so} ('SO ' ln)* ~ f_os: ~ {$Wrt:os} ('OS ' ln)* ~ f_cd: ~ {$Wrt:cd} ('CD ' ln)* ~ f_xx: ~ {$Wrt:xx} ('XX' ln | '//' ln)? ~ # indexing ac: ~ {$In:[fields c:ac] $Out:ac} 'AC' /[0-9A-Za-z]+/ {$Wrt} ~ dt: ~ {$In:[fields c:dt] $Out:dt} 'DT' /([0-9]+).([0-9]+).([0-9]+)/ {$Wrt:[s:($1+$2*100+"19$3"*10000)]} ~ so: ~ {$In:[fields c:so] $Out:so} 'SO' (sep | word {$Wrt})* ~ os: ~ {$In:[fields c:os] $Out:os} 'OS' (sep | word {$Wrt})* ~ oc: ~ {$In:[fields c:cd] $Out:cd} 'CD' (sep | word {$Wrt})* ~ # table display t_field:~ {$In:[fields c:{cd}] $Out} tag ln {$Wrt:$Itc} (tag ln {$App})* ~ # other stuff tag: ~ /[^ \n][^ \n]/ ~ ln: ~ /[^\n]*\n/ ~ word: ~ /[a-zA-Z0-9_]+/ ~ sep: ~ /[^a-zA-Z0-9_]+/ ~ } if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/transfac/cell.dat'] while:$JobHasInput:$job { $JobTokens:[$job name:entry print:1] $JobNext:$job $print:"===============> entry <==============\n" } } sep | word {$Wrt})* ~ # table display t_field:~ {$In:[fields c:{cd}] $Out} tag ln {$Wrt:$Itc} (tag ln {$App})* ~ # other stuff tag: ~ /[^ \n][^ \n]/ ~ ln: ~ /[^\n]*\n/ ~ word: ~ /[a-zA-Z0-9_]+/ ~ sep: ~ /[^a-zA-Z0-9_]+/ ~ } if:$TestMode { $job = $JobNew:[psrs/icarus/db/tfcell.it # # $RCSfile: tfcell.it,v $ # $Revision: 1.3 $ # $Date: 1996/10/10 16:47:13 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $dbInfo={ description: |This table gives short explanations of the cellular sources of proteins |that interact with the sites listed in the SITES table. Among them |may be defined cell lines, tissues / organs, even whole organisms, or |recombinant expression systems. |

www: |\ |http://transfac.gbf-braunschweig.de/TRANSFAC/ citation: |E. Wingender , P. Dietze , H. Karas and R. Knppel, |"TRANSFAC: a database on transcription factors and their DNA binding sites" |Nucleic Acids Res. |24:(21-25), 1996 fields:{ Source: |The terminology of the factor sources (SO) corresponds to that used |in the SITES table (See TFSITE Source Field). Cell lines are given |with their most common name (e. g. , HeLa, 3T3), the most frequently |used tissues may be abbreviated (e.g., rl for rat liver), others are |explicitly mentioned. Organism: |Recombinant materials are explained by the denotation rec([source |organism] - [expressing cell]). Occasionally, a viral expression system |is also indicated: rec(chick-baculovirus-Sf9). Description: |The field contains line cell description. Sometimes some characteristics |of cell matirial are inclided. } date: |25 Jul 1996 } e most frequently |used tissues may be abbreviated (e.g., rl for rat liver), others are |explicitly mentioned. Organism: |Recombinant materials are explained by the denotation rec([source |organism] - [expressing cell]). Occasionally, a viral expression system |is also indicated: rec(chick-baculovirus-Sf9). Description: |The field contains line cell description. Somsrs/icarus/db/tfclass.i # $RCSfile: tfclass.i,v $ # $Revision: 1.5 $ # $Date 1996/02/28 # # Author: Chenna Ramu # TFCLASS_DB:$library:[TFCLASS group:@TRANSFAC_LIBS comment:"The TRANSFAC Database by Edgar Wingender and Rainer Knueppel" format:@TFCLASS_FORMAT maxNameLen:10 ifiles:{"tfclass.i" "tfclass.is"} files:{ $file:class } ] TFCLASS_FORMAT:$libformat:[fileType:@DAT_FILE syntax:@TFCLASS_SYNTAX tableFormat:left fields:{ $field:[@DF_Accession code:ac index:id indexToken:ac] $field:[@DF_ID code:sd index:str indexToken:id] $field:[@DF_Date code:dt index:int indexToken:date] $field:[@DF_CLASS code:cl index:str indexToken:class tableToken:'t_field|cl'] $field:[@DF_Comment code:cc index:str indexToken:cc tableToken:'t_field|cc'] } ] DF_CLASS:$srsfield:[Class short:cl] DF_STRDES:$srsfield:[StrDescrip short:sd] DF_COMM:$srsfield:[Comment short:cc] TFCLASS_SYNTAX:$syntax:[file:"SRSDB:tfclass.is" ignore:" "] $link:[@TFCLASS_DB to:@?PROSITE_DB token:'links|pr' toField:@DF_Accession] $link:[@TFCLASS_DB to:@?TFFACTOR_DB token:'bflink' toField:@DF_Accession] $field:[@DF_CLASS code:cl index:str indexToken:class tableToken:'t_field|cl'] $field:[@DF_Comment code:cc index:str indexToken:cc tableToken:'t_field|cc'] } ] DF_CLASS:$srsfield:[Class short:cl] DF_STRDES:$srsfield:[StrDescrip short:sd] DF_COMM:$srsfield:[Comment short:cc] TFCLASS_SYNTAX:$syntax:[file:"SRSDB:tfclass.is" ignore:" "] $link:[@TFCLASS_DB to:@?PROSITE_DB token:'links|pr' toFielsrs/icarus/db/tfclass.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: tfclass.is,v $ # $Revision: 1.4 $ # $Date: 1997/03/03 18:34:23 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $fn={ ID: id SD:sd RN:rn AC: ac CC:cc RA:ra XX:sp DT: dt BF:bf RT:rt '//':sp CL: cl DR:dr RL:rl } $rules={ entry: ~ {$In:[file:text] $Out pre $Skip:0} ('AC' {$Not} ln)* ('AC ' {$entryFip=$Fip $Wrt} ln {$App} ('AC' {$Not} ln {$App})+)? ~ # fields fields: ~ {$In:entry $Out $Skip:1} (/../ { if:$Ct==$prev $App else $Wrt:$fn.$Ct if:$fn.$Ct=="" $dp:"+++ unknown: $Ct +++" $prev=$Ct } ln {$App})+ ~ # indexing id: ~ {$In:[fields c:id] $Out} 'ID' /[0-9A-Za-z]+/ {$Wrt} ~ ac: ~ {$In:[fields c:ac] $Out} 'AC' /[0-9A-Za-z]+/ {$Wrt} ~ sd: ~ {$In:[fields c:sd] $Out} 'SD' /[0-9A-Za-z+_]+/ {$Wrt} ~ date: ~ {$In:[fields c:dt] $Out} 'DT' /([0-9]+).([0-9]+).([0-9]+)/ {$Wrt:[s:($1+$2*100+"19$3"*10000)]} ~ class: ~ {$In:[fields c:cl] $Out} 'CL' (sep | word {$Uniq})* ~ strDes: ~ {$In:[fields c:sd] $Out} 'SD' (sep | word {$Uniq})* ~ cc: ~ {$In:[fields c:cc] $Out} 'CC' (sep | word {$Uniq})* ~ links: ~ {$In:[fields c:dr] $Out} (tag 'Prosite:' word {$Wrt:pr} ln)+ ~ bflink: ~ {$In:[fields c:bf] $Out} (tag word {$Wrt} ln)+ ~ # table display t_field: ~ {$In:[fields c:{cc cl}] $Out} tag ln {$Wrt:$Itc} (tag ln {$App})* ~ # html display h_links: ~ {$In:[fields c:dr t:html]} (tag word ':' word {$Rep:{$ParStr:prositeR $Ct $Ct}} ln)+ ~ h_bf: ~ {$In:[fields c:bf t:html]} (tag word {$Rep:{$ParStr:tffactorR $Ct $Ct}} ln)+ ~ # other things ln: ~ /[^\n]*\n/ ~ word: ~ /[a-zA-Z0-9_]+/ ~ tag: ~ /[A-Z][A-Z]/ ~ sep: ~ /[^a-zA-Z0-9_]+/ ~ } if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/opt/srs/data/transfac/class.dat'] while:$JobHasInput:$job { $JobTokens:[$job name:links print:1] $JobNext:$job $print:"===============> entry <==============\n" } } + ~ h_bf: ~ {$In:[fields c:bf t:html]} (tag word {$Rep:{$ParStr:tffactorR $Ct $Ct}} ln)+ ~ # other things ln: ~ /[^\n]*\n/ ~ word: ~ /[a-zA-Z0-9_]+/ ~ tag: srs/icarus/db/tfclass.it # # $RCSfile: tfclass.it,v $ # $Revision: 1.3 $ # $Date: 1996/10/10 16:47:13 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $dbInfo={ description: |This record briefly explains some of the main features of the |DNA- binding domains of 26 transcription factor classes. In those |cases where an amino acid consensus motif has been identified, the |corresponding accession number of the PROCLASS database (A. Bairoch) is |included. www: |\ |http://transfac.gbf-braunschweig.de/TRANSFAC/ citation: |E. Wingender , P. Dietze , H. Karas and R. Knppel, |"TRANSFAC: a database on transcription factors and their DNA binding sites" |Nucleic Acids Res. |24:(21-25), 1996 fields:{ Class: |List of avaliable classes: |

    |
  • Factor family with homology to the ets-protooncogenes |
  • LIM domain |
  • MCM1-agamous-deficiens-SRF |
  • POU domain |
  • Rel-related factor |
  • TEA domain |
  • basic region + helix-loop-helix motif |
  • basic region + helix-loop-helix motif + leucine zipper |
  • basic region + leucine zipper |
  • fork head domain |
  • helix-loop-helix motif |
  • helix-loop-helix motif + leucine zipper |
  • helix-turn-helix |
  • high-mobility group protein-like factors |
  • homeodomain plus leucine zipper |
  • homeodomain; homeobox protein |
  • leucine zipper |
  • myb-like DNA-binding domains |
  • paired domain, paired box |
  • paired domain, paired box + homeo domain |
  • protamine-like domain |
  • zinc cluster; zinc-cysteine cluster; C6 zinc finger |
  • zinc finger |
  • zinc finger + homeo domain |
  • zinc finger; zinc twist |
Comment: |This field contains description of the class entry. It is a plain text |describing main characterisitics of DNA-binding protein class. StrDescrip: |List of avaliable structure descriptors: |
    |
  • C6 |
  • CC |
  • CC (g) |
  • CC (rec) |
  • CH |
  • CH+homeo |
  • ETS |
  • HLH |
  • HLH-ZIP |
  • HMG |
  • HTH |
  • LIM-homeo |
  • MADS |
  • POU |
  • Rel |
  • TEA |
  • ZIP |
  • bHLH |
  • bHLH-ZIP |
  • bZIP |
  • fork head |
  • homeo |
  • homeo-Zip |
  • myb |
  • paired |
  • paired-homeo |
  • protamine-like |
} } ors: |
    |
  • C6 |
  • CC |
  • CC (g) |
  • CC (rec) |
  • CH |
  • CH+homeo |
  • ETS |
  • HLH |
  • HLH-ZIP |
  • HMG |
  • HTH |
  • LIM-homeo |
  • MADS |
  • POU |
  • Rel |
  • TEA |
  • ZIP |
  • bHLH |
  • bHLH-ZIP |
  • srs/icarus/db/tffactor.i # $RCSfile: tffactor.i,v $ # $Revision: 1.8 $ # $Date 1996/02/28 # # Author: Chenna Ramu # TFFACTOR_DB:$library:[TFFACTOR group:@TRANSFAC_LIBS comment:"The TRANSFAC Database by Edgar Wingender and Rainer Knueppel" format:@TFFACTOR_FORMAT maxNameLen:15 ifiles:{"tffactor.i" "tffactor.is"} files:{ $file:factor } ] TFFACTOR_FORMAT:$libformat:[fileType:@DAT_FILE syntax:@TFFACTOR_SYNTAX fields:{ $field:[@DF_Accession code:id index:id indexToken:id] $field:[@DF_ID code:id index:str indexToken:id] $field:[@DF_Date code:dt index:int indexToken:dt] $field:[@DF_Organism code:os index:str indexToken:os] $field:[@DF_FF code:ff index:str indexToken:ff] $field:[@DF_Authors code:author index:str indexToken:author] $field:[@DF_Title code:rt index:str indexToken:title] $field:[@DF_REF code:reference index:str indexToken:reference] $field:[@DF_Interaction code:interact index:link indexToken:interact] } ] DF_FF:$srsfield:[FuncFeature short:ff] DF_Interaction:$srsfield:[Interaction short:ia] TFFACTOR_SYNTAX:$syntax:[file:"SRSDB:tffactor.is" ignore:" "] $link:[@TFFACTOR_DB to:@TFFACTOR_DB token:'interact' toName:TFFACTOR_IN fromField:@DF_Interaction toField:@DF_ID] $link:[@TFFACTOR_DB to:@?SWISSPROT_DB token:'links|swiss' toField:@DF_Accession] $link:[@TFFACTOR_DB to:@?EMBL_DB token:'links|embl' toField:@DF_Accession] $link:[@TFFACTOR_DB to:@?PIR_DB token:'links|pir' toField:@DF_Accession] } ] DF_FF:$srsfield:[FuncFeature short:ff] DF_Interacsrs/icarus/db/tffactor.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: tffactor.is,v $ # $Revision: 1.10 $ # $Date: 1997/03/17 23:21:09 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $refDb={EMBL: embl SwissProt:swiss PIR:pir Flybase:flybase} $fn={ ID: id SY:sy CS:cs IN:interact RN:rn DR:xref CP:cp AC: ac HO:ho SZ:sz FF:ff RA:ra XX:sp CN:cn DT: dt OS:os CL:cl BS:bs RT:rt '//':sp FA: fa OC:oc SF:sf MX:mx RL:rl FT:ft } $rules={ entry: ~ {$In:[file:text] $Out pre $Skip:0} ('AC' {$Not} ln)* ('AC ' {$entryFip=$Fip $Wrt} ln {$App} ('AC' {$Not} ln {$App})+)? ~ # fields fields: ~ {$In:entry $Out $Skip:1} (/../ { if:$Ct==$prev $App else $Wrt:$fn.$Ct if:$fn.$Ct=="" $dp:"+++ unknown: $Ct +++" $prev=$Ct } ln {$App})+ ~ # indexing id: ~ {$In:[fields c:id] $Out} 'ID' /[0-9A-Za-z]+/ {$Wrt} ~ dt: ~ {$In:[fields c:dt] $Out:dt} 'DT' /([0-9]+).([0-9]+).([0-9]+)/ {$Wrt:[s:($1+$2*100+"19$3"*10000)]} ~ os: ~ {$In:[fields c:os] $Out:os} 'OS' (sep | word {$Uniq})* ~ ff: ~ {$In:[fields c:ff] $Out:ff} 'FF' (sep | word {$Uniq})* ~ author: ~ {$In:[fields c:author] $Out:author} 'RA' (sep | word {$Uniq})* ~ title: ~ {$In:[fields c:rt] $Out:title} 'RT' (sep | word {$Uniq})* ~ reference: ~ {$In:[fields c:reference] $Out:reference} 'RL' (sep | word {$Uniq})* ~ interact: ~ {$In:[fields c:interact] $Out} (/../ word {$Wrt} ln)* ~ links: ~ {$In:[fields c:xref] $Out} ('DR' name {$db=$Ct} ':' word {$Wrt:$refDb.$db} ln)+ ~ # HTML display h_links: ~ {$In:[fields c:xref t:html]} (/DR/ word {$db=$Ct} ':' word {$Rep:{$parStr:"($refDb.$db)R" $Ct $Ct}} ln)* ~ h_bs: ~ {$In:[fields c:bs t:html]} (tag name ';' name {$Rep:{$ParStr:tfsiteR $Ct $Ct}} ln)+ ~ h_mx: ~ {$In:[fields c:mx t:html]} (tag name {$Rep:{$ParStr:tfmatrixR $Ct $Ct}} ln)+ ~ h_cl: ~ {$In:[fields c:cl t:html]} (tag /[a-zA-Z0-9+_-]+/ {$Rep:{$ParStr:tfclassR $Ct $Ct}} ln)+ ~ # other stuff ln: ~ /[^\n]*\n/ ~ tag: ~ /[A-Z][A-Z]/ ~ name: ~ /[A-Za-z][A-Za-z0-9$_]+/ ~ word: ~ /[a-zA-Z0-9_]+/ ~ sep: ~ /[^a-zA-Z0-9_]+/ ~ } if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/transfac/factor.dat'] while:$JobHasInput:$job { $JobTokens:[$job name:fields print:1] $JobNext:$job $print:"===============> entry <==============\n" } } (tag /[a-zA-Z0-9+_-]+/ {$Rep:{$ParStr:tfclassR $Ct $Ct}} ln)+ ~ # other stuff ln: ~ /[^\n]*\n/ ~ tag: ~ /[A-Z][A-Z]/ ~ name: ~ /[A-Za-z][Asrs/icarus/db/tffactor.it # # $RCSfile: tffactor.it,v $ # $Revision: 1.4 $ # $Date: 1996/10/30 10:20:24 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $dbInfo={ description: |The FACTORS table contains 1236 entries, but this figure doesn't |reflect the number of independent transcription factors. First of all, |homologous factors from different species such as human and mouse SRF |are given in different entries since they may differ in some molecular |aspects. Moreover, factors which have originally been described by |different research groups to bind to different genes may turn out to |be identical as soon as they have been cloned. On the other hand, |more and more factors are recognized to be representatives of whole |transcription factor families comprising products of distinct but very |similar genes or alternative splice products. In many cases, a more |general term originally defining just a specific DNA-binding activity |such as AP-1 appears as one entry. In most cases, this activity has not |been analyzed for its subunit composition by members of the Jun and |Fos families. Nevertheless, all known fos- and jun-related proteins |are included as separate entries.

    All factors that are mentioned |in the SITES table appear in the FACTORS table as well. However, it |includes also polypeptides which do not bind to DNA by themselves. One |well-known example is c-Fos which is forced to contact DNA not until |being complexed with, e. g., c-Jun. Information about non-DNA binding |subunits of transcription factor complexes such as the TAFs is given by |FACTORS as well. There are also proteins that act as inhibitors for a |particular DNA-binding activity and which are of regulatory importance. |Therefore, proteins such as Id, IkappaB or hsp90 have been included in |TRANSFAC FACTORS.

    On the other hand, we have in general not yet |entered proteins just because of the presence of a putative DNA-binding |motif. Thus, there are much more zinc finger or homeo domain proteins |known than are included in FACTORS, but for many of them, no data about |DNA- binding specificity or about other gene important regulatory |features are available. |

    |List of Line Codes |

    |ID Identifier |XX |AC Accession no. |XX |DT Date; author |XX |FA Factor name |XX |SY Synonyms |XX |HO Homologs (suggested) |XX |OS Species |OC Classification |XX |CS Cell specificity |XX |SZ Size |XX |CL Class |XX |SF Structural features |XX |IN Interacting factors |XX |FF Functional features |XX |BS Bound sites |XX |MX Matrix (0/1) |XX |RN Reference no. |RA Reference authors |RT Reference title |RL Reference data |XX |DR External databases (EMBL/GenBank accession no.; EMBL identifier | DR (_g_ene/_r_na); SwissProt accession no.; identifier; PIR | number; |DR code) | www: |\ |http://transfac.gbf-braunschweig.de/TRANSFAC/ literature: |E. Wingender , P. Dietze , H. Karas and R. Knppel, |"TRANSFAC: a database on transcription factors and their DNA binding sites" |Nucleic Acids Res. |24:(21-25), 1996 ftpSite:'' date: |25 Jul 1996 signature: |Anatoly Ulyanov fields:{ Synonyms: |

    TFFACTOR Synonyms Field

    |
    The field Synonyms covers different spelling (AP-1/AP1) |as well as real alternative names (HNF-1: HNF-1alpha, APF, LF-B1). In |contrast, the field Suggested Homologs indicates the names of other |proteins, frequently from evolutionarily more distant species, which |may be functionally and/or structurally related to the factor under |consideration.

    CellSpecif: |

    TFFACTOR CellSpecif Field

    |
    Cell Specificity gives predominant occurrence of a factor |in certain cell types or tissues. Gradual differences between groups of |cells/tissues are indicated by a semicolon. Occasionally, cells from |which the factor has been isolated are indicated in brackets; this |information does not necessarily point to a true cell specificity. |


    The Size field shows the number of amino acid residues of a |polypeptide and its molecular weight. The method by which this figure |has been obtained is indicated in brackets; (cDNA) or (gene) means that |it has been calculated after cloning, (SDS) or (sedim.) hints on the |corresponding experimental approaches.

    Features: |

    TFFACTOR Features Field

    |The field Structural Features may contain information on: |
  • regions that are enriched in some amino acid residues and |may therefore represent trans-activating domains; S/T stands for |serine/threonine-rich, ac for acidic, Pro for proline-rich, Q for |glutamine-rich, A for alanine-rich regions, W for peculiar tryptophan |patterns.
  • the nature of a leucine zipper: L4 means that it |consists of four leucine residues spaced by 6-AA-intervals, L2EL2 |indicates a motif such as L-X6-L-X6-E-X6-L-X6-L. |
  • posttranslational modifications: P or Ph indicates a site of |phosphorylation, glyc of glycosylation.
  • Interaction: |

    TFFACTOR Interaction Field

    |The field Interactions:
  • Since most transcription |factors bind to DNA as dimers, the dimerization partners are |indicated in this field. Repeating the factors name in this |field means that it forms homodimers. Also given are inhibitory |protein-protein-interactions such as NF-kappaB - IkappaB.
|
  • Matrix: |

    TFFACTOR Matrix Field

    |The field Matrix indicates a crossreference if there exists a |nucleotide distribution matrix for this factor in the MATRIX table.

    } } factors bind to DNA as dimers, the dimerization partners are |indicated in this field. Repeating the factors name in this |field means that it forms homodimers. Also given are inhibitory |protein-protein-interactions such as NF-kappaB - IkappaB.entry\n" } } (tag (name {$Rep:{$ParStr:tfsiteR $Ct $Ct}} ';'?)+ ln)+ ~ # others num: ~ /-?[0-9]+/ ~ tag: ~ /[A-Z][A-Z0-9]/ ~ ln: ~ /[^\n]*\n/ ~ name: ~ /[a-zA-Z0-9$_-]+/ ~ word: ~ /[a-zA-Z0-9_]+/ ~ sep: ~ /[^a-zA-Z0-9_\n]+/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/opt/srs/data/transfac/gene.dat'] while:$JobHasInput:$job { $JobTokens:[$job name:fields print:0] $JobNext:$job $print:"-------->entrsrs/icarus/db/tfmatrix.i # $RCSfile: tfmatrix.i,v $ # $Revision: 1.7 $ # $Date 1996/02/28 # # Author: Chenna Ramu # TFMATRIX_DB:$library:[TFMATRIX group:@TRANSFAC_LIBS comment:"The TRANSFAC Database by Edgar Wingender and Rainer Knueppel" format:@TFMATRIX_FORMAT maxNameLen:15 ifiles:{"tfmatrix.i" "tfmatrix.is"} files:{ $file:matrix } ] TFMATRIX_FORMAT:$libformat:[fileType:@DAT_FILE syntax:@TFMATRIX_SYNTAX fields:{ $field:[@DF_ID code:id index:id indexToken:id] $field:[@DF_Accession code:acc index:str indexToken:acc] $field:[@DF_Date code:date index:int indexToken:date] $field:[@DF_BINDFAC code:bf index:str indexToken:bf] $field:[@DF_STATBAS code:statBas index:str indexToken:statBas] $field:[@DF_COMMENT code:comm index:str indexToken:comm] $field:[@DF_Authors code:ra index:str indexToken:ra] $field:[@DF_REFTITLE code:refTit index:str indexToken:refTit] $field:[@DF_REF code:refData index:str indexToken:refData] } ] DF_BINDFAC:$srsfield:[BindingFactor short:bf] DF_STATBAS:$srsfield:[StatisticBasis short:stb] DF_REFTITLE:$srsfield:[Title short:tit] TFMATRIX_SYNTAX:$syntax:[file:"SRSDB:tfmatrix.is" ignore:" "] eld:[@DF_STATBAS code:statBas index:str indexToken:statBas] $field:[@DF_COMMENT code:comm index:str indexToken:comm] $field:[@DF_Authors code:ra index:str indexToken:ra] $field:[@DF_REFTITLE code:refTit index:str indexToken:refTit] $field:[@DF_REF code:refData index:str indexToken:refData] } ] DF_BINDFAC:$srsfield:[BindingFactor short:bfsrs/icarus/db/tfmatrix.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: tfmatrix.is,v $ # $Revision: 1.8 $ # $Date: 1997/03/03 18:34:26 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $fn={ ID:id BF:bf RN:refNum XX:sep AC:acc BA:statBas RP:refp '//':sep DT:date CC:comm SQ:seqln RT:refTit NA:na DE:de RL:refData RA:ra } $rules={ entry: ~ {$In:[file:text] $Out:entry pre $Skip:0} ('AC' {$Not} ln)* ('AC' {$entryFip=$Fip $Wrt} ln {$App} ('AC' {$Not} ln {$App})+)? ~ # fields fields: ~ {$In:entry $Out $Skip:1} (po | /../ { if:$Ct==$prev $App else $Wrt:$fn.$Ct if:$fn.$Ct=="" $dp:"+++ unknown: $Ct in $entryName +++" $prev=$Ct } ln {$App})+ ~ po: ~ {$Wrt:po} 'P0' ln (/[0-9][0-9]/ ln)+ ~ # indexing id: ~ {$In:[fields c:id] $Out} tag /[0-9A-Za-z$_]+/ {$Wrt} ~ ac: ~ {$In:[fields c:acc] $Out:acc} tag /[0-9A-Za-z]+/ {$Wrt} ~ dt: ~ {$In:[fields c:date] $Out:date} tag skipChar /([0-9]+).([0-9]+).([0-9]+)/ {$Wrt:[s:($1+$2*100+"19$3"*10000)]}~ bf: ~ {$In:[fields c:bf] $Out} (tag (sp | word {$Uniq})* '\n')+ ~ ra: ~ {$In:[fields c:ra] $Out:ra $Break} (tag (/([^.,\n]+) +([^,;\n]+)/ {$Uniq:[s:"$1,$2"]} /[,;]/)*)+ ~ statBas: ~ {$In:[fields c:statBas] $Out:statBas} tag (sp | word {$Uniq})* ~ refTit: ~ {$In:[fields c:refTit] $Out:refTit} tag (sp | word {$Uniq})* ~ refData: ~ {$In:[fields c:refData] $Out:refData} tag (sp | word {$Uniq})* ~ comm: ~ {$In:[fields c:comm] $Out:comm} tag (sp | word {$Uniq})* ~ # common things tag: ~ /[A-Z][A-Z]/ ~ ln: ~ /[^\n]*\n/ ~ word: ~ /[a-zA-Z0-9_]+/ ~ sp: ~ /[^a-zA-Z0-9_]+/ ~ skipChar: ~ /[^0-9.]+/ ~ } if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/transfac/matrix.dat'] while:$JobHasInput:$job { $JobTokens:[$job name:fields print:1] $JobNext:$job $print:"===============> entry <==============\n" } } (sp | word {$Uniq})* ~ comm: ~ {$In:[fields c:comm] $Out:comm} tag (sp | word {$Uniq})* ~ # common things tag: ~ /[A-Z][A-Z]/ ~ ln: ~ /[^\n]*\n/ ~ word: ~ /[a-zA-Z0-9_]+/ ~ sp: ~ /[^a-zA-Z0-9_]+/ ~ skipChar: ~ /[^0-9.]+/ ~ } if:$TestMode { $job = $JobNew:[prod:$rulesrs/icarus/db/tfmatrix.it # # $RCSfile: tfmatrix.it,v $ # $Revision: 1.4 $ # $Date: 1996/10/30 10:20:25 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $dbInfo={ description: |The MATRIX table contains 26 nucleotide distribution matrices of |aligned binding sequences. These sequences may have been obtained by in |vitro selection studies or may be compiled sites of genes. The source |is appropriately indicated. |

    |List of Line Codes |

    |AC Accession no. |DT Date; author |BF Binding factor |PO A C G T Position within the aligned | sequences, | frequency of A, C, G, T | residues, resp. |BA Statistical basis |CC Comments |RN Reference no. |RA Reference authors |RT Reference title |RL Reference data | www: |

    |\ |http://transfac.gbf-braunschweig.de/TRANSFAC/ |

    citation: |E. Wingender , P. Dietze , H. Karas and R. Knppel, |"TRANSFAC: a database on transcription factors and their DNA binding sites" |Nucleic Acids Res. |24:(21-25), 1996 date: |25 Jul 1996 signature: |Anatoly Ulyanov } nce no. |RA Reference authors |RT Reference title |RL Reference data srs/icarus/db/tfsite.i # $RCSfile: tfsite.i,v $ # $Revision: 1.10 $ # $Date: 1997/03/03 18:34:27 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TFSITE_DB:$library:[TFSITE group:@TRANSFAC_LIBS comment:"The TRANSFAC Database by Edgar Wingender and Rainer Knueppel" format:@TFSITE_FORMAT maxNameLen:15 ifiles:{"tfsite.i" "tfsite.is"} files:{ $file:site } ] TFSITE_FORMAT:$libformat:[fileType:@DAT_FILE syntax:@TFSITE_SYNTAX tableFormat:left fields:{ $field:[@DF_ID code:id index:id indexToken:id tableToken:id] $field:[@DF_Accession code:ac index:str indexToken:'wrd|ac'] $field:[@DF_Date code:dt index:int indexToken:dt tableToken:t_date] $field:[@DF_SequenceType code:ty index:str indexToken:'wrd|ty'] $field:[@DF_ElemDenom code:el index:str indexToken:'wrd|el'] $field:[@DF_SiteFirstPos code:sf index:int indexToken:sf] $field:[@DF_SiteLastPos code:st index:int indexToken:st] $field:[@DF_DefineFirstPos code:s1] $field:[@DF_Organism code:os index:str indexToken:'words|os'] $field:[@DF_Method code:me index:str indexToken:'words|me'] $field:[@DF_Description code:de index:str indexToken:'words|de' tableToken:'t_field|de'] $field:[@DF_BindingFactor code:bf index:str indexToken:'words|bf'] $field:[@DF_FactorSource code:so index:str indexToken:'words|so'] $field:[@DF_Comment code:cc index:str indexToken:'words|cc' tableToken:'t_field|cc'] $field:[@DF_Sequence code:se index:str indexToken:'wrd|se'] } ] TFSITE_SYNTAX:$syntax:[file:"SRSDB:tfsite.is" ignore:" "] DF_BindingFactor:$srsfield:[BindingFactor short:bf] DF_SequenceType:$srsfield:[SequenceType short:st] DF_FactorSource:$srsfield:[FactorSource short:so] DF_SiteFirstPos:$srsfield:[SiteFirstPos short:sfp] DF_SiteLastPos:$srsfield:[SiteLastPos short:slp] DF_DefineFirstPos:$srsfield:[DefineFirstPos short:dfp] DF_ElemDenom:$srsfield:[ElementDenomination short:eld] $link:[@TFSITE_DB to:@?TFFACTOR_DB toField:@DF_ID token:bfRef] $link:[@TFSITE_DB to:@?TFCELL_DB toField:@DF_ID token:soRef] $link:[@TFSITE_DB to:@?EMBL_DB weight:9 toField:@DF_Accession token:'dr|embl'] $link:[@TFSITE_DB to:@?FLYGENE_DB toField:@DF_ID token:'dr|flybase'] [FactorSource short:so] DF_SiteFirstPos:$srsfield:[SiteFirstPos short:sfp] DF_SiteLastPos:$srsfield:[SiteLastPos short:slp] DF_DefineFirstPos:$srsfield:[DefineFirstPos short:dfp] DF_ElemDenom:$srsfield:[ElementDenomination short:eld] srs/icarus/db/tfsite.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: tfsite.is,v $ # $Revision: 1.8 $ # $Date: 1997/03/03 18:34:27 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $fn={ ID: id DE:de ST:st OS:os RN:rn DR:xref MM:mm AC: ac SE:se S1:s1 OC:oc RA:ra XX:xln SQ:sq DT: dt EL:el CL:cl SO:so RT:rt '//':xln RE:re TY: ty SF:sf BF:bf ME:me RL:rl CC:cc } $rules={ entry: ~ {$In:[file:text] $Out pre $Skip:0} ('AC' {$Not} ln)* ('AC ' {$entryFip=$Fip $Wrt} ln {$App} ('AC' {$Not} ln {$App})+)? ~ # fields fields: ~ {$In:entry $Out $Skip:1} (/../ { if:$Ct==$prev $App else $Wrt:$fn.$Ct if:$fn.$Ct=="" $dp:"+++ unknown: $Ct +++" $prev=$Ct } ln {$App})+ ~ # indexing id: ~ {$In:[fields c:id] $Out $Break} tag /[0-9A-Za-z$_-]+/ {$Wrt} ~ wrd: ~ {$In:[fields c:{ac ty el se dt}] $Out} tag word {$Wrt:$Itc} ~ dt: ~ {$In:[fields c:dt] $Out} 'DT' /([0-9]+).([0-9]+).([0-9]+)/ {$Wrt:[s:($1+$2*100+"19$3"*10000)]} ~ words: ~ {$In:[fields c:{bf so cc de os me}] $Out} (tag (sep | /[a-zA-Z0-9+-]+/ {$Uniq:$Itc})* ln)+ ~ el: ~ {$In:[fields c:el] $Out} tag word {$Wrt} ~ se: ~ {$In:[fields c:se] $Out} tag word {$Wrt} ~ sf: ~ {$In:[fields c:sf] $Out} tag num {$Wrt} ~ st: ~ {$In:[fields c:st] $Out} tag num {$Wrt} ~ #links: bfRef: ~ {$In:[fields c:bf] $Out} (tag name {$Wrt} ln)+ ~ soRef: ~ {$In:[fields c:so] $Out} (tag name {$Wrt} ln)+ ~ dr: ~ {$In:[fields c:dr] $Out} (tag ('EMBL;' word {$Wrt:embl} | 'Flybase;' name {$Wrt:flybase}) ln)+ ~ # table display t_date: ~ {$In:[fields c:dt] $Out} tag /[0-9\.]+]/ {$Wrt} ~ t_field:~ {$In:[fields c:{de cc}] $Out} tag ln {$Wrt:$Itc} (tag ln {$App})* ~ # HTML display h_bf: ~ {$In:[fields c:bf t:html]} (tag name {$Rep:{$ParStr:tffactorR $Ct $Ct}} ln)+ ~ h_so: ~ {$In:[fields c:so t:html]} (tag /[0-9]+/ {$Rep:{$ParStr:tfcellR $Ct $Ct}} ln)+ ~ h_dr: ~ {$In:[fields c:dr t:html]} (tag ('EMBL;' word {$Rep:{$ParStr:emblR $Ct $Ct}} | 'Flybase;' word {$Rep:{$ParStr:flybaseR $Ct $Ct}} ) ln)+ ~ # others num: ~ /-?[0-9]+/ ~ tag: ~ /[A-Z][A-Z0-9]/ ~ ln: ~ /[^\n]*\n/ ~ name: ~ /[a-zA-Z0-9$_-]+/ ~ word: ~ /[a-zA-Z0-9_]+/ ~ sep: ~ /[^a-zA-Z0-9_\n]+/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/data/transfac/site.dat'] while:$JobHasInput:$job { $JobTokens:[$job name:fields print:0] $JobTokens:[$job name:so print:1] $JobNext:$job $print:"-------->entry\n" } } d {$Rep:{$ParStr:flybaseR $Ct $Ct}} ) ln)+ ~ # others num: ~ /-?[0-9]+/ ~ tag: ~ /[A-Z][A-Z0-9]/ ~ ln: ~ /[^\n]*\n/ ~ name: ~ /[a-zA-Z0-9$_-]+/ ~ word: ~ /[a-zA-Z0-srs/icarus/db/tfsite.it # # $RCSfile: tfsite.it,v $ # $Revision: 1.5 $ # $Date: 1997/03/03 18:34:28 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $dbInfo={ description: |As outlined above, SITES gives information on individual (putatively) |regulatory protein binding sites. It contains 4303 entries, 4038 |of them referring to sites within more than 841 eukaryotic genes, |the species of which ranging from yeast to human. Additionally, |this table comprises 315 artificial sequences which resulted from |mutagenesis studies, in vitro selection procedures starting from random |oligonucleotide mixtures or from specific theoretical considerations. |And finally, there are 224 consensus binding sequences given in the |IUPAC code, many of them being taken from the compilation of Faisst and |Meyer (Nucleic Acids Res. 20:3-26, 1992). The symbols used |in addition to A, C, G, or T for these consensi are:

    |
        |W: A or T                           S: C or G
        |R: A or G                           Y: C or T
        |K: G or T                           M: A or C
        |B: C, G, or T                       D: A, G, or T
        |H: A, C, or T                       V: A, C, or G
        |N: A, C, G, or T
        |
    |

    |List of Line Codes |

    |ID Identifier |XX |AC Accession no. |XX |DT Date; author |XX |TY Sequence type |XX |DE Description (gene or gene product) |XX |SE Sequence of the regulatory element |XX |EL Denomination of the element |XX |SF First position of factor binding site |ST Last position of factor binding site |S1 Definition of first position (if not transcription start site) |XX |BF Binding factor (TRANSFAC FACTORS accession no.; name) |XX |OS Species |OC Classification |XX |SO Factor source (TRANSFAC CELLS accession no.; name) |XX |ME Method |XX |RN Reference no. |RA Reference authors |RT Reference title |RL Reference data |XX |CC Comments |XX |DR External databases (EMBL/GenBank accession no.; |DR EMBL identifier (1st:last position of the TRANSFAC sequence |DR element) | ftp: |\ |ftp.gbf-braunschweig.de/pub/transfac/
    |
    \ |ftp.ebi.ac.uk/pub/databases/transfac/
    |file: site.dat address: |Gesellschaft fuer Biotechnologische Forschung mbH |Mascheroder Weg 1, D-38124 Braunschweig, Germany contact: |Edgar Wingender
    |Rainer Knueppel email: |ewi@venus.gbf-braunschweig.d400.de www: | |http://transfac.gbf-braunschweig.de/TRANSFAC/ literature: |
      |
    1. E. Wingender, Recognition of regulatory regions in genomic sequences. |J. Biotechnol. 35:273-280, 1994 |
    2. E. Wingender , P. Dietze , H. Karas and R. Knppel, |"TRANSFAC: a database on transcription factors and their DNA binding sites" |Nucleic Acids Res. |24:(21-25), 1996 |
    example: |HS\$EGFR_12 date: |6-OCT-1996 } | |http://transfac.gbf-braunschweig.de/TRANSFAC/srs/icarus/db/trembl.i # # $RCSfile: trembl.i,v $ # $Revision: 1.2 $ # $Date: 1997/03/03 18:34:28 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TREMBL_DB:$library:[TREMBL group:@SEQUENCE_LIBS format:@TREMBL_FORMAT maxNameLen:12 files:{ $file:trembl } ] TREMBLNEW_DB:$library:[TREMBLNEW group:@SEQUENCE_LIBS format:@TREMBL_FORMAT maxNameLen:12 files:{ $file:tremblnew } ] TREMBL_FORMAT:$libformat:[contains:@PROTSEQ_DATA fileType:{@DAT_FILE @SEQ_FILE} syntax:@TREMBL_SYNTAX tableFormat:left fields:{ $field:[@DF_ID code:id index:id indexToken:id] $field:@DF_ALL $field:[@DF_Description index:str indexToken:des code:des] $field:[@DF_ProtSequence token:sequence] } ] TREMBL_SYNTAX:$syntax:[file:"SRSDB:trembl.is" ignore:" \t"] ] TREMBLNEW_DB:$library:[TREMBLNEW group:@SEQUENCE_LIBS format:@TREMBL_FORMAT maxNameLen:12 files:{ $file:tremblnew } srs/icarus/db/trembl.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: trembl.is,v $ # $Revision: 1.1 $ # $Date: 1997/03/03 18:36:33 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $fn={ ID:id OG:organ OS:org OC:tax DR:link AC:acc FT:ft SQ:sq DE:des CC:cc } $rules={ entry: ~ {$In:[file:text] $Out pre $Skip:0} ('ID ' {$not} lnT)* (/ID +([A-Z0-9_]+)/ {$entryFip=$Fip $Wrt $entryName=$1} lnT {$App} (/( |ID|>>)/ {$Not} lnT {$App})+ )? ~ lnT: ~ /[^\n]+\n?/ ~ # line terminator may be missing if truncated sequence: ~ {$In:[file:seq share:text] $Out pre {$s=$SeqNew:$entryName $seqFip=$Fip} $Wrt:[s:$entryName] $SeqMake:$s} ('ID' {$Not} ln {$SeqApp:[$s s:$Ct]})* ~ gcgseq: ~ {$In:[file:seq] $Out pre {$seqFip=$Fip} $SeqMake:$s} '>>>>' name {$Wrt:[s:$Ct] $s=$SeqNew:$Ct} ln ln ('>>>>' {$Not} ln {$SeqApp:[$s s:$Ct]})+ ~ # extracting data fields fields: ~ {$In:entry $Out $Skip:1} (ftln | /../ { $t=$Ct if:$t==$prev $App else $Wrt:$fn.$t if:$fn.$t=="" $dp:"+++ unknown: $t in $entryName +++" $prev=$t } ln {$App})+ ~ ftln: ~ {$Wrt:ft} 'FT' ln ('FT ' ln)* ~ clFields: ~ {$In:fields $Out $Skip:1} /.. */ ln {$Wrt:$Itc} (/.. */ ln {$App})* ~ # for indexing id: ~ {$In:[entry] $Out} /ID +([a-zA-Z0-9_]+)/ {$Wrt:[s:$1]} ~ acc: ~ {$In:[clFields c:acc] $Out} (/[a-zA-Z0-9_]+/ {$Wrt} | ';')+ ~ des: ~ {$In:[clFields c:des] $Out} (/[a-zA-Z0-9_]+/ {$Uniq} | /\\(EC *([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)/ {$Uniq:[s:$1]}| /[^a-aA-Z0-9(_\n]+/ | /[^\n]/)* ~ seqlen: ~ {$In:[fields c:seqln] $Out} /.* ([0-9]+) * AA/ {$Wrt:[s:$1]}~ molweight: ~ {$In:[fields c:seqln] $Out} /.* ([0-9]+) * MW/ {$Wrt:[s:$1]}~ org: ~ {$In:[clFields c:{org tax}] $Out} (/(AND *)?([^;,.\n(]+[^ (;,.\n])/ {$Wrt:[s:$2]} | /\\(([^)]+)\\)/ {$Wrt:[s:$1]} | /[,;.]/)* ~ organ: ~ {$In:[clFields c:organ] $Out} (/(AND *)?([^,.\n]+)/ {$Wrt:[s:$2]} | /,./)* ~ # printing in HTML format h_id: ~ {$In:[fields c:id t:html]} /../ name {$entryName=$Ct} ~ hl_links: ~ {$In:[fields c:link t:html]} (/DR/ 'EMBL;' name {$Rep:{$ParStr:emblR $Ct $Ct}} ln)+ ~ h_des: ~ {$In:[fields c:des t:html]} (/(\\(EC )([0-9.-]+)/ {$Rep:{"$1($ParStr:enzymeR)" $2 $2}} | /[^ ]+/ )* ~ h_ft: ~ {$In:[fields c:ft t:html]} /.*EC_number="/ /[^"]+/ {$Rep:{$ParStr:enzymeR $Ct $Ct}} ~ # other stuff ln: ~ /[^\n]*\n/ ~ accno: ~ /[A-Z0-9]+/ ~ num: ~ /(<|>)?[0-9?]+/ ~ name: ~ /[a-zA-Z0-9_-]+/ ~ dbName: ~ /[^;]+/ ~ } # debugging $subEntryN=3 if:$TestMode { $job = $JobNew:[prod:$rules skip:" \n" fileName:'/data/trembl/trembl.dat'] while:$JobHasInput:$job { $JobTokens:[$job name:id print:1] $JobTokens:[$job name:des print:1] $JobNext:$job $print:"-------->entry\n" } } /.*EC_number="/ /[^"]+/ {$Rep:{$ParStr:enzymeR $Ct $Ct}} ~ # other stuff ln: ~ /[^\n]*\n/ ~ accno: ~ /[A-Z0-9]+/ ~ num: ~ /(<|>)?[0-9?]+/ ~ name: ~ /[a-zA-Z0-9_-]+/ ~ dbName: ~ /[^;]+/ ~ } # debugging $subEntsrs/icarus/db/views.i # # $RCSfile: views.i,v $ # $Revision: 1.5 $ # $Date: 1997/03/12 19:05:51 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $View:["* Names only *"] $View:[sequence_simple useShortFieldNames:1 root:{$Vlib:@?SWISSPROT_DB $Vlib:@?SWISSNEW_DB $Vlib:@?PIR_DB $Vlib:@?EMBL_DB $Vlib:@?EMBLNEW_DB $Vlib:@?GENBANK_DB} rootFields:{ $Vfield:@?DF_Description $Vfield:@?DF_Date $Vfield:@?DF_SeqLength } ] $View:[proteinChart root:{$Vlib:@?SWISSPROT_DB $Vlib:@?PIR_DB} rootFields:{ $Vfield:@?DF_Description $Vfield:[@?DF_ProtSequence format:proteinChart] } ] $View:[Blast_Ali_Swissprot root:$Vlib:@?BLAST_DB rootFields:{ $Vfield:@?DF_TopScore $Vfield:@?DF_TopMatch } leaves:$Vlib:[@?SWISSPROT_DB fields:{ $Vfield:@?DF_Description $Vfield:@?DF_SeqLength } ] ] $View:[Blast_Swissprot useShortFieldNames:1 root:$Vlib:@?BLAST_DB rootFields:{ $Vfield:@?DF_TopScore } leaves:{ $Vlib:[@?SWISSPROT_DB fields:{ $Vfield:@?DF_Description $Vfield:@?DF_SeqLength } ] $Vlib:[@?PROSITE_DB fields:{ $Vfield:@?DF_Description $Vfield:@?DF_ALLPOS } ] $Vlib:[@?ENZYME_DB fields:{ $Vfield:@?DF_CatActivity } ] } ] $View:[Blast_families useShortFieldNames:1 root:$Vlib:@?BLAST_DB rootFields:{ $Vfield:@?DF_TopScore } leaves:{ $Vlib:[@?SWISSPROT_DB fields:{ $Vfield:@?DF_Description $Vfield:@?DF_SeqLength } ] $Vlib:[@?PROSITE_DB] $Vlib:[@?BLAST_DB query:'entry>prosite>blast' printOnlyEntryN:1 viewName:Blast_Ali_Swissprot ] } ] $View:[Fasta_families useShortFieldNames:1 root:$Vlib:@?FASTA_DB rootFields:{ $Vfield:@?DF_OptScore } leaves:{ $Vlib:[@?SWISSPROT_DB fields:{ $Vfield:@?DF_Description $Vfield:@?DF_SeqLength } ] $Vlib:[@?PROSITE_DB] $Vlib:[@?FASTA_DB query:'entry>prosite>fasta' printOnlyEntryN:1 viewName:Fasta_Ali_Swissprot ] } ] $View:[Fasta_Ali_Swissprot root:$Vlib:@?FASTA_DB rootFields:{ $Vfield:@?DF_OptScore $Vfield:@?DF_Alignment } leaves:$Vlib:[@?SWISSPROT_DB fields:{ $Vfield:@?DF_Description $Vfield:@?DF_SeqLength } ] ] $View:[Sw_Ali_Swissprot root:$Vlib:@?SW_DB rootFields:{ $Vfield:@?DF_PercIdent $Vfield:@?DF_Alignment } leaves:$Vlib:[@?SWISSPROT_DB fields:{ $Vfield:@?DF_Description $Vfield:@?DF_SeqLength } ] ] $View:[Sw_Swissprot useShortFieldNames:1 root:$Vlib:@?SW_DB rootFields:{ $Vfield:@?DF_PercIdent $Vfield:@?DF_MatchLen } leaves:{ $Vlib:[@?SWISSPROT_DB fields:{ $Vfield:@?DF_Description $Vfield:@?DF_SeqLength } ] $Vlib:[@?PROSITE_DB fields:{ $Vfield:@?DF_Description $Vfield:@?DF_ALLPOS } ] $Vlib:[@?ENZYME_DB fields:{ $Vfield:@?DF_CatActivity } ] } ] $View:[prosite_simple root:$Vlib:@?PROSITE_DB rootFields:{ $Vfield:@?DF_Description } ] $View:[clustalw_ali root:$Vlib:@?CLUSTALW_DB rootFields:{ $Vfield:@?DF_NAlign $Vfield:@?DF_SeqList $Vfield:@?DF_Alignment } ] #$View:[familystat # root:[$Vlib:@ReptiliaTax_DB] # rootFields:{$Vfield:@DF_Name} # leaves: # $Vlib:[@GENBANK printOnlyEntryN:y # query:"entry >^ Reptiliatax_down > genbank" # query:"entry >^ Reptiliatax_down > reptilia" # ] #] $View:[reptilia root:$Vlib:@?REPTILIA_DB rootFields:{ $Vfield:@?DF_Synonyms $Vfield:@?DF_Distribution } ] ew:[clustalw_ali root:$Vlib:@?CLUSTALW_DB rootFields:{ $Vfield:@?DF_NAlign $Vfield:@?DF_SeqList $Vfield:@?DF_Alignment } ] #$View:[familystat # root:[$Vlib:@ReptiliaTax_DB] # rootFields:{$Vfield:@DF_Name} # leaves: # $Vlib:[@GENBANK printOnlyEntryN:y # querysrs/icarus/db/vwf.i # $RCSfile: vwf.i,v $ # $Revision: 1.3 $ # $Date: 1997/03/17 23:22:07 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ VWF_DB:$library:[VWF group:@MUTATION_LIBS format:@VWF_FORMAT maxNameLen:30 ifiles:{'vwf.i' 'vwf.is' 'vwf.it'} files:{ $file:'mut-LONG-list' } ] VWF_FORMAT:$libformat:[syntax:@VWF_SYNTAX fileType:@TXT_FILE printFormat:table tableFormat:left fields:{ $field:@DF_ALL $field:[@DF_ID indexToken:id index:id tableToken:id tableFormat:right] $field:[@DF_Class indexToken:class index:str tableToken:t_class] $field:[@DF_NuclChange code:dnaSubst indexToken:'dnaSubst|subst' index:str tableToken:'dnaSubst|subst' tableFormat:left] $field:[@DF_DnaChangePos code:dnaSubst indexToken:'dnaSubst|pos' index:int tableToken:'dnaSubst|pos' tableFormat:right] $field:[@DF_AaChange code:aaSubst indexToken:'aaSubst|subst' index:str tableToken:'aaSubst|subst' tableformat:left] $field:[@DF_ProtChangePos code:aaSubst indexToken:'aaSubst|pos' index:int tableToken:'dnaSubst|pos' tableFormat:right] $field:[@DF_FamilyN code:families indexToken:families index:int tableToken:families tableFormat:right] $field:[@DF_PatientN code:patent indexToken:patient index:int tableToken:patient tableFormat:right] $field:[@DF_PatientOrig code:patOri indexToken:patOri index:str tableToken:t_patOri tableFormat:left] $field:[@DF_AlleleN code:nAllele indexToken:nAllele index:int tableToken:nAllele tableFormat:right] $field:[@DF_FuncStudies code:funcStud indexToken:funcStud index:str tableToken:funcStud] $field:[@DF_LabName code:lab indextoken:lab index:str tableToken:t_lab] $field:[@DF_Comment code:cmnt indexToken:cmnt index:str tableToken:t_cmnt tableFormat:left] } ] VWF_SYNTAX:$syntax:[file:"SRSDB:vwf.is" ignore:" "] tOri index:str tableToken:t_patOri tabsrs/icarus/db/vwf.is #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: vwf.is,v $ # $Revision: 1.4 $ # $Date: 1997/03/18 13:43:24 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $rules={ entry: ~ {$In:[file:text] $Out pre {$Skip:0 $entryN+=1} init $entryN=0} ('Class:' {$Not} ln)* ('Class: ' {$entryFip=$Fip $Wrt} ln {$App} ('---' {$Not} ln {$App})+)? ~ # fields fields: ~ {$In:entry $Out $Skip:1} f_class f_subst f_families f_patient f_patOri f_nAllele f_funcStud f_lab f_cmnt (f_refTit f_ref+)? ~ f_class: ~ {$Wrt:class} ('Class:' ln)+ ~ f_subst: ~ {$Wrt:[s:$aa c:aaSubst] $Wrt:[s:$dna c:dnaSubst]} /[^\n]+/ {$aa=$Ct $Len:40} ln {$dna=$Ct} (' ' /[^\n]+/ {$Print:[$Ct v:$aa] $Len:37} ln {$Print:[$Ct v:$dna]})* ~ f_families: ~ {$Wrt:families} /[^:]+:[^A-Z]+/ ~ f_patient: ~ {$Wrt:patient} 'Affected patients' ln ~ f_patOri: ~ {$Wrt:patOri} 'Patient country' ln ~ f_nAllele: ~ {$Wrt:nAllele} /[^:]+:[^A-Z]+/ ~ f_funcStud: ~ {$Wrt:funcStud} /Function[^:]+:[^L]+/ ~ f_lab: ~ {$Wrt:lab} 'Lab:' ln ~ f_cmnt: ~ {$Wrt:cmnt} 'Comments:' ln (/ *\n/{$Not} ln)* ln ~ f_refTit: ~ {$Wrt:refTit} 'References' ln ln ~ f_ref: ~ {$Wrt:ref} (/ *\n/{$Not} ln)* ln ~ # indexing id: ~ {$In:entry $Out} /./ {$Break:[cond:$entryN=='20'] $print:$ga $Wrt:[s:$entryN]} ~ class: ~ {$In:[fields c:class] $Out} tag (word | sep)+ ~ families: ~ {$In:[fields c:families] $Out} tag num {$Wrt} ~ patient: ~ {$In:[fields c:patient] $Out} tag num {$Wrt} ~ patOri: ~ {$In:[fields c:patOri] $Out} tag (word | sep)+ ~ nAllele: ~ {$In:[fields c:nAllele] $Out} tag num {$Wrt} ~ funcStud: ~ {$In:[fields c:funcStud] $Out} tag /[yn?]/? {$Wrt} ~ lab: ~ {$In:[fields c:lab] $Out} tag (word | sep)+ ~ cmnt: ~ {$In:[fields c:cmnt] $Out} tag (word | sep)+ ~ aaSubst: ~ {$In:[fields c:aaSubst] $Out} tag (mut ('and' mut)*)? ~ dnaSubst: ~ {$In:[fields c:dnaSubst] $Out} tag (mut ('and' mut)*)? ~ # table format t_class: ~ {$In:[fields c:class] $Out} tag /.*/ {$Wrt} ~ t_patOri: ~ {$In:[fields c:patOri] $Out} tag /.*/ {$Wrt} ~ t_lab: ~ {$In:[fields c:lab] $Out} tag /.*/ {$Wrt} ~ t_cmnt: ~ {$In:[fields c:cmnt] $Out} tag /.*/ {$Wrt} ~ # table: ~ {$In:[fields c:{cmnt patOri lab cmnt}] $Out} # tag /.*/ {$Wrt:$Itc} ~ # html h_fields: ~ {$In:[fields t:html]} (x{if:$ParInt:[isTable] == 1 $Fail} (/Refere.+/ {$Rep:"$Ct"} | /[0-9]\..+/ {$Rep:"$Ct"} | /[^:]+:/ {$Rep:"$Ct"} /.*/? {$Rep:"$Ct"})?)? ~ # other stuff ln: ~ /[^\n]*\n/ ~ mut: ~ /([A-Z])([0-9]+)([A-Z*])/ {$Wrt:[s:"$2" c:pos] $Wrt:[s:"$1>$3" c:subst]} | /[A-Za-z0-9]+/ {$Wrt:subst} ~ num: ~ /[0-9]+/ ~ tag: ~ /[^:]+:/ ~ word: ~ /[a-zA-Z0-9_$]+/ {$Uniq} ~ sep: ~ /[^a-zA-Z0-9_$]+/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/u1/srs/data/mutdb/vwf/mut-LONG-list.txt'] while:$JobHasInput:$job { $JobTokens:[$job name:fields print:1] $JobTokens:[$job name:id print:1] $JobNext:$job $print:"-------->entry\n" } } c:pos] $Wrt:[s:"$1>$3" c:subst]} | /[A-Za-z0-9]+/ {$Wrt:subst} ~ num: ~ /[0-9]+/ ~ tag: ~ /[^:]+:/ ~ word: ~ /[a-zA-Z0-9_$]+/ {$Uniq} ~ sep: ~ /[^a-zA-Z0-9_$]+/ ~ } # debugging if:$TestMode { $job = $JobNew:[prod:$rules skip:" " fileName:'/u1/srs/data/mutdb/vwf/mut-LONG-list.txt'] while:$JobHasInputsrs/icarus/db/vwf.it # # $RCSfile: vwf.it,v $ # $Revision: 1.1 $ # $Date: 1996/11/05 19:54:25 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $dbInfo={ description: |The database |of point mutations, insertions, deletions, and polymorphisms found in von |Willebrand Factor is maintained by David Ginsburg and J. Evan Sadler. www: |\ |http://mmg2.im.med.umich.edu/vWF/ # ftp: # | email: |vwfdb@umich.edu # contact: # | # address: # | # literature: # | # updates: # | # fields:{ # } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $dbInfo={ description: |The database |of point mutations, insertions, deletions, and polymorphisms found in von |Willebrand Factor is maintained by David Ginsburg and J. Evan Sadler. www: |)?(.+)(<\/TD>)/ {$Wrt:[s:$2]} | /[^\n]+/ {$Wrt}) ~ # html display h_gb: ~ {$In:[fields t:html c:gb] $Out} tag acc {$Rep:{$ParStr:genbankR $Ct $Ct}}~ h_pir: ~ {$In:[fields t:html c:pir] $Out} tag acc {$Rep:{$ParStr:pirR $Ct $Ct}}~ h_sw: ~ {$In:[fields t:html c:sw] $Out} tag acc {$Rep:{$ParStr:swissR $Ct $Ct}} ~ h_refs: ~ {$In:[fields t:html c:refs] $Out} tag (acc {$Rep:{$ParStr:ypdrefR $Ct $Ct}})* ~ h_fields: ~ {$In:[fields t:html] $Out} ( /.*\\*\\*([^\\*]+)\\*\\*/ {$Rep:"

    $1

    "} | /[^ ][^\n]+/ {$Rep:""} /.+/ {$Rep:""} )? ~ # other acc: ~ /[A-Z0-9]+/ ~ ln: ~ /[^\n]*\n/ ~ num: ~ /<[^>]+>/* /-?[0-9.]+/ {$Wrt:$Itc}~ word: ~ /[a-z0-9A-Z_-]+/ {$Uniq:$Itc} | /<[^>]+>/ | /[^a-z0-9A-Z_-]/ ~ tag: ~ /[^\n]*/ ~ } #$fil = $fileOpen:"/data/ypd/YPD_ASCII" #$job = $jobNew:[prod:$rules skip:" \n\t"] # #$jobNext:[$job file:$fil] #while:$jobTokens:[$job name:words print:1 withCode:1] { ## $jobTokens:[$job name:molw print:1] ## $jobTokens:[$job name:fields withCode:0 print:1] # $jobEnd:$job # $jobNext:[$job file:$fil] # $print:"//\n" #} ~ /[^\n]*\n/ ~ num: ~ /<[^>]+>/* /-?[0-9.]+/ {$Wrt:$Itc}~ word: ~ /[a-z0-9A-Z_-]+/ {$Uniq:$Itc} | /<[^>]+>/ | /[^a-z0-9A-Z_-]/ ~ tag: ~ /[^\n]*/ ~ } #$fil = $fileOpen:"/data/ypd/YPD_ASCII" #$job = $jobNew:[prod:$rules skip:" \n\t"] # #$jobNext:[$job file:$fil] #while:$jobTokens:[$job name:words print:1 withCode:1] { ## $jobTokens:[$job name:molw print:1] ## $jobTokens:[$job name:fields withCode:0 print:1srs/icarus/util/ # # $RCSfile: arglist.i,v $ # $Revision: 1.20 $ # $Date: 1997/03/17 23:18:59 $ # $Author: srs $ # # # definition of command line options for SRS programs # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $command:[name:srsbuild usage:"libName [libName]" vars:{ $arg:[name:"-help" type:help comment:"this message"] $arg:[name:"-w" parameter:showWarnings] $arg:[name:"-c" parameter:compress] $arg:[name:"-m" parameter:mergeIndex] $arg:[name:"-t" parameter:touchIndex] $arg:[name:"-f" parameter:fieldList] $arg:[name:"-b" parameter:buildIndex] $arg:[name:"-d" parameter:parseTest] $arg:[name:"-l" parameter:readLink] $arg:[name:"-r" parameter:relocateLib] $arg:[name:"-i" parameter:indexLink] $arg:[name:"-pn" parameter:buildPartIndex] $arg:[name:"-xdir" parameter:indexDirName] $arg:[name:"-odir" parameter:outDirName] $arg:[name:"-info" parameter:printLibInfo] $arg:[name:"-libs" parameter:printLibs] $arg:[name:"-rel" parameter:releaseName] $arg:[name:"-s" parameter:environment] $arg:["-debug" parameter:icaIsDebug] } ] $command:[name:wgetz usage:"'queryExpression'" vars:{ $arg:[name:"-help" comment:"this message" type:help] $arg:[name:"-e" parameter:printEntireEntry] $arg:[name:"-fun" parameter:wwwFunctionName] $arg:[name:"-id" parameter:"userId"] $arg:[name:"-l" parameter:"libList"] $arg:[name:"-lib" parameter:libName] $arg:[name:"-entry" parameter:entryName] $arg:[name:"-h3" parameter:"isHtml3"] $arg:[name:"-style" parameter:"style"] $arg:[name:"-dbg" parameter:"isDebug"] $arg:[name:"-lo" parameter:"linkToLibs"] $arg:[name:"-qm" parameter:"wwwFunctionName" defaultstr:"PageQueryManager"] $arg:[name:"-qf" parameter:"wwwFunctionName" defaultstr:"PageQueryForm"] $arg:[name:"-top" parameter:"wwwFunctionName" defaultstr:PageStart] $arg:[name:"-start" parameter:"wwwFunctionName" defaultstr:"PageSelectLibrary"] $arg:[name:"-libs" parameter:"wwwFunctionName" defaultstr:"WwwPrintLibList"] $arg:[name:"-rep" parameter:"doRepeat"] $arg:[name:"-info" parameter:"libInfo"] $arg:[name:"-linfo" parameter:"wwwFunctionName" defaultstr:"PageLinkInfo"] $arg:[name:"-from" parameter:fromLibName] $arg:[name:"-to" parameter:toLibName] $arg:[name:"-blast" parameter:"prepBlastSearch"] $arg:[name:"-ht" parameter:"printHelpTopic"] $arg:[name:"-viv" parameter:"visitIndexValue"] $arg:[name:"-f" parameter:fieldList] $arg:[name:"-bl" parameter:listEntriesStartN] $arg:[name:"-ll" parameter:listEntriesChunkSize] $arg:[name:"-bv" parameter:viewEntriesStartN] $arg:[name:"-lv" parameter:viewEntriesChunkSize] $arg:[name:"-lset" parameter:listSetNumber] $arg:[name:"-vset" parameter:viewSetNumber] $arg:[name:"-lquery" parameter:listQuery] $arg:[name:"-msg" parameter:getMessage] $arg:[name:"-sf" parameter:"seqFormat"] $arg:[name:"-sn" parameter:subEntryN] $arg:[name:"-tr" parameter:translateSequence] $arg:[name:"-network" parameter:printNetwork] $arg:[name:"-ls" parameter:linkLibSelect] $arg:[name:"-link" parameter:printLinkTable] $arg:[name:"-odd" parameter:getOddFile] $arg:[name:"-s" parameter:environment] $arg:[name:"-q" parameter:queryString] $arg:[name:"-use" parameter:"readUserFile"] $arg:[name:"-w" parameter:"makeWild"] $arg:[name:"-mime" parameter:"mimeType"] $arg:[name:"-qnum" parameter:"queryNumber"] $arg:[name:"-dp" parameter:"deleteParam"] $arg:[name:"-bm" parameter:"mimeEntriesStartN"] $arg:[name:"-lm" parameter:"mimeEntriesChunkSize"] $arg:[name:"-m" parameter:"method"] $arg:[name:"-vroot" parameter:viewLibListRoot] $arg:[name:"-vleaf" parameter:viewLibListLeaf] $arg:[name:"-cv" parameter:currentView] $arg:[name:"-vt" parameter:isTable] $arg:[name:"-vn" parameter:viewNumber] $arg:[name:"-fbegs" parameter:shiftbeginpos] $arg:[name:"-fends" parameter:shiftendpos] $arg:[name:"-fbegsrend" parameter:isshiftbeginrelend] $arg:[name:"-fendsrbeg" parameter:isshiftendrelbegin] $arg:[name:"-takeuncf" parameter:takeuncompletefeature] $arg:[name:"-takeuncsf" parameter:takeuncompleteshiftfeature] $arg:[name:"-bf" parameter:browseIndex] $arg:[name:"-blib" parameter:browseLibs] $arg:[name:"-color" parameter:wwwColorScheme] $arg:[name:"-sl" parameter:wwwSessionEntryList] $arg:[name:"-ifile" parameter:icarusFileType] $arg:[name:"-newId" parameter:makeNewUserId] } ] $command:[name:getz usage:"'queryExpression'" vars:{ $arg:[name:"-help" comment:"this message" type:help] $arg:[name:"-e" parameter:printEntireEntry] $arg:[name:"-f" parameter:fieldList] $arg:[name:"-vf" parameter:viewFieldList] $arg:[name:"-l" parameter:libList] $arg:[name:"-w" parameter:makeWild] $arg:[name:"-r" parameter:doQueryReport] $arg:[name:"-lv" parameter:queryListValues] $arg:[name:"-lvf" parameter:queryListFromMatch] $arg:[name:"-lmin" parameter:minIndexValN] $arg:[name:"-xdir" parameter:indexDirName] $arg:[name:"-info" parameter:printLibInfo] $arg:[name:"-libs" parameter:printLibs] $arg:[name:"-view" parameter:viewName] $arg:[name:"-rs" parameter:viewRecordSep] $arg:[name:"-cs" parameter:viewColumnSep] # $arg:[name:"-fosn" parameter:listFOSN] # $arg:[name:"-fil" parameter:printToFile] $arg:[name:"-sf" parameter:seqFormat] # $arg:[name:"-pos" parameter:fosnWithPos] # $arg:[name:"-link" parameter:linkTable] $arg:[name:"-si" parameter:getStartupInfo] $arg:[name:"-html" parameter:isHTMLFormat] # $arg:[name:"options for retrieval of sequence features" type:title] # $arg:[name:"-fbegs" parameter:shiftbeginpos] # $arg:[name:"-fends" parameter:shiftendpos] # $arg:[name:"-fbegsrend" parameter:isshiftbeginrelend] # $arg:[name:"-fendsrbeg" parameter:isshiftendrelbegin] # $arg:[name:"-takeuncf" parameter:takeuncompletefeature] # $arg:[name:"-takeuncsf" parameter:takeuncompleteshiftfeature] $arg:[name:"-s" parameter:environment] $arg:[name:"-ifile" parameter:icarusFileType] $arg:["-debug" parameter:icaIsDebug] } ] $command:[name:try usage:"'dataFile'" vars:{ $arg:["-help" comment:"this message" type:help] $arg:["-t" parameter:printTrace] $arg:["-debug" parameter:icaIsDebug] $arg:["-tt" parameter:printSyntaxTree] $arg:["-task" parameter:productionName] $arg:["-synx" parameter:syntaxName] $arg:["-pall" parameter:printAllTokLists] $arg:["-des" parameter:icaDbgExecStack defaultnum:2] $arg:["-dbs" parameter:icaDbgBuildStack defaultnum:4] $arg:["-2c" parameter:ica2cName] $arg:["-use" parameter:useIni] $arg:["-rb" parameter:readBuiltin] $arg:["-class" parameter:doClassInfo] $arg:["-ci" parameter:doCommandInfo] } ] $command:[name:srscheck usage:"" vars:{ $arg:[name:"-help" type:help comment:"this message"] $arg:[name:"-xdir" parameter:indexDirName] $arg:[name:"-odir" parameter:outDirName] $arg:[name:"-info" parameter:printLibInfo] $arg:[name:"-e" parameter:etcDir] $arg:[name:"-l" parameter:checkLibList] $arg:[name:"-L" parameter:notCheckLibList] $arg:[name:"-header" parameter:srsEnvHeader] $arg:[name:"-o" parameter:updateScriptName] $arg:[name:"-s" parameter:environment] } ] $command:[name:srspict usage:"" vars:{ $arg:[name:"-help" type:help comment:"this message"] $arg:[name:"-n" parameter:doNetworkPict] $arg:[name:"-t" parameter:doGraphTablePict] } ] arg:[name:"-info" parameter:printLibInfo] $arg:[name:"-e" parameter:etcDir] $arg:[name:"-l" parameter:checkLibList] $arg:[name:"-L" parameter:notCheckLibList] $arg:[name:"-header" parameter:srsEnvHeader] $arg:[name:"-o" parameter:updateScriptName] $arg:[nsrs/icarus/util/arglist.ic # $RCSfile: arglist.ic,v $ # $Revision: 1.2 $ # $Date: 1996/07/24 22:07:11 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ O_GETARG:$object:[name:arg typname:"arg_t" declname:args status:system attrs:{ $attribute:[name:name type:string declname:name valtype:{name text} required:y unnamed:y] $attribute:[name:type declname:type type:int valtype:name defaultval:0 enum:{ $value:[name:bool val:2] $value:[name:string val:6] $value:[name:number val:3] $value:[name:real val:4] $value:[name:parameter val:0] $value:[name:help val:1] $value:[name:title val:2] } ] $attribute:[name:parameter declname:parameter type:string valtype:{name text} ] $attribute:[name:comment declname:comment type:string valtype:{name text}] $attribute:[name:check type:function declname:check defaultstr:"(void *)" valtype:constant] $attribute:[name:defaultnum type:int valtype:num declname:defaultNum] $attribute:[name:defaultstr type:string valtype:{name text} declname:defaultStr] $attribute:[name:defaultreal type:float valtype:num declname:defaultReal] } ] O_COMMAND:$object:[name:command typname:"ARGoLIST" declname:"argList" nchilds:1 child:@O_GETARG status:system attrs:{ $attribute:[name:name declname:name type:string valtype:name unnamed:y] $attribute:[name:usage declname:usage type:string valtype:{name text}] $attribute:[name:vars declname:"arg" type:child defaultval:@O_GETARG] $attribute:[declname:"argN" type:nr_of_childs defaultval:@O_GETARG] } ] $attribute:[name:defaultreal type:float valtype:num declname:defaultReal] } ] O_COMMAND:$object:[name:command typname:"ARGoLIST" declname:"argList" nchilds:1 child:@O_GETARG status:system attrs:{ $attribute:[name:name declname:name type:string valtype:name unnamed:y] $attribsrs/icarus/util/ascii.it # $RCSfile: ascii.it,v $ # $Revision: 1.4 $ # $Date: 1997/03/17 23:19:21 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $queryReport={ head: | |//////////////////////////////////////////////////////////////////////////// library: | |Values in "%s" value: | %-65s %d tail: | |//////////////////////////////////////////////////////////////////////////// | |report of query "%s" | } $libInfo={ head: |Databank: "%s" from group "%s", Release: %s | |Data Fields (B=busy, C=compressed): | |Name Short Type Inx Ids No No Creation B C | Name (kb) (kb) Words IDs Date |------------------------------------------------------------------------------- field:{ head: |%-20s %-5s %-5s index: |%6d %7d %8d %9s %d %d tail: |%s } links:{ head: | |Links: | link: |%s "%s" to "%s" } Source:{ dir:{ head: |Directory: name: | "%s" tail: | } files:{ head: |Filename(s): } } } $linkInfo={ } $classInfo={ } $entry={ inList:{ envelope:{ head: { preformatted: '' topicList: '' table: '' } tail: { preformatted: '' topicList: '' table: '' } } entry:{ name:'' #? inListNoId: |%s rootName: |%s leafName: |%s head:'' tail:'' } } inTable:{ # before first entry in a set head: '' # table header title:{ library: '' field: '' tail: '' } entry:{ head: '' tail: "($ParStr:viewRecordSep)" rootName: "%s($ParStr:viewColumnSep)" leafName: "%s($ParStr:viewColumnSep)" value:{ leftAlign: '' rightAlign: '' center: '' listing: '' value: '%s' empty: ' ' next: '|' tail: "($ParStr:viewColumnSep)" } emptyValue: " ($ParStr:viewColumnSep)" onlyEntryN: "%d ($ParStr:viewColumnSep)" } tail: '' } } ld: '' tail: '' } entry:{ head: '' tail: "($ParStr:viewRecordSep)" rootName: "%s($ParStr:viewColumnSep)" leafName: "%s($ParStr:viewColumnSep)" value:{ leftAlign: '' rightAlign:srs/icarus/util/builtin.i # # commands for processing icarus 4 with icarus 4 # $com:[_prog f:IopProg_] $com:[_opnd f:IopOpnd_ return:var args:{ $var:[opnd t:strv unnamed:y] $var:[t t:strv] } ] $com:[_list f:IopList_ return:var] $com:[_assoc f:IopAssoc_ return:var args:{ $var:[val t:var unnamed:y] $var:[key t:var] } ] $com:[_binop f:IopBinop_ return:var args:{ $var:[op t:strv unnamed:y] $var:[a t:var] $var:[b t:var] } ] $com:[_strmake f:IopStrMake_ return:var] $com:[_makearg f:IopMakeArg_ return:var args:{ $var:[val t:var unnamed:y] $var:[name t:var] } ] $com:[_select f:IopSelect_ return:var args:{ $var:[key t:var] $var:[index t:var] $var:[var t:var] } ] $com:[_setwrt f:IopSetWrite_ return:var args:{ $var:[var t:var unnamed:y] } ] $com:[_func f:IopFunc_ return:var] $com:[_body f:IopBody_ return:var] $com:[_ref f:IopRef_ return:var args:{ $var:[name t:var unnamed:y] $var:[opt t:int] } ] #flow control $com:[_file f:IopFile_ return:var args:{$var:[file t:var unnamed:y]}] $com:[_pre f:IopPre_ return:var args:{$var:[body unnamed:y t:var]}] $com:[_init f:IopInit_ return:var args:{$var:[body unnamed:y t:var]}] $com:[_for f:IopFor_ return:var args:{ $var:[i t:var] $var:[c t:var] $var:[u t:var] $var:[b t:var] } ] $com:[_foreach f:IopForeach_ return:var args:{ $var:[body t:var] $var:[list t:var] $var:[var t:var] } ] $com:[_while f:IopWhile_ return:var args:{ $var:[c t:var] $var:[b t:var] } ] $com:[_if f:IopIf_ return:var] #parsinge BNF rules $com:[_prod f:IopProd_ return:object returnClass:node] $com:[_endProd f:IopEndProd_ return:var args:{ $var:[node t:object class:node] $var:[prod t:object class:node] } ] $com:[_expr f:IopExpr_ return:object returnClass:node] $com:[_term f:IopTerm_ return:object returnClass:node] $com:[_regexp f:IopRegexp_ return:object returnClass:node args:{$var:[reStr t:strv unnamed:y]} ] $com:[_literal f:IopLiteral_ return:object returnClass:node args:{$var:[name t:strv unnamed:y]} ] $com:[_makeOpt f:IopMakeOpt_ return:object returnClass:node args:{ $var:[node t:object unnamed:y] $var:[t t:strv] } ] $com:[_nodeProg f:IopNodeProg_ return:object returnClass:node args:{ $var:[node t:object unnamed:y] $var:[prog t:var unnamed:y ] } ] $com:[_prodName f:IopProdName_ return:object returnClass:node args:{ $var:[name t:strv unnamed:y] $var:[lookahead t:int] } ] $com:[_doCom f:IopCommand_ return:object returnClass:node] $com:[_doInputEnd f:IopInputEnd_ return:object returnClass:node] $com:[_nullNode f:IopNullNode_ return:object returnClass:node] ###### $com:[_push f:IopPush_ args:{$var:[value t:var unnamed:y] $var:[stack t:int defInt:0]}] $com:[_push1 f:IopPush_ args:{$var:[value t:var unnamed:y] $var:[stack t:int defInt:1]}] $com:[_push2 f:IopPush_ args:{$var:[value t:var unnamed:y] $var:[stack t:int defInt:2]}] $com:[_push3 f:IopPush_ args:{$var:[value t:var unnamed:y] $var:[stack t:int defInt:3]}] $com:[_push4 f:IopPush_ args:{$var:[value t:var unnamed:y] $var:[stack t:int defInt:4]}] $com:[_push5 f:IopPush_ args:{$var:[value t:var unnamed:y] $var:[stack t:int defInt:5]}] $com:[_pop f:IopPop_ return:var args:{$var:[stack t:int defInt:0]}] $com:[_pop1 f:IopPop_ return:var args:{$var:[stack t:int defInt:1]}] $com:[_pop2 f:IopPop_ return:var args:{$var:[stack t:int defInt:2]}] $com:[_pop3 f:IopPop_ return:var args:{$var:[stack t:int defInt:3]}] $com:[_pop4 f:IopPop_ return:var args:{$var:[stack t:int defInt:4]}] $com:[_pop5 f:IopPop_ return:var args:{$var:[stack t:int defInt:5]}] # # end of icarus 4 build commands ############################################################################## # # commands for debugging icarus productions # $com:[Break show:y f:IopBreak time:initpre args:{ $var:[prod unnamed:y t:strv] $var:[cond t:int rem:"Breaks only if condition is met." defInt:1] $var:[time t:int enum:{ $val:[pre n:1] $val:[post n:2] } ] } ] $com:[break f:IopBreak time:init args:{ $var:[prod unnamed:y t:strv] $var:[time t:int enum:{ $val:[pre n:1] $val:[post n:2] } ] } ] $com:[next show:y f:IopNext] $com:[cont show:y f:IopContinue] $com:[tree show:y f:IopTree] $com:[TestMode show:y f:IopTestMode return:int] ###### end debugging ############################### $com:[prod f:IopProd args:{ $var:[name unnamed:y] } ] $com:[Prod f:IopProd show:y args:{ $var:[name unnamed:y] } ] $com:[CDefine f:IopCDefine args:{ $var:[n t:int unnamed:y] $var:[name] } ] # 'normal' icarus commands (level 3) $com:[test f:IopTest rem:"Test command." return:int args:{ $var:[x t:int] $var:[y t:int] $var:[color] } ] $com:[printProd f:IopPrintProduction rem:"Prints a production." return:int args:{ $var:[prod t:object class:production unnamed:y] } ] #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # commands for parsing # $com:[Parse show:y f:IopParse rem:"Parses a string." args:{ $var:[prod t:list] $var:[string t:strv unnamed:y] $var:[start t:strv rem:"The name of the start symbol (production)."] $var:[file t:object class:file rem:"Selects opened file to be read for input."] $var:[fileName t:strv rem:"Selects opened file to be read for input."] $var:[show t:int rem:"Sets display of the syntax before parsing."] $var:[skip t:strv rem:"The set of characters to be skipped as white space"] $var:[comment t:strv rem:"Regular expression for skipping comments"] $var:[tree t:int rem:"Flag if set requests printing the syntax tree."] } ] $com:[JobNew show:y f:IopJobNew rem:"" return:object returnClass:job rem: |Creates a new parsing job and associates it with a syntax and |the input. Use \$JobTokens to start the parsing (lazy parsing) and |\$JobNext to move to the next job in the input stream. args:{ $var:[prod t:list unnamed:y] $var:[skip t:strv rem:"The set of characters to be skipped as white space"] $var:[comment t:strv rem:"Regular expression for skipping comments"] $var:[file t:object class:file rem:"Sets opened file as input."] $var:[str t:strv rem:"Sets string as input."] $var:[show t:int rem:"Sets display of the syntax before parsing."] $var:[tree t:int rem:"Flag if set requests printing the syntax tree."] $var:[fileName t:strv rem:"Name of the file to be opened as input."] } ] $com:[Fail show:y f:IopFail rem: |Can be used only in an action symbol (like x{...}). If called the action node reports |a parsing error which is treated in the same way as a 'normal' parsing |error from, eg, a literal. ] $com:[JobHasInput show:y f:IopJobHasInput return:int rem:|Returns TRUE if the input file of the job is not | finished args: { $var:[job t:object class:job unnamed:y] } ] $com:[JobNext show:y f:IopJobNext rem:"" args:{ $var:[job t:object class:job unnamed:y] $var:[string t:string] $var:[start rem:"The name of the start symbol (production)."] $var:[file t:object class:file rem:"Selects opened file to be read for input."] $var:[fileName rem:"Selects opened file to be read for input."] } ] $com:[JobHasInput show:y f:IopJobHasInput return:int rem:|Returns TRUE if the input file of the job is not | finished args: { $var:[job t:object class:job unnamed:y] } ] $com:[JobKill show:y f:IopJobEnd rem:"" args: { $var:[job t:object class:job unnamed:y] } ] $com:[JobTokens show:y f:IopJobTokens return: int args:{ $var:[job t:object class:job unnamed:y] $var:[name rem:"Name of the token list."] $var:[code] $var:[n t:int] $var:[print t:int] $var:[task] $var:[withCode t:int defInt:1] $var:[outFile t:object class:file rem:"Output file object."] } ] $com:[In f:IopIn show:y time:initpre return:int rem: |Sets the input token table for parsing. |Controls the lazy parsing execution by defining the connections |between productions args:{ $var:[in unnamed:y required:y t:strv rem:"Name of the input token table."] $var:[ic t:strv rem:"Token code."] $var:[n t:int defInt:-1 rem:"Numerical token code."] $var:[p t:strv rem:"Name of production to be linked."] $var:[t t:strv rem:"Name of task that if results in forced parsing."] $var:[count t:strv rem:""] $var:[var t:var rem:""] $var:[file t:strv rem:"Symbolic name of the input file."] $var:[share t:strv rem:"Symbolic name file that shares physical file."] $var:[select t:int rem:|Selects token with specified count number. |The value 0 selects all tokens |(only in combination with "count"). ] $var:[c t:var rem:""] } ] $com:[Out f:IopOut show:y time:initpre rem: |Sets the output table for all writing of tokens for the |current production and its dependants. args:{ $var:[name unnamed:y t:strv rem:"Name of ouput token table."] } ] $com:[out f:IopOut time:initpre rem: |Sets the output table for all writing of tokens for the |current production and its dependants. args:{ $var:[name unnamed:y t:strv rem:"Name of ouput token table."] } ] $com:[Getc f:IopGetc call:direct args:{$var:[len]} rem: |Defines \$Ct to be a token starting at the current position |and with the given length. Moves the current position, as if | the given number of characters would have been really parsed ] $com:[Len f:IopRestrictLength time:prepost call:direct args:{$var:[len]} rem: |Limits the parsing to stop after 'len' characters |Must be the last command in a production. See also \$Mov ] $com:[Mov f:IopMove show:y call:direct time:pre args:{$var:[len]} rem: |Skips the next 'len' characters while parsing ] $com:[Wrt f:IopWrt show:y call:direct rem: |This function can be called inside an action attached to the symbol of |a production. It writes the match of the current symbol or a specified |string into the output table specified by the most recent call of \$out. args:{ $var:[c unnamed:y rem:"token code as a name"] $var:[n t:int rem:"token code as a number"] $var:[s rem: |string to be written to the token table. |If left unspecified the current match, or current token (\$Ct) |is written. ] } ] $com:[wrt f:IopWrt call:direct rem: |This function can be called inside an action attached to the symbol of |a production. It writes the match of the current symbol or a specified |string into the output table specified by the most recent call of \$out. args:{ $var:[c unnamed:y rem:"token code as a name"] $var:[n t:int rem:"token code as a number"] $var:[s rem: |string to be written to the token table. |If left unspecified the current match, or current token (\$Ct) |is written. ] } ] $com:[Uniq f:IopUniq show:y call:direct rem: |Exactly as \$Wrt but writes the token only into the table if it does |not already exist. Unique here means that both the token string as the |token code are used for comparison. args:{ $var:[c unnamed:y rem:"token code as a name"] $var:[n t:int rem:"token code as a number"] $var:[s rem: |string to be written to the token table. |If left unspecified the current match, or current token (\$Ct) |is written. ] } ] $com:[App show:y f:IopApp call:direct args:{ $var:[s unnamed:y rem:"String to be written to the token table."] } rem:|Appends the string token to the output token table ] $com:[app f:IopApp call:direct args:{ $var:[s unnamed:y rem:"String to be written to the token table."] } rem:|Old syntax, see \$App ] $com:[Rep show:y f:IopRep rem: |Replaces the current token (\$Ct) in case of a symbol match. The |input cursor is moved after the replaced string. args:{ $var:[s t:var unnamed:y rem:"String with which current match is to be replaced"] } ] $com:[rep f:IopRep rem:|Old syntax, see \$Rep args:{ $var:[s t:var unnamed:y rem:"String with which current match is to be replaced"] } ] $com:[Not show:y f:IopNot time:init rem:|The rest of the production matches only if the preceding |terminal doesn't match. (see \$Probe) The parsing position |(cursor) is not moved when matching the preceding terminal ] $com:[not f:IopNot time:init] $com:[Probe show:y f:IopProbe time:init rem:|The rest of the production matches only if the preceding |terminal matches. (see \$Not) The parsing position |(cursor) is not moved when matching the preceding terminal ] $com:[Noskip show:y f:IopNoskip time:init rem:|Inactivates skipping of white space ] $com:[noskip f:IopNoskip time:init] $com:[Request show:y f:IopRequest args:{ $var:[name unnamed:y rem:"Name of requested token table."] } rem:|Activates the lazy parsing chain producing the |requested token table, but doesn't connect the input |to it. (see \$In) ] $com:[Nocase show:y f:IcaOpSetFlag args:{$var:[flag defStr:nocase]} ] $com:[push f:IopPush args:{ $var:[value t:var unnamed:y] $var:[stack t:int defInt:0] } ] $com:[push1 f:IopPush args:{ $var:[value t:var unnamed:y] $var:[stack t:int defInt:1] } ] $com:[push2 f:IopPush args:{ $var:[value t:var unnamed:y] $var:[stack t:int defInt:2] } ] $com:[push3 f:IopPush args:{ $var:[value t:var unnamed:y] $var:[stack t:int defInt:3] } ] $com:[push4 f:IopPush args:{ $var:[value t:var unnamed:y] $var:[stack t:int defInt:4] } ] $com:[push5 f:IopPush args:{ $var:[value t:var unnamed:y] $var:[stack t:int defInt:5] } ] $com:[pop f:IopPop return:var args:{$var:[stack t:int defInt:0]}] $com:[pop1 f:IopPop return:var args:{$var:[stack t:int defInt:1]}] $com:[pop2 f:IopPop return:var args:{$var:[stack t:int defInt:2]}] $com:[pop3 f:IopPop return:var args:{$var:[stack t:int defInt:3]}] $com:[pop4 f:IopPop return:var args:{$var:[stack t:int defInt:4]}] $com:[pop5 f:IopPop return:var args:{$var:[stack t:int defInt:5]}] $com:[Exit show:y f:IopExit args:{$var:[val unnamed:y defInt:0]}] $com:[exit f:IopExit args:{$var:[val unnamed:y defInt:0]}] # global parameter list $com:[parStr f:IopParStr return:strv rem: |Returns the value of a 'string' parameter or sets its value if ".set" is |defined. args:{ $var:[name t:strv unnamed:y rem:"Parameter name."] $var:[set t:strv] } ] $com:[parInt f:IopParInt return:int rem: |Returns the value of an 'int' parameter or sets its value if ".set" is |defined. args:{ $var:[name t:strv unnamed:y rem:"Parameter name."] $var:[set t:int defInt:2] } ] $com:[ParStr show:y f:IopParStr return:strv rem: |Returns the value of a 'string' parameter or sets its value if ".set" is |defined. args:{ $var:[name t:strv unnamed:y rem:"Parameter name."] $var:[set t:strv] } ] $com:[ParInt show:y f:IopParInt return:int rem: |Returns the value of an 'int' parameter or sets its value if ".set" is |defined. args:{ $var:[name t:strv unnamed:y rem:"Parameter name."] $var:[set t:int defInt:2] } ] $com:[ParDel show:y f:IopParDel rem: |Deletes the parameter with specified name. args:{ $var:[name t:strv unnamed:y rem:"Parameter name."] } ] $com:[Env show:y f:IopEnv return:strv rem: |Optionally sets and returns the value an environment variable. args:{ $var:[name t:strv unnamed:y rem:"Name of environment variable."] $var:[set t:strv rem:"New string value of the environment variable."] } ] $com:[AltStr f:IopAltStr return:strv rem:|Returns one of two strings depending whether condition is |true or false. args:{ $var:[cond t:int required:y unnamed:y rem:"The condition."] $var:[t t:strv rem:"String to be returned if condition is true."] $var:[f t:strv rem:"String to be returned if condition is false"] } ] $com:[Alt f:IopAltStr show:y return:strv rem:|Returns one of two strings depending whether condition is |true or false. args:{ $var:[cond t:int required:y unnamed:y rem:"The condition."] $var:[t t:strv rem:"String to be returned if condition is true."] $var:[f t:strv rem:"String to be returned if condition is false"] } ] $com:[Foreach f:IopPrintForeach show:y return:strv rem:|prints each element in the list with specified separators. args:{ $var:[var t:var unnamed:y rem:'Name of variable used for iteration'] $var:[in t:list rem:'The list.'] $var:[s t:var rem:'String to print for each list element'] $var:[sep t:var rem:'Separator strings to be printed between elements'] } ] $com:[subStr f:IcaOpSubStr return:strv args:{ $var:[str t:strv unnamed:y rem:"Classical substr function"] $var:[s t:int required:y rem:"Start posilion inside of string"] $var:[l t:int required:n defInt:0 rem:"subStr length if ommited - suffix"] } ] $com:[System f:IopSystem return:strv args:{ $var:[com required:y t:strv unnamed:y rem:"Unix command"] $var:[script t:strv rem:"String (text) that is written to a script and then executed"] $var:[scriptName t:strv rem:"Name of the script that is to be generated."] $var:[out t:strv rem:"Name of output file (Use 'stdout' for standard output)."] $var:[error t:strv rem:"Name of error output file (Use 'stdout' for standard output)."] } ] $com:[FileOpen show:y f:IopFileOpen return:object returnClass:file args:{ $var:[name t:strv unnamed:y rem:|The name of the file; if omitted stdin (for read access mode) |or stdout (write access mode) are assumed. ] $var:[mode t:int defInt:1 rem:'Access mode for opened file' enum:{ $val:[read n:1] $val:[write n:2] } ] } ] $com:[FileClose show:y f:IopFileClose args:{ $var:[file t:object class:file unnamed:y] } ] $com:[FileName show:y f:IopFileName return:strv args:{ $var:[type t:int unnamed:y defInt:1 enum:{ $val:[path n:1] $val:[dir n:2] $val:[name n:3] $val:[file n:4] $val:[ext n:5] } ] } ] $com:[Print show:y f:IopPrint rem:"Prints a string." args:{ $var:[s t:var unnamed:y] $var:[f t:object class:file] $var:[mode t:int enum:{ $val:[normal n:0] $val:[raw n:1] } ] $var:[v t:var rem:"Appends the string to specified string variable."] } ] $com:[dp show:y f:IopDebugPrint rem:"Printing within the debugger" args:{ $var:[s t:var unnamed:y] } ] $com:[print f:IopPrint rem:"Prints a string." args:{ $var:[s t:var unnamed:y] $var:[f t:object class:file] $var:[mode t:int enum:{ $val:[normal n:0] $val:[raw n:1] } ] $var:[v t:var rem:"Appends the string to specified string variable."] } ] $com:[StrFormat f:IopPrintFormat return:strv rem:|Prints a string with the specified format. args:{ $var:[s t:strv unnamed:y] $var:[label t:strv rem:"Label to be printed at begin of each line."] $var:[width t:int rem:"Maximum width of output lines."] $var:[indent t:int rem:"Indentation for all lines."] $var:[firstIndent t:int rem:"Indentation of first line."] } ] $com:[It show:y f:IopInToken return:strv args:{ $var:[n t:int unnamed:y] } rem: |Returns the input token (token which serves as input for |the current production through the \$In command) ] $com:[itc f:IopInTokenCode return:strv] $com:[Itc show:y f:IopInTokenCode return:strv rem: |Returns the token code of the input token (see \$It) ] $com:[ct f:IopCurrToken return:strv] $com:[Ct show:y f:IopCurrToken return:strv rem: |Returns the current token (string parsed in the preceding |parsing block) ] $com:[Key show:y f:IopKey return:strv args:{ $var:[val t:var unnamed:y] } rem:|Returns the symbolic tag associated with the given list element ] $com:[IsLast show:y f:IopIsLast return:int rem:|Returns TRUE if the element is the last in the list. ] $com:[IsFirst show:y f:IopIsFirst return:int rem:|Returns TRUE if the element is the first in the list. ] $com:[ListLen show:y f:IopListLen return:int rem:|Returns the number of elements in the list args: { $var:[list t:var unnamed:y] } ] $com:[Fip show:y f:IopFip return:int args:{ $var:[switch t:int unnamed:y] } rem: |Returs the file pointer to the current |position in the input file ] $com:[fip f:IopFip return:int args:{ $var:[switch t:int unnamed:y] } ] $com:[File show:y f:IopFile return:object returnClass:file rem:|Returns the file object of the currrent job. ] $com:[skip f:IopSetSkip rem: |Controls skipping of white space during parsing which is |active by default. args:{ $var:[state t:int unnamed:y rem: |0: turns skipping white space off
    |1: turns it on again ] $var:[s t:strv] } ] $com:[Skip show:y f:IopSetSkip rem: |Controls skipping of white space during parsing which is |active by default. args:{ $var:[state t:int unnamed:y rem: |0: turns skipping white space off
    |1: turns it on again ] $var:[s t:strv] } ] $com:[Eval show:y f:IopEval args:{ $var:[prog t:strv unnamed:y] } ] $com:[Trim show:y f:IopStrTrim return:strv rem:"Cuts leading or trailing white space from the string." args:{ $var:[s t:strv unnamed:y] $var:[skip t:strv rem:|String containing characters to be removed from ends. ] } ] $com:[1 show:y f:IopSubMatch return:strv args:{$var:[n defInt:1 t:int]} rem: |Returns the first submatch of the most recent regular expression |matching. The submatch is indicated by parentheses within the |regular expression and the opening parenthesis is used for counting. |\$2, \$3 until \$9 will return the submatches with the respective |number. \$0 returns the entire match. ] $com:[2 f:IopSubMatch return:strv args:{$var:[n defInt:2 t:int]}] $com:[3 f:IopSubMatch return:strv args:{$var:[n defInt:3 t:int]}] $com:[4 f:IopSubMatch return:strv args:{$var:[n defInt:4 t:int]}] $com:[5 f:IopSubMatch return:strv args:{$var:[n defInt:5 t:int]}] $com:[6 f:IopSubMatch return:strv args:{$var:[n defInt:6 t:int]}] $com:[7 f:IopSubMatch return:strv args:{$var:[n defInt:7 t:int]}] $com:[8 f:IopSubMatch return:strv args:{$var:[n defInt:8 t:int]}] $com:[9 f:IopSubMatch return:strv args:{$var:[n defInt:9 t:int]}] $com:[SetFunctions f:IopSetFunctions args:{ $var:[name unnamed:y] } ] #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # implementation of the srs query language # $com:[SetResult f:QuerySaveResult args:{ $var:[set t:object class:set unnamed:y] $var:[q t:strv] } ] $com:[DbGroup f:QueryDBGroup return:object returnClass:dbGroup args:{ $var:[init] $var:[db t:string] $var:[group t:object class:dbGroup unnamed:y] } ] $com:[SetRetrRange f:QueryRangeSearch return:object returnClass:set args:{ $var:[index required:y] $var:[group t:object class:dbGroup unnamed:y] $var:[l t:string] $var:[h t:string] $var:[le t:int] $var:[re t:int] } ] $com:[SetRetrStr f:QueryStrSearch return:object returnClass:set args:{ $var:[s t:strv] $var:[index required:y] $var:[group t:object class:dbGroup unnamed:y] } ] $com:[SetLogOp f:QueryLogOp return:object returnClass:set args:{ $var:[op unnamed:y] $var:[s1 t:object class:set] $var:[s2 t:object class:set] } ] $com:[SetLinkOp f:QueryLinkOp return:object returnClass:set args:{ $var:[op unnamed:y] $var:[s1 t:object class:set] $var:[s2 t:object class:set] } ] $com:[SetAssign f:QuerySetAssign return:object returnClass:set args:{ $var:[name unnamed:y t:strv] $var:[s t:object class:set] } ] $com:[SetGet f:QuerySetGet return:object returnClass:set args:{ $var:[name unnamed:y] $var:[fileName] } ] $com:[MakeWild f:QueryOpMakeWild return:strv args:{ $var:[s t:strv unnamed:y] } ] #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $com:[GCGwordsearch f:GCGWordsearch args:{ $var:[infile1 rem:"Name of input file with the search probe."] $var:[infile2 rem:"Name of input file with the data bank."] } ] $com:[setFormat f:EntryIopSetFieldFormat args:{ $var:[field t:strv unnamed:y ] $var:[set t:strv] } ] #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # sequence manipulation # $com:[SeqGet2Bit show:y f:SeqIopGet2Bit rem: |Reads a sequence in GCG's 2BIT format into supplied sequence object |which can be created by \$SeqNew. If the sequence object contains |a sequence already the sequence read is appended. This is useful |to collect split sequences as found in the GCG formatted sequence |databanks. args:{ $var:[s unnamed:y t:object class:sequence rem:"Sequence in which to store the sequence."] $var:[file t:object class:file unnamed:y rem:"File object with the sequence."] $var:[len t:int rem:"Length of the sequence to be read."] # $var:[overlap t:int rem:"Overlap of split sequence parts."] } ] $com:[SeqCut show:y f:SeqIopCut rem: |Cuts away specified part of the sequence args:{ $var:[s unnamed:y t:object class:sequence] $var:[from t:int] $var:[len t:int] } ] $com:[SeqNew show:y f:SeqIopNew return:object returnClass:sequence rem: |Creates a new sequence object. args:{ $var:[name t:strv unnamed:y ] $var:[list t:object class:sequence] } ] $com:[SeqApp show:y f:SeqIopApp return:object returnClass:sequence args:{ $var:[seq unnamed:y t:object class:sequence] $var:[s t:strv] } ] $com:[SeqMake show:y f:SeqIopMake return:object returnClass:sequence args:{ $var:[seq unnamed:y t:object class:sequence] } ] $com:[SeqTrunc show:y f:SeqIopTrunc return:object returnClass:sequence args:{ $var:[seq unnamed:y t:object class:sequence] $var:[len t:int] } ] $com:[SeqLen show:y f:SeqIopLen return:int args:{$var:[seq unnamed:y t:object class:sequence]} rem:"Returns the length of the sequence." ] $com:[SeqPrint show:y f:SeqIopPrint rem:"Prints a sequence in various formats." args:{ $var:[seq unnamed:y t:object class:sequence] $var:[s t:strv rem:'The sequence as a string value.'] $var:[name] $var:[format t:int enum:{ $val:[gcg n:1] $val:[msf n:2] $val:[pir n:3] $val:[plain n:4] $val:[fasta n:5] $val:[embl n:6] $val:[swiss n:7] $val:[clustal n:8] } ] $var:[width t:int defInt:60] } ] #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $com:[calc f:IopCalc return:int args:{ $var:[op unnamed:y] $var:[l t:int] $var:[r t:int] } ] $com:[strlen f:IopStrlen return:int args:{ $var:[s unnamed:y] } ] $com:[Strlen f:IopStrlen return:int args:{ $var:[s unnamed:y] } ] $com:[StrLen show:y f:IopStrLen return:int args:{ $var:[s unnamed:y t:strv] } ] $com:[StrApp show:y f:IopStrApp args: { $var:[v unnamed:y t:var] $var:[s t:strv] } ] $com:[StrTrans f:IopStrTrans show:y return:strv rem:|Translates all characters in the 'from' set to the character |at the equivalent position in the 'to' set. args:{ $var:[s t:strv unnamed:y] $var:[from t:strv] $var:[to t:strv] } ] $com:[StrReplace f:IopStrReplace show:y return:strv rem:|Translates all occurences of 'from' |to strings specified by 'to'. args:{ $var:[s t:strv unnamed:y] $var:[from t:strv] $var:[to t:strv] } ] $com:[StrLower f:IopStrLower show:y return:strv rem:|Converts all characters of the input string into lower case. args:{ $var:[s t:strv unnamed:y] } ] $com:[StrUpper f:IopStrUpper show:y return:strv rem:|Converts all characters of the input string into upper case. args:{ $var:[s t:strv unnamed:y] } ] $com:[StrPad show:y f:IopStrPad return:strv rem:|Pads a string with specified character if input string is |shorter than requested length. args:{ $var:[s t:strv unnamed:y rem:"Input string."] $var:[len t:int rem:"Length of the result string."] $var:[c t:strv rem:"Character used for padding."] } ] $com:[HtmlSpace f:IopHtmlSpace return:string args:{ $var:[thirds t:int unnamed:y] $var:[s t:int] $var:[l t:int] } ] #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # binary operators # #$com:['+' f:IopAdd return:int args:{$var:[t:int] $var:[t:int]}] #$com:['+' f:IopPlusReal return:real args:{$var:[t:real] $var:[t:real]}] #$com:['+' f:IopPlusStr return:string args:{$var:l $var:r}] #$com:['+' f:IopPlusVar return:string args:{$var:l $var:r}] $com:['=' f:IopAss return:var args:{$var:[l t:var] $var:[r t:var]}] $com:['+' f:IopAdd return:int args:{$var:[l t:var] $var:[r t:var]}] $com:['<' f:IopLT return:int args:{$var:[l t:var] $var:[r t:var]}] $com:['>' f:IopGT return:int args:{$var:[l t:var] $var:[r t:var]}] $com:['==' f:IopEq return:int args:{$var:[l t:var] $var:[r t:var]}] $com:['*' f:IopMul return:int args:{$var:[l t:var] $var:[r t:var]}] $com:['/' f:IopDivide return:int args:{$var:[l t:var] $var:[r t:var]}] $com:['!=' f:IopNEq return:int args:{$var:[l t:var] $var:[r t:var]}] $com:['-' f:IopSubt return:int args:{$var:[l t:var] $var:[r t:var]}] $com:['+=' f:IopAddAss return:int args:{$var:[l t:var] $var:[r t:var]}] $com:['&&' f:IopLogAnd return:int args:{$var:[l t:var] $var:[r t:var]}] $com:['||' f:IopLogOr return:int args:{$var:[l t:var] $var:[r t:var]}] #$convert:[int to:string cost:] #$convert:[int to:strv cost:] #$convert:[int to:strv] $com:[debug f:IopSetDebug args:{ $var:[state t:int unnamed:y defInt:0] } ] # for the 'templ' module $com:[labelAdd f:TemplIcaAddLabel args:{ $var:[name t:strv unnamed:y] $var:[fip t:int] } ] #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # commands for feature parsing # #calculator stack $com:[SdbRetrieve f:SdbRetrieve return:strv args: { $var:[acc t:strv unnamed:y defstr:""] $var:[db t:strv defstr:""] } ] $com:[SdbPop f:SdbPop ] $com:[SdbPush f:SdbPush] $com:[SdbEval f:SdbEval return:strv] $com:[SdbChunk f:SdbChunk args:{ $var:[seq t:strv unnamed:y] $var:[to t:int defint:-2] $var:[uncertain t:int defint:0] } ] $com:[SdbFeature f:SdbFeature args:{ $var:[feature t:int unnamed:y] } ] $com:[SdbComplement f:SdbComplement] $com:[SdbReplace f:SdbReplace] $com:[SdbJoin f:SdbJoin] $com: [SeqGetFt f:SdbGetFeatureSequence return:strv args: { $var:[expr t:strv unnamed:y] $var:[db t:strv] $var:[shift t:int defint:0] $var:[left t:int defint:0] $var:[right t:int defint:0] } ] $com: [SdbFunctions f:SdbFunctions] # NULL terminator - must be the last definition in the file $com:["" ] ] $com:[SdbFeature f:SdbFeature args:{ $var:[feature t:int unnamed:y] } ] $com:[SdbComplement f:SdbComplement] $com:[SdbReplace f:SdbReplace] $srs/icarus/util/builtin.ic $object:[function declname:"X" status:system attrs:{ $attribute:[name type:protofunction declname:"fnctnam" max:30 valtype:text] $attribute:[args type:string declname:"args" max:132 valtype:text required:y] $attribute:[module type:string declname:"module" max:30] } ] file:"SRSICA:icacom.ic" $def:[infile:"SRSICA:srswin.sdl" outfile:"SRSSOU:builtin.h" section_name:"builtin" section_size:2000 ] } ] $com:[SdbComplement f:SdbComplement] $com:[SdbReplaceplace] $srs/icarus/util/classes.i # # $RCSfile: classes.i,v $ # $Revision: 1.4 $ # $Date: 1996/10/01 18:32:20 $ # $Author: etzold $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # O_VALUE:$object:[name:value typname:ODDoVAL ppname:SDL declname:defval attrs:{ $attribute:[name:name declname:nam type:string valtype:name unnamed:y] $attribute:[name:val declname:val type:uint valtype:{num constant}] } ] O_ATTRTYPE:$object:[name:attrtype typname:ODDoATYP ppname:SDL declname:defatyp attrs:{ $attribute:[name:make type:function declname:make valtype:constant defaultstr:"(struct SDLoOBJ *, struct SDLoATTR *, unsigned int *)"] $attribute:[name:insert type:function declname:insert defaultstr:"(void *, void *, void *, void ***, char *, unsigned int,int)" valtype:constant] $attribute:[name:calcsize type:function declname:size valtype:constant defaultstr:"(struct SDLoOBJ *, struct SDLoATTR *)"] $attribute:[name:write type:function declname:write defaultstr:"(void)" valtype:constant] $attribute:[name:declare type:function declname:declare defaultstr:"(FILE *, struct SDLoATTR *, char *, char *)" valtype:constant] $attribute:[name:check type:function declname:check defaultstr:"(struct SDLoATTR *, int, char *)" valtype:constant] $attribute:[name:gentype type:function declname:gentype defaultstr:"(struct SDLoOBJ *, struct SDLoATTR *)" valtype:constant] $attribute:[name:save_address type:uchar declname:save_f defaultval:0 enum:{ $value:[name:yes val:1] $Value:[name:no val:0] } ] $attribute:[name:typname type:string declname:tnam max:20] } ] O_ATTR:$object:[name:attribute typname:SDLoATTR ppname:SDL declname:defpar CHILD:{@O_VALUE @O_ATTR} NCHILDS:2 attrs:{ $attribute:[name:rem declname:rem type:string valtype:{name text} min:0 max:512] $attribute:[declname:class type:object defaultval:@O_OBJECT] # pointer to list of possible values $attribute:[name:enum declname:val type:child defaultval:@O_VALUE] # number of values in list $attribute:[declname:val_n type:nr_of_childs defaultval:@O_VALUE] $attribute:[name:name declname:nam type:string min:0 max:$SDLxXNAM valtype:{name text} unnamed:y] $attribute:[name:typname declname:tnam type:string min:0 max:$SDLxXNAM valtype:{name text}] # switch used for alternative SDLxUSER type name $attribute:[name:switchname declname:sw_nm type:string valtype:{name text} min:0 max:$SDLxXNAM] # alternative SDLxUSER type name $attribute:[name:alttypname declname:alt_nm type:string valtype:{name text} min:0 max:$SDLxXNAM] # declaration name in C interface $attribute:[name:declname declname:dnam type:string min:0 max:$SDLxXNAM valtype:{name text}] $attribute:[name:unnamed declname:unnamed type:int min:0 defaultval:0 enum:{ $value:[name:y val:1] $value:[name:n val:0] } ] $attribute:[name:type declname:typ type:uchar required:y valtype:name enum:{ $value:[name:int val:@AT_INT] $value:[name:uint val:@AT_UINT] $value:[name:uchar val:@AT_UCHAR] $value:[name:string val:@AT_STRING] $value:[name:protofunction val:@AT_PROTOFNCT] $value:[name:function val:@AT_FNCT] $value:[name:child val:@AT_CHILD] $value:[name:nr_of_childs val:@AT_CHILD_N] $value:[name:object val:@AT_OBJECT] $value:[name:clone val:@AT_CLONE] $value:[name:defer val:@AT_DEFER] $value:[name:inherit val:@AT_INHERIT] $value:[name:user val:@AT_USER] $value:[name:float val:@AT_FLOAT] $value:[name:allobjects val:@AT_ALLOBJ] $value:[name:nr_of_objects val:@AT_ALLOBJ_N] $value:[name:generic val:@AT_GENERIC] $value:[name:generic_typ val:@AT_GENERIC_TYP] $value:[name:generic_obj val:@AT_GENERIC_OBJ] $value:[name:overload val:@AT_OVERLOAD] $value:[name:store val:@AT_STORE] $value:[name:bnf val:@AT_EBNF] } ] # type of value attribute may receive $attribute:[name:valtype declname:ptyp type:uchar defaultval:0 repeat:4 valtype:name enum:{ $value:[name:num val:$SDLxPNUM] $value:[name:name val:$SDLxPNAM] $value:[name:text val:$SDLxPTXT] $value:[name:constant val:$SDLxPCNST] } ] # array size if multivalued attribute $attribute:[name:repeat declname:arrsz type:int min:1 max:10000 defaultval:1 valtype:{num constant}] $attribute:[name:min declname:min type:int min:-1000000000 max:1000000000 defaultval:-1000000000 valtype:{num constant}] $attribute:[name:max declname:max type:int min:0 max:1000000000 valtype:{num constant} defaultval:1000000000] $attribute:[declname:off type:int] $attribute:[name:required declname:req type:uchar valtype:name defaultval:0 enum:{ $value:[name:y val:$TRUE] $value:[name:n val:$FALSE] } ] $attribute:[name:status declname:status type:uchar valtype:name defaultval:0 repeat:2 enum:{ $value:[name:obsolete val:1] $value:[name:system val:2] $value:[name:api val:3] } ] $attribute:[declname:isrd type:uchar min:0 max:0 required:n] $attribute:[name:defaultval declname:dfltv type:int valtype:{num constant} min:-1000000000 max:1000000000 defaultval:0] $attribute:[name:defaultstr declname:dflts type:string valtype:{name constant text} min:0 max:$SDLxXLN defaultstr:""] $attribute:[name:defaultvalf declname:dfltvf type:float valtype:num min:-1000000000 max:1000000000 defaultvalf:0] $attribute:[declname:scnt type:int] # some attribute types need object-class ID's $attribute:[name:objectclass declname:obj type:object defaultval:@O_OBJECT valtype:constant] $attribute:[declname:hasObjsN type:int defaultval:-1] $attribute:[declname:"*hasFirstObj" type:user typname:void] } ] O_OBJECT:$object:[name:object typname:SDLoOBJ ppname:SDL declname:defstrct child:@O_ATTR nchilds:1 attrs:{ #used in SDL $attribute:[name:name declname:nam type:string valtype:{name text} min:0 max:$SDLxXNAM unnamed:y] $attribute:[name:rem declname:rem type:string valtype:{name text} min:0 max:512] # `typedef' name to get access through C interface $attribute:[name:typname declname:tnam type:string valtype:{name text} min:0 max:$SDLxXNAM] #used for #define's - preprocessor name $attribute:[name:ppname declname:pp_nm type:string valtype:{name text} min:0 max:$SDLxXNAM] $attribute:[name:declname declname:dnam type:string min:0 max:$SDLxXNAM valtype:{name text}] $attribute:[name:type declname:typ type:uchar valtype:{num constant} min:0 max:12 defaultval:0] $attribute:[name:status declname:status type:uchar valtype:name defaultval:0 repeat:2 enum:{ $value:[name:obsolete val:1] $value:[name:system val:2] $value:[name:api val:3] } ] $attribute:[declname:siz type:int] $attribute:[declname:s type:string] $attribute:[declname:ns type:int min:0 max:10000] $attribute:[declname:uobj_coff type:string] $attribute:[declname:gbl_n type:int] $attribute:[declname:loc_n type:int] $attribute:[name:nchilds declname:nss type:uchar valtype:num max:$SDLxXSS] $attribute:[name:child declname:ss type:uchar repeat:$SDLxXSS valtype:constant min:0 max:255 defaultval:0] $attribute:[declname:np type:nr_of_childs min:1 max:256 defaultval:@O_ATTR] $attribute:[name:attrs declname:p typname:SDLoATTR type:child defaultval:@O_ATTR] #Inheritance #Pointer(s) to object class descriptor(s) $attribute:[declname:gtyp_n type:int defaultval:0] #generic typedef name that object typedef using generic type receives $attribute:[declname:gtypdef_nm type:string repeat:$SDLxXSS repeat:$SDLxXSS] #generic type $attribute:[declname:gtyp_nm type:string repeat:$SDLxXSS repeat:$SDLxXSS] #typdef name for the object with functions and data-header $attribute:[name:orgtypname declname:orgtyp_nm type:string valtype:{text name} max:40] } ] O_SDL:$object:[name:def typname:SDLo declname:def ppname:SDL child:@O_OBJECT nchilds:1 attrs:{ $attribute:[name:infile declname:ifnam type:string min:1 max:$FILxXNAM required:y valtype:{constant text}] $attribute:[name:outfile declname:ofnam type:string min:1 max:$FILxXNAM valtype:{constant text}] #name of map-section $attribute:[name:section_name declname:sec_nm type:string min:0 max:50 valtype:{name text}] #section size in blocks $attribute:[name:section_size declname:sec_z type:int min:1 max:100000 valtype:num defaultval:1000] # objects $attribute:[declname:oc_n type:nr_of_objects defaultval:@O_OBJECT] $attribute:[declname:oc type:allobjects defaultval:@O_OBJECT] # attribute types $attribute:[declname:at_n type:nr_of_objects defaultval:@O_ATTRTYPE] $attribute:[declname:at type:allobjects defaultval:@O_ATTRTYPE] $attribute:[declname:error type:uchar defaultval:0] $attribute:[declname:action type:uchar defaultval:0] $attribute:[declname:pass_n type:uchar defaultval:0] $attribute:[declname:keepst_f type:uchar defaultval:0] $attribute:[declname:section_f type:uchar defaultval:0] } ] te:[declname:oc type:allobjects defaultval:@O_OBJECT] # attribute types $attribute:[declname:at_n type:nr_of_objects defaultval:@O_srs/icarus/util/colicarus.i #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # $RCSfile: colicarus.i,v $ # $Revision: 1.1 $ # $Date: 1997/03/03 18:33:15 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $nameBeg = " " $nameEnd = "" $resBeg = "" $resEnd = "" $varBeg = "" $varEnd = "" $funcBeg = "" $funcEnd = "" $refBeg = "" $refEnd = "" $sqBeg = "" $sqEnd = "" $dqBeg = "" $dqEnd = "" $reBeg = "" $reEnd = "" $cmntBeg = "" $cmntEnd = "" $rules={ readProg: ~ {$In:[file:text] $Out pre $Skip:0 $Skip:1} ln {$Wrt:[s:$StrReplace:[$Ct from:'<' to:'<']]} ln* {$App:[s:$StrReplace:[$Ct from:'<' to:'<']]} ~ ln: ~ /[^\n]*\n/ ~ prog: ~ {$In:[readProg t:color]} x{$Rep: |
     
                    } 
                    stmnt+ ~
      body:       ~ ('{' stmnt* '}' | stmnt) ~
      stmnt:      ~ (if | foreach | for | while | init | pre | file | 
                     stassoc | expr | comment) ~
      stassoc:    ~ key ident ~
      comment:    ~ {$Rep:"$cmntBeg$Ct$cmntEnd"} ('#' ln)+ ~
    
      # expression
      expr:       ~ term (op term)* ~
      term:       ~ '(' expr ')' | value ~
      op:         ~ /[+|&=*\/%!>-]+/ | '<' ~
    
      list:       ~ '{' comment? (assoc comment? | value comment?)* '}' ~
      assoc:      ~ key (value | '~' {$Rep:"$resBeg$Ct$resEnd"} 
                    production '~' {$Rep:"$resBeg$Ct$resEnd"})  ~
      key:        ~ /([a-zA-Z0-9_]+)(:)/ {$Rep:"$nameBeg$1$nameEnd$2"} |
                    /('(([^']+|\\\\.)*)')(:)/ {$Rep:"$nameBeg$1$nameEnd$4"} ~
      value:      ~ int | name | string | ident | list | reference ~
      int:        ~ /-?[0-9]+/ ~
    
      # variable names, paths and function calls
      path:       ~ name {$Rep:{"$funcBeg$Ct$funcEnd$varEnd" $Ct}} 
                    ('.' (name {$Rep:"$varBeg$Ct$varEnd"} | '(' ident ')' |
                     string | ident) | '[' expr ']')* args? ~
      ident:      ~ '$' {$Rep:"$varBeg$Ct"}  path ~ 
      args:       ~ ':' ('[' (named | unnamed)? named* ']' | unnamed) ~
      unnamed:    ~ argvalue comment? ~
      named:      ~ /([a-zA-Z_0-9]+) *:/ {$Rep:"$nameBeg$Ct$nameEnd"} argvalue 
                    comment? ~
      argvalue:   ~ int | expr | reference ~
      name:       ~ /[a-zA-Z0-9_]+/ ~
      strname:    ~ /[a-zA-Z_][a-zA-Z0-9_]*/ ~
      reference:  ~ {$Rep:"$refBeg$Ct$refEnd"} /@\\??/ name ~
    
      # strings
      string:     ~ /[^"'|]/ {$Not} (sqString | bqString | 
                    '"'{$Rep:"$dqBeg$Ct"} dqString '"' {$Rep:"$Ct$dqEnd"})~
      sqString:   ~ {$Rep:"$sqBeg$Ct$sqEnd"} /'/ /[^']*/  /'/ ~ #'"
      bqString:   ~ ('|' {$Rep:"$resBeg$Ct$resEnd" $Skip:0} bqLine {$Skip:1})+ ~
      bqLine:     ~ (/[^\n\\$(]+/  | /\\\\[^\n]/ | var | var2 | /[^\n]/)* '\n' ~ 
      dqString:   ~ (/[^"\\$(]+/ | /\\\\./ | var | var2 | '(')* ~ #"
      var2:       ~ /(\\()($)/  path ')' ~
      var:        ~ /\\$([a-zA-Z0-9_]+)/ ~
    
      # flow control
      file:       ~ 'file'{$Rep:"$resBeg$Ct$resEnd"} ':' string ~
      pre:        ~ 'pre' {$Rep:"$resBeg$Ct$resEnd"} body ~
      init:       ~ 'init' {$Rep:"$resBeg$Ct$resEnd"} body ~
      foreach:    ~ 'foreach'{$Rep:"$resBeg$Ct$resEnd"} 
                     ':''[' ident  'in' ':' expr ']' body ~
      for:        ~ 'for' {$Rep:"$resBeg$Ct$resEnd"} ':''{' expr+ '}' body ~
      while:      ~ 'while' {$Rep:"$resBeg$Ct$resEnd"} ':' cond body ~
      if:         ~ 'if' {$Rep:"$resBeg$Ct$resEnd"} ':' 
                    cond body ('elif' {$Rep:"$resBeg$Ct$resEnd"} ':' cond body)*
                    ('else' {$Rep:"$resBeg$Ct$resEnd"} body)? ~
      cond:       ~ '(' expr ')' | '{' expr '}' | '[' expr ']' | expr ~
     
      production: ~ nodeProg? bnfExpr ~
      bnfExpr:    ~ bnfTerm ('|' bnfTerm)* ~
      bnfTerm:    ~ factor comment? (factor comment?)* ~
      factor:     ~ (/x[ {\n\t]/ {$Probe} command | 
                     ((regexp | literal | eoi | prodName | laProdName) occur?))
                    nodeProg | '(' bnfExpr ')' occur? ~
      regexp:     ~ {$skip:1 $Rep:"$reBeg$Ct$reEnd"} '/' {$skip:0} reStr '/' ~
      reStr:      ~ (/[^\/\\]+/ | /\\\\./)+ ~
      literal:    ~ {$skip:1 $Rep:"$sqBeg$Ct$sqEnd"} /'/ {$skip:0} litStr /'/ ~
      litStr:     ~ (/[^'\\]+/ | /\\\\./)+ ~
      command:    ~ {$Rep:"$resBeg$Ct$resEnd"} /x:?/  ~
      eoi:        ~ '.'  ~
      occur:      ~ {$Rep:"$resBeg$Ct$resEnd"} '?'  | '*'  | '+'  ~
      nodeProg:   ~ ('{' stmnt+ '}')? ~
      prodName:   ~ /[a-zA-Z0-9_]+/ ~
      laProdName: ~ '_' /[a-zA-Z0-9_]+/ ~
    }
    
    
    $job = $JobNew:[prod:$rules skip:" \n\t" 
             fileName:'SRSDB/embl.is']
    $JobTokens:[$job name:readProg print:1 task:color withCode:0] 
    
    
    ~
      literal:    ~ {$skip:1 $Rep:"$sqBeg$Ct$sqEnd"} /'/ {$skip:0} litStr /'/ ~
      litStr:     ~ (/[^'\\]+/ | /\\\\./)+ ~
      command:    ~ {$Rep:"$resBeg$Ct$resEnd"} /x:?/  ~
      eosrs/icarus/util/command.i
    programm =     [ '$' ] command  { ';'   [ '$' ] [command] }
    ;              
    command =        ica_instruct
                   | user_instruct 
                   | check 
                   | equation
                   | usercom
    ;              
    ica_instruct =   'rd'  
                        ':' ( name | variable )
    		  [ 'c'  ':' value ]
    		  [ 't'  ':' name 
    		  [ 'l'  ':' name  ] ]
                   | 'ct'   [':' ( name |variable )] 
                   | 'et'   [':' ( name |variable )] 
                   | 'wrt'  { argument }
                   | 'app'  { argument }
                   | 'rep'  { argument }
                   | 'len'  ':' integer 
                   | 'mov'  ':' integer 
                   | 'not'    
                   | 'noskip' 
                   | 'nocase' 
                   | 'uniq'   
    ;
    argument =       'c'   ':' value
                   | 's'   ':' ( format | string | value )
    ;
    check =          'if' '(' variable '=='  
                     (integer | variable | name) ')'
    ;
    equation =       variable ('='  |
                               ':='  ) expression ;
    expression =     operand { op operand }
    ;
    operand =        variable
                   | float
    	       | integer
    	       | l_bracket expression r_bracket
                   | command 
                   | string 
    ;
    op =             '+'  
                   | '-'  
                   | '*' 
                   | '/' 
    ;
    identifier =     float | integer | variable | name
    ;
    value =          integer | variable | name
    ;
    format =         l_brace (string|variable) { variable } r_brace
    ;
    arglist =        name { ',' identifier }
    ;
    string =         '"' /[^"]*/  '"'
    ;              
    integer =        /[0-9]+/                    
    ;              
    float =          /[0-9]+\.[0-9]/             
    ;              
    name =           /[A-Za-z][0-9A-Za-z_-]*/    
    ;              
    oneword =        /[^ \t]+/                   
    ;              
    variable =       '$$' /[0-9A-Za-z]*/         
    ;              
    l_bracket =      '('                         
    ; 
    r_bracket =      ')'                         
    ;
    l_brace =        '{'                          
    ;
    r_brace =        '}'                         
    ;
    
    user_instruct=   'push1'    ':' userval
                   | 'push2'    ':' userval
                   | 'push3'    ':' userval
                   | 'push4'    ':' userval
                   | 'push5'    ':' userval
                   | 'push'     ':' userval
                   | 'pop1'     
                   | 'pop2'     
                   | 'pop3'     
                   | 'pop4'     
                   | 'pop5'     
                   | 'pop'      
                   | 'test'     
                   | 'com'      
                     ':' value 'f'  ':' value 
                   | 'arg'      
    	         ':' name { /(t|unnamed|required)/  ':' name }
                   | 'return'   
    	         ':' name { /(t|unnamed|required)/  ':' name }
                      {/(a|b|c|d)/  ':'  /[0-9]+/ }
                   | 'p'        ':' ( string | oneword )
                   | 'trigger'  ':' name
                   | 'setTask'  ':' name
    ;
    userval      = l_bracket command r_bracket | /[0-9a-zA-Z-_]+/ 
                   | variable | string;
    usercom      = /[a-zA-Z]+[a-zA-Z0-9_-]+/ 
    	        
                   [ ':' userval] 
                   { /[a-zA-Z0-9_-]+/  ':' userval} 
    ..
    
    # 0: separator (';')
    # 1-59: operators, first digit: 1: build time, 2:preparse, 4:postparse
    #       second is priority
    # 100-109,112,113 operands
    # 110: argName
    # 111: end of the argument list
    # 114: end of user argument list
    
    nd r_bracket | /[0-9a-zA-Z-_]+/ 
                   | variable | string;
    usercom      = /[a-zA-Z]+[a-zA-Z0-9_-]+/ 
    	        
                   [ ':' userval] 
                   { /[a-zA-Z0-9_-]+/  ':' userval} 
    ..
    
    # 0: separator (';')
    srs/icarus/util/ica2c.it
    #
    #    $RCSfile: ica2c.it,v $
    #    $Revision: 1.15 $
    #    $Date: 1997/03/12 16:18:50 $
    #    $Author: srs $
    #
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    
    ###############################################################################
    #
    # for conversion of the icarus commands to C functions
    #
    $prog={
      head:
        |#include 
        |#include "srs.h"
        | 
        |#include "odd.h"
        |#define _INITOBJS
        |#define _CONSTANTS
        |#define _SDL
        |#define _FUNCTION 
        |#include "oddclass.h"
        | 
        |static VARoSCOPE *scope = NULL;
        | 
        |main ()
        |{
        |  SrsEnv ();
        |  LibOpen ("srs5");
        | 
        |  IcarusFunc1 ();
        |}
        | 
        |INT4 %s ()
        |{
      func:{
        end:
          |}
      }
      body:{
        head:
          |
          |void %s ()
          |{
        tail:
          |}
      }
      stmnt:{
        head:  |  \
        tail: |;
      }
      binop:{
        '=': | = \
      }
      call:{
        name:   |%s (0\
        argint: |%d\
        argstr: |"%s"\
        argstrv:|StrCpyS ("%s")\
        argval: |%s\
        argvar: |%s\
    #    argvar: |VarGet (&scope, "%s")\
        argsep: |, \
        tail:  |)\
      }
      var:
        |%s
    #    |VarGet (&scope, "%s")\
      convert:{
        int:{
    #      var:     |VarSetInt (VarTemp (), \
          string:  |VarSetInt (VarTemp (), \
        }
        string:{
          var:  |VarSetStr (VarTemp (), \
          strv: |StrCpyS (\
        }
        strv:{
          string: |_Str (\"
          var:    |VarSetStrv (VarTemp (), \
        }
        object:{
          var:  |VarSetObject (NULL, VarTemp (), (void*)\
        }
        var:{
          object:  |VarGetObject (NULL, (void*)\
          strv:    |VarGetStrv (\
        }
        alias:{
           object: |VarGetObject (NULL, (void*)\
    #      int:   |VarGetInt (\
        }
        tail:       |)\
      }
      staticStrv:
        |static struct { int u; int l; int d; char arr[8]} str1={1,7,8,"\$ct := "};
    }
    
    ###############################################################################
    #
    # for conversion of the syntax tree to C structures
    #
    
    $bnf2c = {
      str: "%s"
      prologue:
        |#include 
        |#include 
        |#include 
        |#include 
        |#include 
        |#include 
        |
        |#define DECLARE_ONLY
        |#define DEFIGNORE " \\n\\t"
        |#define DEFCOMMENT "^#[^\\n]*\\n"
        |
        |#include "srs.h"
        |#include "regexp.h"
        |
        |static VARoSCOPE *scope = NULL;
        |
        |extern ICAoJOB *Job;
        |extern ICAoSYNTAX *Syntax;
        |
        |INT4  BnfParseProduction(BNFoPRODUCTION *);
        |INT4  BnfParseProdLoop(BNFoPRODUCTION *);
        |INT4  BnfParseRegExp(BNFoREGEXP *); 
        |INT4  BnfParseLiteral(BNFoLITERAL *);
        |INT4  BnfParseCommand(BNFoNODE *);
        |INT4  BnfParseLineStart(BNFoNODE *);
        |INT4  BnfParseInputEnd(BNFoNODE *);
        |INT4  BnfParseTerm(BNFoTERM *);
        |INT4  BnfParseChoice(BNFoCHOICE *);
        |INT4  BnfParseProdName(BNFoPRODNAME *); 
        |void  BnfPruneTree (BNFoNODE **, Int4 passN);
        |
        |VARo *IopPop_(INT4, INT4);
        |VARo *IopBody_ (Int4 runTime);
        |
        |STRv  IopInterpStr_(VARo *var, STRv str, ...);
        |STRv  IopInterpStr2(VARo *var, STRv str, ...);
        |STRv  IopSubMatch(INT4, INT4);
        |STRv  IopCurrToken();
        |
        |/* Declaration of C variables used by some translated functions */
        |VARo  *a, *b, *c, *d, *e, *u, *i, *str;
        |Int4  opt;
        |
      epilogue:
        |ICAoSYNTAX *IcaInitSyntax(ICAoSYNTAX *syntax)
        |{
        |  static ICAoSYNTAX  syntaxStatic;
        |  static ICAoJOB     job;
        |  BNFoNODE *tmp;
        |  VARo     *prodList=VarNew ();
        |  INT4     i,j;
        |
        |  if (syntax && syntax->prod) /* already initialized */
        |    return syntax;
        |
        |  if (!syntax)
        |    syntax = &syntaxStatic;
        |
        |
        |  Job = &job;
        |  Job->time = BNFxBUILDTIME;
        |
        |  j = 0;
        |  for(i=0; icurrNode = (BNFoNODE *) &_prod[i];
        |    _BnfExecInit (&_prod[i]);
        |  }
        |
        |  for(i=0; icurrNode = (BNFoNODE *) &_prodN[i];
        |    _BnfExecInit (&_prodN[i]);
        |  }  
        |
        |#ifdef LITLNUM 
        |
        |  for(i=0; icurrNode = (BNFoNODE *) &_lit[i];
        |    _BnfExecInit (&_lit[i]);
        |  }  
        |
        |#endif
        |#ifdef REGNUM 
        |
        |  for(i=0; icurrNode = (BNFoNODE *) &_reg[i];
        |    _BnfExecInit (&_reg[i]);
        |  }  
        |
        |#endif
        |#ifdef COMMNUM 
        |
        |  for(i=0; icurrNode = (BNFoNODE *) &_comm[i];
        |    _BnfExecInit (&_comm[i]);
        |  }  
        |
        |#endif
        |#ifdef STRTNUM 
        |
        |  for(i=0; icurrNode = (BNFoNODE *) &_strt[i];
        |    _BnfExecInit (&_strt[i]);
        |  }  
        |
        |#endif
        |#ifdef EOINNUM 
        |
        |  for(i=0; icurrNode = (BNFoNODE *) &_eoin[i];
        |    _BnfExecInit (&_eoin[i]);
        |  }  
        |
        |#endif
        |
        |  VarGet (&job.scope, "");
        | 
        |  syntax->prod = prodList;
        |  syntax->ign = DEFIGNORE;
        |  if (syntax == &syntaxStatic) {
        |    syntax->cmnt = DEFCOMMENT;
        |    syntax->ignAlt = "";
        |  }
        |  if ((syntax->cmntRe = RegComp (syntax->cmnt)) == NULL)
        |    _ErrExit2 (e__regerror, syntax->cmntRe);
        |
        |  Syntax = syntax;
        |  for (i=0; inode, 2);
        |  }
        |  return syntax;
        |}
      node: {
        prod: {
          arrName:  |_prod\
          defNumber:|#define PRODNUM %d
          typeDef:  |BNFoPRODUCTION %%s[] = {
          format:   | {\"%%s\",Production,0,One, \
                    |BnfParseProduction, 0,0,0,0%%s, \
                    |(BNFoNODE*)&%%s[%%d], NULL, 0, 0},
        }
        prodN: {  
          arrName:  |_prodN\
          defNumber:|#define PRODNNUM %d
          typeDef:  |BNFoPRODNAME %%s[] = {
          format:   | {\"%%s\",ProdName, 0, One, \
                    |BnfParseProdName, 0,0,0,0%%s, &%%s[%%d]},
        }
        lit: {
          arrName:  |_lit\
          defNumber:|#define LITLNUM %d
          typeDef:  |BNFoLITERAL %%s[] = {
          format:   | {\"%%s\",Literal,0,One, BnfParseLiteral, 0,0,0,0%%s },
        }
        reg: {
          arrName:  |_reg\
          defNumber:|#define REGNUM %d
          typeDef:  |BNFoREGEXP %%s[] = {
          format:   | {\"%%s\",Regexp,0,One, BnfParseRegExp, 0,0,0,0%%s },
        }
        term: {
          arrName:  |_term\
          defNumber:|#define TERMNUM %d
          typeDef:  |BNFoTERM %%s[] = {
          format:   | {"TERM",Term,0, One, BnfParseTerm },
        }
        choi: {
          arrName:  |_choi\
          defNumber:|#define CHOINUM %d
          typeDef:  |BNFoCHOICE %%s[] = {
          format:   | {"CHOI",Choice,0, One, BnfParseChoice },
        }
        comm: {
          arrName:  |_comm\
          defNumber:|#define COMMNUM %d
          typeDef:  |BNFoNODE %%s[] = {
          format:   | {"COMM",Command,0, One, BnfParseCommand, 0,0,0,0%%s },
        }
        strt: {
          arrName:  |_strt\
          defNumber:|#define STRTNUM %d
          typeDef:  |BNFoNODE %%s[] = {
          format:   | {"STRT",LineStart,0,One, BnfParseLineStart, 0,0,0,0%%s },
        }
        eoin: {
          arrName:  |_eoin\
          defNumber:|#define EOINNUM %d
          typeDef:  |BNFoNODE %%s[] = {
          format:   | {"EOIN",EndOfInput,0,One, BnfParseInputEnd, 0,0,0,0%%s },
        }
        reprt: {
          arrName:  | { 0, NULL },
          defNumber:|#define RAPORTNUM %d
          typeDef:  |BNFoREPORT _report[] = {
          format:   | { %%d, (BNFoNODE *)&%%s[%%d] },
        }
        set: {
          arrName:  | NULL,
          defNumber:|#define SETNUM %d
          typeDef:  |BNFoNODE *_choiceSet[] = {
          format:   | (BNFoNODE *)&%%s[%%d],
        }
        var: {
          arrName:  |_var\
          defNumber:|#define VARNUM %d
          typeDef:  |VARo %%s[] = {
          format:   | { NULL,1,0,1,1,0,0,0, {(Func) %%s}, NULL, NULL },
        }
        scope: {
          arrName:  |_scopeName\
          defNumber:|#define NAMENUM %d
          typeDef:  |char *%%s[] = {
          format:   | \"%%s\",
        }
      }
    }
    
    ODE *)&%%s[%%d] },
        }
        set: {
          arrName:  | NULL,
          defNumber:|#define SETNUM %d
          typeDef:  |BNFoNODE *_choiceSet[] = {
          format:   | (BNFoNODE *)&%%s[%%d],
        }
        var: {
          arrName:  |_var\
          srs/icarus/util/icacom.ic
    #
    #    $RCSfile: icacom.ic,v $
    #    $Revision: 1.4 $
    #    $Date: 1997/03/06 20:15:32 $
    #    $Author: srs $
    #
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    
    
    Class_Value:$object:[val 
      typname:"ODDoVALUE" declname:"ODDValue" 
      rem:"Value in an enumeration" 
      attrs:{ 
        $attribute:[name declname:name unnamed:y required:y type:string 
          rem:"Name of value."]
        $attribute:[n declname:n required:y type:int rem:"Number value."] 
        $attribute:[rem declname:"rem" type:string rem:"Comment field."] 
      }
    ]
    
    Class_Var:$object:[var 
      typname:"IARGoVALUE" declname:"IARGVALUE" nchilds:1 child:@Class_Value
      rem:"Argument of Icarus command." 
      attrs:{ 
        $attribute:[name declname:"name" type:string unnamed:y   
          rem:"Name of the argument in an Icarus program."] 
        $attribute:[rem declname:"rem" type:string rem:"Comment field."] 
        $attribute:[unnamed declname:isUnnamed type:uchar defaultval:0 
          rem:"Defines if parameter may be unnamed." 
          enum:{ 
            $value:[y val:1] 
            $value:[n val:0]  
          } 
        ] 
        $attribute:[required 
          declname:isRequired type:uchar defaultval:0 
          rem:"Defines if parameter is required." 
          enum:{ 
            $value:[y val:1] 
            $value:[n val:0]  
          } 
        ] 
        $attribute:[t 
          declname:type type:uchar defaultval:2 
          rem:"Type of the argument" 
          enum:{ 
            $value:[int    val:1]  
            $value:[string val:2] 
            $value:[strv   val:9] 
            $value:[object val:3] 
            $value:[real   val:4] 
            $value:[var    val:6] 
            $value:[list   val:16] 
          } 
        ] 
        $attribute:[class declname:className type:string]
        $attribute:[defInt 
          declname:defInt type:int 
          rem:"Default value of type 'int' arguments."] 
        $attribute:[defStr  
          declname:defaultStr type:string 
          rem:"Default value of type 'string' arguments."] 
        $attribute:[enum declname:vals type:child defaultval:@Class_Value] 
        $attribute:[declname:valsN type:nr_of_childs defaultval:@Class_Value] 
        $attribute:[declname:isSet type:uchar defaultval:0] 
        $attribute:[declname:"*val" typname:"struct VARo" type:user] 
      } 
    ] 
     
    
    Class_Com: $object:[com 
      typname:IARGoCOM declname:IARGCOM nchilds:1 child:@Class_Var
      attrs:{  
        $attribute:[name unnamed:y declname:"name" type:string required:y 
          rem:"Name of command in Icarus programs."] 
        $attribute:[f declname:"functionName" type:string 
          rem:"C function that implements the command."] 
        $attribute:[show declname:isShow type:int
          rem:
            |Determines whether the command should appear in the 
            |Icarus functions reference list.
          enum:{
            $value:[n val:0]
            $value:[y val:1]
          }
        ]
        $attribute:[rem declname:"rem" type:string rem:"Comment field."] 
        $attribute:[return 
          declname:returnType defaultval:2 type:uchar 
          rem:"Type of value to be returned (if any)." 
          enum:{ 
            $value:[int    val:1]  
            $value:[string val:2] 
            $value:[strv   val:9] 
            $value:[object val:3] 
            $value:[real   val:4] 
            $value:[var    val:6] 
            $value:[list   val:16] 
          } 
        ] 
        $attribute:[time 
          declname:time defaultval:8 type:int  
          rem:"Execution time of command." 
          enum:{ 
            $value:[init     val:2]  
            $value:[pre      val:4] 
            $value:[initpre  val:6] 
            $value:[post     val:8] 
            $value:[prepost  val:12] 
          } 
        ] 
        $attribute:[returnClass declname:returnClass type:string]
        $attribute:[call 
          declname:isDirectCall defaultval:0 type:uchar 
          rem:"Call function directly or via C-interface." 
          enum:{ 
            $value:[direct    val:1] 
            $value:[interface val:0]  
          } 
        ] 
        $attribute:[methodOf declname:methodOf type:string 
           rem:|The class of which this function is a method otherwise treated as
               |normal function.
        ]
        $attribute:[args declname:args type:child defaultval:@Class_Var] 
        $attribute:[declname:argsN type:nr_of_childs defaultval:@Class_Var] 
        $attribute:[declname:"(*function)()" typname:INT4 type:user 
          rem:"Function to be executed for command."]
        $attribute:[declname:"orderN" type:int 
          rem:"Number of arguments ordered from C function (via 'IargGetArgs')."]
        $attribute:[declname:"orderAllocN" type:int 
          rem:"Number of orders currently allocated."]
        $attribute:[declname:"**order" typname:"struct IARGoVALUE" type:user 
          rem:"Array with a list of argument orders."]
      } 
    ] 
    type:nr_of_childs defaultval:@Class_Var] 
        $attribute:[declname:"(*function)()" typname:INT4 type:user 
          rem:"Function to be executed for command."]
        $attribute:[declname:"orderN" type:int 
          rem:"Number of arguments ordered from C function (via 'IargGetArgs')."]
        $attribute:[declname:"orderAllocN" type:int 
          rem:"Number of orders currently allocated."]
        $attribute:[declname:"**order" typname:"struct IARGoVALUE" typesrs/icarus/util/icarus.i
    # functions for building the executable structure
    #
    #
    # high level productions
    #
    entry      = 
                ln  { ln } ;   
    ln        = /[^$]+/ ;
    
    prog  = *  stmnt { stmnt } 
                *  ;
    body      = *  ('{' { stmnt  } '}' | stmnt ) 
                * ;
    stmnt      = (if | for | while | init | pre | file | stassoc | expr);
    
    stassoc   = key  
                ident ;
    #
    # expression
    #
    expr      = term1 {logop term1 makeop};
    term1     = term2 {(compop|assop) term2 };
    term2     = term3 {op1  term3 };
    term3     = term4 {op2 term4 makeop};
    term4     = '(' expr ')' | [unopleft] value [unopright];
    makeop    = * ;
    nullopnd  = * ;
    #
    # operators
    #
    logop     = '&&'  | '||'  ;
    assop     = '=+'  | '='   | 
                '-='  | '*='  |
                '/='  ;	     
    compop    = '<='  | '=<'  | 
                '>='  | '=>'  | 
                '<'   | '>'   | 
                '=='  | '!='  ;	     
    op1       = '+'     | '-'   |
                '%'   ;	        
    op2       = '*'     | '/'   ;
    unopleft  = '++'  | '--'  | 
                '-'   | '+'   ;
    unopright = '++'  | '--'  ;
    #
    # variables values and lists
    #
    list      = '{' 
                 {assoc|value} '}' ;
    assoc     = key  
                (value |'~' production '~') * ;
    key       = /([a-zA-Z0-9_]+):/;
    value     = int  |
                string | ident | list | namestr | reference;
    
    #
    # flow control
    #
    file      = 'file' ':' string * ;
    pre       = 'pre' body ;
    init      = 'init' body ;
    for       = 'for'':''{' (expr|nullopnd) (expr|nullopnd) (expr|nullopnd)
                '}' body ;
    while     = 'while'':' cond body ;
    if        = 'if'':' cond body {'elif'':' cond body}
                ['else'   body] *;
    cond      = '(' expr ')' | '{' expr '}' | '[' expr ']' |  expr;
    case      = 'case'ident 
                '{' { '?' value  ':' body } '}'
                ; 
    
    #/(else|for|while|if|case|\?)[^a-zA-Z0-9]/  
    ic         = 'installClasses';
    print      = 'print'  args * ;
    #
    # variable name or function call
    #
    ident     = '$$' path;
    path      = name  
                { '.'(name  | 
                  '(' ident ')'  |
                  string  |
                  ident )|
                /\\[([0-9]+)\\]/  |
                '[' expr ']'  } 
                [ args ];
    args      = ':' 
                ('[' [named | unnamed] {named} ']' | unnamed );
    unnamed   = argvalue  | ':::::' ;
    named     = /([a-zA-Z_0-9]+) *:/ 
                argvalue ;
    argvalue  = int  |
                ident | string | strname | list | '(' expr ')' | reference;
    
    
    reference = '@' ('?'<$opt=1> | *<$opt=0>) 
                name ;
    name      = /[a-zA-Z0-9_]+/;
    real      = /[0-9]*\\.[0-9]*/;
    int       = /-?[0-9]+/;
    namestr   = /[a-zA-Z0-9_]+/ ;
    string    = '"' mystring  '"'  
                | /'/ /[^']*/  /'/;
    
    
    
    mystring = * 
                {/((\\\\.)+|[^"\\$$]+)/ | '$$$$' | strident };
    strident   = '$$(' path | '$$' path;
                
    strname   = /[a-zA-Z_][a-zA-Z0-9_]*/ ;
    #"
    #
    # commands for creating the syntax tree
    #
    #
    # the 'Backus-Naur format' derived syntax description'
    #
    production = *  [nodeProg] 
                 bnfExpr ; 
    bnfExpr    = *  term  { '|' term } * ;
    term       = *  factor { factor } * ;
    factor     = (regexp | literal | command | prodName | laProdName) [occur]
                 [nodeProg] | '(' bnfExpr ')' [occur];
    regexp     =  '/'  sqString  '/';
    sqString   =  {/((\\\\.)+|[^\/\\]+)/};
    literal    =  /'/ /[^']*/  /'/ ;
    command    = 'x:' ;
    occur      = '?'  | 
                 '*'  | 
                 '+' ;
    nodeProg   = '{' * stmnt{stmnt} * '}'
                 ;
    prodName   =  /[0-9a-zA-Z_]+/ ;
    laProdName = '_' /[a-zA-Z_]+/ ;
    
    end = 'end'.
    
    
    
    
    skip; push3:(literal:"$ct")> /'/ ;
    command    = 'x:' ;
    occur      = '?'  | 
                 '*'  | 
                 '+' ;
    nodeProg   = '{' * stmnt{stmnt} * '}'
                 ;
    srs/icarus/util/icarus.is
      prog:       ~ {$out pre{$push:$opnd:[ga t:mark]} $prog} stmnt (stmnt)* ~
      stmnt:      ~ {$out} for | init | pre | doFile | assoc | expr ~
      body:       ~ {pre{$push:$opnd:[t:mark]} $push:$body:"IopBody"} 
                    ('{' (stmnt)* '}' | stmnt) ~ 
    
      # expression
      expr:       ~ term1 (logop term1 makeop)* ~  
      term1:      ~ term2 ((compop | assop) term2 makeop)* ~
      term2:      ~ term3 (op1  term3 makeop)* ~
      term3:      ~ term4 (op2 term4 makeop)* ~
      term4:      ~ '(' expr ')' | (unopleft)? value (unopright)? ~
      makeop:     ~ x:{$push:$op2:[$pop1 b:$pop a:$pop]} ~
      nullopnd:   ~ x:{$push:$opnd:[t:null]} ~
      
      # operators
      logop:      ~ '&&' {$push1:IcaOpAnd}    | '||' {$push1:IcaOpOr} ~
      assop:      ~ '=+' {$push1:IopAddAss}   | '='  {$push1:IopAss} | 
                    '-=' {$push1:IcaOpAssSub} | '*=' {$push1:IcaOpAssMul} |
                    '/=' {$push1:IcaOpAssDiv} ~
      compop:     ~ '<=' {$push1:IcaOpLE}     | '=<' {$push1:IcaOpLE} | 
                    '>=' {$push1:IcaOpGE}     | '=>' {$push1:IcaOpGE} | 
                    '<'  {$push1:IopLT}       | '>'  {$push1:IcaOpGT} | 
                    '==' {$push1:IcaOpGE} ~ 
      op1:        ~ '+'  {$push1:IopAdd}      | '-'  {$push1:IopSubt} |
                    '%'  {$push1:IcaOpMod} ~ 
      op2:        ~ '*'  {$push1:IopMul}      | '/'  {$push1:IcaOpDev} ~
      unopleft:   ~ '++' {$push1:IcaOpIncr}   | '--' {$push1:IcaOpDecr} | 
                    '-'  {$push1:IcaOpNeg}    | '+'  {$push1:IcaOpPos} ~
      unopright:  ~ '++' {$push1:IcaOpIncr}   | '--' {$push1:IcaOpDecr} ~
    
      # variables values and lists
      list:       ~ '{' {$push:$opnd:[t:mark]} (assoc | value) '}' {$push:$list} ~
      assoc:      ~ {$push:$assoc:[val:$pop key:$pop5]}
                    key {$push5:$opnd:["$1" t:string]} (value|'~' production '~') ~
      key:        ~ /([a-zA-Z0-9_]+):/ ~
      value:      ~ int {$push:$opnd:["$ct" t:int]} |
                    string | ident | list | namestr | reference ~
      # flow control
      doFile:     ~ {$push:$file:$pop} 'file' ':' string ~
      pre:        ~ {$push:$Pre:$pop} 'pre' body ~
      init:       ~ {$push:$init:$pop} 'init' body ~
      for:        ~ 'for'':''{' (expr | nullopnd) (expr | nullopnd) (expr|nullopnd)
                    '}' body {$push:$for:[IopFor b:$pop u:$pop c:$pop i:$pop]} ~
    
      # variable name or function call
      objId:      ~ /_[a-zA-Z0-9_]+/ {$newId:"$ct"} ~
      ident:      ~ '$' path ~ #'
      path:       ~ name {$push:$opnd:["$ct" t:ident]} 
                    ('.'(name {$push:$select:[$pop key:"$ct"]} | 
                    '(' ident ')' {$push:$select:[keyvar:$pop var:$pop]} |
                    string {$push:$select:[keyvar:$pop var:$pop]} |
                    ident {$push:$select:[keyvar:$pop var:$pop]}) |
                    /\\[([0-9]+)\\]/ {$push:$select:[$pop n:"$1"]})* 
                    (args {$push:$func})? ~
      args:       ~ ':' {$push:$opnd:[t:mark]} 
                    ('[' ((named | unnamed) (named)*)* ']' | unnamed) ~
      unnamed:    ~ argvalue {$push:$Makearg:[$pop name:$opnd:[":::::" t:str]]} ~
      named:      ~ /([a-zA-Z_0-9]+) *:/ {$push:$opnd:["$1" t:str]}
                    argvalue {$push:$Makearg:[$pop name:$pop]} ~
      argvalue:   ~ int {$push:$opnd:["$ct" t:int]} |
                    ident | string | strname | list | '(' expr ')' | reference ~
      reference:  ~ '@' ('?'{$opt=1} | x:{$opt=0}) 
                    name {$push:$oddRef:["$ct"]} ~
      name:       ~ /[a-zA-Z0-9_]+/ ~
      real:       ~ /[0-9]*\\.[0-9]*/ ~
      int:        ~ /-?[0-9]+/ ~
      namestr:    ~ /[a-zA-Z0-9_]+/ {$push:$opnd:["$ct" t:str]} ~
      string:     ~ '"' mystring {$noskip $push:$opnd:["$ct" t:istr]} '"'  
                    | /'/ /[^']*/ {$noskip $push:$opnd:["$ct" t:str]} /'/ ~ #'
      mystring:   ~ {$noskip pre{$push:$opnd:[t:mark]}} 
                    (/((\\\\.)+|[^"\\$$]+)/ {$noskip} | '$$' | strident)* ~ #"
      strident:   ~ '$(' path | '$' path ~ #'
      strname:    ~ /[a-zA-Z_][a-zA-Z0-9_]*/ {$push:$opnd:["$ct" t:str]} ~
    
    
      # the 'Backus-Naur format' derived syntax description
      production: ~ {pre{$push3:$prod}} (nodeProg)?
                    bnfExpr {$push:$endProd:[node:$pop3 prod:$pop3]} ~
      bnfExpr:    ~ {pre{$push3:$nullNode} $push3:$expr} term ('|' term)* ~
      term:       ~ {pre{$push3:$nullNode} $push3:$term} factor (factor)* ~
      factor:     ~ (regexp | literal | command | prodName | laProdName)
                    (nodeProg)? | '(' bnfExpr ')' (optional | repeat)? ~
      regexp:     ~ '/' /[^\|]*/ {$noskip $push3:$regexp:"$ct"} '/' ~
      literal:    ~ /'/ /[^']*/ {$noskip $push3:$literal:"$ct"} /'/ ~ #'
      command:    ~ 'x:' {$push3:$doCom} ~
      optional:   ~ '?' {$push3:$makeOpt:[$pop3 t:once]} ~
      repeat:     ~ x:{$push3:$makeOpt:[$pop3 t:multi]} ~
      nodeProg:   ~ {$push3:$nodeProg:[$pop3 prog:$pop]} 
                    '{' {$push:$opnd:[t:mark]} stmnt (stmnt)*
                    x:{$push:$body:IopBody} '}' ~
      prodName:   ~ /[a-zA-Z_]+/ {$push3:$ProdName:"$ct"} ~
      laProdName: ~ '_' /[a-zA-Z_]+/ {$push3:$ProdName:["$ct" lookahead:1]} ~
    }
    /' ~
      literal:    ~ /'/ /[^']*/ {$noskip $push3:$literal:"$ct"} /'/ ~ #'
      command:    ~ 'x:' {$push3:$doCom} ~
      optional:   ~ '?' {$push3:$makeOpt:[$pop3 t:once]} ~
      repeat:     ~ x:{$push3:$makeOpt:[$pop3 t:msrs/icarus/util/makewild.i
    #    $RCSfile: makewild.i,v $
    #    $Revision: 1.3 $
    #    $Date: 1997/03/03 18:32:49 $
    #    $Author: srs $
    #
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    $rules={
      query:    ~ {init{$SetFunctions:QuerySetFunctions}}
                  factor (op factor)* ~
      op:       ~ /[|&<>!=]/ ~
      factor:   ~ set | retrieve | '(' query ')' ~
      set:      ~ /[a-zA-Z0-9_]+/ ~
      retrieve: ~ '[' libs '-' name (':' wordExpr | /#[^]]+/) ']' ~
      wordExpr: ~ wordTerm (logop wordTerm)* ~
      wordTerm: ~ '(' wordExpr ')' | word ~  
      logop:    ~ /[!|&]/ ~
      name:     ~ /[a-zA-Z0-9_]+/ ~
      word:     ~ '"' /([^"\\]+|\\\\.)*/ 
                   {if:$parInt:makeWild $rep:$MakeWild:$ct} '"' | #"
                   '\'' /([^'\\]+|\\\\.)*/ 
                   {if:$parInt:makeWild $rep:$MakeWild:$ct} '\'' |
                   /\/([^\/\\]+|\\\\.)*\//  | # regexp - do nothing!
                   /[^]|&!)]*[^]|&!) ]/ {if:$parInt:makeWild $rep:$MakeWild:$ct}
                ~
      libs:     ~ /([a-zA-Z0-9_]+) *=/? ('{' (name)* '}' | name) ~
    }
    
    #$parInt:[makeWild set:1]
    #$parse:['(a&[a={pir embl}-def:1&"arg"])' prod:$rules start:expr skip:" "]
     /([^"\\]+|\\\\.)*/ 
                   {if:$parInt:makeWild $rep:$MakeWild:$ct} '"' | #"
                   '\'' /([^'\\]+|\\\\.)*/ 
                   {if:$parInt:makeWild $rep:$MakeWild:$ct} '\'' |
                   /\/([^\/\\]+|\\\\.)*\//  | # regexp - do nothing!
                   /[^]|&!)]*[^]|&!) ]/ {if:$parInt:makeWild $rep:$MakeWild:$csrs/icarus/util/man_capi.i
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    #    $RCSfile: man_capi.i,v $
    #    $Revision: 1.12 $
    #    $Date: 1997/03/19 21:13:47 $
    #    $Author: srs $
    #
    # Generates the HTML with the documentation of the functions in C language
    # modules
    #
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    #
    #
    
    $entry = { 
               name:"" api:0 comment:"" 
               input:{
                 {write:"" type:"" name:"" rem:""}
                 {write:"" type:"" name:"" rem:""}
                 {write:"" type:"" name:"" rem:""}
                 {write:"" type:"" name:"" rem:""}
                 {write:"" type:"" name:"" rem:""}
                 {write:"" type:"" name:"" rem:""}
                 {write:"" type:"" name:"" rem:""}
                 {write:"" type:"" name:"" rem:""}
                 {write:"" type:"" name:"" rem:""}
                 {write:"" type:"" name:"" rem:""}
                 {write:"" type:"" name:"" rem:""}
                 {write:"" type:"" name:"" rem:""}
                 {write:"" type:"" name:"" rem:""}
                 {write:"" type:"" name:"" rem:""}
                 {write:"" type:"" name:"" rem:""}
               }
               retCom:{"" "" "" "" "" "" "" "" "" ""}
             }
    
    $Xfiles={
      templ	    
    }
    
    $files={
      arglist
      bnf2c     
      btree        
      cursor
      dict         
      entry        
      field
      futil        
      hash         
      ica2c     
      icaarg    
      icabnf      
      icaop     
      icarus    
      icatask   
      id           
      ids          
      idx       
      index          
      library      
      link         
      logicals     
      lst
      message      
      oldlistbuf   
      par         
      print        
      query        
      queryass     
      regexp       
      sdlget       
      seq          
      seqlib       
      set          
      sm           
      srswww
      strv         
      templ	    
      tm           
      toklist
      unix_map     
      variable     
      view
      wgetz	    
    }
    
    $testfiles={
      variable     
    }
    
    
    $rules={
    
      # the entire function header
      header:    ~ { $Out 
                     pre{
                       $Skip:0 
                       $inputN=1
                       $argN=1
                       $returnN=1
                       $implicitN=1
                       $entry.name=''
                       $entry.fname=''
                       $entry.api=0
                     }
                   }
                   (/.\\*\\*+(API|api).+[a-zA-Z0-9]+ +\\*+/ {$Not} ln)* 
                   (/[*\/]+(API|api)/ {$Wrt} 
                     ln {$App}(/[*\/]+/ appLn)* x{$App:[s:'@@\n']} 
                     (/.*{ *\n/ {$Not} appLn)+ /[^{]*/ {$App} 
                   )? ~
    
      # fields inside the function header
      fields:    ~ {$Out $In:header}
                   title comment input? implicit? return? proto ~
      title:     ~ /\/\\*\\*/ ('api' {$entry.api=1} | 'API' {$entry.api=2})? 
                   /\\** */ name {$entry.fname=$Ct} ln ~
      comment:   ~ {$entry.comment=$Ct} (/([ \t]+[A-Z]+ *:|@@)/{$Not} ln)+ ~ 
      input:     ~ /[ \t]+INPUT *:/ ln {$Wrt:input}
                   (/([ \t]+[A-Z]+ *:|@@)/{$Not} appLn)* ~ 
      implicit:  ~ /[ \t]+IMPLICIT:/ ln {$Wrt:implicit}
                   (/([ \t]+[A-Z]+ *:|@@)/{$Not} appLn)* ~ 
      return:    ~ /[ \t]+RETURNS? *:/ ln {$Wrt:return}
                   ('@@'{$Not} appLn)* ~ 
      proto:     ~ ln /.*/ {$Wrt:proto}  ~
    
      # break lists
      l_input:   ~ {$In:[fields c:input] $Out:input} l_item* ~
      l_implicit:~ {$In:[fields c:implicit t:dod] $Out:implicit}
                   l_item* ~
      l_return:  ~ { $In:[fields c:return] $Out:return} 
                   l_item* {$entry.retCom[$returnN] = $Ct $returnN=$returnN+1} ~
      l_item:    ~ /[ \t]+o[ \t]/ ln {$Wrt $s=$Ct} (/[ \t]+o[ \t]/ {$Not} appLn)* |
                   /[ \t\n]+([^\n \t][^\n]+)\n/ {$Wrt:[s:$1] $s=$1} ~  
      i_inputRW: ~ { $In:[input] $Out:gaga 
                     pre{$arg=$entry.input[$inputN] $arg.write='read'}
                     $arg.rem=$Ct 
                     $inputN=$inputN+1
                     
                   } (/[^[]*/ ('[W]'{$arg.write='write' $Rep:''}|
                     '[R]'{$arg.write='read' $Rep:''} | '[')? )+ ~
    
      # break prototype into single arguments
      l_proto:   ~ { $In:[fields c:proto] 
                     $Out:proto 
                     pre{$Skip:1}
                     $Skip:0
                   } 
                   typeName {$entry.return = $Ct}
                   name {$entry.name=$Ct} '(' (l_arg (',' l_arg)*)? ')' 
                 ~
      l_arg:     ~ { pre{$arg=$entry.input[$argN]}
                     $argN=$argN+1
                   }
                   typeName {$arg.type=$Ct} 
                    argName {$arg.name=$Ct} | 
                    '...' {$arg.type=$Ct $arg.name=' '} ~
    
      # for replacing function names by hypertext links
      function:  ~ {$Out pre{$Skip:1}}
                   ('

    ' {$Not} ln {$Print:[$Ct f:$outf]})* ('

    ' {$Wrt} appLn ('

    ' {$Not} appLn)*)? ~ h_function:~ {$In:function $Out} /[^\n]+A>([a-zA-Z0-9]+)[^\n]+\n/ { $Print:[$Ct f:$outf] if:$example.($1).isOk { # $Print:"... linking function $1 to examples\n" $Print:['Used in:' f:$outf] foreach:[$ex in:$example.($1).link] $Print:[$ex f:$outf] $Print:['
    ' f:$outf] } } h_line+ {$Print:[$Ct f:$outf]} ~ h_line: ~ ( /[A-Za-z0-9_]+/ { if:$funct.$Ct !="" $Rep: |$Ct\ } | /[^A-Za-z0-9_\n]+/ )* '\n' ~ # others typeName: ~ /(static|struct|enum|unsigned|long)/? /[a-zA-Z0-9_]+/ /[ *]*/{$Noskip} ~ argName: ~ (/[][a-zA-Z0-9_*]+/ /[ *]*/{$Noskip} | '(*' /[^)]+\\)/ /\\([^)]*\\)/) ~ name: ~ /[a-zA-Z0-9_*]+/ ~ ln: ~ /[^\n]*\n/ ~ appLn: ~ /[^\n]*\n/ {$App} ~ } # # build the functions index and the function documentation page # $outf = $FileOpen:["SRSMAN:mtoc2_func.html" mode:write] $outt = $FileOpen:["SRSMAN:mtoc_func.html" mode:write] $Print:[f:$outf s: | | |Module $SRS functions list | | | ] $Print:[f:$outt s: | | |Module $SRS module list | | | |

    Modules in SRS

    |
      ] $Print:|...parsing C files foreach:[$module in:$files] { $fil = $FileOpen:"SRSSOU:$module.c" $outm = $FileOpen:["SRSMAN:mff_$module.html" mode:write] $Print:[f:$outt s: |
    • $module ] $Print:[f:$outf s: |

      Module "$module"

      |
        ] $Print:[f:$outm s: | | |Descriptions of module "$module" functions | | ] $job = $JobNew:[prod:$rules skip:" \n\t" file:$fil] while:$JobHasInput:$job { $JobTokens:[$job name:fields] $JobTokens:[$job name:gaga] $JobTokens:[$job name:return] $JobTokens:[$job name:proto] if:($entry.name!='' && $entry.api) { $nam = $entry.name $funct.$nam = $module # save for inserting hypertext links $Print:[f:$outf s: |
      • ($entry.name) ] # print the function information $Print:[f:$outm s: |

        $nam

        |($entry.comment)

        ] # print the function arguments $Print:[f:$outm s: |

        |
    $Ct:$Ct
    | | | | ] for:{$l=1 $l<$inputN $l=$l+1} { $Print:[f:$outm s: | | | | | ] } if:$l==1 $Print:[f:$outm s: | | ] # type of return value if:$entry.return=="void " $rem="
    nothing
    " else $rem=$entry.retCom[1] $Print:[f:$outm s: | | | | | | |
    TypeNameR/WComment
    |Arguments
    ($entry.input[$l].type)($entry.input[$l].name)($entry.input[$l].write)($entry.input[$l].rem)
       none
    |Returns
    ($entry.return)  ($rem)
    | ] } $JobNext:$job } $FileClose:$fil $FileClose:$outm $Print:[''f:$outf] } $FileClose:$outt # # read the programming manual insert hypertext links and examples # $progRules={ file: ~ {pre{$Skip:0}} (title {$Print:[$Ct f:$mprog]} | include | line { $Print:[$Ct f:$mprog]})+ ~ title: ~ /.*(name|NAME)="([a-zA-Z0-9_-]+)".*\n/ {$chapter=$2} ~ line: ~ ( /[^\na-zA-Z0-9_]+/ | /[a-zA-Z0-9_]+/ {if:$funct.$Ct !="" $Rep:|$Ct\ } )* '\n' ~ include: ~ /.*INCLUDE EXAMPLE:/ /[a-zA-Z0-9.]+/ { $Print:[| |
    \
                     f:$mprog] 
                   $exName = $Ct
                   $Parse:[prod:$exRules start:file 
                     fileName:"SRSDEMO:$Ct"]
                   $Print:['
    ' f:$mprog] } ~ } $exRules={ file: ~ {pre{$Skip:0}} line+ {$Print:[$Ct f:$mprog]} ~ line: ~ ( /[^\na-zA-Z0-9_]+/ | /[a-zA-Z0-9_]+/ { $name = $Ct if:$funct.$Ct !="" { $Rep:|$Ct\ # $Print:|found $name <-> $exName $example.($name).isOk = 1 $example.($name).link.$exName = | $exName\ } } )* '\n' ~ } $mprog = $FileOpen:["SRSMAN:m_prog.html" mode:write] $Print:|...parsing the C API manual $Parse:[prod:$progRules start:file fileName:"SRSDOC:prog.html"] # # go over the function documentation page again and search for # known function names that will be promoted to hypertext links # $Print:|...parsing the module descriptions in HTML foreach:[$module in:$files] { $inf = $FileOpen:["SRSMAN:mff_$module.html"] $outf = $FileOpen:["SRSMAN:mf_$module.html" mode:write] $job = $JobNew:[prod:$rules skip:" \t" file:$inf] $Print:'.' while:$JobHasInput:$job{ $JobTokens:[$job name:h_function print:0] $JobNext:$job } $FileClose:$inf $FileClose:$outf } $Print:'\n' mentation page again and searsrs/icarus/util/man_chap.i $chapter={ {path:"SRSDOC:srswww.html" part:srswww} {path:"SRSDOC:tour.html" part:tour} {path:"SRSDOC:srsmaint.html" part:srsmaint} {path:"SRSDOC:icarus.html" part:icarus} {path:"SRSDOC:install.html" part:install} {path:"SRSDOC:query.html" part:query} {path:"SRSDOC:debugger.html" part:debugger} {path:"SRSMAN:class.html" part:class} {path:"SRSMAN:icafunc.html" part:icafunc} {path:"SRSMAN:usage.html" part:usage} {path:"SRSDOC:internal.html" part:internal} } # get the list of all documented icarus functions $icaFunRules={ title: ~ (/.*<[Hh][1-4]>/ /<(A NAME|a name)="?([^>"]+)"?>/ {$name=$2} #" /.*(\\$[a-zA-Z0-9_]+)<\/[hH]/? {$fun.($1).flag=1 $fun.($1).file=$fileName $fun.($1).name=$name} | ln )+ ~ ln: ~ /[^\n]*\n/ ~ } $rules={ # extract titles and bodies field: ~ {$Out pre $skip:0} x{$Wrt:dummy} ( (/[ \t\n]*<[Hh][1-6]>/ {$Not} ln {$App})+ (/[ \t\n]*<[Hh][1-6]>/ {$Wrt:title} (/.*<\/[Hh][1-6]>/ {$Not} ln {$App})* /.*<\/[Hh][1-6]>/ {$App} ln {$Wrt:text})? )+ ~ # inserting of links to index words text: ~ {$In:[field t:rep] $Out} word* ~ word: ~ /<(BODY|body)>/ {$Rep:| } | /<[hH][1-4]>.*<\/[hH][1-4]>/ | /<(PRE|pre)>/ {$Rep:"

    "}|
                /<\/(PRE|pre)>/{$Rep: "

    "} | /\\$[a-zA-Z0-9_]+/ {if:$fun.($Ct).flag==1 $Rep: |$Ct\ } | /[^$<]+/ | /./ ~ # other stuff ln: ~ /[^\n]*\n?/~ } # make a list of all icarus functions and classes foreach:[$fileName in:{'icafunc' 'class'}] { $Parse:[fileName:"SRSMAN:$fileName.html" prod:$icaFunRules start:title ] } # process the chapters $job = $JobNew:[prod:$rules skip:" "] foreach:[$chap in:$chapter] { $ifil = $FileOpen:"($chap.path)" $ofil = $FileOpen:["SRSMAN:m_($chap.part).html" mode:write] $print:|...processing ($chap.path) $JobNext:[$job file:$ifil] while:$JobHasInput:$job { $JobTokens:[$job name:field task:rep print:1 withCode:0 outFile:$ofil] $JobNext:$job } $FileClose:$ofil $FileClose:$ifil } { srs/icarus/util/man_inx.i $chapter={ {path:"SRSMAN:m_install.html" part:install n:1} {path:"SRSMAN:m_srswww.html" part:srswww n:1} {path:"SRSMAN:m_query.html" part:query n:2} {path:"SRSMAN:m_usage.html" part:usage n:3} {path:"SRSMAN:m_icarus.html" part:icarus n:4} {path:"SRSMAN:m_icafunc.html" part:icafunc n:5} {path:"SRSMAN:m_debugger.html" part:debugger n:6} {path:"SRSMAN:m_tour.html" part:tour n:7} {path:"SRSMAN:m_srsmaint.html" part:srsmaint n:8} {path:"SRSMAN:m_prog.html" part:prog n:9} {path:"SRSMAN:m_class.html" part:class n:11} # {path:"SRSMAN:m_internal.html" part:internal n:11} } $indexWords={ 'action' 'argument' 'associative list' 'class' 'data-field' 'databank' 'element' 'expression' 'flatfile' 'for statement' 'forced parsing' 'foreach statement' 'grammar' 'icarus' 'if statement' 'input' 'instance' 'interpretation' 'interpreter' 'language' 'lazy parsing' 'nonterminal' 'object class' 'output' 'perl' 'position' 'production' 'recursive' 'regular expression' 'scanner' 'strings' 'substitution' 'symbol' 'syntax' 'task' 'tcl' 'terminal' 'token table' 'token code' 'variable' 'while statement' } $rules={ # extract sections section: ~ {$Out pre{$Skip:0}} x{$Wrt} (/[ \t\n]*<[Hh][1-2]>/ {$Not} ln {$App})* (/[ \t\n]*<[Hh][1-2]>/ {$Wrt} (/[ \t\n]*<[Hh][1-2]>/ {$Not} ln {$App})*)+ ~ # inserting of links to index words inxSect: ~ {$In:[section t:inx] pre{foreach:[$i in:$inx] $i.n=0}} index ~ index: ~ (/[a-zA-Z_][a-zA-Z0-9_-]+/ {if:$inx.($Ct).ok { $key=$inx.($Ct) if:$inx.($Ct).n < 1 { $inx.($Ct).n += 1 $locN += 1 $key.list += |$chapN\ $Rep:"$Ct" } } if:$concat && $inx."$prev $Ct".ok { $s = "$prev $Ct" $key=$inx."$prev $Ct" if:$inx.($s).n < 1 { $inx.($s).n += 1 $locN += 1 $key.list += |$chapN\ $Rep:"$Ct" } } $concat=0 $prev=$Ct } | /[ \n\t]+/ {$concat=1} | /[^a-zA-Z]+/ | /./)* ~ # other stuff ln: ~ /[^\n]*\n/ ~ } # initialize index word list foreach:[$iw in:$indexWords] { $inx.($iw).name = $iw $inx.($iw).ok = 1 $inx.($iw).list = {} } $job = $JobNew:[prod:$rules] foreach:[$chap in:$chapter] { $print:|...processing "($chap.path)" $fil = $FileOpen:"($chap.path)" $ofil = $FileOpen:["SRSMAN:mi_($chap.part).html" mode:write] $fileName="($chap.part).html" $chapN = $chap.n $locN = 0 $JobNext:[$job file:$fil] while:$JobHasInput:$job { $JobTokens:[$job name:section withCode:0 print:1 outFile:$ofil task:inx] $JobNext:$job } $FileClose:$ofil } # print the index file $inxFile=$FileOpen:["SRSMAN:m_inx.html" mode:write] $print:[ | | |SRS Manual - Index | | | |

    Index

    f:$inxFile] foreach:[$i in:$inx] if:$i.ok { $print:["($i.name) " f:$inxFile] foreach:[$p in:$i.list] $print:[" $p" f:$inxFile] $print:["
    \n" f:$inxFile] } $print:[ | | f:$inxFile] ex file $inxFile=$FileOpen:["SRSMAN:m_inx.html" mode:write] $print:[ | | |SRS Manual - Index | |/ {$Not} ln {$App})+ (/[ \t\n]*<[Hh][1-6]>/ {$Wrt:title} (/.*<\/[Hh][1-6]>/ {$Not} ln {$App})* /.*<\/[Hh][1-6]>/ {$App} ln {$Wrt:text})? )+ ~ # table of contents index: ~ {init{$prev=0} $In:[field c:title] $Out} /<.1>/ label+ /(.*)<\/.1>/ {$print:["$1\n" f:$toc] $prev=0} | /<.([2-4])>/ {$n=$1-1} label+ /(.*)<\/.[2-4]>/ { if:$prev==0 { $prev=$n-1 } if:$n>$prev for:{$k=$n-$prev $k $k=$k-1} $print:[ "
      " f:$toc] elif:$prev>$n for:{$k=$prev-$n $k $k=$k-1} $print:["
    " f:$toc] $print:["
  • \n" f:$toc] if:$n==1 $print:["$1\n" f:$toc] elif:$n==2 $print:["$1\n" f:$toc] else $print:["$1\n" f:$toc] $prev = $n } ~ # other stuff ln: ~ /[^\n]*\n?/ ~ label: ~ / *<(A +NAME|a +name)="?([^">]+)"?>(<\/[Aa]>)?/ {$label="$2"}~ #" } foreach:[$chap in:$chapter] { $fil = $FileOpen:"($chap.path)" $toc = $FileOpen:["SRSMAN:mtoc_($chap.part).html" mode:write] $fileName="mi_($chap.part).html" $print:[f:$toc s: | | |Table of Contents for Chapter "$part" | | | ] $job = $JobNew:[prod:$rules skip:" " file:$fil] while:$JobHasInput:$job { $JobTokens:[$job name:index withCode:0] $JobNext:$job } $print:['' f:$toc] $FileClose:$toc } .html" mode:write] $fileName="mi_($chap.part).html" $print:[f:$toc s: | | |Table of Contents for Chapter "$part" | | |Name |Type |Default |Comment | ] foreach:[$a in:$arg] if:$a.name!="" && $Trim:[$a.text skip:" \n"] != "" $Print:[f:$oFile s: | |($a.name) |($a.type) |($a.value) |($a.text) | ] $Print:['\n' f:$oFile] } | ln {$Print:[f:$oFile s:$ct]})+ ~ ln: ~ /[^\n]*\n/ ~ } $arg={} $oFile = $FileOpen:["SRSMAN:usage.html" mode:write] $Parse:[fileName:"SRSDOC:usage.html" prod:$rules start:file] $FileClose:$oFile N=TOP>($a.name) |($a.type) |($a.value) |($a.text) | ] $Print:['\n' f:$oFile] } | ln {$Print:[f:$oFile s:$ct]})+ ~ ln: ~ /[^\n]*\n/ ~ } $arg={} $oFile = $FileOpen:[srs/icarus/util/odd.i # # $RCSfile: odd.i,v $ # $Revision: 1.2 $ # $Date: 1996/05/24 14:11:51 $ # $Author: ulyanov $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ file:"SRSICA:oddgen.i" file:"SRSICA:oddfncts.i" file:"SRSICA:icacom.ic" file:"SRSICA:classes.i" $partable:[ vars:{ $parameter:[name:"doInitHeader" type:bool num:0 comment:"h-file with struct declaration and initialization"] $parameter:[name:"doHeader" type:bool num:0 comment:"h-file with struct declaration"] $parameter:[name:"doSection" type:bool num:0 comment:"binary section file (can be combined with '-h')"] $parameter:[name:"doMetaData" type:bool num:0 comment:"h-file with meta data initialization"] $parameter:[name:"doClassInfo" type:bool num:0 comment:"file with class information"] $parameter:[name:"printProgress" type:bool num:0 comment:"print a line for each ODD-file read"] $parameter:[name:"printProgress" type:bool num:0 comment:"print a line for each ODD-file read"] $parameter:[name:"printDots" type:bool num:0 comment:"print a dot for each ODD-file read"] PART_BOOLEAN:$partype:[name:"boolean" max:3 min:0 charset:"yYnN01oOfFjJ"] } ] $command:[name:odd usage:"sectionName" vars:{ $arg:[name:"-help" type:help comment:"this message"] $arg:[name:"-i" parameter:doInitHeader] $arg:[name:"-h" parameter:doHeader] $arg:[name:"-s" parameter:doSection] $arg:[name:"-m" parameter:doMetaData] $arg:[name:"-c" parameter:doClassInfo] $arg:[name:"-r" parameter:printProgress] $arg:[name:"-d" parameter:printDots] } ] $def:[infile:"SRSICA:sdl.sdl" outfile:"SRSSOU:odd5.h" section_name:"sdl" section_size:50] "] } ] $command:[name:odd usage:"sectionName" vars:{ $arg:[name:"-help" type:help comment:"this message"] $arg:[name:"-i" parameter:doInitHeader] $arg:[name:"-h" parameter:doHeader] $arg:[name:"-s" psrs/icarus/util/odd.ic # # $RCSfile: odd.ic,v $ # $Revision: 1.2 $ # $Date: 1996/05/24 14:11:52 $ # $Author: ulyanov $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ file:"SRSICA:oddgen.i" file:"SRSICA:oddfncts.i" file:"SRSICA:classes.i" file:"SRSICA:parameter.ic" file:"SRSICA:arglist.ic" $def:[infile:"SRSICA:odd.i" outfile:"SRSSOU:oddclass.h" section_name:"sdl" section_size:500] $e:"-s" psrs/icarus/util/oddfncts.i # # $RCSfile: oddfncts.i,v $ # $Revision: 1.1 $ # $Date: 1996/05/06 16:14:03 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # functions return attribute size F_SIZINHERIT:$function:[name:OFInheritSize args:"(SDLoOBJ *, SDLoATTR *)"] F_SIZ4BARR:$function:[name:OF4BArrSize args:"(SDLoOBJ *, SDLoATTR *)"] F_SIZ4B:$function:[name:OF4BSize args:"(SDLoOBJ *, SDLoATTR *)"] F_SIZPTRARR:$function:[name:OFPtrArrSize args:"(SDLoOBJ *, SDLoATTR *)"] F_SIZPTR:$function:[name:OFPtrSize args:"(SDLoOBJ *, SDLoATTR *)"] F_SIZBNF:$function:[name:OFBNFSize args:"(SDLoOBJ *, SDLoATTR *)"] F_SIZBARR:$function:[name:OFBArrSize args:"(SDLoOBJ *, SDLoATTR *)"] # function to postprocess attributes F_MAKEDFLT:$function:[name:OFMakeDefault args:"(SDLoOBJ *, SDLoATTR *, unsigned int *)"] F_MAKENODFLT:$function:[name:OFMakeNoDefault args:"(SDLoOBJ *, SDLoATTR *, unsigned int *)"] F_MAKECHILD:$function:[name:OFMakeChild args:"(SDLoOBJ *, SDLoATTR *, unsigned int *)"] F_MAKECHILDN:$function:[name:OFMakeChildN args:"(SDLoOBJ *, SDLoATTR *, unsigned int *)"] F_MAKEALLOBJ:$function:[name:OFMakeAllObj args:"(SDLoOBJ *, SDLoATTR *, unsigned int *)"] F_MAKEALLOBJN:$function:[name:OFMakeAllObjN args:"(SDLoOBJ *, SDLoATTR *, unsigned int *)"] # functions to write member declarations F_DEFSIMPLE:$function:[name:OFDefSimple args:"(FILE *, SDLoATTR *, char *, char *)"] F_DEFSTR:$function:[name:OFDefStr args:"(FILE *, SDLoATTR *, char *, char *)"] F_DEFFNCT:$function:[name:OFDefFnct args:"(FILE *, SDLoATTR *, char *, char *)"] F_DEFHEADER:$function:[name:OFDefHeader args:"(FILE *, SDLoATTR *, char *, char *)"] F_DEFSTRUCTPTR:$function:[name:OFDefStructPtr args:"(FILE *, SDLoATTR *, char *, char *)"] F_DEFGENERICTYP:$function:[name:OFDefGenericTyp args:"(FILE *, SDLoATTR *, char *, char *)"] F_DEFUSER:$function:[name:OFDefUser args:"(FILE *, SDLoATTR *, char *, char *)"] F_DEFEBNF:$function:[name:OFDefEbnf args:"(FILE *, SDLoATTR *, char *, char *)"] # functions for inserting attributes in target structures F_INSERTFLOAT:$function:[name:OFInsertFloat args:"(void *, void *, void *, void ***, char *, unsigned int, int)"] F_INSERTINT:$function:[name:OFInsertInt args:"(void *, void *, void *, void ***, char *, unsigned int, int)"] F_INSERTUINT:$function:[name:OFInsertUInt args:"(void *, void *, void *, void ***, char *, unsigned int, int)"] F_INSERTUCHAR:$function:[name:OFInsertUChar args:"(void *, void *, void *, void ***, char *, unsigned int, int)"] F_INSERTUSER:$function:[name:OFInsertUser args:"(void *, void *, void *, void ***, char *, unsigned int, int)"] F_INSERTSTR:$function:[name:OFInsertStr args:"(void *, void *, void *, void ***, char *, unsigned int, int)"] F_INSERTFUNCTION:$function:[name:OFInsertFunction args:"(void *, void *, void *, void ***, char *, unsigned int, int)"] F_INSERTOBJECT:$function:[name:OFInsertObject args:"(void *, void *, void *, void ***, char *, unsigned int, int)"] F_INSERTHEADER:$function:[name:OFInsertHeader args:"(void *, void *, void *, void ***, char *, unsigned int, int)"] F_INHERIT:$function:[name:OFInherit args:"(void *, void *, void *, void ***, char *, unsigned int, int)"] F_GENERIC:$function:[name:OFGeneric args:"(void *, void *, void *, void ***, char *, unsigned int, int)"] # functions for writing attribute values to the header file F_WRTINT:$function:[name:OFWrtInt args:"(SDLoATTR *, char *, void **)"] F_WRTUCHAR:$function:[name:OFWrtUChar args:"(SDLoATTR *, char *, void **)"] F_WRTUINT:$function:[name:OFWrtUInt args:"(SDLoATTR *, char *, void **)"] F_WRTFLOAT:$function:[name:OFWrtFloat args:"(SDLoATTR *, char *, void **)"] F_WRTSTR:$function:[name:OFWrtStr args:"(SDLoATTR *, char *, void **)"] F_WRTNAME:$function:[name:OFWrtName args:"(SDLoATTR *, char *, void **)"] F_WRTNULL:$function:[name:OFWrtNULL args:"(SDLoATTR *, char *, void **)"] F_WRTADDR:$function:[name:OFWrtAddr args:"(SDLoATTR *, char *, void **)"] F_WRTEBNF:$function:[name:OFWrtEBNF args:"(SDLoATTR *, char *, void **)"] # functions for checking attribute values F_CHECKNUM:$function:[name:OFCheckNum args:"(SDLoATTR *, int, char *)"] F_CHECKSTR:$function:[name:OFCheckStr args:"(SDLoATTR *, int, char *)"] # functions for generic attribute types F_GENSIMPLE:$function:[name:OFGenSimple args:"(SDLoOBJ *, SDLoATTR *)"] F_GENOBJECT:$function:[name:OFGenObject args:"(SDLoOBJ *, SDLoATTR *)"] # attribute type definitions AT_FLOAT:$attrtype:[calcsize:@F_SIZ4BARR make:@F_MAKEDFLT declare:@F_DEFSIMPLE insert:@F_INSERTFLOAT write:@F_WRTFLOAT check:@F_CHECKNUM typname:float gentype:@F_GENSIMPLE] AT_UCHAR:$attrtype:[calcsize:@F_SIZBARR make:@F_MAKEDFLT declare:@F_DEFSIMPLE insert:@F_INSERTUCHAR write:@F_WRTUCHAR check:@F_CHECKNUM typname:"unsigned char"] AT_INT:$attrtype:[calcsize:@F_SIZ4BARR make:@F_MAKEDFLT declare:@F_DEFSIMPLE insert:@F_INSERTINT write:@F_WRTINT check:@F_CHECKNUM typname:INT4 gentype:@F_GENSIMPLE] AT_UINT:$attrtype:[calcsize:@F_SIZ4BARR make:@F_MAKEDFLT declare:@F_DEFSIMPLE insert:@F_INSERTUINT write:@F_WRTUINT check:@F_CHECKNUM typname:UINT4] AT_STRING:$attrtype:[calcsize:@F_SIZPTRARR make:@F_MAKEDFLT declare:@F_DEFSTR insert:@F_INSERTSTR write:@F_WRTSTR save_address:yes check:@F_CHECKSTR gentype:@F_GENSIMPLE typname:char] AT_ALLOBJ:$attrtype:[calcsize:@F_SIZPTR make:@F_MAKEALLOBJ declare:@F_DEFSTRUCTPTR write:@F_WRTADDR save_address:yes] AT_CHILD:$attrtype:[calcsize:@F_SIZPTR make:@F_MAKECHILD declare:@F_DEFSTRUCTPTR write:@F_WRTADDR save_address:yes] AT_CHILD_N:$attrtype:[calcsize:@F_SIZ4B make:@F_MAKECHILDN declare:@F_DEFSIMPLE write:@F_WRTINT typname:INT4] AT_ALLOBJ_N:$attrtype:[calcsize:@F_SIZ4B make:@F_MAKEALLOBJN declare:@F_DEFSIMPLE write:@F_WRTINT typname:INT4] AT_OBJECT:$attrtype:[calcsize:@F_SIZPTRARR make:@F_MAKEDFLT declare:@F_DEFSTRUCTPTR insert:@F_INSERTOBJECT write:@F_WRTADDR save_address:yes gentype:@F_GENOBJECT] AT_PROTOFNCT:$attrtype:[calcsize:@F_SIZPTR make:@F_MAKENODFLT insert:@F_INSERTSTR write:@F_WRTNAME check:@F_CHECKSTR] AT_FNCT:$attrtype:[calcsize:@F_SIZPTR make:@F_MAKEDFLT declare:@F_DEFFNCT insert:@F_INSERTFUNCTION write:@F_WRTNAME save_address:yes] AT_USER:$attrtype:[calcsize:@F_SIZPTRARR make:@F_MAKEDFLT declare:@F_DEFUSER insert:@F_INSERTUSER write:@F_WRTNULL save_address:yes] AT_GENERIC_TYP:$attrtype:[insert:@F_GENERIC] AT_GENERIC_OBJ:$attrtype:[insert:@F_GENERIC] AT_GENERIC:$attrtype:[calcsize:@F_SIZPTRARR declare:@F_DEFGENERICTYP save_address:yes] AT_DEFER:$attrtype:[] AT_INHERIT:$attrtype:[calcsize:@F_SIZINHERIT make:@F_MAKENODFLT insert:@F_INHERIT] AT_OVERLOAD:$attrtype:[] AT_STORE:$attrtype:[calcsize:@F_SIZPTRARR make:@F_MAKEDFLT declare:@F_DEFHEADER insert:@F_INSERTHEADER write:@F_WRTNULL save_address:yes] AT_CLONE:$attrtype:[calcsize:@F_SIZPTRARR make:@F_MAKEDFLT declare:@F_DEFSTRUCTPTR insert:@F_INSERTOBJECT save_address:yes] AT_EBNF:$attrtype:[calcsize:@F_SIZBNF declare:@F_DEFEBNF write:@F_WRTEBNF] $CDefine:[@AT_CHILD name:AT_CHILD] $CDefine:[@AT_PROTOFNCT name:AT_PROTOFNCT] $CDefine:[@AT_FNCT name:AT_FNCT] $CDefine:[@AT_CLONE name:AT_CLONE] AD:$attrtype:[] AT_STORE:$attrtype:[calcsize:@F_SIZPTRARR make:@F_MAKEDFLT declare:@F_DEFHEADER insert:@F_INSERTHEADER write:@F_WRTNULL save_address:yes] AT_CLONE:$attrtype:[calcsize:@F_SIZPTRARR make:@F_MAKEDFLT declare:@F_DEFSTRUCTPTR insert:@F_INSERTOBJECT save_address:yes] AT_EBNF:$attrtype:[calcsize:@F_SIZBNF declare:@F_DEFEBNF write:@F_WRTEBNF] $CDefine:[@AT_CHILD name:AT_CHILD]srs/icarus/util/oddgen.i # # $RCSfile: oddgen.i,v $ # $Revision: 1.2 $ # $Date: 1997/03/12 16:18:51 $ # $Author: srs $ # # Some general definitions needed for the ODD compiler # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $FALSE=0 $TRUE=1 $SDLxXOBJCLASS=255 $SDLxFLOAT=0 $SDLxUCH=1 $SDLxINT=2 $SDLxUINT=3 $SDLxSTR=4 $SDLxGBLSS=5 $SDLxOWN=6 $SDLxOWN_N=7 $SDLxGBLNSS=8 $SDLxCHILD=9 $SDLxPFNCT=10 $SDLxFNCT=11 $SDLxUSER=12 $SDLxGTYP=13 $SDLxGTYPDEF=14 $SDLxGTYP_P=15 $SDLxDEFER=16 $SDLxINHERIT=17 $SDLxOVERLAY=18 $SDLxORG=19 $SDLxCLONE=20 $SDLxBNF=21 # $SDLxVIRTUAL=1 # $SDLxPNUM=9 $SDLxPNAM=10 $SDLxPTXT=11 $SDLxPCNST=12 # $SDLxREQ=1 $SDLxNOREQ=0 $SDLxXSS=7 $SDLxXNAM=25 $SDLxXLN=132 $FILxXNAM=132 $SDLxHDR=1 $SDLxHDR2=2 $SDLxNOHDR=0 O_FUNCTION:$object:[name:function type:$SDLxFNCT declname:"X" status:system attrs:{ $attribute:[name type:protofunction declname:"fnctnam" max:30 valtype:text] $attribute:[args type:string declname:"args" max:132 valtype:text required:y] $attribute:[module type:string declname:"module" max:30 valtype:{text name}] } ] $SDLxPNAM=10 $SDLxPTXT=11 $SDLxPCNST=12 # $SDLxREQ=1 $SDLxNOREQ=0 $SDLxXSS=7 $SDLxXNAM=25 $SDLxXLN=132 $FILxXNAM=132 $SDLxHDR=1 $SDLxHDR2=2 $SDLxNOHDR=0 O_FUNCTION:$object:[name:function type:$SDLxFNCT declname:"X" status:system attrs:{ $attribute:[name type:protofunction declname:"fnctnam" max:30 valtype:text] $attribusrs/icarus/util/parameter.i # # $RCSfile: parameter.i,v $ # $Revision: 1.18 $ # $Date: 1997/03/17 23:18:58 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # functions for checking #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ F_CHECKFIELDLIST:$function:[name:LibParSetFields args:"(char *)"] F_CHECKLIBLIST:$function:[name:LibParSetLibs args:"(char *)"] F_CHECKLINKLIBLIST:$function:[name:LibParSetLinkLibs args:"(char *)"] F_SETENVIRONMENT:$function:[name:LibSetEnvironment args:"(char *)"] F_CHECKLIBLISTVIEWR:$function:[name:"LibParSetLibsViewRoot" args:"(char *)"] F_CHECKLIBLISTVIEWL:$function:[name:"LibParSetLibsViewLeaf" args:"(char *)"] $partable:[ vars:{ $parameter:[seqFormat type:string set:'$setFormat:[Sequence set:"%s"]' get:'$setFormat:Sequence' comment:"format of sequence output file"] $parameter:[printText type:bool num:0 isVolatile:1 comment:"copy complete text (annotation) part of entry"] $parameter:[printData type:bool num:0 isVolatile:1 comment:"copy data (eg, sequence) part of entry"] $parameter:[printEntireEntry type:bool num:0 isVolatile:1 comment:"Print entire entry."] $parameter:[viewFieldList type:string comment:"List of fields that will be placed into a table view."] $parameter:[fieldList type:string parType:@PART_FIELDLIST comment:"include fields in entry list "] $parameter:[doQueryReport type:bool num:0 comment:"write a report about the query"] $parameter:[queryListValues type:bool num:0 isVolatile:1 comment:"List all values that match the query."] $parameter:[queryListValues type:bool num:0 isVolatile:1 comment:"List all values that match the query."] $parameter:[queryListFromMatch type:bool num:0 isVolatile:1 comment:"List all values after the first match of."] $parameter:[minIndexValN type:number num:0 comment: |List only values that occur at least specified number of times. \ |Use together with "lv". ] $parameter:[listFOSN type:bool num:0 comment:"produces a FOSN (File Of Sequence Names)"] $parameter:[printToFile type:bool num:0 comment:"print resultant entries to file(s)"] $parameter:[fosnWithPos type:bool num:0 comment:"output FOSN includes sequence feature locations"] $parameter:[isHTMLFormat type:bool num:0 isVolatile:1 comment:"Select HTML format for output."] # #file and directory names # $parameter:[indexDirName type:string str:"SRSINX:" comment:"directory with the indices"] $parameter:[outDirName type:string str:"SRSINX:" comment:"name of output directory"] $parameter:[etcDir type:string str:"SRSETC:" comment:"path of script that prepares SRS environment"] $parameter:[updateScriptName type:string str:"" comment:"File name of output script file."] $parameter:[environment type:string partype:@PART_ENVIRONMENT comment:"Name of the library environment" str:unix] # #query options # $parameter:[setName type:string partype:@PART_SETNAME] $parameter:[makeWild type:bool partype:@PART_BOOLEAN num:0 comment:"appends a wildcard to each search word"] $parameter:[linkToLibs type:bool partype:@PART_BOOLEAN num:0 comment:"links a single entry to selected libraries"] $parameter:[linkToSet type:bool partype:@PART_BOOLEAN num:0 comment:"links result of query to selected libraries"] $parameter:[libList type:string parType:@PART_LIBLIST comment:"select libraries of group"] $parameter:[linkLibList type:string parType:@PART_LINKLIBLIST comment:"list of libraries to be linked to"] $parameter:[queryFileName type:string comment:"name of file containing a list of queries"] # #others # $parameter:[printLibInfo type:bool num:0 comment:"prints info about specified library"] $parameter:[printLibs type:bool num:0 comment:"prints a list of all active libraries"] $parameter:[linkTable type:string comment:"print link table of entries found by query to selected libs"] $parameter:[getStartupInfo type:bool partype:@PART_BOOLEAN comment:"Startup info for client programs."] # #options for retrieval of sequence features # $parameter:[shiftbeginpos type:number comment:"shift feature begin position"] $parameter:[shiftendpos type:number comment:"shift feature end position"] $parameter:[isshiftbeginrelend type:bool num:0 comment:"shift of feature begin is relative to end pos"] $parameter:[isshiftendrelbegin type:bool comment:"shift of feature end is relative to begin pos"] $parameter:[takeuncompletefeature type:bool comment:"accecpt incomplete features" num:1] $parameter:[takeuncompleteshiftfeature type:bool comment:"accecpt incomplete shifted features"] # #building indices # $parameter:[showWarnings num:0 type:bool comment:"display warnings caused by errors in the databank"] $parameter:[buildPartIndex num:0 type:number comment: |specifies the number of the library part or flat file for which |indices shall be built separately. ] $parameter:[compress type:bool comment:"compresses indices built previously"] $parameter:[touchIndex type:bool comment:"touch index"] $parameter:[mergeIndex type:bool comment:"Merge index partitions to a single index."] $parameter:[relocateLib type:bool comment:"relocate library, ie, build a new IDX file"] $parameter:[buildIndex num:1 type:bool comment:"build all or selected search indices for library"] $parameter:[parseTest type:bool comment:"display only extracted values"] $parameter:[readLink type:bool comment:"read library and process link information"] $parameter:[indexLink type:bool comment:"build a link using two indices"] $parameter:[releaseName type:string comment:"assign a release name to a set of indices"] # #checking and maintaining indices # $parameter:[procIndexSize type:number num:15000 comment:"total index size (kb) to be processed in one go"] $parameter:[checkLibList type:string comment:"list of libraries to be checked - else all libraries"] $parameter:[notCheckLibList type:string comment:"list of libraries to be exclued from checking"] $parameter:[srsEnvHeader type:bool comment:"produces 'srsenv.h' defining all SRS env variables"] # #options for WWW programs # $parameter:[getOddFile type:string comment:"The name of the file with the databank description."] $parameter:[dontShowOrig type:bool comment:"don't list the query..only links to it"] $parameter:[userId type:string comment:"user ID, or file, name associated with a WWW session"] $parameter:[visitIndexValue type:string comment:"visit the set of entries belonging to an index value"] $parameter:[queryManager type:bool comment:"activates query manager"] $parameter:[setListPar type:bool comment:"allows to set parameters for viewing a set"] $parameter:[printHelpTopic type:string comment:"prints specified help topic"] $parameter:[queryCombine type:bool comment:"executes query that was specified in the query manager"] $parameter:[topPage type:bool comment:"revisists top page"] $parameter:[doRepeat type:bool comment:"revisits query form with same input as before"] $parameter:[doHyperTextLinks type:bool comment:"revisits query form with same input as before"] $parameter:[doQueryForm type:bool comment:"present the query form"] $parameter:[doQuery type:bool comment:"do the query"] $parameter:[libInfo type:string comment:"print some info about library"] $parameter:[linkInfo type:bool comment:"print some info about link between 2 libraries"] $parameter:[listSetNumber type:number isVolatile:1 comment:"number (in history) of set to be listed"] $parameter:[viewSetNumber type:number comment:"number (in history) of set to be viewed"] $parameter:[listQuery type:string comment:"query of set to be listed"] $parameter:[doBlastSearch type:bool comment:"perform a search with Blast and index results"] $parameter:[prepBlastSearch type:bool comment:"collect user input for a search with Blast"] $parameter:[listEntriesChunkSize type:number num:50 comment:"number of entries to be listed in one go"] $parameter:[listEntriesStartN type:number isVolatile:1 comment:"number of first entry in set to be listed"] $parameter:[viewEntriesChunkSize type:number num:30 comment:"number of entries to be viewed in one go"] $parameter:[viewEntriesStartN type:number isVolatile:1 comment:"number of first entry in set to be viewed"] $parameter:[maxValN type:number num:0 comment:"print only words that occur number of times"] $parameter:[getMessage type:bool comment:"get a message from user"] $parameter:[sendMessage type:bool comment:"send a user message to the messages file"] $parameter:[subEntryN type:number comment:"number of subentry to be accessed"] $parameter:[translateSequence type:bool comment:"print the translation product instead of DNA sequence"] $parameter:[linkLibSelect type:bool comment:"display a table with all possible links"] $parameter:[linkToLibs type:bool comment:"link set/entry to other libraries"] $parameter:[printLinkTable type:bool comment:"print a link table"] $parameter:[printNetwork type:bool comment:"print a network in tabular form."] $parameter:[linksPicture type:bool comment:"Print page with picture describing network in tabular form."] $parameter:[networkPicture type:bool comment:"Print page with network picture."] # # new wgetz # $parameter:[printEntireEntry type:bool isVolatile:1] $parameter:[downloadEntireEntry type:bool isVolatile:1] $parameter:[libName type:string isVolatile:1 comment: |Name of the input library. ] $parameter:[entryName type:string isVolatile:1 comment: |Name of the input entry without library name. ] $parameter:[makeNewUserId type:bool isVolatile:1 comment:|Forces wgetz to create a new user-ID if none exists yet. ] $parameter:[fromLibName type:string] $parameter:[toLibName type:string] $parameter:[useMime type:bool comment: |Mime type for saving the results on clients disk. |Argument "none" prevents output of a Content-type header. ] $parameter:[mimeType type:string comment:"MIME type to printed on top of the output page."] $parameter:[readUserFile type:bool comment:"readUserFile switch associated with a WWW session"] $parameter:["wwwFunctionName" type:string isVolatile:1 comment:"Name of function to be called in wgetz."] $parameter:["isHtml3" type:bool num:1 comment:"Client supports new HTML3 standard"] $parameter:["style" type:string comment:"Mode can be 'fancy' or nothing."] $parameter:["isDebug" type:bool comment:"Determines whether or not to print debug information."] $parameter:["queryString" type:string comment:"A string with an SRS query language expression."] $parameter:["delete" type:string set:'$ParDel:"%s"' isVolatile:1 comment: |A command to delete all the parameters matching the regular |expression assigned to it. ] $parameter:["nextFunction" type:string comment:"A Function to be called by WWW Link Page."] $parameter:["viewNumber" type:number comment:"For internal use of wgetz."] $parameter:[queryNumber type:number comment:"refer query by number"] $parameter:[deleteParam type:string comment:"delete parameters in history from command line"] $parameter:[mimeEntriesChunkSize type:number num:100 comment:"number of entries exported to client at a time"] $parameter:[mimeEntriesStartN type:number comment:"nth Entry to start with for mime export "] $parameter:[viewName type:string comment:"Name of view to be used when displaying entries."] $parameter:[viewRecordSep type:string str:'\n' comment:"String of one or more characters to separate records in view."] $parameter:[viewColumnSep type:string str:'\t' comment:"String of one or more characters to separate columns in view."] $parameter:[currentView type:number comment:"to print fields set for this view number"] $parameter:[isTable type:bool comment:"prints view result in table format"] $parameter:[method type:string comment:"method function to apply on a querystring"] $parameter:["viewLibListRoot" type:string isVolatile:1 parType:@PART_LIBLISTVIEWROOT comment:"select libraries of group as root for view"] $parameter:["viewLibListLeaf" type:string isVolatile:1 parType:@PART_LIBLISTVIEWLEAF comment:"select libraries of group as leaf for view"] $parameter:[wwwColorScheme type:string str:plain] $parameter:[wwwSessionEntryList type:bool isVolatile:1] $parameter:[icarusFileType type:string comment: |Selects the type of the Icarus file: 'i' (structure), 'is' (syntax), |'it' (info)." ] $parameter:["viewNumber" type:number isVolatile:1] $parameter:["browseIndex" type:string isVolatile:1 comment: |Selects a data-field or index to be displayed for browsing on |the next page. ] $parameter:["browseLibs" type:string isVolatile:1] # #trembl options # $parameter:[tremblInFile type:string comment: |Optional input file name. The file extension and format must be |the same as of the specified library. ] $parameter:[findAccNoCommand type:string comment: |The command with which to obtain a sequence file from an accession |number. Put a '%%s' where the accession number should be placed |within the command (eg, 'findacc %%s'). ] $parameter:[inputSeqFile type:string comment: |Name of the file obtained by the above command; again a '%%s' |must be placed in lieu of the accession number (eg, '%%s.seq'). ] # #reflink # $parameter:[readLib type:string comment:"name of library to be read for references"] $parameter:[searchLib type:string str:medline comment:"name of library to be searched for references"] $parameter:[journalListFile type:string comment:"name of journal list to be read/written"] $parameter:[doJournalList type:bool comment:"make a new journal list"] $parameter:[doMergeJournalLists type:bool comment:"merge two journal lists to one"] $parameter:[doRefLink type:bool comment:"link the two libraries using their references"] $parameter:[doRefLinkFile type:bool comment:"write a text file with all links found"] $parameter:[printSeparateFiles type:bool comment:"If set then each entry will be written into a separate file."] $parameter:[outputFileName type:string comment: |Name of the output file name. Prints to terminal if no name |is specified. ] # #srspict # $parameter:[doNetworkPict type:bool comment:"Create a file with the network picture."] $parameter:[doGraphTablePict type:bool comment:"Create a file with the graph table picture."] # #try # $parameter:[icaIsDebug type:bool comment:"Puts the Icarus interpreter into debugging mode."] $parameter:[doClassInfo type:bool comment: |Prints information about all object classes that were defined in |the Icarus file. ] $parameter:[doCommandInfo type:bool comment: |Prints information about the builtin functions of Icarus. ] $parameter:[printTrace type:bool comment:"Prints the trace information."] $parameter:[printSyntaxTree type:bool comment:"Prints the syntax tree."] $parameter:[syntaxName type:string comment:"Name of the file with test syntax."] $parameter:[productionName type:string comment:"Name of the target production name."] $parameter:[printAllTokLists type:bool comment:"Prints the contents of all token lists."] $parameter:[icaDbgExecStack type:number comment:"Prints all program stack before execution."] $parameter:[icaDbgBuildStack type:number comment:"Prints Icarus commands and the generated program stacks."] $parameter:[ica2cName type:string comment: |Program is not executed but written to a C language file with the |specified file name. ] $parameter:[useIni type:bool comment:"Use interpreter written to a C language file."] $parameter:[readBuiltin type:bool comment:"Read the file 'builtin.i' before starting."] #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # parameter type objects #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PART_SETNAME:$partype:[name:setName max:20 min:0 charset:"a-zA-Z0-9_"] PART_BOOLEAN:$partype:[name:boolean max:3 min:0 charset:"yYnN01oOfFjJ"] $partype:[name:fieldQuery max:200 min:0 charset:"a-zA-Z0-9\-_\$[]().;*?&|!'"] $partype:[name:inFileName max:200 min:0 charset:"a-zA-Z0-9\-_\$[]().;*?&|!'"] $partype:[name:outFileName max:200 min:0 charset:"a-zA-Z0-9\-_\$[]().;*?&|!'"] $partype:[name:query max:200 min:0 charset:"a-zA-Z0-9\-_\$[]().;*?&|!'"] PART_FIELDLIST:$partype:[name:fieldList check:@F_CHECKFIELDLIST charset:"a-zA-Z0-9 "] PART_LIBLIST:$partype:[name:libList check:@F_CHECKLIBLIST charset:"a-zA-Z0-9_\- "] PART_LINKLIBLIST:$partype:[name:libList check:@F_CHECKLINKLIBLIST charset:"a-zA-Z0-9_\- "] PART_ENVIRONMENT:$partype:[name:env check:@F_SETENVIRONMENT charset:"a-zA-Z0-9_\- "] # -- # added by ramu # -- PART_LIBLISTVIEWROOT:$partype:[name:viewLibListRoot check:@F_CHECKLIBLISTVIEWR charset:"a-zA-Z0-9_\-~ "] PART_LIBLISTVIEWLEAF:$partype:[name:"viewLibLisLeaf" check:@F_CHECKLIBLISTVIEWL charset:"a-zA-Z0-9_\-~ "] PART_ENVIRONMENT2:$partype:[name:"env" check:@F_SETENVIRONMENT charset:"a-zA-Z0-9_\- "] } ] @F_CHECKLINKLIBLIST charset:"a-zA-Z0-9_\- "] PART_ENVIRONMENT:$partype:[name:env check:@F_SETENVIRONMENT charset:"a-zA-Z0-9_\- "] # -- # added by ramu # -- PART_LIBLISTVIEWROOT:$partype:[nasrs/icarus/util/parameter.ic # $RCSfile: parameter.ic,v $ # $Revision: 1.1 $ # $Date: 1996/05/06 16:14:05 $ # $Author: srs $ # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ O_PAR:$object:[name:parameter typname:PARo declname:ODD_par attrs:{ $attribute:[declname:"*intern" type:user typname:"char" rem:"for internal use for the list manager"] $attribute:[declname:classId type:int defaultval:0 rem:"for internal use for the list manager"] $attribute:[name:name declname:"name" type:string valtype:{text name} unnamed:y rem:"name of associated global parameter"] $attribute:[name:str declname:str type:string valtype:{text name} rem:"Value of 'string' parameter."] $attribute:[name:num declname:num type:int valtype:num rem:"Value of 'number' parameter."] $attribute:[name:real declname:real type:float rem:"Value of 'real' parameter."] $attribute:[name:function declname:function type:function valtype:constant rem:"Value of 'function' parameter."] $attribute:[name:object typname:"void" declname:"*object" type:user rem:"Value of 'object' parameter."] $attribute:[name:isVolatile type:uchar declname:isVolatile] $attribute:[name:type type:uchar declname:type valtype:name rem:"Parameter type." enum:{ $value:[name:string val:1] $value:[name:number val:2] $value:[name:real val:4] $value:[name:function val:8] $value:[name:bool val:16] $value:[name:object val:32] } ] $attribute:[name:comment declname:comment type:string valtype:text rem:"Short description of parameter."] $attribute:[name:helpTopic declname:helpTopic type:string valtype:{name text} status:obsolete rem:"help topic associated to parameter"] $attribute:[name:key type:string declname:key max:1 valtype:{text name} rem:"keystroke associated to parameter or value" status:obsolete] $attribute:[name:partype declname:parType type:object defaultval:@O_PARTYPE valtype:constant rem:"Object 'partype' for validating the parameter value."] $attribute:[name:check declname:check type:object defaultval:@O_PARTYPE valtype:constant status:obsolete rem:"Object 'partype' for validating the parameter value."] $attribute:[declname:isLocked type:int defaultval:0 rem:"internal use..."] $attribute:[set declname:set type:string rem:"Icarus command to set the current value."] $attribute:[get declname:get type:string rem:"Icarus command to get the current value."] } ] O_PARTYPE:$object:[name:partype typname:PARoTYPE declname:Odd_parType rem:"Describes further a parameter type by specifying constraints or a function for checking the parameter value." attrs:{ $attribute:[declname:"*intern" type:user typname:"char" rem:"for internal use for the list manager"] $attribute:[declname:classId type:int defaultval:0 rem:"for internal use for the list manager"] $attribute:[name:name declname:"name" type:string valtype:{text name} rem:"Name of associated global parameter."] $attribute:[name:check declname:check type:function valtype:constant defaultstr:"(void *)" rem:"Function that checks parameter value."] $attribute:[name:max declname:max type:int defaultval:0 valtype:num rem:"Max value, or max length."] $attribute:[name:min declname:min type:int defaultval:0 valtype:num rem:"Mmin value, or min length."] $attribute:[name:maxReal declname:maxReal type:float defaultval:0 valtype:num rem:"Max real value."] $attribute:[name:minReal declname:minReal type:float defaultval:0 valtype:num rem:"Min real value."] $attribute:[name:charSet declname:"charSet" type:string valtype:{text name} rem:"Permissible set of chars for parameter value string."] }] O_PARTABLE:$object:[name:partable typname:PARoLIST status:system nchilds:2 child:{@O_PAR @O_PARTYPE} declname:ODD_parTable attrs:{ $attribute:[name:vars declname:"par" type:child defaultval:@O_PAR rem:"List of all predefined parameters."] $attribute:[declname:"parN" type:nr_of_childs defaultval:@O_PAR rem:"Number of predefined parameters."] $attribute:[declname:"parType" type:child defaultval:@O_PARTYPE rem:"List of all predefined parameter types."] $attribute:[declname:"parTypeN" type:nr_of_childs defaultval:@O_PARTYPE rem:"Number of predefined parameter types."] }] DD_parTasrs/icarus/util/script.i $parStr:[agazik set:'asfd \n\n\n\n\nsafdkljalksdfjlkasjf'] $viewManager={ head: "this ($parStr:outDirName) is \n $$%d %s |%10d| \the\" heaT\n" aa: |aarararar | end gu:{ ra: | holo | holo \ | hala \ ru: | .. ..... ruhhhhh($parStr:outDirName)HHHHHHHHH holo | ru holo \ | ru hala } bb: 'bbrararar\n' cc: 'ccrararar' dd: 'ddrararar' ee: 'eerararar' ff: "ffra(\$arrr.asfd) rarar" } $viewManagerl={ head: | |:SRS: NEWSRS VIEW Manager Page |
    |($buttons:viewManager) |
    | | | | | | | | | | | | | | |
    | | | | |a new view
    | | |selected view
    selected view
    |

    | | | | | | | | | | | root: |%s
    leaf: |%s
    field:{ head: | root: |%s
    leaf: |%s
    } listing: | | tail: |
    View Listing
    View Name Root Libs Root Fields Leaf Libs Leaf Fields
    tail: |
    | %s | footer: |

    } $viewtable={ header: |%(mimehtml) | | | View Print Fields: | |
    | | | | | title: { libname: | field: | trail: | } rowbeg: | rowend: | entry: { name: | field: { empty: | listing: | } } } $queryform={ header: |@@ |%(mimehtml) | | ($gaga) | |SRS:Query Form Page | | | | | | | |@@print2 %(FANCY)HEADER-BUTTONS srsbar_qf2.gif fafa |

    |Search lib: |%s title: |

    | | | | |


    |Compose query and select fields to be included in entry list. | Not all fields may be searchable or to be displayed table:{ header: |

    |

    View: %s

    %s%s
    | %s | left: | right: | center: |@@ value: |%s
    end: |
    | | | | | field: | | | | | | rangefield: | | | | | | | | | | | | subentry: | noquery: | | | | | | rowend: | trailer: |
    |Field NameQueryInclude in ListRetrieve
    Subentries
    |%s |%s | | |
    |
    |%s |%s | | | | | | | | | | | | |Subentry only |
    |%s | %s | | |
    |
    } getbool: |
    |Combine searches with | | Append wildcard '*' to search words |?!

    chunkset: |Entry list in chunks of | view:{ header: |Select a view | } trailer: |

    | | } $result={ header: |@@ |%(mimehtml) | | QueryResult | |
    | | | | | | Query "%s" found %d entries | | |
    | | | | | | | | | | | | | with chunk size | | | | | | Query "%s" found %d entries | | |
    | | | | | | | | | | | | | with chunk size | | | | | | |Start a new SRS session | | | | | |The SRS Manual | | |The SRS Manual | | | |Status of all databanks served by all SRSWWW sites | |Status of all databanks served by all SRSWWW sites | | | |The SRS Newsgroup |The SRS newsgroup | # developers | |\ |SRS Brains | |SRS Developers | # the link to the home page | |\ |Home Page | |Back to the EMBL home page | | | | | | | 

    This is the SRSWWW server at ($parStr:siteName), |version ($parStr:srsVersion) | | | } ############################################################################### # # displays help for one or all Icarus command # $icarusCommand={ title: | | |Descriptions of built in Icarus functions | | |

    The Icarus Commands

    |The names are still not alphabetically ordered. head: |

    $%s

    |%s |

    |

    | | | | | | noArgs: | arglist:{ name: | type:{ int: | string: | object: | real: | alias: | var: | d1: | d2: | strv: | d3: | d4: | d5: | d6: | d7: | d8: | list: | enum:{ head: | } } unnamed: | named: | required: | optional: | comment: | defaultNum: | defaultStr: | empty: | tail: | } return:{ head: | preType: | postType: | nothing: | } tail: |
    Name TypeUnn ReqDefault Comment
    |Arguments
    none
    %sintstring%s objectrealaliasvarunknownunknownstrvunknownunknownunknownunknownunknownunknownlistenum:
    value: |%s tail: |
    + +-%s%d%s 
    |Returns
            
    Nothing
    |
    | } ############################################################################### # # displays help for one or all SRS object classes. # # $classInfo={ head: | | |

    List of SRS Object Classes

    |
    |
    Date: %s
    |
    |The following lists among others the object classes that are used to |describe the integrated databanks. dir:{ head: |

    List Object Classes in SRS

    |
    Date: %s
    |
      class: |
    • \$%s tail: |

    } class:{ head: |

    \$%s

    remark: |%s

    |

    | | | | | | | | | attrib:{ head: | empty: | remark: | unnamed: | named: | typeHead: | type: |%s listType: |list of $%s ptrType: |%s $%s arrSize: |
    list size: %d | default:{ option: | num: | real: | } minmaxNum: |
    min: %d
    max: %d minmaxStr: |
    min length: %d
    max length: %d required: | optionList:{ head: |\ option: |
  • %s tail: |\ } infoEnd: |
  • tail:'' } tail: |
    Arguments
    NameCommentUnnReqTypeDefault
    %s %s+  typeTail: |%s string: |"%s"%d%f+

    } } ############################################################################### # # Very importantly, sets a few color schemas # # $colorScheme={ plain:{ page: '' cell: |BGCOLOR="#d3b5b5"\ } white:{ page: |text="#000000" bgcolor="#FFFFF0" link="#0000FF" \ | vlink="#FF0000" alink="#FF0000"\ cell: |BGCOLOR="#d3b5b5"\ } yellow:{ page: |text="#400040" bgcolor="#FFFF80" link="#0000FF" |vlink="#008000" alink="#FF0080" cell: |BGCOLOR="#"\ } blue:{ page: |text="#FFFFFF" bgcolor="#000080" link="#FFFF00" |vlink="#8080FF" alink="#FF00FF" cell: |BGCOLOR="#0000A0"\ } black:{ page: |text="#FFFFFF" bgcolor="#000000" link="#FFFF00" |vlink="#C0C0C0" alink="#COFFCO" cell: |BGCOLOR="#0000A0"\ } grayRock:{ page: |background=($parStr:imgdir)/gray_rock.gif cell: |BGCOLOR="#C0C0C0"\ } yellowWeave:{ page: |background=($parStr:imgdir)/yellow_weave.gif cell: |BGCOLOR="#d3b5b5"\ } greenPaper:{ page: |background=($parStr:imgdir)/greenwhite_paper.gif cell: |BGCOLOR=\"#edeafb\"\ } bluePaper:{ page: |background=($parStr:imgdir)/blue_paper.gif cell: |BGCOLOR=\"#edeafb\"\ } grayAluminium:{ page: |background=($parStr:imgdir)/gray_aluminum.gif cell: |BGCOLOR=\"#edeafb\"\ } tanPaper:{ page: |background=($parStr:imgdir)/tan_paper.gif cell: |BGCOLOR=\"#edeafb\"\ } yellowStucco:{ page: |background=($parStr:imgdir)/yellow_stucco.gif cell: |BGCOLOR="#d3b5b5"\ } purpleWeave:{ page: |background=($parStr:imgdir)/lipurple_weave.gif cell: |BGCOLOR=\"#edeafb\"\ } orangePaper:{ page: |background=($parStr:imgdir)/orange_paper.gif cell: |BGCOLOR=\"#edeafb\"\ } tealPaper:{ page: |background=($parStr:imgdir)/teal_paper.gif cell: |BGCOLOR=\"#edeafb\"\ } summerPaper:{ page: |background=($parStr:imgdir)/summer_paper.gif cell: |BGCOLOR=\"#edeafb\"\ } peachPaper:{ page: |background=($parStr:imgdir)/peach_paper.gif cell: |BGCOLOR=\"#edeafb\"\ } greenMarble:{ page: |background=($parStr:imgdir)/greenred_marble.gif cell: |BGCOLOR="#d3b5b5"\ } } ############################################################################### # # the list of libraries # # $libList={ head: | |SRSWWW at ($parStr:siteName): list of available data banks | | |

    | title: |

    Data Banks Available at ($parStr:siteName)

    |%s

    |

    | | | |
    |
    |

    | | | | | | | | | libraryGood: | | | | | | | | libraryBad: | | | | | | | | tail: |
    Data BankReleaseNo EntriesIndexing DateGroupAvailability
    |%s%s%d%s%sok
    |%s   %s 
    | } ############################################################################### # # the "Select databanks" or "top" page # # $selectLibrary={ head: | |NEW SRS:Select Libraries Page | | |

    | | submit: | \ |Show only fields that selected databanks have in common |

    | | | | libs:{ html3:{ libGroupName: |


    |%s
    | | libGroupNameSearch: |
    |%s | | |

    |

    | newRow: | | library: | | tail: | |
    |%s%s
    } html2:{ libGroupsName: |
            |
    %s

    newRow: '\n' library: | \ |%s\ |%-($parStr:l)s\ tools:{ blast: |\ |Do BLAST Search } tail: |

    } } tail: |
    |
    | |... tired of looking at all this data? Change their color! | \ | colorScheme:{ head: | | | | |If you find problems or have suggestions please mail the |SRS administrator |
    |
    | | } } ############################################################################### # # the Page with the library network # # $libNetwork={ head: | | |SRSWWW at ($parStr:siteName): Library Network Distance Table | | | |
    | title: |

    The Library Network shown as a Distance Table

    |
    | | | |
    |

    | fromLib: | | link:{ direct: | indirect: | none: | } rowEnd: | toLibs: | toLib:{ head: | } tail: | |
    \ |%s1%d.
    letter: |%c
    last: |%c\ tail: |
    |

    | | } ############################################################################### # # the information about a pairwise link # $linkInfo={ head: | | |SRSWWW at ($parStr:siteName): Link Information | | | |
    | title: |
    |

    Link Information

    noLink: |A link from %s to %s does not exist. direct: |The link from %s to %s is direct. |

    indirect:{ head: |%d entries in %s are linked to %d entries in %s.
    |The link is indirect and has been resolved to the path "%s>\ pathLib: |%s>\ lastLib: |%s". |

    } table:{ head: | | | | | | | | | names: | | | | | total: | read: | index: | creTime: | notCreated: | rowEnd: | } tail: |
    FromLinked
    Entries
    ToLinked
    Entries
    Total No
    of Links
    Information UsedCreation
    Time
    \ |%s%d\ |%s%d%dCross-references in %s referring to contents of the |%s field in %sMatching strings in the %s field of %s and the %s field in %s.%snot available
    | | } ############################################################################### # # the Query form page # # $queryForm={ head: | | |SRS:Query Form Page | | |

    | | | |

    searchInfo: |Search listLibs: |%s submit: |

    | | chunkSize:{ head: | } selectView:{ head: | } searchOptions: | | |
    |\ | | | |Entry List in chunks of\ | | |Use view | |
    |  | |Combine searches with \ | | | | | Append wildcard '*' to words. |
    queryInput: { html3: { head: | | | | | fieldHeader: | | fieldNum: | | | | | | | fieldText: | | | | | subEntry: | rowEnd: | tail: |
    |\ |Field Name |\ |Query\ |Include
    in List
    |
    \ |Retrieve
    SubEntries (SE)

    |%s
    |%s%s |\ | | | | | | |\ |\ |
    |%s%s | | |\ |\ | |feature SE # |Subentry only |
    } } tail: |


    |    |Separate multiple values by & (and), | (or), |! (and not) | | | } ############################################################################### # # the "Library Information" page # $parStr:[cellCols set:"bgcolor=\"#000080\"> | | View Select Page | |
    | title: |
    |

    | | description:{ head: | | } literature:{ head: | | } address:{ head: | | } contact:{ head: | | } email:{ head: | } www:{ head: | } ftp:{ head: | } updates:{ head: | | } tail:'' } example: | | fields:{ head: | } links:{ to: | | | } tail: |
    Name |

    %s

    |
    | | | | |
    Status noRelease: |The current release has %d entries and was indexed %s. release: |The current release %s has %d entries and was indexed %s. notIndexed: |The databank is currently not available. t:{ head: |
    Description tail: |
    Literature tail: |
    Address tail: |
    Contact tail: |
    E-mail tail: |
    WWW tail: |
    FTP tail: |
    Updates tail: |
    Example Entry |%s |
    |Data-fields
    in SRS
    | | | | | | | | | name: |%s
    short: |%s
    type: |%s
    valN: |%d
    refN: |%d
    date: |%s
    status: |%s
    empty: |
    tail: | | | | | | | | |
    NameShort
    Name
    TypeNo of
    Keys
    No of Entry
    References
    Indexing DateStatus
    %s%s%s%s%s%s%s
    |Links To
      toLib: |
    • %s from: |
    |
    |Links From
      fromLib: |
    • %s none: |none tail: |
    } icarusFiles:{ head: |
    SRS Description
    | | } ############################################################################### # # page with an icarus file # $icarusFile={ head: | | |

      tail:
        |
    | | } ############################################################################### # # the "View Create" page - part I of creating views # $viewCreate={ head: | | | View Select Page | |
    | | # help |
    |Help
    |
    |
    edit:{ head: |
    | | | |

    |Edit an existing view

    |
    | | | | |or use the | | | |
    |
    } create:{ logo: |

    Create new view

    head: |
    | | | | | } rootHeader: | #view name | | | | | | leafHeader: | | |
    | | | #display as table | | | # print short or long field names in header | | | # common fields only | | | |
    |Name of view (optional)
    | |
    | | |Display view as table |
    | | |Print short field names in header |
    | |Show only fields common
    to selected root databanks |

    |

    | | | |

    | |

    |Select databanks for whose
    entries you want to define
    the view |
    |Select databanks to be linked
    to displayed entries (optional)
    |
    | separator: | | |
    |
    | | } ############################################################################### # # the "select fields" page - part II of creating views # $viewSelectFields={ head: | | NEWSRS View Field Select Page | |

    |

    | | | | | | # help |
    |Help
    | |
    | |

    Select Fields for View "%s"

    |Select fields to be appended to entries displayed and continue with |one of the options below |

    | | | | | | | | | | | | |


    |

    |
    | root:{ lib:{ head: | |
    | name: | |%s tail: |
    } rowBeg: | rowEnd: | newRow: | fieldHeader: | field: | tail: |

    %s
     \ |\ |%s\ format:{ head: |\ } fieldTail:|
    |

    } leaf:{ head: | | | | | | | | |
    |%30.*s | |%s |
    | | newRow: | fieldHeader: | field: | extraOptions: | |

    %s
    \ | |%s%s format:{ head: | } fieldTail:|
    | | | | | | | # | # | # | # | | | | | | |
    | |Use query |instead link | |
    | selectView:{ head: |use view to display entries | } tail: |
    # |  # | # |Input form for # | # |
    | |Display only number of linked entries |
    |
    | |

    } tail: |

    | | | | | } ############################################################################### # # the queryResult page # $queryResult={ head: | QueryResult | |

    | title: | Query "%s" found %d entries |

    options:{ head: # | } selectView:{ head: | } tail: | } tail: | | |
    }
    
    
    
    
    
    
    
    
    
    
    
    List Entries">
        chunkSize:{
          head:
      	|
    } selectView:{ head: | #include #include "message.h" #include "futil.h" #include "sm.h" #include "strv.h" #include "dict.h" #include "variable.h" #include "icarus.h" #include "library.h" #include "appl.h" #define _SRS #define _SLB #include SRSINCLUDE APPLo *ApplNamed (char *name) { APPLo *appl; appl = (APPLo*) LibObjByName ("application", name); return appl; } /**api* function ************************************************************** ** ** Returns next application object for Data type object. ** ** INPUT: o address o data type object object [R] ** o address of context [W] ** IMPLICIT: ** ** RETURNS: application object ** NULL: the list is exhausted (next call will start at begin) */ APPLo *ApplNextInDataType (LIBoDataType *dataType, INT4 *c) { if (*c >= 20/*te!!!*/ || !dataType->applications[*c]) { *c=0; return NULL; } else return dataType->applications[(*c)++]; } char *ApplGetName (APPLo *appl) { return appl->name; } char *ApplGetTitle (APPLo *appl) { return appl->title; } /**api* function ************************************************************** ** ** Returns whether specified characteristic is true or false. ** ** INPUT: o application object [R] ** o characteristic: "search", "multi", "single" [R] ** ** RETURNS: 1: characteristic is true ** 0: not true */ Int4 ApplIs (APPLo *appl, char *option) { Int4 flag=0, type, k; for (k=0; k < 5; k++) { type = appl->type[k]; switch (_Index (tolower(option[0]), tolower (option[1]))) { case _Index('s','e'): /* search */ if (type == 1) flag = 1; break; case _Index('m','u'): /* multi */ if (type == 3) flag = 1; break; case _Index('s','i'): /* single */ if (type == 2) flag = 1; break; default: _ErrExit2 (e__unknownoption, option); } } return flag; } Int4 ApplIsInSeq (APPLo *appl, char *option) { Int4 flag=0, type, k; switch (_Index (tolower(option[0]), tolower (option[1]))) { case _Index('g','c'): /* gcg */ if (appl->inSeqFormat == 1) flag = 1; break; case _Index('p','i'): /* pir */ if (appl->inSeqFormat == 3) flag = 1; break; case _Index('f','a'): /* fasta */ if (appl->inSeqFormat == 2) flag = 1; break; default: _ErrExit2 (e__unknownoption, option); } return flag; } void ApplInit (APPLo *appl) { if (appl->com) StrClear (&appl->com); } void ApplEval (APPLo *appl, char *s) { IcaEval (&appl->interp, s); } char *ApplGetCommand (APPLo *appl) { ANYv list, any; if (!appl->com || !StrLen (appl->com)) { IcaEval (&appl->interp, appl->command); list = VarGet (&appl->interp->scope, "opt"); any = AnyGetListAssoc (list, "command"); appl->com = VarGetStrv (any); } return _Str (appl->com); } void ApplLaunch (APPLo *appl) { ApplGetCommand (appl); IcaEval (&appl->interp, appl->launch); } APPLoOpt *ApplNextOpt (APPLo *appl, Int4 *c) { if (*c >= appl->optionsN) { *c=0; return NULL; } else return &appl->options[(*c)++]; } APPLoOpt *ApplOptNamed (APPLo *appl, char *name) { APPLoOpt *opt; Int4 k; for (k=0; (opt=ApplNextOpt (appl, &k));) { if (SmEqs (ApplOptGetName (opt), name)) return opt; } return NULL; } char *ApplOptGetName (APPLoOpt *opt) { return opt->name; } char *ApplOptGetDefValue (APPLoOpt *opt) { static char tmp[100]; Int4 k; if (ApplOptIs (opt, "real")) { sprintf (tmp, "%f", opt->defReal); for (k=strlen (tmp)-1; k>0 && tmp[k]=='0'; k--) ; tmp[tmp[k]=='.' ? k+2 : k+1] = '\0'; return tmp; } else if (ApplOptIs (opt, "int")) { sprintf (tmp, "%d", opt->defInt); return tmp; } else return *opt->defStr ? opt->defStr : ""; } Int4 ApplOptGetDefInt (APPLoOpt *opt) { return opt->defInt; } /**api* function ************************************************************** ** ** Returns whether specified characteristic is true or false. ** ** INPUT: o application object [R] ** o characteristic: "list", "int", "real" [R] ** ** RETURNS: 1: characteristic is true ** 0: not true */ Int4 ApplOptIs (APPLoOpt *opt, char *option) { Int4 flag=0; switch (_Index (tolower(option[0]), tolower (option[1]))) { case _Index('l','i'): /* list */ if (opt->valuesN) flag = 1; break; case _Index('m','e'): /* menu */ if (opt->guiType==4) flag = 1; break; case _Index('r','a'): /* radio */ if (opt->guiType==3) flag = 1; break; case _Index('m','u'): /* multi */ if (opt->guiType==2) flag = 1; break; case _Index('r','e'): /* real */ if (opt->type==2) flag = 1; break; case _Index('i','n'): /* int */ if (opt->type==1) flag = 1; break; case _Index('b','o'): /* bool */ if (opt->type==3) flag = 1; break; case _Index('s','t'): /* string */ if (opt->type==4) flag = 1; break; default: _ErrExit2 (e__unknownoption, option); } return flag; } APPLoOptGroup *ApplOptGetGroup (APPLoOpt *opt) { return opt->group; } char *ApplOptGetPrompt (APPLoOpt *opt) { return *opt->prompt ? opt->prompt : ""; } APPLoOptVal *ApplOptNextVal (APPLoOpt *opt, Int4 *c) { if (*c >= opt->valuesN) { *c=0; return NULL; } else return &opt->values[(*c)++]; } char *ApplOptValGetName (APPLoOptVal *val) { return val->name; } char *ApplOptValGetPrompt (APPLoOptVal *val) { return val->prompt; } char *ApplOptValGetValue (APPLoOpt *opt, APPLoOptVal *val) { static char tmp[100]; Int4 k; if (ApplOptIs (opt, "real")) { sprintf (tmp, "%f", val->valReal); for (k=strlen (tmp)-1; k>0 && tmp[k]=='0'; k--) ; tmp[tmp[k]=='.' ? k+2 : k+1] = '\0'; return tmp; } else if (ApplOptIs (opt, "int")) { sprintf (tmp, "%d", val->valInt); return tmp; } else return *val->valStr ? val->valStr : ApplOptValGetName (val); } Int4 ApplOptValGetInt (APPLoOpt *opt, APPLoOptVal *val) { return val->valInt; } Int4 ApplOptValIs (APPLoOptVal *val, char *option) { Int4 flag=0; switch (_Index (tolower(option[0]), tolower (option[1]))) { case _Index('n','a'): /* named */ if (*val->name) flag = 1; break; case _Index('o','n'): /* menu */ if (val->on) flag = 1; break; default: _ErrExit2 (e__unknownoption, option); } return flag; } char *ApplOptGroupGetName (APPLoOptGroup *group) { return group->name; } Int4 ApplOptGroupGetSize (APPLo *appl, APPLoOptGroup *group) { APPLoOpt *opt; Int4 i, n; for (i=0, n=0; (opt=ApplNextOpt (appl, &i));) if (group == ApplOptGetGroup (opt)) n++; return n; } n','a'): /* named */ if (*val->name) flag = 1; break; case _Index('o','n'): /* menu */ if (val->on) flag = 1; break; default: _ErrExit2 (e__unknownoption, option); } return flag; } char *ApplOptGroupGetName (APPLoOptGroup *group) { return group->name; } Int4 ApplOptGroupGetSize (APPLo *appl, APPLoOptGroup *group) { APPLoOpt *srs/src/appl.h struct APPLo *ApplNamed (char *name); char *ApplGetTitle (struct APPLo *appl); struct APPLo *ApplNextInDataType (struct LIBoDataType *dataType, INT4 *c); /* accessing an application object */ char *ApplGetName (struct APPLo *appl); char *ApplGetCommand (struct APPLo *appl); void ApplLaunch (struct APPLo *appl); Int4 ApplIsInSeq (struct APPLo *appl, char *option); struct APPLoOpt *ApplNextOpt (struct APPLo *appl, Int4 *c); struct APPLoOpt *ApplOptNamed (struct APPLo *appl, char *name); /* accessing an application's option object */ char *ApplOptGetName (struct APPLoOpt *opt); char *ApplOptGetDefValue (struct APPLoOpt *opt); struct APPLoOptVal *ApplOptNextVal (struct APPLoOpt *opt, Int4 *c); struct APPLoOptGroup *ApplOptGetGroup (struct APPLoOpt *opt); char *ApplOptGetPrompt (struct APPLoOpt *opt); /* accessing an application's option's value object */ char *ApplOptValGetName (struct APPLoOptVal *val); char *ApplOptValGetValue (struct APPLoOpt *opt, struct APPLoOptVal *val); Int4 ApplOptValGetInt (struct APPLoOpt *opt, struct APPLoOptVal *val); char *ApplOptValGetPrompt (struct APPLoOptVal *val); /* accessing an application's option's group object */ char *ApplOptGroupGetName (struct APPLoOptGroup *group); Int4 ApplOptGroupGetSize (struct APPLo *appl, struct APPLoOptGroup *group); *opt); /* accessing an application's option's value object */ char *ApplOptValGetName (struct APPLoOptVal *val); char *ApplOptValGetValue (struct APPLoOpt *opt, struct APPLoOptVal *val); Int4 ApplOptValsrs/src/arglist.c char arglist_ID[] = "$Id: arglist.c,v 1.4 1997/03/04 21:56:27 srs Exp $"; /* ** ** $RCSfile: arglist.c,v $ ** $Revision: 1.4 $ ** $Date: 1997/03/04 21:56:27 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** */ /* arglist - command line argument processor for C programs * * See getargs.doc and header file for full explanation * (C) Copyright 1985, Allen I. Holub. All rights reserved. * This program may be copied for personal, non-profit use only * * history... * * May 1985 published in Dr. Dobb's Journal #103. * 19 May 85 Transcribed by James R. Van Zandt * Oct 1993 Extended/modified by Philip lijnzaad@embl-heidelberg.de * * ------------------------------------------------------------------ * * * * Permission to copy all or part of this work is granted, provided * * that this NO WARRANTY and this copyright notice are retained * * verbatim and are displayed conspicuously. If anyone needs other * * permissions that aren't covered by the above, please contact the * * author. * * * * NO WARRANTY: THIS WORK IS PROVIDED ON AN "AS IS" BASIS. THE * * AUTHOR PROVIDES NO WARRANTY WHATSOEVER, EITHER EXPRESS OR * * IMPLIED, REGARDING THE WORK, INCLUDING WARRANTIES WITH THE WORK, * * INCLUDING WARRANTIES WITH RESPECT TO ITS MERCHANTABILITY OR * * FITNESS FOR ANY PARTICULAR PURPOSE. * * * * * * ------------------------------------------------------------------ */ #include #include #include #include #include "message.h" #include "futil.h" #include "par.h" #include "strv.h" #define _SRS #define _SLB #include SRSINCLUDE #include "arglist.h" typedef void (*PFV)(void); typedef void (*PFS)(char*); #define USAGE_MESSAGE "Usage:" #define OPT_FIRSTCHAR "-+" /* first chars that imply an option */ #define ERR_EXIT_STATUS 1 /* exit status upon user error */ #define INT_ERR_EXIT_STATUS 2 /* exit status upon internal error */ enum arg_type {ARGxPARAMETER, ARGxHELP, ARGxTITLE}; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** external, global and module wide variables */ static INT4 (*print)(char *,...)=NULL; /* function for printing errors */ static INT4 boolval; /* used in setarg */ static INT4 help=0; char * usage_message; /* printed by ArgUsage; user-setable */ /* BCB */ /* static INT4 (*myexit)(INT4); */ /* function for handling errors */ /* #define exit myexit */ /* end BCB */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of static functions */ static INT4 ArgSet (arg_t *argp, char **argv); static arg_t *ArgFind (char * name, ARGoLIST *arglist); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** default function for printing lines */ static INT4 ArgPrintMessage (char *formatStr, ...) { va_list ap; va_start (ap, formatStr); vfprintf (stdout, formatStr, ap); va_end (ap); return 1; } /****** ArgSet **************************************************************** ** ** set an argument. argp points at the argument table entry corresponding ** to argv[0]. Returns number of items that now can be taken out of ** argument list, ie. 1 for BOOLEAN and PROC, 2 for rest, and 0 for ** error ** ** INPUT: name [R] ** arglist object [R] ** IMPLICIT: ** help (int) [W] ** boolval (int) [R] ** ** RETURNS: returns pointer to argument object */ static INT4 ArgSet (arg_t *arg, char **argv) { PARo *par; INT4 parType, rv; char *cp; if (arg->type == ARGxHELP) { help=1; return (0); } if (!(par = ParGetWrite (arg->parameter, NULL))) _ErrExit2 (e__parnotdefined, arg->parameter); if ((parType = ParOGetType (par)) & PARxBOOL) { ParODefNum (par, boolval); return 1; } /* was added for the new SRSWWW ...transmitting function names */ if ((parType = ParOGetType (par)) == PARxSTR && *arg->defaultStr) { ParODefStr (par, arg->defaultStr); return 1; } /* was added for the new SRSWWW ...transmitting function names */ else if (parType == PARxNUM && arg->defaultNum) { ParODefNum (par, arg->defaultNum); return 1; } /* following functions all need a value, so see if it's there: */ if ( (! argv[1]) || (!argv[1][0] ) ) { print ("option %s needs additional argument", argv[0]); return(0); } switch (parType) { case PARxNUM: rv = ParODefNum (par, strtol (argv[1], &cp, 0)); if (_ErrIs (rv)) exit (INT_ERR_EXIT_STATUS); if (*cp) { print ("malformed integer: %s\n", argv[1]); return 0; } return 2; case PARxSTR: rv = ParODefStr (par, argv[1]); if (_ErrIs (rv)) exit (INT_ERR_EXIT_STATUS); return 2; case PARxREAL: rv = ParODefReal (par, strtod (argv[1], &cp)); if (_ErrIs (rv)) exit (INT_ERR_EXIT_STATUS); if (*cp) { print ("malformed double: %s\n", argv[1]); return 0; } return 2; default: break; } print ("getargs internal error: bad argument type %d for %s in %s %s\n", parType, par->name, argv[0], argv[1]); exit (INT_ERR_EXIT_STATUS); return 1; /* compilers ..please shut up!*/ } /****** ArgFind *************************************************************** ** ** searches an argument in the table by name ** ** INPUT: name [R] ** arglist object [R] ** IMPLICIT: ** ** RETURNS: returns pointer to argument object */ static arg_t *ArgFind (char * name, ARGoLIST *arglist) { arg_t *arg; INT4 k; for (k=0 ; k < arglist->argN; k++) { arg = &arglist->arg[k]; if (arg->type != ARGxTITLE && ! strcmp (arg->name, name) ) return (arg); } return (NULL); } /**api* ArgUsageBuild ********************************************************* ** ** prints a list with all commmand line options ** ** INPUT: address of symboltable [R] ** address of file descr. [W] ** IMPLICIT: ** help (int) [R] ** ** RETURNS: 1 */ char *ArgUsageBuild (ARGoLIST *arglist) { static STRv str=NULL; STRv tmp=StrNew (); PARo *par; arg_t *arg; INT4 k, isBoolOpts=0; if (!str) str = StrNew (str); StrPrintf (&str, "Usage: %s", arglist->name); StrAppS (&tmp, "[-"); /* ** collect all boolean options ...should be all optional and one letter names */ for (k=0; k < arglist->argN; k++) { arg = &arglist->arg[k]; if (arg->type == ARGxPARAMETER) { par = ParGetRead (arg->parameter, NULL); if (ParOGetType (par) & PARxBOOL && strlen (arg->name) == 2) { isBoolOpts = 1; StrAppS (&tmp, &arg->name[1]); } } } if (isBoolOpts) StrPrintf (&str, " %s]", _Str (tmp)); /* ** now the others */ for (k=0; k < arglist->argN; k++) { arg = &arglist->arg[k]; if (arg->type == ARGxPARAMETER) { par = ParGetRead (arg->parameter, NULL); if (ParOGetType (par) & PARxBOOL || strlen (arg->name) > 2) { if (ParOGetType (par) == PARxBOOL) StrPrintf (&str, " [%s]", arg->name); else StrPrintf (&str, " [%s %s]", arg->name, par->name); } } } StrPrintf (&str, " %s", arglist->usage); StrSet (&str, StrFormat (str, 80, 0, 10, NULL)); StrDel (tmp); return _Str (str); } /**api* ArgUsage ************************************************************** ** ** prints a list with all commmand line options ** ** INPUT: address of symboltable [R] ** address of file descr. [W] ** IMPLICIT: ** help (int) [R] ** ** RETURNS: 1 */ void ArgUsage (ARGoLIST *arglist) { PARo *par; arg_t *arg; STRv s; char assign[40], tmp[132], *str; INT4 k; print ("%s\n\n", ArgUsageBuild (arglist)); /* this is an error, not a HELP type */ if (!help) { print ("Info: %s -help\n", arglist->name); return; } s = StrNew (); for (k=0; k < arglist->argN; k++) { StrClear (&s); arg = &arglist->arg[k]; if (arg->type == ARGxPARAMETER) { par = ParGetRead (arg->parameter, NULL); switch (ParOGetType (par)) { case PARxBOOL: StrPrintf (&s, " %-20s[%s] %s", arg->name, ParOGetNum (par) ? "TRUE" : "FALSE", par->comment); break; case PARxNUM: sprintf (assign, "%s ", arg->name); StrPrintf (&s, " %-20s[%d] %s", assign, ParOGetNum (par), par->comment); break; case PARxSTR: sprintf (assign, "%s ", arg->name); if ((str = ParOGetStr (par))) sprintf (tmp, "[\"%s\"]" , str); StrPrintf (&s, " %-20s%s %s", assign, str ? tmp : "", par->comment); break; case PARxREAL: sprintf (assign, "%s ", arg->name); StrPrintf (&s, " %-20s[%f] %s", assign, ParOGetReal (par), par->comment); break; } StrTrim (&s, "\n"); StrTranslate (&s, "\n", " "); print ("%s\n", _Str (StrFormat (s, 80, 0, 22, NULL))); } else if (arg->type == ARGxTITLE) print ("\n%s\n\n", arg->name); else if (arg->type == ARGxHELP) print (" %-20s%s\n", arg->name, arg->comment); } } /**api* ArgGet *************************************************************** ** ** Process command line arguments, stripping all command line switches ** out of argv. Return a new argc. If an error is found, ** exit(ERR_EXIT_STATUS) is called (getargs won't return) and a usage ** message is printed, showing all arguments in the table ** module must be initialized before first query is done ** ** INPUT: o name of command, for which command line is to be ** processed [R] ** o number of args on command line [R] ** o pointer to address of argument array [W] ** ** IMPLICIT: ** print (INT4 (*print)(char *,...)) [W] ** ** RETURNS: new value for "argc" */ INT4 ArgGet (ARGoLIST *arglist, INT4 argc, char **argv) { INT4 nargc, i; char **nargv, *cp, oneletter[3], *savarg; arg_t *argp; if (!print) print = ArgPrintMessage; /* ** BCB /MS : major ! */ if (ParGetFunction ("ArgPrintf") != NULL) print = (INT4 (*)(char *, ...)) ParGetFunction ("ArgPrintf"); #define USAGE_EXIT ArgUsage (arglist),exit(ERR_EXIT_STATUS) /* would be nice to have _this_ in a further release */ /* if ( ParGetFunction ("UserExit") != NULL ) { myexit = (INT4 (*)(INT4)) ParGetFunction ("UserExit"); } else { myexit = exit; } #define USAGE_EXIT ArgUsage (arglist),myexit(ERR_EXIT_STATUS) */ nargc = 1; /* argv[0] is program name */ memset (oneletter, 0, sizeof (oneletter)); /* make zero */ for (nargv = ++argv; --argc > 0; argv++) { /* walk all arguments */ /* for now no provision for '\-'; do it with '--' */ if ( strchr( OPT_FIRSTCHAR, (INT4)*argv[0]) ) { /* an option (or more) */ if (! strcmp("--", *argv)) { /* signals end of options */ argv++; /* skip this one */ nargc += (argc-1); /* all the rest but '--' */ for ( ; --argc > 0 ; argv++) /* shift the rest */ *nargv++ = *argv; return (nargc); } if (! argv[0][1] ) { /* "-" or "+": never an option, */ *nargv++ = *argv; /* always an argument: shift it */ nargc++; continue; } boolval = (*argv[0] == '-'); /* 1 if -option, 0 if +option */ if ((argp = ArgFind (*argv, arglist))) { /* first try to find this arg as a complete word in the table */ if ((i=ArgSet (argp, argv))) { i--; argv += i; argc -= i; continue; } else USAGE_EXIT; /* wrong or no argument */ } else { /* try finding it as a letter arg */ oneletter[0]= argv[0][0]; /* any of OPT_FIRSTCHAR (typically -)*/ for ( cp = &argv[0][1]; *cp; cp++ ) { oneletter[1] = *cp; if ((argp = ArgFind (oneletter, arglist))){ /* find arg in table */ /* ** we seem to have found a matching one-letter option. ** Temporarily change this *argv, so as not to confuse ** the error messages: */ savarg = *argv; /* save current arg */ *argv = &oneletter[0]; /* argv[1] still 'normal' */ if ((i = ArgSet (argp, argv))) { /* not-nil: succes ! */ *argv = savarg; /* restore original */ if (i==2) { /* option that takes a value: */ argv++; /* must have been eaten */ argc--; break; /* continues at upper for-loop */ } /* else: continues at cp++ */ } else /* 0: failure */ USAGE_EXIT; /* wrong or no argument */ } else { print ("Unrecognized option \'%s\'\n", *argv); USAGE_EXIT; /* option not found */ } } } } else { /* not an option: shift arguments */ *nargv++ = *argv; nargc++; } } return(nargc); } /* getargs */ /**api* ArgSetPrint ************************************************************ ** ** allows other modules to set their own function for outputting ** messages; ** ** INPUT: address of function [R] ** IMPLICIT: ** print (int (*)) [W] ** */ void ArgSetPrint (INT4 (*fnct)(char *,...)) { if (fnct) print = fnct; } not found */ } } } srs/src/arglist.h * * See arglist.doc and header file for full explanation * (C) Copyright 1985, Allen I. Holub. All rights reserved. * This program may be copied for personal, non-profit use only * * history... * * May 1985 published in Dr. Dobb's Journal #103. * 19 May 85 Transcribed by James R. Van Zandt * Oct 1993 Extended/modified by Philip lijnzaad@embl-heidelberg.de * * ------------------------------------------------------------------ * * * * Permission to copy all or part of this work is granted, provided * * that this NO WARRANTY and this copyright notice are retained * * verbatim and are displayed conspicuously. If anyone needs other * * permissions that aren't covered by the above, please contact the * * author. * * * * NO WARRANTY: THIS WORK IS PROVIDED ON AN "AS IS" BASIS. THE * * AUTHOR PROVIDES NO WARRANTY WHATSOEVER, EITHER EXPRESS OR * * IMPLIED, REGARDING THE WORK, INCLUDING WARRANTIES WITH THE WORK, * * INCLUDING WARRANTIES WITH RESPECT TO ITS MERCHANTABILITY OR * * FITNESS FOR ANY PARTICULAR PURPOSE. * * * * * * ------------------------------------------------------------------ */ /* arglist.h - typedefs and defines needed for getargs */ #include /* for prototypes */ #include #include #ifndef _ARGoLIST #define _ARGoLIST typedef struct ARGoLIST { char *name; char *usage; struct arg_t *arg; INT4 argN; } ARGoLIST; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of exported functions */ INT4 ArgGet (ARGoLIST *arglist, INT4 argc, char **argv); void ArgUsage (ARGoLIST *arglist); void ArgSetPrint (INT4 (*fnct)(char *,...)); otypes */ #include #include #ifndef _ARGoLIST #define _ARGoLIST typedef struct ARGoLIST { chasrs/src/auxinfo.c #include #include "srs.h" INT4 PrintMessage (MSGo *msg) { if (msg->msg_code == i__readingname) putc ('.', stderr); switch (msg->msg_code) { case i__wroteset: return 0; default: if (msg->msg_t != MSGxINFO) fprintf (stderr, "ERROR: %s, %s\n", msg->primsg, msg->secmsg); else fprintf (stderr, "%s\n", msg->secmsg); return 1; } } #ifdef BUILD int main (int argc, char **argv) { SMoBUFF *buff=NULL, *auxBuff=NULL; struct IDXo *idx; SLBoFIELD *field; SLBo *lib; ENTRYv entry; char *name, *ln, indexName[133], *format; int errCode, n=0, len; SrsEnv (); LibOpen ("srswin"); MsgSetFnct (PrintMessage); argc = ArgGet ((ARGoLIST *) LibObjByName ("arglist", "srsbuild"), argc, argv); if (!(lib = (SLBo *) LibObjByName ("library", argv[1]))) _ErrExit3 (e__objectunknown, "library", argv[1]); if (SmEqs(LibGetName (lib, "full"), "swissprot")) format = "ID %*s %*[^;]; %*[^;]; %d"; else if (SmEqs(LibGetName (lib, "full"), "embl")) format = "ID %*s %*[^;]; %*[^;]; %*[^;]; %d"; entry = EntryOpenStream (lib); LibGetIndexName (lib, NULL, indexName, "write"); idx = IdxOpen (indexName, "write", 0, &errCode); _ErrExit2 (errCode, indexName); while (EntryNext (entry)) { while (field = EntryToNextField (entry)) { name = LibGetFieldName (field); if (SmEqs (name, "ID")) { while (ln = EntryFieldNextLine (entry)) { sscanf (ln, format, &len); } } else if (SmEqs (name, "Definition")) { buff = BuffInit (buff, 100); auxBuff = BuffInit (auxBuff, 100); while (ln = EntryFieldNextLine (entry)) BuffCopyString (buff, ln); ; while (BuffMatch (buff, "((DE )|(GN ))")) BuffSubstMatch (buff, 1, ""); while (BuffMatch (buff, "(\n)")) BuffSubstMatch (buff, 1, " "); BuffPack (auxBuff, "ia60", len, BuffGetPtr (buff)); IdxPutBuff (idx, auxBuff); } else EntrySkipField (entry); } if (!(++n % 300)) _ErrMsg3 (i__processingentry, n, EntryGetFullName (entry)); } IdxClose (idx); } #else int main () { SMoBUFF *buff; SETo *set; IDoENTRY id; ENTRYv entry; int n, entryN, len; char ln[100]; SrsEnv (); LibOpen ("srswin"); if (QryDo ("[swissprot-definition:protein]", "Q")) { set = SetGet ("Q"); entryN = SetSize ("Q"); for (n=1; n <= entryN; n++) { SetGetID (set, n, &id); entry = EntryOpen (&id); buff = EntryGetAuxInfo (entry); BuffUnpack (buff, "ia60", &len, ln); printf ("entry: %s, len: %d | %s\n", EntryGetFullName (entry), len, ln); EntryClose (&entry); } } } #endif int n, entryN, len; char ln[100]; SrsEnv (); LibOpen ("srswin"); if (QryDo ("[swissprot-definition:protein]", "Q")) { set = SetGet ("Q"); entryN = SetSize ("Q"); for (n=1; n <= entryN; n++) { SetGetID (set, n, &id); entry = EntryOpen (&id); buff = EntryGetAuxInfo (entry); BuffUnsrs/src/binpack.h ** ** $RCSfile: binpack.h,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:16:18 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** Macros for packing and unpacking data into/from platform independent ** binary format. ** */ #define BYTE1 0xFFUL #define BYTE2 0xFF00UL #define BYTE3 0xFF0000UL #define BYTE4 0xFF000000UL /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** macros for packing and unpacking filepointers and numbers */ #define _BinUnpackFip(buff, fip) \ do { \ fip = ((UINT4) ((unsigned char) buff[0])) + \ ((UINT4) ((unsigned char) buff[1]) << 8) + \ ((UINT4) ((unsigned char) buff[2]) << 16) + \ ((UINT4) ((unsigned char) buff[3]) << 24); \ buff += 4; \ } while (0) #define _BinUnpackNum(buff, num) \ do { \ (num) = ((UINT4) ((unsigned char) buff[0])) + \ ((UINT4) ((unsigned char) buff[1]) << 8) + \ ((UINT4) ((unsigned char) buff[2]) << 16) + \ ((UINT4) ((unsigned char) buff[3]) << 24); \ buff += 4; \ } while (0) #define _BinUnpack3Byte(buff, num) \ do { \ (num) = ((UINT4) ((unsigned char) buff[0])) + \ ((UINT4) ((unsigned char) buff[1]) << 8) + \ ((UINT4) ((unsigned char) buff[2]) << 16); \ buff += 3; \ } while (0) #define _BinUnpack2Byte(buff, num) \ do { \ (num) = ((UINT4) ((unsigned char) buff[0])) + \ ((UINT4) ((unsigned char) buff[1]) << 8); \ buff += 2; \ } while (0) #define _BinUnpackByte(buff, byte) \ byte = buff[0]; \ buff += 1 #define _BinUnpackStr(buff, s) \ s = buff; \ buff += strlen (buff) + 1 #define _BinUnpackFixStr(buff, s, len) \ strcpy (s, buff); \ buff += len + 1 #define _BinFileUnpackNum(file, num) \ do { char buff[4]; \ fread (buff, 4, 1, file); \ num = ((UINT4) ((unsigned char) buff[0])) + \ ((UINT4) ((unsigned char) buff[1]) << 8) + \ ((UINT4) ((unsigned char) buff[2]) << 16) + \ ((UINT4) ((unsigned char) buff[3]) << 24); \ } while (0) #define _BinPackFip(buff, fip) \ do { \ buff[0] = fip & BYTE1; \ buff[1] = (fip & BYTE2) >> 8; \ buff[2] = (fip & BYTE3) >> 16; \ buff[3] = (fip & BYTE4) >> 24; \ buff += 4; \ } while (0) #define _BinPackNum(buff, num) \ do { \ buff[0] = num & BYTE1; \ buff[1] = (num & BYTE2) >> 8; \ buff[2] = (num & BYTE3) >> 16; \ buff[3] = (num & BYTE4) >> 24; \ buff += 4; \ } while (0) #define _BinPack3Byte(buff, num) \ do { \ buff[0] = num & BYTE1; \ buff[1] = (num & BYTE2) >> 8; \ buff[2] = (num & BYTE3) >> 16; \ buff += 3; \ } while (0) #define _BinPack2Byte(buff, num) \ do { \ buff[0] = num & BYTE1; \ buff[1] = (num & BYTE2) >> 8; \ buff += 2; \ } while (0) #define _BinPackByte(buff, byte) \ buff[0] = byte; \ buff += 1 #define _BinPackFixStr(buff, s, len) \ strcpy(buff, s); \ buff += len + 1 #define _BinPackStr(buff, s) \ strcpy(buff, s); \ buff += strlen (s) + 1; #define _BinFilePackNum(file, num) \ do { char buff[4]; \ buff[0] = num & BYTE1; \ buff[1] = (num & BYTE2) >> 8; \ buff[2] = (num & BYTE3) >> 16; \ buff[3] = (num & BYTE4) >> 24; \ fwrite (buff, 4, 1, file); \ } while (0) hile (0) #define _BinPackByte(buff, byte) \ buff[0] = byte; \ buff += 1 #define _BinPackFixStr(buff, s, len) \ strcpy(buff, s); \ buff += len + 1 #define _Bisrs/src/blub.c #include #include "def.h" #include "blub.h" #include "parse.h" #include "listv.h" /**************************************************** ** ALLOCATION */ #define MAX_OFFS 0xFFFFFFFFL #define _getVal(obj) (obj) STRoStatic_20 attrDescr_strs[] = { {{}, "int"}, {{}, "PTR"}, {{}, "STRv"}, {{}, "OBJv"}, {{}, "ListAttr"}, {{}, "CLASSBODYv"}, {{}, "ATTRv"}, }; ATTRoDescr attrDescr[] = { {(STRv)(attrDescr_strs+ATTR_int), sizeof(int)}, {(STRv)(attrDescr_strs+ATTR_PTR), sizeof(PTR)}, {(STRv)(attrDescr_strs+ATTR_STRv), sizeof(STRv)}, {(STRv)(attrDescr_strs+ATTR_OBJv), sizeof(OBJv)}, {(STRv)(attrDescr_strs+ATTR_ListAttr), sizeof(ListAttr)}, {(STRv)(attrDescr_strs+ATTR_CLASSBODYv), sizeof(CLASSBODYv)}, {(STRv)(attrDescr_strs+ATTR_ATTRv), sizeof(ATTRv)} }; /* the descriptor for all list attribute headers */ STRoStatic_20 attrListName= {{}, "list"}; ATTRv attrListAttr= { (STRv)&attrListName, ATTR_ListAttr, NULL, 0 }; void AttrNamesInit() { _StrInitStatic(attrDescr_strs,7); _StrInitStatic(&attrListName,1); } /**************************************************** ** POLYMORPHIC OPERATIONS ON ATTRIBUTES ****************************************************/ void ObjDoAttrRecursive(void* obj, CLASSv descr, AttrAction act, void* info) { CLASSv inherits=descr->inherits; ATTRv* attr; ATTRv* list=descr->attrs; if (inherits) ObjDoAttrRecursive(obj, inherits, act, info); for (attr=list; attrfixed; attr++) { call(act)(offset(obj, attr->offs, void*), attr, info); } } void ObjDoAttr(void* obj, AttrAction act, void* info) { CLASSv descr=ObjClass(obj); ObjDoAttrRecursive(obj, descr, act, info); } void ObjDoInList(void* obj, AttrAction act, ATTRv* elem, void* info, void* from, void* to) { int elemSize=attrDescr[elem->type].size; while (fromtype].size; to=cast(to,BYTE*)-elemSize; while (to>=from) { call (act)(to, elem, info); to=cast(to,BYTE*)-elemSize; } } void ObjDoList(void* obj, AttrAction act, void* info) { ListAttr* list; ATTRv* elem; ASSERT (ObjListInfo(obj, &elem, &list),"NotAList"); ObjDoInList(obj, act, elem, info, list+1, list->tail); } void ObjDoAll(void* obj, AttrAction act, void* info) { ListAttr* list; ATTRv* elem; ObjDoAttr(obj, act, info); if (ObjListInfo(obj, &elem, &list)) { call (act)(list, &attrListAttr, info); ObjDoInList(obj, act, elem, info, list+1, list->tail); } } BOOL ObjDoCondRecursive(void* obj, CLASSv descr, AttrCondition act, void* info) { CLASSv inherits=descr->inherits; ATTRv* attr; ATTRv* list=descr->attrs; if (inherits) if (!ObjDoCondRecursive(obj, inherits, act, info)) return FALSE; for (attr=list; attrfixed; attr++) { if (!call(act)(offset(obj, attr->offs, void*), attr, info)) return FALSE; } return TRUE; } /* operates on attributes, performing an AND operation on cond. * Stops as soon as the result is FALSE */ BOOL ObjDoCond(void* obj, AttrCondition act, void* info) { ListAttr* list; ATTRv* elem; if (!ObjDoCondRecursive(obj, _getObj(obj)->descr, act, info)) return FALSE; if (ObjListInfo(obj, &elem, &list)) { int elemSize; void *from,*to; if (!call (act)(list, &attrListAttr, info)) return FALSE; elemSize=attrDescr[elem->type].size; from=list+1; to=list->tail; while (fromtail=offset(d,displ(s->tail, s),BYTE*); d->end=d->tail; /* ??? what if grow is reserved? */ } void PolyClassCpy(CLASSBODYv* d, CLASSBODYv* s) { d->inherits=ObjCpy(s->inherits); d->fixed=offset(d, displ(s->fixed, s), ATTRv*); d->byName=s->byName; d->values=NULL; } void PolyAttrCpy(ATTRv* d, ATTRv* s) { if (s->name) d->name=StrCpy(s->name); else d->name=NULL; d->offs=s->offs; d->type=s->type; d->more=s->more; /*...???? how do I copy this? */ } void AttrCopyAction(void* attr, ATTRv* a, void* copyOffs) { static ValCopier copyOp[] = { (ValCopier) PolyIntCpy, (ValCopier) PolyPtrCpy, (ValCopier) PolyStrCpy, (ValCopier) PolyObjCpy, (ValCopier) PolyListCpy, (ValCopier) PolyClassCpy, (ValCopier) PolyAttrCpy }; call (copyOp[a->type])(offset(attr, (int)copyOffs, void*), attr); }; /**************************************************** ** MOVING */ typedef void (*ValMover) (void* dest, void* src); void PolyClassMove(CLASSBODYv* d, CLASSBODYv* s) { DICTv byName=s->byName; if (byName && (s->inherits && byName!=s->inherits->byName)) { /* had a local dictionary, offset attributes */ ListAttr* slist=cast(s+1,ListAttr*); ListAttr* dlist=cast(d+1,ListAttr*); DictOffsetWithin(byName, slist, displ(slist->tail,slist), dlist); } d->inherits=s->inherits; d->fixed=offset(d, displ(s->fixed, s), ATTRv*); d->byName=s->byName; d->values=s->values; } void PolyAttrMove(ATTRv* d, ATTRv* s) { d->name=s->name; d->offs=s->offs; d->type=s->type; d->more=s->more; } void AttrMoveAction(void* attr, ATTRv* a, void* moveOffs) { static ValMover moveOp[] = { (ValMover) PolyIntCpy, (ValMover) PolyPtrCpy, (ValMover) PolyPtrCpy, (ValMover) PolyPtrCpy, (ValMover) PolyListCpy, (ValMover) PolyClassMove, (ValMover) PolyAttrMove }; call (moveOp[a->type])(offset(attr,(int)moveOffs,void*),attr); } /**************************************************** ** DELETING */ typedef void (*ValDeleter) (void* val); void PolyStrDel(STRv* v, void* nothing) { StrDel(*v); } void PolyObjDel(void** v, void* nothing) { ObjDel(*v); } void PolyClassDel(CLASSBODYv* c) { DICTv* byName=&c->byName; if (*byName && (c->inherits && *byName!=c->inherits->byName)) { /* had a local dictionary, delete */ DictDestroy(*byName); } if (c->values) DictDestroy(c->values); ObjDel(c->inherits); } void PolyAttrDel(ATTRv* a, void* nothing) { if (a->name) StrDel(a->name); } void AttrDelAction(void* attr, ATTRv* a, void* nothing) { static ValDeleter delOp[] = { (ValDeleter) PolyNothing, (ValDeleter) PolyNothing, (ValDeleter) PolyStrDel, (ValDeleter) PolyObjDel, (ValDeleter) PolyNothing, (ValDeleter) PolyClassDel, (ValDeleter) PolyAttrDel }; call (delOp[a->type])(attr); } /**************************************************** ** HASHING */ /* rotates right sum by 5 bits (*index) and xores with num */ #define _hash(sum, num) sum=(sum>>5)^(sum<<27)^num; #define _hashGo(sum,index) {int disp=(index<<2+index)&31;sum=(sum>>disp)^(sum<<(32-disp));} UINT4 StrHash1(STRv s) { UINT4 sum=0; if (s) { int len=StrLen(s); char* p=Str(s); char* stop=p+len; _hash(sum,len); while (p!=stop) _hash(sum,*p++); } return sum; } typedef UINT4 (*ValHasher1) (void* val); UINT4 PolyIntHash1(int* i) { return i; } UINT4 PolyPtrHash1(PTR* p) { return (WORD) *p; } UINT4 PolyStrHash1(STRv* sp) { return StrHash1(*sp); } UINT4 PolyObjHash1(void** obj) { return ObjHash1(*obj); } UINT4 PolyListHash(ListAttr* l) { return displ(l->tail,l); } UINT4 PolyClassHash(CLASSBODYv* c) { return ObjHash1(c->inherits); } UINT4 PolyAttrHash(ATTRv* a) { UINT4 sum=0; _hash(sum, StrHash1(a->name)); _hash(sum, a->type); return sum; } void AttrHashAction(void* attr, ATTRv* a, void* hashVal) { static ValHasher1 hashOp[]= { (ValHasher1) PolyIntHash1, (ValHasher1) PolyPtrHash1, (ValHasher1) PolyStrHash1, (ValHasher1) PolyObjHash1, (ValHasher1) PolyListHash, (ValHasher1) PolyClassHash, (ValHasher1) PolyAttrHash }; UINT4 hash=*(WORD*)hashVal; _hash(hash, call (hashOp[a->type])(attr)); *(WORD*)hashVal=hash; } /**************************************************** ** COMPARING */ typedef BOOL (*ValComparer1) (void* val1, void* val2); BOOL PolyObjEqual(void** obj1,void** obj2) { return ObjEqual(*obj1,*obj2); } BOOL PolyListEqual(ListAttr* l1, ListAttr* l2) { return displ(l1->tail,l1)==displ(l2->tail,l2);} BOOL PolyClassEqual(CLASSBODYv* c1, CLASSBODYv* c2) { return c1->inherits==c2->inherits; } BOOL PolyAttrEqual(ATTRv* a1,ATTRv* a2) { return StrEqual(a1->name,a2->name) && a1->type==a2->type && ObjEqual(a1->more,a2->more); } BOOL AttrEqualCond(void* attr, ATTRv* a, void* compOffs) { static ValComparer equalCond[]= { (ValComparer1) PolyIntEqual, (ValComparer1) PolyPtrEqual, (ValComparer1) PolyStrEqual, (ValComparer1) PolyObjEqual, (ValComparer1) PolyListEqual, (ValComparer1) PolyClassEqual, (ValComparer1) PolyAttrEqual }; return call(equalCond[a->type])(attr, offset(attr,(int)compOffs, void*)); } /************************************************* ** PREDEFINED CLASSES *************************************************/ #define SIZE_HEAD sizeof(OBJo) #define SIZE_CLASSHEAD (sizeof(CLASSo)-sizeof(ListAttr)-sizeof(ATTRv)*10) #define SIZE_ATTR sizeof(ATTRv) CLASSo bootClassClass= { { 2, &bootClassClass }, NULL, /* should inherit BootObjClass */ &bootClassClass.attrs[1], NULL, NULL, {(BYTE*)&bootClassClass.attrs[2], (BYTE*)&bootClassClass.attrs[2]}, { { NULL, ATTR_CLASSBODYv, NULL, SIZE_HEAD }, { NULL, ATTR_ATTRv, NULL, SIZE_CLASSHEAD } } }; CLASSo bootObjClass = { { 2, &bootClassClass}, NULL, &bootObjClass.attrs[0], NULL, NULL, { (BYTE*)&bootObjClass.attrs[1], (BYTE*)&bootObjClass.attrs[1] }, { { NULL, -1, NULL, SIZE_HEAD } } }; OBJo objBuf = { 1, &bootObjClass }; void* Object=&objBuf; void* Class=&bootObjClass; /************************************************************************* ** NAMED VALUES MNGM. *************************************************************************/ /* a val can have several names associated with it, but the first one counts */ struct { DICTv vals; DICTv names; DICTv ids; int lastId; } sysVals; void SysInclude(SYSoName* list) { static CLASSoDICT* valsIndex=NULL; static CLASSoDICT* namesIndex=NULL; static CLASSoDICT* idsIndex=NULL; if (!valsIndex) { valsIndex=DictCreateClassPtrKey(NULL, mPtr(SYSoName, val), TRUE); namesIndex=DictCreateClassStrKey(NULL, mPtr(SYSoName, name), FALSE); idsIndex=DictCreateClassIntKey(NULL, mPtr(SYSoName, id), FALSE); sysVals.vals=DictCreate(valsIndex); sysVals.names=DictCreate(namesIndex); sysVals.ids=DictCreate(idsIndex); } while (list->name) { list->id=sysVals.lastId++; DictAddPtr(&sysVals.names,list); DictAddPtr(&sysVals.vals,list); DictAddPtr(&sysVals.ids,list); list++; } } int SysIdNum() { return sysVals.lastId; } void SysName(STRv name,void* val) { struct SYSoName* v = _palloc(SYSoName); v->name=StrCpy(name); v->val=ObjCpy(val); v->id=-1; DictAddPtr(&sysVals.vals, v); DictAddPtr(&sysVals.names, v); } void SysForgetName(STRv name) { Iter i=DictWith(sysVals.names,&name); SYSoName* v=DictIn(i,SYSoName*); if (v->id==-1) { /* only forget if run-time defined */ DictRemovePtr(&sysVals.vals,v); DictRemove(&sysVals.names,i); StrDel(v->name); ObjDel(v->val); _pfree(v); } } void** SysFromName(STRv name) { Iter n=DictWith(sysVals.names,&name); if (n) return &DictIn(n,SYSoName*)->val; else return NULL; } void** SysFromId(int id) { Iter n=DictWith(sysVals.ids,&id); if (n) return &DictIn(n,SYSoName*)->val; else return NULL; } STRv SysToName(void* val) { Iter n=DictWith(sysVals.vals,&val); if (n) return DictIn(n,SYSoName*)->name; else return NULL; } int SysToId(void* val) { Iter n=DictWith(sysVals.vals,&val); if (n) return DictIn(n,SYSoName*)->id; else return -1; } /********************************************************** ** INITIALIZATION **********************************************************/ STRoStatic_20 blubNames[]= { {{},"NULL"}, {{},"Class"}, {{},"Object"} }; SYSoName blubValues[]= { {(STRv)&blubNames[0], NULL }, {(STRv)&blubNames[1], &bootClassClass}, {(STRv)&blubNames[2], &bootObjClass}, {NULL, NULL} }; CLASSoDICT byNameProp = { PolyStrEqual, PolyStrHash, (KeyAccessor)KeyOffset, 0, /* to be initialized */ FALSE }; void ObjInit() { AttrNamesInit(); _StrInitStatic(blubNames,3); SysInclude(blubValues); byNameProp.toKeyInfo=mPtr(ATTRv,name); } /************************************************************ ** INTERNAL IMPLEMENTATION hiding functions */ int ObjSize(OBJv obj) { ATTRv* fixed=ObjClass(obj)->fixed; int size=fixed->offs; if (fixed->type!=-1) { /* it's a list */ ListAttr* list=offset(obj, size, ListAttr*); size+=displ(list->tail, list); } return size; } OBJv ObjRealloc(OBJv obj, int grow) { OBJv o=(OBJv)malloc(ObjSize(obj)+grow); o->usage=1; o->descr=ObjCpy(obj->descr); return o; } void ObjFree(OBJv obj) { CLASSv descr=obj->descr; if (descr->values) { Iter i=DictWith(descr->values,obj); /* is the object is under value-management, remove it */ if (DictIn(i,OBJv)==obj) DictRemove(&descr->values, i); } ObjDel(obj->descr); free(obj); } CLASSv ObjClass(void* obj) { return _getObj(obj)->descr; } /***************************************************************** ** Object buffer operations */ void* ObjChangeImpl(void** obj) { OBJv o=_getObj(*obj); if (o->usage>1) { OBJv old=o; *obj=o=ObjRealloc(old, 0); ObjDoAll(old, AttrCopyAction, (void*)displ(o, old)); old->usage--; } else { DICTv vals=o->descr->values; if (vals) { /* if value managed, uncommit value */ DictRemoveWith(&vals,o); o->descr->values=vals; } } return _getVal(o); } void ObjDel(void* obj) { if (obj) { OBJv o=_getObj(obj); if (!--o->usage) { ObjDoAll(obj, AttrDelAction, NULL); ObjFree(o); } } } CLASSoDICT dictValueClass = { (ValComparer) ObjEqual, (ValHasher) ObjHash, (KeyAccessor) KeyItself, NULL, FALSE }; void ObjCommit(void** obj) { OBJv o=*obj; OBJv *vp, v; CLASSv descr=_getObj(o)->descr; if (!descr->values) { /* create class value dictionary in class */ descr->values=DictCreate(&dictValueClass); } vp=&DictSet(&descr->values, o, OBJv); v=*vp; if (v) ObjSet(obj, v); /* equal value already there */ else *vp=o; /* new value */ } /***************************************************************** ** REFERENCE COUNTING operations */ void* ObjCpy(void* obj) { if (obj) _getObj(obj)->usage++; return obj; } void ObjSet(void** dest, void* src) { ObjDel(*dest); *dest=ObjCpy(src); } int ObjShared(void* obj) { return _getObj(obj)->usage-1; } UINT4 ObjHash1(void* obj) { UINT4 hash=0; if (obj) ObjDoAll(obj, AttrHashAction, &hash); return hash; } int ObjHash(void* obj, int max) { int n= ObjHash1(obj)%max; return n; } BOOL ObjEqual(void* obj1, void* obj2) { if (obj1==obj2) return TRUE; /* if value managed, I can only check the pointers here */ if (_getObj(obj1)->descr!=_getObj(obj2)->descr) return FALSE; if (ObjSize(obj1)!=ObjSize(obj2)) return FALSE; return ObjDoCond(obj1, AttrEqualCond, displ(obj2, obj1)); } /**************************************************************************** ** CLASS MANAGEMENT ****************************************************************************/ void ObjMakeClass(void* obj, STRv name) { PATHv p; CLASSv descr=_getObj(obj)->descr; SysName(name,descr); } AttrIter ClassAttrNew(CLASSv* cl, STRv name, AttrTypeId type, void* more) { CLASSv descr=*cl; ATTRv* attr; int offs; offs=descr->fixed->offs; offs+=align(offs,attrDescr[type].size); ASSERT(descr->fixed->type==-1, "CannotInheritFromList"); if (ObjShared(descr)) { CLASSv old=descr; descr=ObjCpy(Class); attr=&ObjListApp(&descr, ATTRv); descr->inherits=old; } else { attr=&ObjListApp(&descr, ATTRv); } /* last ATTRv is fake, only for size: set it */ descr->fixed=attr; attr->offs=offs+attrDescr[type].size; attr->type=-1; attr->name=NULL; /* now set attribute descriptor */ attr--; attr->type=type; attr->more=more; attr->offs=offs; /* manage now name */ if (name) { DICTv* byName=&descr->byName; if (!*byName) *byName=DictCreate(&byNameProp); else if (descr->inherits && *byName==descr->inherits->byName) { /* copy old dictionary if it was shared */ *byName=DictCopy(descr->inherits->byName); } DictAdd(byName, &name, ATTRv*)=attr; attr->name=StrCpy(name); } else attr->name=NULL; /* now value manage */ ObjCommit(&descr); *cl=descr; return offs; } AttrIter ClassListNew(CLASSv* cl, AttrTypeId type, void* more) { CLASSv descr=*cl; ATTRv* attr;int offs; ASSERT(descr->fixed->type==-1, "CannotInheritFromList"); offs=descr->fixed->offs; offs+=align(offs,attrDescr[type].size); if (ObjShared(descr)) { CLASSv old=descr; descr=ObjCpy(Class); attr=ObjChange(&descr, CLASSv)->fixed; descr->inherits=old; } else { attr=ObjChange(&descr, CLASSv)->fixed; } attr->type=type; attr->more=more; attr->name=NULL; attr->offs=offs; ObjCommit(&descr); *cl=descr; return offs; } AttrIter ClassAttrWith(CLASSv descr, STRv name, ATTRv** attr) { AttrIter i; ATTRv* ia=NULL; if (isalpha(Str(name)[0])) { /* a normal attribute name */ Iter a=DictWith(descr->byName, &name); if (a) { ia=DictIn(a, ATTRv*); i=ia->offs; } else i=NULL; } else { /* a list element */ int pos=atoi(Str(name)); ia=descr->fixed; ASSERT(ia->type!=-1,"NotAList"); i=ia->offs+sizeof(ListAttr)+attrDescr[ia->type].size*pos; } *attr=ia; return i; } AttrIter ClassAttrFirst(CLASSv descr) { if (descr->inherits && descr!=Class) return ClassAttrFirst(descr->inherits); else { ATTRv* first=&descr->attrs[0]; if (first->type!=-1) return first->offs; else return NULL; } } void ClassAttrNext(CLASSv descr, AttrIter* i) { } void* ClassAlloc(CLASSv cl, int nElem) { ATTRv* fixed=cl->fixed; int size=fixed->offs; int lSize; OBJv o; BOOL isList=fixed->type!=-1; if (isList) { lSize=nElem*attrDescr[fixed->type].size; size+=sizeof(ListAttr)+lSize; } o=(OBJv)malloc(size); o->descr=ObjCpy(cl); o->usage=1; if (isList) { /* init list attribute, empty list of given size */ ListAttr* l=offset(o, fixed->offs, ListAttr*); l->tail=(BYTE*)(l+1); l->end=l->tail+lSize; l->tail=l->end; } return o; } /************************************************************** ** ATTRIBUTE OPERATIONS ***************************************************************/ void* ObjAttrNewImpl(void** obj, STRv name, int type, void* more) { OBJv old=_getObj(*obj); OBJv o; int offs; o=ObjRealloc(old, attrDescr[type].size); ObjDoAttr(old, AttrCopyAction, (void*)displ(o,old)); ObjDel(old); offs=ClassAttrNew(&o->descr, name, type, more); *obj=o; return offset(o, offs, void*); } /* attribute access */ void* ObjAttrInImpl(void* obj, AttrIter i) { return offset(obj, i, void*); } ATTRp lastAttr=NULL; void* ObjAttrImpl(void* obj, STRv name, int type) { AttrIter offs=ObjAttrWith(obj,name); ASSERT(type!=-1 || lastAttr->type==type, "TypeMismatch"); return offset(obj, offs, void*); } /* attribute iteration */ AttrIter ObjAttrWith(void* obj, STRv name) { CLASSv descr=_getObj(obj)->descr; AttrIter i; if (isalpha(Str(name)[0])) { /* a normal attribute name */ lastAttr=DictAt(descr->byName, &name, ATTRv*); i=lastAttr->offs; } else { /* a list element */ int pos=atoi(Str(name)); void* a=ObjListWith(obj,pos); ASSERT(a,"NoSuchElem"); i=displ(a,obj); } return i; } AttrIter ObjAttrFirst(void* obj) { return sizeof(OBJo); } void ObjAttrNext(void* obj, AttrIter* i) { AttrIter p=*i; ATTRv* attr=ObjAttrInfo(obj, p); p=p+attrDescr[attr->type].size; if (p>=ObjSize(obj)) p=NULL; *i=p; } /* attribute information */ ATTRv* ObjAttrInfoFixed(CLASSv descr, int offs) { ATTRv* minAttr=&descr->attrs[0]; if (offsoffs) { CLASSv inherits=descr->inherits; ASSERT(inherits, "InvalidAttribute"); return ObjAttrInfoFixed(inherits,offs); } else { /* perform a binary search on offsets, they are sorted */ ATTRv* maxAttr=descr->fixed; int diff=maxAttr-minAttr; while (diff>1) { ATTRv* attr=minAttr+(diff>>1); if (offsoffs) maxAttr=attr; else minAttr=attr; diff=maxAttr-minAttr; } return minAttr; } } ATTRv* ObjAttrInfo(void* obj, AttrIter offs) { void* a=offset(obj, offs, void*); ATTRv* elem; ListAttr* l; if (ObjListInfo(obj, &elem, &l) && a>=(void*)l && a<(void*)l->tail) { /* it's a list element */ if (a==l) return &attrListAttr; return elem; } else { CLASSv descr=_getObj(obj)->descr; ASSERT(offsfixed->offs, "InvalidAttribute"); return ObjAttrInfoFixed(descr, offs); } } STRv ObjAttrName(void* obj, AttrIter offs) { void* a=offset(obj, offs, void*); ATTRv* elem; ListAttr* l; if (ObjListInfo(obj, &elem, &l) && a>=(void*)l && a<(void*)l->tail) { /* it's a list element */ if (a==l) return StrCpy(attrListAttr.name); else { int pos=ObjListPos(obj,a); return StrFromInt(pos); } } else { CLASSv descr=_getObj(obj)->descr; ASSERT(offsfixed->offs, "InvalidAttribute"); return StrCpy(ObjAttrInfoFixed(descr, offs)->name); } } /************************************************************************** ** LIST OPERATIONS **************************************************************************/ void* ObjListNewImpl(void** obj, int dim, int type, void* more) { OBJv old=_getObj(*obj); OBJv o; int offs; ListAttr* list; int dimSize=attrDescr[type].size*dim; o=ObjRealloc(old, sizeof(ListAttr)+dimSize); ObjDoAttr(old, AttrCopyAction, (void*)displ(o,old)); ObjDel(old); offs=ClassListNew(&o->descr, type, more); /* initialize the ListAttr */ list = offset(o,offs,ListAttr*); list->tail=offset(list+1,dimSize,BYTE*); list->end=list->tail; *obj=o; return offset(o, offs+sizeof(ListAttr), void*); } void* ObjListAddImpl(void** obj, Iter pos, int numAdd) { OBJv o=_getObj(*obj); ListAttr* list; ATTRv* elem; int addSize; BYTE* head; BYTE* tail; ASSERT(ObjListInfo(o, &elem, &list), "NotAList"); head=(BYTE*)(list+1); tail=list->tail; addSize=numAdd*attrDescr[elem->type].size; if (!pos) pos=tail; /* append */ if (o->usage>1) { /* make a real copy with space for new elements */ OBJv old=o; int offs; o=ObjRealloc(old, addSize); offs=displ(o, old); ObjDoAttr(old, AttrCopyAction, (void*)offs); ObjDoInList(old, AttrCopyAction, elem, (void*)offs, head, pos); ObjDoInList(old, AttrCopyAction, elem, cast(offs+addSize,void*), pos, tail); list=offset(list, offs, ListAttr*); list->tail=tail+offs+addSize; list->end=list->tail; old->usage--; pos=cast(pos,BYTE*)+offs; } else { if (tail+addSize<=list->end) { /* can grow, only move tail */ ObjDoInListReverse(obj, AttrMoveAction, elem, (void*)addSize, pos, tail); list->tail+=addSize; } else { /* allocate a buffer, move old obj in new */ OBJv old=o; int offs; o=ObjRealloc(old, addSize); offs=displ(o, old); ObjDoAttr(old, AttrMoveAction, (void*)offs); ObjDoInList(old, AttrMoveAction, elem, (void*)offs, head, pos); ObjDoInList(old, AttrMoveAction, elem, cast(offs+addSize,void*), pos, list->tail); list=offset(list, offs, ListAttr*); list->tail=tail+offs+addSize; list->end=list->tail; ObjFree(old); pos=cast(pos,BYTE*)+offs; } } *obj=_getVal(o); return pos; } void* ObjListAppImpl(void** obj, int num) { return ObjListAddImpl(obj, NULL, num); } void* ObjListInsImpl(void** obj, int num) { return ObjListAddImpl(obj, ObjListFirst(*obj), num); } void ObjListCut(void** obj, Iter pos, int numRem) { OBJv o=_getObj(*obj); ListAttr* list; ATTRv* elem; int remSize; BYTE* head; BYTE* tail; void* cutPos; ASSERT(ObjListInfo(o, &elem, &list),"NotAList"); head=(BYTE*)(list+1); tail=list->tail; remSize=attrDescr[elem->type].size*numRem; if (!pos) pos=offset(tail, -remSize, Iter); /* remove at the end */ cutPos=offset(pos, remSize, void*); if (o->usage>1) { /* make a real copy skipping the removed elements */ OBJv old=o; int offs; o=ObjRealloc(old, -remSize); offs=displ(o, old); ObjDoAttr(old, AttrCopyAction, (void*)offs); ObjDoInList(old, AttrCopyAction, elem, (void*)offs, head, pos); ObjDoInList(old, AttrCopyAction, elem, cast(offs-remSize,void*), cutPos, tail); list=offset(list, offs, ListAttr*); list->tail=tail+offs-remSize; list->end=list->tail; old->usage--; } else { /* only move tail,leave space for grow */ ObjDoInList(o, AttrDelAction, elem, NULL, pos, cutPos); ObjDoInList(o, AttrMoveAction, elem, (void*)(-remSize), cutPos, tail); list->tail-=remSize; } *obj=_getVal(o); } void ObjListGrow(void** obj, int num) { OBJv o=_getObj(*obj); ListAttr* list; ATTRv* elem; int size; BYTE* head; BYTE* tail; void* cutPos; ASSERT(ObjListInfo(o, &elem, &list),"NotAList"); head=(BYTE*)(list+1); tail=list->tail; size=attrDescr[elem->type].size*num; if (o->usage>1 || offset(tail, size, BYTE*)>list->end) { /* copy the list into a new buffer, making space for n elements */ OBJv old=o; int offs; o=ObjRealloc(old, size-displ(tail, head)); offs=displ(o, old); ObjDoAll(old, AttrCopyAction, (void*)offs); list=offset(list, offs, ListAttr*); list->end=offset(list->tail, size, BYTE*); ObjDel(old); } *obj=o; } /* list access */ void* ObjListInImpl(Iter i) { ASSERT(i, "NoSuchElem"); return i; } /* list iteration */ Iter ObjListFirst(void* obj) { Iter i; ATTRv* elem; ListAttr* list; ASSERT(ObjListInfo(obj, &elem, &list), "NotAList"); i=list+1; if (i>=(void*)list->tail) i=NULL; return i; } void ObjListNext(void* obj, Iter* i) { Iter p=*i; ATTRv* elem; ListAttr* list; ASSERT(ObjListInfo(obj, &elem, &list), "NotAList"); p=offset(p, attrDescr[elem->type].size, Iter); if (p>=(void*)list->tail) p=NULL; *i=p; } Iter ObjListLast(void* obj) { Iter i; ATTRv* elem; ListAttr* list; ASSERT(ObjListInfo(obj, &elem, &list), "NotAList"); i=offset(list->tail, -attrDescr[elem->type].size, Iter); if (itype].size, Iter); if (ptype].size,Iter); if (i>=(void*)list->tail) i=NULL; return i; } /* conversions */ int ObjListPos(void* obj, Iter i) { ATTRv* elem; ListAttr* list; ASSERT(ObjListInfo(obj, &elem, &list), "NotAList"); ASSERT(i,"NoSuchElem"); return displ(i, list+1)/attrDescr[elem->type].size; } /* information */ int ObjListCard(void* obj) { ATTRv* elem; ListAttr* list; if (ObjListInfo(obj, &elem, &list)) return displ(list->tail, list+1)/attrDescr[elem->type].size; else return 0; } BOOL ObjListInfo(void* obj, ATTRp* elem, struct ListAttr** list) { ATTRv* fixed=ObjClass(obj)->fixed; if (fixed->type==-1) return FALSE; *list=offset(obj, fixed->offs, ListAttr*); lastAttr=*elem=fixed; return TRUE; } typedef struct IntList { int num; int size; int arr[1]; } IntList; typedef struct STRvList { int num; int size; STRv arr[1]; } STRvList; typedef struct OBJvList { int num; void* end; OBJv arr[1]; } OBJvList; else return 0; } BOOL ObjListInfo(void* srs/src/blub.h #define _OBJ_H #include "strv.h" #include "dict.h" /**************************************************** ** BASIC ATTRIBUTE TYPE DEFINITIONS ****************************************************/ typedef enum AttrTypeId { ATTR_int, ATTR_PTR, ATTR_STRv, ATTR_OBJv, ATTR_ListAttr, ATTR_CLASSBODYv, ATTR_ATTRv, ATTR_UNDEF } AttrTypeId; typedef struct ATTRoDescr { STRv name; int size; } ATTRoDescr; extern ATTRoDescr attrDescr[]; /* pre-defined attribute types */ typedef void* PTR; typedef struct CLASSo* CLASSv; typedef struct PATHo* PATHv; typedef void* REF; typedef int AttrIter; typedef struct ListAttr { BYTE* tail; BYTE* end; } ListAttr; typedef struct ATTRv { STRv name; AttrTypeId type; /* int num; *//* 0=list obj, 1=single attr, >=2 array */ void* more; int offs; } ATTRv, *ATTRp; typedef struct CLASSBODYv { CLASSv inherits; ATTRv* fixed; DICTv byName; DICTv values; } CLASSBODYv; /* pre-defined object types */ typedef struct OBJo { int usage; CLASSv descr; } OBJo, *OBJv; typedef struct CLASSo { OBJo head; CLASSv inherits; ATTRv* fixed; DICTv byName; DICTv values; /* ATTRv list, open */ ListAttr list; ATTRv attrs[10]; } CLASSo; typedef void (*AttrAction) (void* attr, ATTRp a, void* more); typedef BOOL (*AttrCondition) (void* attr, ATTRp a, void* more); /* pre-defined objects */ extern void* Object; extern void* Class; /* system definition mngm */ typedef struct SYSoName { STRv name; void* val; int id; } SYSoName; void SysInclude(SYSoName* list); int SysIdNum(); void SysName(STRv name,void* val); void SysForgetName(STRv name); void** SysFromName(STRv name); void** SysFromId(int id); STRv SysToName(void* val); int SysToId(void* val); void ObjInit(); /* object operations */ #define _getObj(val) ((OBJv)(val)) void* ObjCpy(void* obj); void ObjDel(void* obj); void ObjSet(void** dest, void* src); void* ObjChangeImpl(void** obj); #define ObjChange(valPtr,type) ((type)ObjChangeImpl((void**)valPtr)) void ObjMakeClass(void* obj, STRv name); /* object information */ int ObjShared(void* obj); int ObjSize(OBJv obj); /* attribute operations */ void* ObjAttrNewImpl (void** obj, STRv name, int type, void* more); #define ObjAttrNew(valPtr,name,type) (*(type*)ObjAttrNewImpl((void**)valPtr,name,ATTR_##type,NULL)) #define ObjAttrNewRef(valPtr,name,refType) (*(refType*)ObjAttrNewImpl((void**)valPtr,name,ATTR_OBJv,NULL)) ATTRp ObjAttrInfo(void* obj, AttrIter i); /* attribute access */ void* ObjAttrInImpl(void* obj, AttrIter i); void* ObjAttrImpl(void* obj, STRv name, int type); #define ObjAttrIn(obj, iter, type) (*(type*)ObjAttrInImpl(obj, iter)) #define ObjAttr(obj, name, type) (*(type*)ObjAttrImpl(obj, name, ATTR_##type)) /* attribute iteration */ AttrIter ObjAttrWith(void* obj, STRv name); AttrIter ObjAttrFirst(void* obj); void ObjAttrNext(void* obj, AttrIter* i); STRv ObjAttrName(void* obj, AttrIter offs); /* member pointer support */ CLASSv ObjClass(void* obj); AttrIter ClassAttrWith(CLASSv descr, STRv name, ATTRp* attr); AttrIter ClassAttrFirst(CLASSv descr); void ClassAttrNext(CLASSv descr, AttrIter* i); /* list operations */ void* ObjListNewImpl(void** obj, int dim, int type, void* more); void* ObjListAddImpl(void** obj, Iter pos, int numAdd); void* ObjListAppImpl(void** obj, int num); void* ObjListInsImpl(void** obj, int num); void ObjListCut (void** obj, Iter pos, int numRem); void ObjListGrow (void** obj, int num); #define ObjListNew(valPtr,dim,type) (*(type*)ObjListNewImpl((void**)valPtr,dim,ATTR_##type,NULL)) #define ObjListApp(valPtr,type) (*(type*)ObjListAppImpl((void**)valPtr,1)) #define ObjListIns(valPtr,type) (*(type*)ObjListInsImpl((void**)valPtr,1)) #define ObjListAdd(valPtr,pos,type) (*(type*)ObjListAddImpl((void**)valPtr,pos,1)) #define ObjListAppMany(valPtr,num, type) (*(type*)ObjListAppImpl((void**)valPtr,num)) #define ObjListInsMany(valPtr,num, type) (*(type*)ObjListInsImpl((void**)valPtr,num)) #define ObjListAddMany(valPtr,pos, num, type) (*(type*)ObjListAddImpl((void**)valPtr,pos,num)) /* list access */ void* ObjListInImpl(Iter i); #define ObjListAt(obj, pos, type) ObjListIn(ObjListWith(obj, pos), type) #define ObjListIn(iter, type) (*(type*)ObjListInImpl(iter)) /* list iteration */ Iter ObjListFirst(void* obj); void ObjListNext(void* obj, Iter* i); Iter ObjListLast(void* obj); void ObjListPrev(void* obj, Iter* i); /* id conversions */ Iter ObjListWith(void* obj, int pos); int ObjListPos(void* obj, Iter pos); AttrIter ObjListAttr(void* obj, Iter pos); Iter ObjListWithAttr(void* obj, AttrIter a); /* information */ int ObjListCard(void* obj); BOOL ObjListInfo(void* obj, ATTRp* elem, struct ListAttr** list); /* services */ void ObjPrint(void* obj); void ObjScan(void* obj); BOOL ObjEqual(void* obj1, void* obj2); UINT4 ObjHash1(void* obj); int ObjHash(void* obj,int max); void ObjDebug(void* obj); /* dictionary services */ /* action dispatchers */ void ObjDoAttr(void* obj, AttrAction act, void* info); void ObjDoInList(void* obj, AttrAction act, ATTRp elem, void* info, void* from, void* to); void ObjDoInListReverse(void* obj, AttrAction act, ATTRp elem, void* info, void* from, void* to); void ObjDoList(void* obj, AttrAction act, void* info); void ObjDoAll(void* obj, AttrAction act, void* info); /* predefined actions */ void AttrCopyAction(void* attr, ATTRp a, void* copyOffs); void AttrMoveAction(void* attr, ATTRp a, void* moveOffs); void AttrDelAction(void* attr, ATTRp a, void* nothing); void AttrHashAction(void* attr, ATTRp a, void* hashVal); BOOL AttrEqualCond(void* attr, ATTRp a, void* compOffs); /* exported polymorphic functions */ void PolyNotImpl(); void PolyNothing(); #endif bjDoList(void* obj, AttrAction act, void* info); void ObjDoAll(void* obj, AttrAction act, void* info); /* predefined actions */ void AttrCopyAction(void* attr, ATTRp a, void* copyOffs); void AttrMoveAction(void* attr, ATTRp a, srs/src/bnf2c.c ** ** $RCSfile: bnf2c.c,v $ ** $Revision: 1.9 $ ** $Date: 1997/03/19 11:17:25 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** */ #include #include #include #include #include "message.h" #include "regexp.h" #include "futil.h" #include "templ.h" #include "sm.h" #include "lst.h" #include "par.h" #include "strv.h" #include "dict.h" #include "variable.h" #include "toklist.h" #include "cursor.h" #include "icatask.h" #include "icarus.h" #include "icaarg.h" #include "icabnf.h" #define i2cNodeClassNum 9 #define _PrintClose(x) { \ char *p; \ p = strrchr(BuffGetPtr(x), ','); \ if(p) { \ *p = ' '; \ p = BuffGetPtr(x); \ BuffPrintF(x, "};\n\n"); \ TemplPrint("str", p); \ } \ } (void *)NULL typedef struct I2CoNode { void *ptr; INT4 index; INT4 exeIndex[3]; } I2CoNode, *I2CpNode; CLASSoDICT nodeDictClass = { PolyPtrEqual, PolyPtrHash, (KeyAccessor)KeyOffset, NULL, FALSE }; static char s1[999]; static char s2[999]; static char s3[999]; static DICTv i2cNodeDict; static I2CpNode i2cNode; static INT4 i2cNodeCount[i2cNodeClassNum]; static SMpBUFF i2cNodeBuff[i2cNodeClassNum], i2cVarBuff, i2cScopeNameBuff, i2cTermReportBuff, i2cChoiceSetBuff; extern ICAoJOB *Job; /****** I2cPrintVar ***************************************************** ** */ static INT4 I2cPrintVar(VARo *var) { static INT4 i2cVarCount=-1; if(var) { BuffPrintF(i2cVarBuff, TemplSPrint(s3, TemplN(12, "format")), I2cBody(var)); return(++i2cVarCount); } else return(-1); } /****** I2cRegisterNode ***************************************************** ** */ static void I2cRegisterNode(BNFoNODE *bnfNode, INT4 level) { I2CpNode *p; INT4 i; /* printf("Name:%s, level=%d\n", bnfNode->name, level); */ p=&DictSet(&i2cNodeDict, &bnfNode, I2CpNode); if(!*p) { if(bnfNode->name) { SmSwapS(bnfNode->name, "\\", "\\\\");/* do this first!*/ SmSwapS(bnfNode->name, "\"", "\\\""); SmSwapS(bnfNode->name, "\n", "\\n"); SmSwapS(bnfNode->name, "\t", "\\t"); } i2cNode = typeAlloc(I2CoNode); i2cNode->ptr = (void *)bnfNode; i2cNode->index = i2cNodeCount[bnfNode->type]++; if(bnfNode->type != Term && bnfNode->type != Choice) for(i=0; i<3; i++) i2cNode->exeIndex[i] = I2cPrintVar(bnfNode->exec[i]); *p=i2cNode; } return; } /****** I2cPrintVarPtr ***************************************************** ** */ static char *I2cPrintVarPtr(INT4 *counter) { static char buff[999]; static char ref[999]; INT4 i; buff[0]='\0'; for(i=0; i<3; i++) { if(*counter == -1) strcat(buff, ", 0"); else { sprintf(ref, ", &%s[%d]", TemplSPrint(s3, TemplN(12, "arrName")), *counter); strcat(buff, ref); } counter++; } return(buff); } /****** I2cPrintNode ***************************************************** ** */ static void I2cPrintNode(BNFoPRODUCTION *node, INT4 level) { I2CoNode *dependNode; INT4 i; i = node->type; i2cNode = DictAt(i2cNodeDict, &node, I2CpNode); switch (i) { case Production: dependNode = DictAt(i2cNodeDict, &(node->node), I2CpNode); BuffPrintF(i2cNodeBuff[i], TemplSPrint(s1, TemplN(i+1, "format")), node->name, I2cPrintVarPtr(i2cNode->exeIndex), TemplSPrint(s2, TemplN(node->node->type+1, "arrName")), dependNode->index); break; case ProdName: dependNode=DictAt(i2cNodeDict,&((BNFoPRODNAME *)node)->production, I2CpNode); BuffPrintF(i2cNodeBuff[i], TemplSPrint(s1, TemplN(i+1, "format")), node->name, I2cPrintVarPtr(i2cNode->exeIndex), TemplSPrint(s2, TemplN(Production+1, "arrName")), dependNode->index); break; case Literal: BuffPrintF(i2cNodeBuff[i], TemplSPrint(s1, TemplN(i+1, "format")), node->name, I2cPrintVarPtr(i2cNode->exeIndex)); break; case Regexp: BuffPrintF(i2cNodeBuff[i], TemplSPrint(s1, TemplN(i+1, "format")), node->name, I2cPrintVarPtr(i2cNode->exeIndex)); break; case Command: case LineStart: BuffPrintF(i2cNodeBuff[i], TemplSPrint(s1, TemplN(i+1, "format")), I2cPrintVarPtr(i2cNode->exeIndex)); break; case Choice: case Term: BuffPrintF(i2cNodeBuff[i], TemplSPrint(s1, TemplN(i+1, "format"))); break; default: break; } } /****** I2cPrintTermReport ************************************************* ** */ static void I2cPrintTermReport(BNFoNODE *node, INT4 level) { BNFoREPORT *report; BNFoNODE *nextNode; switch (node->type) { case Term: report = ((BNFoTERM *)node)->factorList; while( report->node ) { nextNode = report->node; i2cNode = DictAt(i2cNodeDict, &nextNode, I2CpNode); BuffPrintF(i2cTermReportBuff, TemplSPrint(s1, TemplN(10, "format")), report->counter, TemplSPrint(s2, TemplN(nextNode->type+1, "arrName")), i2cNode->index); report++; } BuffPrintF(i2cTermReportBuff, TemplSPrint(s1, TemplN(10, "arrName"))); break; default: break; } } /****** I2cPrintChoiceSet ************************************************* ** */ static void I2cPrintChoiceSet(BNFoNODE *node, INT4 level) { BNFoNODE **termList; BNFoNODE *nextNode; switch (node->type) { case Choice: termList = ((BNFoCHOICE *)node)->termList; while( *termList ) { nextNode = *termList; i2cNode = DictAt(i2cNodeDict, &nextNode, I2CpNode); BuffPrintF(i2cChoiceSetBuff, TemplSPrint(s1, TemplN(11, "format")), TemplSPrint(s2, TemplN(nextNode->type+1, "arrName")), i2cNode->index); termList++; } BuffPrintF(i2cChoiceSetBuff, TemplSPrint(s1, TemplN(11, "arrName"))); break; default: break; } } /*api** I2cBnfGenerator ************************************************* ** ** Take the BNF production list and generate initialization arrays and ** C code to reproduce this list in the computer memory ** ** INPUT: address of production list object [R] ** ** RETURNS: */ void I2cBnfGenerator(VARo *prodList) { VARo *var; TEMPLv template; INT4 i; nodeDictClass.toKeyInfo = mPtr(I2CoNode, ptr); i2cNodeDict = DictCreate(&nodeDictClass); template=TemplOpen("SRSICA:ica2c.it", ParGetStr("ica2cName")); I2cSetTemplate(template); TemplWith(template, "$bnf2c"); TemplPrint("prologue"); TemplWith(template, "node"); for(i=0; iscope->varN; i++) { BuffPrintF(i2cScopeNameBuff, TemplSPrint(s1, TemplN(13, "format")), VarGetName(&Job->scope->var[i])); } for(i=0; iscope->varN); TemplEndWith(); TemplPrint("str", "\n"); _PrintClose(i2cScopeNameBuff); _PrintClose(i2cVarBuff); for(i=2; iscope->varN); TemplEndWith(); TemplPrint("str", "\n"); _PrintClose(i2cScopeNameBuff); _Psrs/src/btree.c char btree_ID[] = "$Id: btree.c,v 1.9 1997/03/18 17:20:17 srs Exp $"; /* ** ** $RCSfile: btree.c,v $ ** $Revision: 1.9 $ ** $Date: 1997/03/18 17:20:17 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.x Copyright by Thure Etzold ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** Requires: ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include "message.h" #include "futil.h" #include "sm.h" #include "tm.h" #include "binpack.h" #include "btree.h" #include "ids.h" #ifdef __ALPHA # define MBCW , "mbc=16" # define MBCR , "mbf=10" , "mbc=16" #else # ifdef VAX # define MBCW , "mbc=16" # define MBCR , "mbf=10" , "mbc=16" # else # define MBCW # define MBCR # endif #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** for encapsulating bucket types as 'objects' */ #ifdef xxx RecordHasher switch (indexCurr->valueType) { case BTRxSTR: case BTRxIDENTRY: p = ((HASHSTROBJ*) obj)->value; len = strlen(p); break; case BTRxNUM: p = (char*) &((HASHNUMOBJ*) obj)->value; len = sizeof(((HASHNUMOBJ*) obj)->value); break; case BTRxREAL: p = (char*) &((HASHREALOBJ*) obj)->value; len = sizeof(((HASHREALOBJ*) obj)->value); break; } for (i=0; i> 24)) ^ g; } return (INT4) h % table->max_hash_elem; RecordPacker case BTRxIDENTRY: _BinPackFip (bucketBuff, record->r.id.textFip); _BinPackFip (bucketBuff, record->r.id.dataFip); _BinPackByte (bucketBuff, record->r.id.fileX); break; case BTRxVALUE: _BinPackFip (bucketBuff, record->r.value.firstIdFip); _BinPackFip (bucketBuff, record->r.value.lastIdFip); _BinPackNum (bucketBuff, record->r.value.idN); break; case BTRxPOINTER: _BinPackFip (bucketBuff, record->r.pointer.downFip); _BinPackNum (bucketBuff, record->r.pointer.downSize); break; RecordCopier switch (record->type) { case BTRxIDENTRY: recordSize = 9; break; case BTRxVALUE: recordSize = 12; break; case BTRxPOINTER: recordSize = 8; break; } RecordUnpacker case BTRxIDENTRY: _BinUnpackFip (bucketBuff, record->r.id.textFip); _BinUnpackFip (bucketBuff, record->r.id.dataFip); _BinUnpackByte (bucketBuff, record->r.id.fileX); break; case BTRxVALUE: _BinUnpackFip (bucketBuff, record->r.value.firstIdFip); _BinUnpackFip (bucketBuff, record->r.value.lastIdFip); _BinUnpackNum (bucketBuff, record->r.value.idN); break; case BTRxPOINTER: _BinUnpackFip (bucketBuff, record->r.pointer.downFip); _BinUnpackNum (bucketBuff, record->r.pointer.downSize); break; RecordComparer switch (indexCurr->valueType) { case BTRxSTR: case BTRxIDENTRY: return strcmp( ((HASHSTROBJ*)obj1)->value, ((HASHSTROBJ*)obj2)->value ); case BTRxNUM: return ((HASHNUMOBJ*)obj1)->value - ((HASHNUMOBJ*)obj2)->value; case BTRxREAL: if ( ((HASHREALOBJ*)obj1)->value < ((HASHREALOBJ*)obj2)->value ) return -1; if ( ((HASHREALOBJ*)obj1)->value > ((HASHREALOBJ*)obj2)->value ) return 1; return 0; } #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** function BTRoComparer */ static Int4 BtrCompareInt (BTRoREC *rec1, BTRoREC *rec2) { return (atoi (rec1->str) - atoi (rec2->str)); } static Int4 BtrCompareStr (BTRoREC *rec1, BTRoREC *rec2) { return SmStrCmp (rec1->str, rec2->str); } static Int4 BtrCompareReal (BTRoREC *rec1, BTRoREC *rec2) { return (atof (rec1->str) - atof (rec2->str)); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** some contants */ #define BTRxMAXLEVEL 2 #define BTRxPTRRECADDSIZ 8 #define BTRxBUCKETADDSIZ 16 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of static functions */ static void BtrWriteInfo (BTRo *btree); static INT4 BtrReadInfo (BTRo *btree); static void BtrFlush (BTRo *btree); static FIP BtrWrite (BTRo *btree, char *buff, INT4 size, INT4 levelN); static BTRoBUCKET *BtrBucketGet (BTRo *btree, enum BtrStep option); static BTRoBUCKET *BtrReadBucket (BTRo *btree, FIP bucketFip, INT4 bucketSize); static FIP BtrGetRecordNumber (BTRo *btree, BTRoBUCKET *bucket, INT4 bucketRecX); static INT4 BtrFixedBucketSize (BTRo *btree, FIP fip); static void BtrSetMethods (BTRo *btree); static void BtrBucketKill (BTRoBUCKET **bucket); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** external or module wide variables */ static BTRo *btreeCurr; /**api* BtrOpen ************************************************************* ** ** Opens a B-tree for various access types. To close it again use ** BtrClose. ** ** INPUT: o address of file name [R] ** o string specifying access type: ** "read", "update", "write", "merge" [R] ** o address of error code [W] or NULL if not wanted
    ** returned values can be
    ** e__filopenerr
    ** e__indexbusy
    ** e__iscompressed ** ** IMPLICIT: ** ** RETURNS: new btree object ** NULL if there is a problem */ BTRo *BtrOpen (char *indexName, char *option, INT4 *errCode) { BTRo *btree; INT4 rv; *errCode = 0; if ((btree = (BTRo *) calloc (1, sizeof (BTRo))) == NULL) _ErrExit2 (e__allocfail, "btree-object"); btree->file = FileNew (indexName); FileSetName (btree->file, "ext", "inx"); FileSetUnixIo (btree->file); switch (tolower (option[0])) { case 'r': /* read */ if (!FileOpen (btree->file)) { _ErrSet (errCode, e__filopenerr); break; } rv = BtrReadInfo (btree); _ErrIf (rv) break; if (btree->isBusy) { _ErrSet (errCode, e__indexisbusy); break; } btree->isFixedRecordSiz = btree->fixedRecordSiz ? 1 : 0; btree->firstBucketFip = btree->levelFip[2]; btree->lastBucketFip = btree->fileSize - btree->lastBucketSize; btree->bucketCurr = NULL; BtrSetMethods (btree); return btree; case 'c': /* compress */ case 'u': /* update */ if (!FileOpen (FileSetUpdate (btree->file))) { _ErrSet (errCode, e__filopenerr); break; } if (_ErrIs (BtrReadInfo (btree))) return NULL; if (btree->isBusy) { _ErrSet (errCode, e__indexisbusy); return NULL; } if (btree->isCompressed && option[0] == 'c') { _ErrExit2 (e__iscompressed, FileGetName (btree->file, "path")); } btree->isFixedRecordSiz = btree->fixedRecordSiz ? 1 : 0; btree->firstBucketFip = btree->levelFip[2]; btree->lastBucketFip = btree->fileSize - btree->lastBucketSize; btree->bucketCurr = NULL; btree->isBusy = 1; btree->levelWriteFip[2] = btree->firstBucketFip; BtrWriteInfo (btree); BtrSetMethods (btree); return btree; case 'm': /* merge */ btree->isCompressed = 1; case 'w': /* write */ if (!FileOpen (FileSetWrite (btree->file))) { _ErrSet (errCode, e__filopenerr); break; } btree->bucketRecordN = 0; btree->isWriteOpen = 1; btree->isBusy = 1; return btree; default: _ErrExit2 (e__unknownoption, option); } return btree; } /**api* BtrClose ************************************************************* ** ** Closes a btree which was opened by BtrOpen. ** ** INPUT: address of B-tree object [R] ** */ void BtrClose (BTRo *btree) { if (btree->isBusy) { if (btree->isWriteOpen) { BtrFlush (btree); btree->fileSize = btree->levelWriteFip[2]; _ErrMsg5 (i__wrotebtree, FileGetName (btree->file, "path"), ((btree->fileSize + 999) / 1000), btree->bucketRecordN, btree->recordN); } btree->isBusy = 0; btree->timeCreated = TimeGet (); BtrWriteInfo (btree); } FileDelete (btree->file); if (btree->bucketCurr) BtrBucketKill (&btree->bucketCurr); free (btree); } /****** BtrBucketNew ********************************************************** ** ** creates a new bucket; ** ** INPUT: address of Btree object [R] ** level number [R] ** ** IMPLICIT: ** ** RETURNS: ** address of new bucket */ static BTRoBUCKET *BtrBucketNew (BTRo *btree, INT4 levelN) { BTRoBUCKET *bucket; INT4 size; if ((bucket = (BTRoBUCKET *) calloc (1, sizeof (BTRoBUCKET))) == NULL) _ErrExit2 (e__allocfail, "bucket"); if ((bucket->record = (BTRoREC *) malloc (btree->bucketRecordN * sizeof (BTRoREC))) == NULL) _ErrExit2 (e__allocfail, "bucket buffer"); size = btree->bucketRecordN * BTRxTMPRECORDSIZ; if ((bucket->bucketBuff = (char *) malloc (size)) == NULL) _ErrExit2 (e__allocfail, "bucket buffer"); bucket->recordN = 0; bucket->up = 0; bucket->writePtr = 0; if (levelN == 2) { bucket->type = btree->leafType; bucket->fixedRecordSize = btree->fixedRecordSiz; } else { bucket->type = BTRxPOINTER; bucket->fixedRecordSize = 0; } return bucket; } /****** BtrBucketKill *********************************************************** ** deletes a bucket ** ** INPUT: address of Btree object [R] ** type of record to be put into bucket [R] ** ** IMPLICIT: ** ** RETURNS: ** address of new bucket */ static void BtrBucketKill (BTRoBUCKET **bucket) { if (*bucket) { if ((*bucket)->record) free ((*bucket)->record); if ((*bucket)->bucketBuff) free ((*bucket)->bucketBuff); free (*bucket); *bucket = NULL; } } /**api* BtrSetType ************************************************************ ** ** Sets the type of a Btree. See also BtrSetNumType. ** ** INPUT: o address of btree object [R] ** o string specifying btree type: ** "ID", "str", "num", "real" [R] ** IMPLICIT: ** ** RETURNS: */ void BtrSetType (BTRo *btree, char *option) { if (btree->type) _ErrExit2 (e__parisdefined, "B-tree type"); switch (tolower (option[0])) { case 'i': BtrSetNumType (btree, BTRxIDENTRY); break; case 's': BtrSetNumType (btree, BTRxSTR); break; case 'n': BtrSetNumType (btree, BTRxNUM); break; case 'r': BtrSetNumType (btree, BTRxREAL); break; default: _ErrExit2 (e__unknownoption, option); } } /**api* BtrSetNumType ********************************************************* ** ** Sets the type of a Btree. Same as BtrSetType but takes type number ** instead of the name ** ** INPUT: btree object [W] ** type number [R] */ void BtrSetNumType (BTRo *btree, Int4 type) { if (btree->type) _ErrExit2 (e__parisdefined, "B-tree type"); switch (type) { case BTRxIDENTRY: btree->leafType = BTRxID; btree->isFixedRecordSiz = 1; btree->recordSiz = 9; break; case BTRxSTR: btree->leafType = BTRxVALUE; btree->recordSiz = 12; btree->compare = BtrCompareStr; break; case BTRxNUM: btree->leafType = BTRxVALUE; btree->recordSiz = 12; btree->compare = BtrCompareInt; break; case BTRxREAL: btree->leafType = BTRxVALUE; btree->recordSiz = 12; btree->compare = BtrCompareReal; break; default: _ErrExit2 (e__unknownoption, type); } btree->type = type; BtrSetMethods (btree); } static void BtrSetMethods (BTRo *btree) { switch (btree->type) { case BTRxIDENTRY: break; case BTRxSTR: btree->compare = BtrCompareStr; break; case BTRxNUM: btree->compare = BtrCompareInt; break; case BTRxREAL: btree->compare = BtrCompareReal; break; default: _ErrExit2 (e__unknownoption, btree->type); } } /****** BtrWrite ************************************************************** ** ** writes a buffer to a file and returns its file offset; ** ** INPUT: o address of Btree object [R] ** o buffer [R] or NULL ** o size of bucket buffer [R] ** o level number (0,1,2 and -1 for info block) [R] ** IMPLICIT: ** ** RETURNS: file pointer to data written out */ static FIP BtrWrite (BTRo *btree, char *buff, INT4 size, INT4 levelN) { #define BTRxTMPBUFSIZ 20000 char tmp[BTRxTMPBUFSIZ]; long writeFip; INT4 sizeWritten; /* ** go to appropriate file offset */ if (levelN == -1) FileSeek (btree->file, 0); else { FileSeek (btree->file, btree->levelWriteFip[levelN]); } /* ** if buffer address is NULL write junk of specified size to file */ if (!buff) { for (sizeWritten=0; sizeWritten + BTRxTMPBUFSIZ <= size; sizeWritten += BTRxTMPBUFSIZ) FileWrite (btree->file, tmp, BTRxTMPBUFSIZ); FileWrite (btree->file, tmp, size - sizeWritten); } else FileWrite (btree->file, buff, size); /* ** and go back to previous location - assumed to be the end of file */ if (levelN < BTRxMAXLEVEL) FileSeekEnd (btree->file, 0); if (levelN == -1) return 0; else { writeFip = btree->levelWriteFip[levelN]; btree->levelWriteFip[levelN] += size; return writeFip; } } /****** BtrCopyRecord ********************************************************* ** ** copies a record into the appropriate position in the bucket ** ** INPUT: address of bucket object [W] ** address of record [R] ** IMPLICIT: ** btreeCurr (BTRo *) [R] ** ** RETURNS: ** the number of new record within bucket */ static INT4 BtrCopyRecord (BTRoBUCKET *bucket, BTRoREC *record) { BTRoREC *outrecord; INT4 recordSize; switch (record->type) { case BTRxIDENTRY: recordSize = 9; break; case BTRxVALUE: recordSize = 12; break; case BTRxPOINTER: recordSize = 8; break; } if (!bucket->writePtr) { bucket->writePtr = bucket->bucketBuff + (bucket->fixedRecordSize ? 0 : BTRxBUCKETADDSIZ); } bucket->writePtr += recordSize; outrecord = &bucket->record[bucket->recordN++]; memcpy (outrecord, record, sizeof (BTRoREC)); outrecord->str = bucket->writePtr; strcpy (outrecord->str, record->str); bucket->writePtr += bucket->fixedRecordSize ? btreeCurr->maxStrSiz : strlen (record->str) + 1; return bucket->recordN; } /****** BtrWriteInfo ********************************************************** ** ** writes an info block to the beginning of the file; ** ** INPUT: address of B-tree object [R] ** IMPLICIT: ** ** RETURNS: */ static void BtrWriteInfo (BTRo *btree) { char *buff = btree->infoBuff; char *buffSave = buff; INT4 buffSize; _BinPackNum (buff, BTRxINFOSIZE); _BinPackNum (buff, BTRxCURRENT_VERSION); /* version number */ _BinPackFip (buff, btree->writeFip); _BinPackFip (buff, btree->levelFip[0]); _BinPackFip (buff, btree->levelFip[1]); _BinPackFip (buff, btree->levelFip[2]); _BinPackFip (buff, btree->rootSize); _BinPackFip (buff, btree->firstBucketSize); _BinPackFip (buff, btree->lastBucketSize); _BinPackNum (buff, btree->leafType); _BinPackNum (buff, btree->type); _BinPackNum (buff, btree->bucketRecordN); _BinPackNum (buff, btree->recordN); _BinPackNum (buff, btree->fileSize); _BinPackNum (buff, btree->fixedRecordSiz); _BinPackNum (buff, btree->maxStrSiz); _BinPackNum (buff, btree->timeCreated); _BinPackByte (buff, btree->isCompressed); _BinPackByte (buff, btree->isBusy); _BinPackNum (buff, 0); /* dummies for later use */ _BinPackNum (buff, 0); _BinPackNum (buff, 0); _BinPackNum (buff, 0); _BinPackNum (buff, 0); FileSeek (btree->file, 0); buffSize = buff - buffSave; /* ** info block is written twice to the file ...once just after opening ** the index for writing (busy flag set to 1) and again just befor the ** index is closed; */ if (!btree->writeFip) BtrWrite (btree, buffSave, buffSize, -1); else FileWrite (btree->file, buffSave, buffSize); } /****** BtrReadInfo *********************************************************** ** ** Reads and unpacks info block of btree; ** ** INPUT: address of B-tree object [R] ** IMPLICIT: ** ** RETURNS: 1 if OK ** e__indexwrongversion + */ static INT4 BtrReadInfo (BTRo *btree) { char *buff = btree->infoBuff; INT4 tmp; FileSeek (btree->file, 0); FileRead (btree->file, buff, BTRxINFOSIZE); if (FileIsEof (btree->file)) return e__filnotok; _BinUnpackNum (buff, btree->infoSize); _BinUnpackNum (buff, btree->versionN); if (btree->versionN != BTRxCURRENT_VERSION) _ErrRet4 (e__indexwrongversion, FileGetName (btree->file, "path"), btree->versionN, BTRxCURRENT_VERSION); _BinUnpackFip (buff, btree->writeFip); _BinUnpackFip (buff, btree->levelFip[0]); _BinUnpackFip (buff, btree->levelFip[1]); _BinUnpackFip (buff, btree->levelFip[2]); _BinUnpackFip (buff, btree->rootSize); _BinUnpackFip (buff, btree->firstBucketSize); _BinUnpackFip (buff, btree->lastBucketSize); _BinUnpackNum (buff, tmp); btree->leafType = (enum recType) tmp; _BinUnpackNum (buff, tmp); btree->type = (enum btrType) tmp; _BinUnpackNum (buff, btree->bucketRecordN); _BinUnpackNum (buff, btree->recordN); _BinUnpackNum (buff, btree->fileSize); _BinUnpackNum (buff, btree->fixedRecordSiz); _BinUnpackNum (buff, btree->maxStrSiz); _BinUnpackNum (buff, btree->timeCreated); _BinUnpackByte (buff, btree->isCompressed); _BinUnpackByte (buff, btree->isBusy); btree->rootFip = btree->levelFip[0]; return 1; } /****** BtrBucketPack *********************************************************** ** ** packs a bucket into platform independent format; ** ** INPUT: btree object [R] ** address of bucket object [R] ** IMPLICIT: ** ** RETURNS: ** size of bucket in bytes */ static INT4 BtrBucketPack (BTRo *btree, BTRoBUCKET *bucket) { BTRoREC *record; char *bucketBuff = bucket->bucketBuff; char *bucketBuffSave = bucketBuff; INT4 k; if (!bucket->fixedRecordSize) { _BinPackNum (bucketBuff, bucket->bucketSize); _BinPackNum (bucketBuff, bucket->prevBucketSize); _BinPackNum (bucketBuff, bucket->type); _BinPackNum (bucketBuff, bucket->recordN); } for (k=0; k < bucket->recordN; k++) { record = &bucket->record[k]; switch (bucket->type) { case BTRxIDENTRY: _BinPackFip (bucketBuff, record->r.id.textFip); _BinPackFip (bucketBuff, record->r.id.dataFip); _BinPackByte (bucketBuff, record->r.id.fileX); break; case BTRxVALUE: _BinPackFip (bucketBuff, record->r.value.firstIdFip); _BinPackFip (bucketBuff, record->r.value.lastIdFip); _BinPackNum (bucketBuff, record->r.value.idN); break; case BTRxPOINTER: _BinPackFip (bucketBuff, record->r.pointer.downFip); _BinPackNum (bucketBuff, record->r.pointer.downSize); break; } bucketBuff += bucket->fixedRecordSize ? btree->maxStrSiz : strlen (bucketBuff) + 1; } bucket->bucketSize = bucketBuff - bucketBuffSave; if (!bucket->fixedRecordSize) _BinPackNum (bucketBuffSave, bucket->bucketSize); /* to page begin */ return bucket->bucketSize; } /****** BtrBucketUnpack ********************************************************* ** ** unpacks a bucket from platform independent format; if readSize ** is by 4 bytes greater the actual bucket size then it reads the ** first four bytes of the next bucket with its size; ** ** INPUT: btree object [R] ** address of bucket object [R] ** IMPLICIT: ** ** RETURNS: ** size of bucket in bytes */ static void BtrBucketUnpack (BTRo *btree, BTRoBUCKET *bucket, INT4 readSize) { BTRoREC *record; char *bucketBuff = bucket->bucketBuff; INT4 k, tmp; if (!bucket->fixedRecordSize) { _BinUnpackNum (bucketBuff, bucket->bucketSize); _BinUnpackNum (bucketBuff, bucket->prevBucketSize); _BinUnpackNum (bucketBuff, tmp); bucket->type = (enum recType) tmp; _BinUnpackNum (bucketBuff, bucket->recordN); } else { bucket->type = btree->leafType; bucket->bucketSize = BtrFixedBucketSize (btree, bucket->fip); bucket->recordN = bucket->bucketSize / bucket->fixedRecordSize; bucket->prevBucketSize = btree->firstBucketFip == bucket->fip ? 0 : BtrFixedBucketSize (btree, btree->firstBucketFip); } for (k=0; k < bucket->recordN; k++) { record = &bucket->record[k]; switch (bucket->type) { case BTRxIDENTRY: _BinUnpackFip (bucketBuff, record->r.id.textFip); _BinUnpackFip (bucketBuff, record->r.id.dataFip); _BinUnpackByte (bucketBuff, record->r.id.fileX); break; case BTRxVALUE: _BinUnpackFip (bucketBuff, record->r.value.firstIdFip); _BinUnpackFip (bucketBuff, record->r.value.lastIdFip); _BinUnpackNum (bucketBuff, record->r.value.idN); break; case BTRxPOINTER: _BinUnpackFip (bucketBuff, record->r.pointer.downFip); _BinUnpackNum (bucketBuff, record->r.pointer.downSize); break; } record->str = bucketBuff; bucketBuff += bucket->fixedRecordSize ? btree->maxStrSiz : strlen (bucketBuff) + 1; } if (bucket->fip == btree->lastBucketFip) bucket->nextBucketSize = 0; else if (bucket->fixedRecordSize) bucket->nextBucketSize = BtrFixedBucketSize (btree, bucket->fip + bucket->bucketSize); else _BinUnpackNum (bucketBuff, bucket->nextBucketSize); } /****** BtrBucketInsertRecord *************************************************** ** ** inserts a record into bucket - recursive! ** ** INPUT: address of btree object [R] ** pointer to address of bucket object [W] ** address of record to be inserted [R] ** IMPLICIT: ** ** RETURNS: */ static void BtrBucketInsertRecord (BTRo *btree, BTRoBUCKET **bucketPtr, BTRoREC *record, INT4 levelN) { BTRoBUCKET *newbucket, *bucket = *bucketPtr; BTRoREC ptrrec; char stringBuff[133]; if (levelN < 0) return; /* ** if bucket == NULL it is assumed that the bucket is the new root bucket ** the first bucket of each ** level becomes the root ..since the tree grows from leafs to root ...the ** first bucket of the highest level will finally be the root */ if (!bucket) { bucket = BtrBucketNew (btree, levelN); btree->root = bucket; *bucketPtr = bucket; } /* ** if the bucket is full now, it can be written out ** ....a pointer to the bucket must be created and inserted in the upper ** level (recursive procedure) ** ... then a new empty bucket must be created */ if (BtrCopyRecord (bucket, record) == btree->bucketRecordN) { ptrrec.type = BTRxPOINTER; bucket->bucketSize = ptrrec.r.pointer.downSize = BtrBucketPack (btree, bucket); if (levelN == 2) { /* record bucket size of first and last */ if (bucket == btree->root) /* first in level 2 */ btree->firstBucketSize = bucket->bucketSize; else btree->lastBucketSize = bucket->bucketSize; } ptrrec.r.pointer.downFip = BtrWrite (btree,bucket->bucketBuff, bucket->bucketSize, levelN); ptrrec.str = stringBuff; strcpy (ptrrec.str, record->str); newbucket = BtrBucketNew (btree, levelN); newbucket->prevBucketSize = bucket->bucketSize; newbucket->up = bucket->up; newbucket->type = record->type; BtrBucketKill (&bucket); /* old bucket can now be deleted */ BtrBucketInsertRecord (btree, &newbucket->up, &ptrrec, levelN-1); *bucketPtr = newbucket; } } /****** BtrFlush ************************************************************** ** ** writes all buckets that exist in memory to file proceeds from leaves to ** root; ** ** INPUT: address of Btree object [R] ** IMPLICIT: ** ** RETURNS: */ static void BtrFlush (BTRo *btree) { BTRoBUCKET *bucket, *nextbucket; BTRoREC ptrrec, *record; char stringBuff[133]; INT4 level; if (!(bucket = btree->bucket)) return; for (level=2; level >= 0; level--) { /* ** if bucket contains any records then the last record must be inserted ** one level above as a pointer to the bucket; */ if (bucket->recordN || bucket->bucketSize == 1) { ptrrec.type = BTRxPOINTER; bucket->bucketSize = ptrrec.r.pointer.downSize = BtrBucketPack (btree, bucket); if (level == 2) btree->lastBucketSize = bucket->bucketSize; ptrrec.r.pointer.downFip = BtrWrite (btree, bucket->bucketBuff, bucket->bucketSize, level); record = &bucket->record[bucket->recordN-1]; /** last record in bucket*/ ptrrec.str = stringBuff; strcpy (ptrrec.str, record->str); if (level == 0) /** root level is reached */ break; BtrBucketInsertRecord (btree, &bucket->up, &ptrrec, level-1); } nextbucket = bucket->up; BtrBucketKill (&bucket); bucket = nextbucket; } btree->rootSize = btree->root->bucketSize; if (bucket == btree->root) BtrBucketKill (&bucket); } /****** BtrReadBucket ********************************************************* ** ** reads a bucket from Btree; ** ** INPUT: address of Btree object [W] ** file pointer to bucket [R] ** size of bucket in bytes [R] ** IMPLICIT: ** ** RETURNS: */ static BTRoBUCKET *BtrReadBucket (BTRo *btree, FIP bucketFip, INT4 bucketSize) { BTRoBUCKET *bucket; INT4 size; /* ** get a bucket object */ bucket = BtrBucketNew (btree, bucketFip >= btree->firstBucketFip ? 2 : 0); bucket->fip = bucketFip; /* ** read from file and unpack bucket */ FileSeek (btree->file, bucketFip); /* ** try to read the bucket + the first 4 bytes of the next bucket that ** specifies its size ...this can be used for traversing a level */ size = bucketSize + (btree->isFixedRecordSiz ? 0 : 4); FileRead (btree->file, bucket->bucketBuff, size); BtrBucketUnpack (btree, bucket, size); return bucket; } /**api* BtrSearch ************************************************************* ** ** searches a value in btree; string comparison is case insensitive ** ** INPUT: btree object [R] ** string value [R] ** address of record ID [W] or NULL ** comparison length [R] or 0 ** ** IMPLICIT: ** ** RETURNS: pointer to found record or NULL */ BTRoREC *BtrSearch (BTRo *btree, char *str, FIP *recNPtr, INT4 cmpLen) { BTRoBUCKET *bucket=btree->bucketCurr; BTRoREC *recordCurr; FIP bucketFip = btree->rootFip; INT4 bucketSize = btree->rootSize, k, l; double cmp; double searchval = 0; if (recNPtr) *recNPtr = 0; /*PURIFY*/ if (bucket) { BtrBucketKill (&bucket); btree->bucketCurr = NULL; } if (btree->type == BTRxNUM) searchval = atoi(str); if (btree->type == BTRxREAL) searchval = atof(str); for (k=0; k < 3; k++) { bucket = BtrReadBucket (btree, bucketFip, bucketSize); for (l=0; l < bucket->recordN; l++) { recordCurr = &bucket->record[l]; /* ** goto lower level bucket if current record's value is equal or lesser */ switch (btree->type) { case BTRxNUM: cmp = searchval - atoi(recordCurr->str); break; case BTRxREAL: cmp = searchval - atof(recordCurr->str); break; default: cmp = (cmpLen) ? SmStrCmpLen (str, recordCurr->str, cmpLen) : SmStrCmp (str, recordCurr->str); } if (cmp <= 0) { if (bucket->type != BTRxPOINTER) { /* ** if found then save the record number and the context ** and return ...don't delete the bucket */ if (bucket->type == BTRxID && recNPtr) *recNPtr = BtrGetRecordNumber (btree, bucket, l); btree->bucketCurr = bucket; bucket->recordXCurr = l; recordCurr->type = btree->leafType; return (cmp == 0) ? recordCurr : NULL; } else { bucketFip = recordCurr->r.pointer.downFip; bucketSize = recordCurr->r.pointer.downSize; break; } } } BtrBucketKill (&bucket); btree->bucketCurr = NULL; if (cmp > 0) { /* value is even greater than last string ...no hope! */ return NULL; } } return recordCurr; } /**api* BtrIsSearchGreaterMaxVal ********************************************** ** ** Returns 1 if value from previous search exceeded the max value in ** index; ** ** INPUT: o btree object [R] ** IMPLICIT: ** ** RETURNS: pointer to found record or NULL */ INT4 BtrIsSearchGreaterMaxVal (BTRo *btree) { return btree->bucketCurr ? 0 : 1; } /**api* BtrIsSearchLessMinVal *********************************************** ** ** Returns 1 if value from previous search is below the min value in ** index; Use only after unsuccessful search. ** ** INPUT: o btree object [R] ** IMPLICIT: ** ** RETURNS: pointer to found record or NULL */ INT4 BtrIsSearchLessMinVal (BTRo *btree) { return (btree->bucketCurr->fip == btree->firstBucketFip) && (btree->bucketCurr->recordXCurr == 0) ? 1 : 0; } /**api* BtrSearchId *********************************************************** ** ** searches a string value in btree; ** ** INPUT: o btree object [R] ** o string value [R] ** IMPLICIT: ** ** RETURNS: pointer to found record or NULL */ BTRoID *BtrSearchId (BTRo *btree, char *str, FIP *fip) { BTRoREC *record; if (!(record = BtrSearch (btree, str, fip, 0))) return NULL; return &(record->r.id); } /**api* BtrSearchStr ********************************************************** ** ** searches a string value in btree; ** ** INPUT: o btree object [R] ** o string value [R] ** IMPLICIT: ** ** RETURNS: pointer to found record or NULL */ BTRoVALUE *BtrSearchStr (BTRo *btree, char *str) { BTRoREC *record; if (!(record = BtrSearch (btree, str, NULL, 0))) return NULL; return &(record->r.value); } /**api* BtrSearchNum ********************************************************** ** ** searches a num (integer) value in btree; ** ** INPUT: o btree object [R] ** o num value [R] ** IMPLICIT: ** ** RETURNS: pointer to found record or NULL */ BTRoVALUE *BtrSearchNum (BTRo *btree, INT4 num) { BTRoREC *record; char str[20]; sprintf(str, "%d", num); if (!(record = BtrSearch (btree, str, NULL, 0))) return NULL; return &(record->r.value); } /**api* BtrSearchReal ******************************************************* ** ** searches a real (double) value in btree; ** ** INPUT: o btree object [R] ** o real value [R] ** IMPLICIT: ** ** RETURNS: pointer to found record or NULL */ BTRoVALUE *BtrSearchReal (BTRo *btree, double real) { BTRoREC *record; char str[20]; sprintf(str, "%18.6f", real); if (!(record = BtrSearch (btree, str, NULL, 0))) return NULL; return &(record->r.value); } /****** BtrGetRecordNumber **************************************************** ** ** searches a string value in btree; ** ** INPUT: btree object [R] ** bucket object [R] ** index of record in bucket [R] ** IMPLICIT: ** ** RETURNS: number of record within the whole btree */ static FIP BtrGetRecordNumber (BTRo *btree, BTRoBUCKET *bucket, INT4 bucketRecX) { return (bucket->fip + (bucketRecX+1) * btree->fixedRecordSiz - btree->firstBucketFip) / btree->fixedRecordSiz; } /**api* BtrBuildStartPhase1 *************************************************** ** ** Initializes building phase 1.
    ** ** INPUT: address of Btree object [W] ** number of records to be inserted [R] ** IMPLICIT: ** ** RETURNS: */ void BtrBuildStartPhase1 (BTRo *btree, INT4 recordN) { INT4 k, bucketRecordN; if (!btree->isWriteOpen) _ErrExit2 (e__notwriteopen, FileGetName (btree->file, "path")); if (!btree->type) _ErrExit2 (e__parnotdefined, "B-tree type"); /* ** calculate the bucket size ... the btree must have three ** levels so the calculation is: bucketsize^3 > no of values */ if (recordN == 1) bucketRecordN = 1; /* k*k*k >= recordN should also work now ...*/ else for (k=0; k < 1000; k += k<10 ? 1 : 10) if (k*k*k > recordN) { bucketRecordN = k; break; } btree->bucketRecordN = bucketRecordN; btree->buildPhase = 1; btree->isBuildPhaseInit = 0; btreeCurr = btree; } /**api* BtrBuildStartPhase2 ********************************************** ** ** initializes building phase 2; ** ** INPUT: address of Btree object [W] ** IMPLICIT: ** ** RETURNS: */ void BtrBuildStartPhase2 () { if (btreeCurr->buildPhase != 1) _ErrExit2 (e__btreenotprep, 2); btreeCurr->buildPhase = 2; btreeCurr->isBuildPhaseInit = 0; } /**api* BtrInsertValue *************************************************** ** ** ** INPUT: address of Btree object [W] ** file pointer to bucket [R] ** size of bucket in bytes [R] ** IMPLICIT: ** btreeCurr [W] ** ** RETURNS: */ void BtrInsertRecord (BTRoREC *record) { static INT4 bucketRecordN, levelFip[3], recordCnt[3], strSiz; switch (btreeCurr->buildPhase) { /* ** phase I calculates the size of all records of all three levels */ case 1: if (!btreeCurr->isBuildPhaseInit) { /* init counters at begin */ btreeCurr->isBuildPhaseInit = 1; bucketRecordN = btreeCurr->bucketRecordN; levelFip[0] = levelFip[1] = levelFip[2] = 0; recordCnt[0] = recordCnt[1] = recordCnt[2] = 0; btreeCurr->maxStrSiz = 0; } /* ** add record string length and level specific record size to overall ** level size ....if record is last in bucket then do the same in uppper ** level */ strSiz = strlen (record->str) + 1; if (strSiz > btreeCurr->maxStrSiz) btreeCurr->maxStrSiz = strSiz; recordCnt[2]++; /* level 2 */ if (!(recordCnt[2] % bucketRecordN)) { recordCnt[1]++; /* level 1 */ levelFip[2] += strSiz + BTRxPTRRECADDSIZ; if (!(recordCnt[1] % bucketRecordN)) { recordCnt[0]++; /* level 0 - root bucket */ levelFip[1] += strSiz + BTRxPTRRECADDSIZ; } } break; case 2: if (!btreeCurr->isBuildPhaseInit) { btreeCurr->isBuildPhaseInit = 1; if (btreeCurr->isFixedRecordSiz) btreeCurr->fixedRecordSiz = btreeCurr->recordSiz + btreeCurr->maxStrSiz; else btreeCurr->fixedRecordSiz = 0; /* ** if the last record counted in phase one is not at the end(level II) ** of bucket then it must be entered in levels I and 0 */ btreeCurr->recordN = recordCnt[2]; { int isAddedToLevel2 = 0; if (recordCnt[2] % bucketRecordN) { recordCnt[1]++; levelFip[2] += strSiz + BTRxPTRRECADDSIZ; isAddedToLevel2 = 1; } if (recordCnt[1] % bucketRecordN || isAddedToLevel2) { recordCnt[0]++; levelFip[1] += strSiz + BTRxPTRRECADDSIZ; } } /* ** now, to get the sizes of the levels right the size of the ** extra information per bucket must be added */ levelFip[1] += BTRxBUCKETADDSIZ; /* only 1 bucket in level 0 */ levelFip[2] += ((recordCnt[1] + bucketRecordN-1) / bucketRecordN) * BTRxBUCKETADDSIZ; /* ** finally we can give for each level the offset within the output ** file (..offset for level 0 is directly after the btree-info-block) */ levelFip[0] = BTRxINFOSIZE; btreeCurr->levelFip[0] = btreeCurr->levelWriteFip[0] = levelFip[0]; btreeCurr->levelFip[1] = btreeCurr->levelWriteFip[1] = levelFip[0] + levelFip[1]; btreeCurr->levelFip[2] = btreeCurr->levelWriteFip[2] = levelFip[0] + levelFip[1] + levelFip[2]; /* ** reserve some space for all internal nodes in levels 0 and 1 ** this is done by writing some junk to the file */ BtrWrite (btreeCurr, NULL, btreeCurr->levelFip[2], -1); BtrWriteInfo (btreeCurr); btreeCurr->bucket = NULL; } BtrBucketInsertRecord (btreeCurr, &btreeCurr->bucket, record, 2); break; default: _ErrExit2 (e__btreenotprep, 1); } } /**api* BtrCompress *********************************************************** ** ** compress an btree, that is it's associated ID-list file; ** ** INPUT: address of Btree object [W] ** IMPLICIT: ** ** RETURNS: */ void BtrCompress (char *fileName) { IDSoFILE *idsFile; BTRoBUCKET *bucket; BTRo *btree; BTRoREC *record; INT4 opt, idN, errCode, k=0; btree = BtrOpen (fileName, "compress", &errCode); _ErrExit2 (errCode, FileGetName (btree->file, "path")); if (!(idsFile = IdsOpen (fileName, "compress", 512, NULL, &errCode))) _ErrExit2 (errCode, fileName); if (btree->recordN) { btree->levelWriteFip[2] = btree->firstBucketFip; for (opt=BTRxFIRST; (record = BtrRecordGet (btree, opt)); opt=BTRxNEXT) { k++; idN = IdsCompress (idsFile, &record->r.value.firstIdFip); record->r.value.lastIdFip = record->r.value.firstIdFip; if (idN != record->r.value.idN) printf ("old: %d, new: %d\n", record->r.value.idN, idN); bucket = btree->bucketCurr; if (bucket->recordXCurr == bucket->recordN - 1) { BtrBucketPack (btree, bucket); BtrWrite (btree, bucket->bucketBuff, bucket->bucketSize, 2); } } } IdsClose (idsFile); btree->isCompressed = 1; BtrClose (btree); } /**api* BtrTouch ************************************************************** ** ** sets the internal index time to current time; ** ** INPUT: address of Btree object [W] ** IMPLICIT: ** ** RETURNS: */ void BtrTouch (char *fileName) { BTRo *btree; INT4 errCode; btree = BtrOpen (fileName, "update", &errCode); _ErrExit2 (errCode, FileGetName (btree->file, "path")); btree->timeCreated = TimeGet (); BtrClose (btree); } /****** BtrFixedBucketSize **************************************************** ** ** calculates the size of a bucket in a btree with fixed record size ** ** INPUT: address of Btree object [W] ** file address of bucket ** IMPLICIT: ** ** RETURNS: bucket size in Bytes */ static INT4 BtrFixedBucketSize (BTRo *btree, FIP fip) { INT4 size; if (!(fip == btree->lastBucketFip)) return (btree->fixedRecordSiz * btree->bucketRecordN); size = ((size = btree->recordN % btree->bucketRecordN) ? size : btree->bucketRecordN) * btree->fixedRecordSiz; return size; } /**api* BtrRecordById ********************************************************* ** ** gets record with specified number; recordId ranges from 0 to ** total no of records - 1; ** ** INPUT: address of Btree object [W] ** IMPLICIT: ** ** RETURNS: pointer to record ** NULL if not found */ BTRoREC *BtrRecordById (BTRo *btree, FIP recordId) { BTRoBUCKET *bucket=btree->bucketCurr; FIP fip; INT4 recordX, bucketSize=btree->fixedRecordSiz * btree->bucketRecordN; recordId--; /* convert number into index */ fip = recordId * btree->fixedRecordSiz; fip = btree->firstBucketFip + (fip / bucketSize) * bucketSize; if (!bucket || bucket->fip != fip) { /* get new bucket */ bucket = BtrReadBucket (btree, fip, BtrFixedBucketSize (btree, fip)); BtrBucketKill (&btree->bucketCurr); btree->bucketCurr = bucket; } recordX = recordId % btree->bucketRecordN; btree->bucketCurr->recordXCurr = recordX; return &btree->bucketCurr->record[recordX]; } /**api* BtrRecordGet ********************************************************** ** ** gets record by specified option; ** ** INPUT: address of Btree object [W] ** location: BTRxFIRST, BTRxLAST, BTRxPREV, BTRxCURR, ** BTRxNEXT [R] ** IMPLICIT: ** ** RETURNS: pointer to record ** NULL if no more records */ BTRoREC *BtrRecordGet (BTRo *btree, enum BtrStep option) { BTRoBUCKET *bucket=btree->bucketCurr; BTRoREC *record; INT4 recordX; if (!btree->recordN) return NULL; switch (option) { case BTRxFIRST: bucket = BtrBucketGet (btree, BTRxFIRST); recordX = 0; break; case BTRxLAST: bucket = BtrBucketGet (btree, BTRxLAST); recordX = bucket->recordN - 1; break; case BTRxPREV: if (bucket->recordXCurr == 0) { if (!(bucket = BtrBucketGet (btree, BTRxPREV))) return NULL; recordX = bucket->recordN - 1; } else recordX = bucket->recordXCurr - 1; break; case BTRxCURR: if (!bucket) return NULL; recordX = bucket->recordXCurr; break; case BTRxNEXT: if (bucket->recordXCurr == bucket->recordN-1) { if (!(bucket = BtrBucketGet (btree, BTRxNEXT))) { BtrBucketKill (&btree->bucketCurr); btree->bucketCurr = NULL; return NULL; } recordX = 0; } else recordX = bucket->recordXCurr + 1; break; default: return NULL; } record = &bucket->record[recordX]; bucket->recordXCurr = recordX; record->type = btree->leafType; return record; } /****** BtrBucketGet ********************************************************** ** ** gets specified bucket ** ** INPUT: address of Btree object [W] ** location: BTRxFIRST, BTRxLAST, BTRxPREV, BTRxNEXT [R] ** IMPLICIT: ** ** RETURNS: pointer to bucket ** NULL if no more buckets */ static BTRoBUCKET *BtrBucketGet (BTRo *btree, enum BtrStep option) { BTRoBUCKET *bucket, *bucketCurr=btree->bucketCurr; switch (option) { case BTRxFIRST: bucket = BtrReadBucket (btree, btree->firstBucketFip, btree->firstBucketSize); break; case BTRxLAST: bucket = BtrReadBucket (btree, btree->lastBucketFip, btree->lastBucketSize); break; case BTRxPREV: if (bucketCurr && bucketCurr->fip == btree->firstBucketFip) return NULL; /* end of file */ bucket = BtrReadBucket (btree, bucketCurr->fip - bucketCurr->prevBucketSize, bucketCurr->prevBucketSize); break; case BTRxNEXT: if (bucketCurr && (bucketCurr->fip >= btree->lastBucketFip || btree->bucketRecordN == btree->recordN)) /*btree has only one bucket */ return NULL; /* end of file */ bucket = BtrReadBucket (btree, bucketCurr->fip + bucketCurr->bucketSize, bucketCurr->nextBucketSize); break; default: return NULL; } if (bucket) { BtrBucketKill (&btree->bucketCurr); btree->bucketCurr = bucket; } return bucket; } /**api* BtrGetFileSize ******************************************************** ** ** gets file size in bytes; ** ** INPUT: address of Btree object [R] ** IMPLICIT: ** ** RETURNS: file size in bytes */ INT4 BtrGetFileSize (BTRo *btree) { return btree->fileSize; } /**api* BtrGetRecordN ********************************************************* ** ** gets number of records in btree; ** ** INPUT: address of Btree object [R] ** IMPLICIT: ** ** RETURNS: number of records */ INT4 BtrGetRecordN (BTRo *btree) { return btree->recordN; } /**api* BtrGetType ************************************************************ ** ** Returns the type of the btree. ** ** INPUT: address of Btree object [R] ** ** RETURNS: type of btree (enumeration) */ INT4 BtrGetType (BTRo *btree) { return btree->type; } /**api* BtrGetTimeCreated ***************************************************** ** ** gets creation time ** ** INPUT: address of Btree object [R] ** IMPLICIT: ** ** RETURNS: number of records */ UINT4 BtrGetTimeCreated (BTRo *btree) { return btree->timeCreated; } /**api* BtrIsBusy ************************************************************* ** ** returns TRUE if the btree is still busy ** ** INPUT: address of Btree object [R] ** IMPLICIT: ** ** RETURNS: 1 or 0; */ INT4 BtrIsBusy (BTRo *btree) { return btree->isBusy; } /**api* BtrCompare ************************************************************ ** ** Compares two records. ** ** INPUT: address of Btree object [R] ** first record [R] ** second record [R] ** ** RETURNS: 1: first record greater than second ** 0: first and second records are equal ** -1: first record is lesser than second */ Int4 BtrCompare (BTRo *btree, BTRoREC *rec1, BTRoREC *rec2) { return (*btree->compare)(rec1, rec2); } i* BtrCompare srs/src/btree.h ** ** $RCSfile: btree.h,v $ ** $Revision: 1.3 $ ** $Date: 1996/09/09 20:17:12 $ ** $Author: etzold $ ** ** $Locker: $ ** $State: Exp $ ** ** SRS Copyright by Thure Etzold ** */ #define BTRxCURRENT_VERSION 1000000 #define BTRxTMPRECORDSIZ 132 #define BTRxINFOSIZE 96 enum btrType {BTRxIDENTRY=1, BTRxSTR, BTRxNUM, BTRxREAL}; enum recType {BTRxID=1, BTRxVALUE, BTRxPOINTER}; enum BtrStep {BTRxFIRST=1, BTRxLAST, BTRxCURR, BTRxNEXT, BTRxPREV}; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** record of various types to be inserted into a bucket of a btree */ typedef struct BTRoPOINTER { FIP downFip; /* fip of lower level bucket */ INT4 downSize; /* size of lower level bucket */ } BTRoPOINTER; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** record of various types to be inserted into a bucket of a btree */ typedef struct BTRoVALUE { INT4 idN; /* number of IDs associated to value */ FIP firstIdFip; /* file address of first ID */ FIP lastIdFip; /* file address of last ID */ } BTRoVALUE; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** record of various types to be inserted into a bucket of a btree */ typedef struct BTRoID { FIP textFip; /* file address of text part of entry */ FIP dataFip; /* file address of data part of entry */ char fileX; /* file index to point to source file in array of flatfiles */ } BTRoID; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** record of various types to be inserted into a bucket of a btree */ typedef struct BTRoREC { union { BTRoPOINTER pointer; BTRoID id; BTRoVALUE value; } r; char *str; /* string value */ enum recType type; } BTRoREC; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** bucket object; */ typedef struct BTRoBUCKET { char *bucketBuff; /* pointer to the buffer containing the packed bucket */ FIP fip; /* buckets address in the file */ enum recType type; char *writePtr; BTRoREC *record; /* array of records */ INT4 recordN; /* number of records in bucket */ struct BTRoBUCKET *up; /* address to upper level bucket */ INT4 bucketSize; /* size of bucket in bytes */ INT4 fixedRecordSize; INT4 nextBucketSize; /* size of bucket in bytes */ INT4 prevBucketSize; /* size of bucket in bytes */ INT4 recordXCurr; /* index of current record - for iteration */ } BTRoBUCKET; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** top level object describing a Btree */ /* types of the method functions */ typedef Int4 (*BTRoComparer) (BTRoREC*, BTRoREC*); typedef struct BTRo { struct FILEo* file; /* file handle to INX file */ BTRoBUCKET* root; /* pointer to root bucket */ struct BTRoBUCKET* bucketCurr; FIP rootFip; /* file pointer to root node */ INT4 rootSize; /* size of root node */ char infoBuff[BTRxINFOSIZE]; /* buffer for info block */ char infoSize; FIP writeFip; /* write file pointer */ FIP levelWriteFip[3]; /* write file pointer */ FIP levelFip[3]; /* write file pointer */ INT4 buildPhase; INT4 isBuildPhaseInit; INT4 isWriteOpen; /* file open for write access */ INT4 isBusy; INT4 isCompressed; INT4 isFixedRecordSiz; INT4 maxStrSiz; INT4 recordSiz; /* size of record without string */ INT4 fixedRecordSiz; enum btrType type; /* type of Btree */ enum recType leafType; /* type of records in leaf */ INT4 bucketRecordN; INT4 fileSize; INT4 recordN; INT4 firstBucketSize; INT4 lastBucketSize; FIP firstBucketFip; FIP lastBucketFip; UINT4 timeCreated; INT4 versionN; BTRoBUCKET* bucket; /* pointer to leaf bucket currently written */ /* methods */ BTRoComparer compare; } BTRo; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of exported functions */ BTRo *BtrOpen (char *file_nm, char *opt, INT4 *errCode); void BtrClose (BTRo *btree); void BtrCompress (char *fileName); void BtrTouch (char *fileName); /* manipulating or writing to Btree */ void BtrSetBucketSize (BTRo *btree, INT4 size); void BtrSetType (BTRo *btree, char *option); void BtrSetNumType (BTRo *btree, Int4 type); void BtrBuildStartPhase1 (BTRo *btree, INT4 recordN); void BtrBuildStartPhase2 (); void BtrInsertRecord (BTRoREC *record); /* reading from Btree */ BTRoREC *BtrSearch (BTRo *btree, char *str, FIP *fip, INT4 compLen); BTRoVALUE *BtrSearchStr (BTRo *btree, char *value); BTRoVALUE *BtrSearchNum (BTRo *btree, INT4 num); BTRoVALUE *BtrSearchReal (BTRo *btree, double real); BTRoID *BtrSearchId (BTRo *btree, char *str, FIP *idFip); INT4 BtrIsSearchGreaterMaxVal (BTRo *btree); INT4 BtrIsSearchLessMinVal (BTRo *btree); BTRoREC *BtrRecordGet (BTRo *btree, enum BtrStep option); BTRoREC *BtrRecordById (BTRo *btree, FIP recordId); Int4 BtrCompare (BTRo *btree, BTRoREC *rec1, BTRoREC *rec2); /* info about btree */ INT4 BtrGetFileSize (BTRo *btree); INT4 BtrGetRecordN (BTRo *btree); INT4 BtrIsBusy (BTRo *btree); UINT4 BtrGetTimeCreated (BTRo *btree); Int4 BtrGetType (BTRo *btree); ID *BtrSearchId (BTRo *btree, char *str, FIP *idFip); INT4 BtrIsSearchGreaterMaxVal (BTRo *btree); INT4 BtrIsSearchLessMinVal (BTRo *btree); BTRoREC *BtrRecordGet (BTRo *btree, enum BtrStep option); BTRoREC *BtrRecordById (BTRo *btree, FIP recordsrs/src/builtin.h ** ** $RCSfile: builtin.h,v $ ** $Revision: 1.26 $ ** $Date: 1997/03/13 17:04:49 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** from ODD file: "srsica:srswin.sdl" ** date of ODD compilation: 13-MAR-1997 12:06 ** */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Value in an enumeration */ #ifndef _ODDoVALUE #define _ODDoVALUE typedef struct ODDoVALUE { char *name; /* Name of value. */ INT4 n; /* Number value. */ char *rem; /* Comment field. */ } ODDoVALUE; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Argument of Icarus command. */ #ifndef _IARGoVALUE #define _IARGoVALUE typedef struct IARGoVALUE { char *name; /* Name of the argument in an Icarus program. */ char *rem; /* Comment field. */ unsigned char isUnnamed; /* Defines if parameter may be unnamed. */ unsigned char isRequired; /* Defines if parameter is required. */ unsigned char type; /* Type of the argument */ char *className; INT4 defInt; /* Default value of type 'int' arguments. */ char *defaultStr; /* Default value of type 'string' arguments. */ struct ODDoVALUE *vals; INT4 valsN; unsigned char isSet; struct VARo *val; } IARGoVALUE; #endif #ifndef _IARGoCOM #define _IARGoCOM typedef struct IARGoCOM { char *name; /* Name of command in Icarus programs. */ char *functionName; /* C function that implements the command. */ INT4 isShow; /* Determines whether the command should appear in the Icarus functions reference list. */ char *rem; /* Comment field. */ unsigned char returnType; /* Type of value to be returned (if any). */ INT4 time; /* Execution time of command. */ char *returnClass; unsigned char isDirectCall; /* Call function directly or via C-interface. */ char *methodOf; /* The class of which this function is a method otherwise treated as normal function. */ struct IARGoVALUE *args; INT4 argsN; INT4 (*function)(); /* Function to be executed for command. */ INT4 orderN; /* Number of arguments ordered from C function (via 'IargGetArgs'). */ INT4 orderAllocN; /* Number of orders currently allocated. */ struct IARGoVALUE **order; /* Array with a list of argument orders. */ } IARGoCOM; #endif extern ODDoVALUE ODDValue[]; extern IARGoVALUE IARGVALUE[]; extern IARGoCOM IARGCOM[]; #ifdef _INITOBJS ODDoVALUE ODDValue[] = { {"pre", 1, ""}, {"post", 2, ""}, {"pre", 1, ""}, {"post", 2, ""}, {"read", 1, ""}, {"write", 2, ""}, {"path", 1, ""}, {"dir", 2, ""}, {"name", 3, ""}, {"file", 4, ""}, {"ext", 5, ""}, {"normal", 0, ""}, {"raw", 1, ""}, {"normal", 0, ""}, {"raw", 1, ""}, {"gcg", 1, ""}, {"msf", 2, ""}, {"pir", 3, ""}, {"plain", 4, ""}, {"fasta", 5, ""}, {"embl", 6, ""}, {"swiss", 7, ""}, {"clustal", 8, ""} }; IARGoVALUE IARGVALUE[] = { {"opnd", "", 1, 0, 9, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"t", "", 0, 0, 9, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"val", "", 1, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"key", "", 0, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"op", "", 1, 0, 9, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"a", "", 0, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"b", "", 0, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"val", "", 1, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"name", "", 0, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"key", "", 0, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"index", "", 0, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"var", "", 0, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"var", "", 1, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"name", "", 1, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"opt", "", 0, 0, 1, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"file", "", 1, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"body", "", 1, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"body", "", 1, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"i", "", 0, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"c", "", 0, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"u", "", 0, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"b", "", 0, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"body", "", 0, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"list", "", 0, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"var", "", 0, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"c", "", 0, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"b", "", 0, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"node", "", 0, 0, 3, "node", 0, "", &ODDValue[0], 0, 0, NULL}, {"prod", "", 0, 0, 3, "node", 0, "", &ODDValue[0], 0, 0, NULL}, {"reStr", "", 1, 0, 9, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"name", "", 1, 0, 9, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"node", "", 1, 0, 3, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"t", "", 0, 0, 9, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"node", "", 1, 0, 3, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"prog", "", 1, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"name", "", 1, 0, 9, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"lookahead", "", 0, 0, 1, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"value", "", 1, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"value", "", 1, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 1, "", &ODDValue[0], 0, 0, NULL}, {"value", "", 1, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 2, "", &ODDValue[0], 0, 0, NULL}, {"value", "", 1, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 3, "", &ODDValue[0], 0, 0, NULL}, {"value", "", 1, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 4, "", &ODDValue[0], 0, 0, NULL}, {"value", "", 1, 0, 6, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 5, "", &ODDValue[0], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 1, "", &ODDValue[0], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 2, "", &ODDValue[0], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 3, "", &ODDValue[0], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 4, "", &ODDValue[0], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 5, "", &ODDValue[0], 0, 0, NULL}, {"prod", "", 1, 0, 9, "", 0, "", &ODDValue[0], 0, 0, NULL}, {"cond", "Breaks only if condition is met.", 0, 0, 1, "", 1, "", &ODDValue[0], 0, 0, NULL}, {"time", "", 0, 0, 1, "", 0, "", &ODDValue[0], 2, 0, NULL}, {"prod", "", 1, 0, 9, "", 0, "", &ODDValue[2], 0, 0, NULL}, {"time", "", 0, 0, 1, "", 0, "", &ODDValue[2], 2, 0, NULL}, {"name", "", 1, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"name", "", 1, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"n", "", 1, 0, 1, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"name", "", 0, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"x", "", 0, 0, 1, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"y", "", 0, 0, 1, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"color", "", 0, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"prod", "", 1, 0, 3, "production", 0, "", &ODDValue[4], 0, 0, NULL}, {"prod", "", 0, 0, 16, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"string", "", 1, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"start", "The name of the start symbol (production).", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"file", "Selects opened file to be read for input.", 0, 0, 3, "file", 0, "", &ODDValue[4], 0, 0, NULL}, {"fileName", "Selects opened file to be read for input.", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"show", "Sets display of the syntax before parsing.", 0, 0, 1, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"skip", "The set of characters to be skipped as white space", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"comment", "Regular expression for skipping comments", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"tree", "Flag if set requests printing the syntax tree.", 0, 0, 1, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"prod", "", 1, 0, 16, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"skip", "The set of characters to be skipped as white space", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"comment", "Regular expression for skipping comments", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"file", "Sets opened file as input.", 0, 0, 3, "file", 0, "", &ODDValue[4], 0, 0, NULL}, {"str", "Sets string as input.", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"show", "Sets display of the syntax before parsing.", 0, 0, 1, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"tree", "Flag if set requests printing the syntax tree.", 0, 0, 1, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"fileName", "Name of the file to be opened as input.", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"job", "", 1, 0, 3, "job", 0, "", &ODDValue[4], 0, 0, NULL}, {"job", "", 1, 0, 3, "job", 0, "", &ODDValue[4], 0, 0, NULL}, {"string", "", 0, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"start", "The name of the start symbol (production).", 0, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"file", "Selects opened file to be read for input.", 0, 0, 3, "file", 0, "", &ODDValue[4], 0, 0, NULL}, {"fileName", "Selects opened file to be read for input.", 0, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"job", "", 1, 0, 3, "job", 0, "", &ODDValue[4], 0, 0, NULL}, {"job", "", 1, 0, 3, "job", 0, "", &ODDValue[4], 0, 0, NULL}, {"job", "", 1, 0, 3, "job", 0, "", &ODDValue[4], 0, 0, NULL}, {"name", "Name of the token list.", 0, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"code", "", 0, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"n", "", 0, 0, 1, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"print", "", 0, 0, 1, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"task", "", 0, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"withCode", "", 0, 0, 1, "", 1, "", &ODDValue[4], 0, 0, NULL}, {"outFile", "Output file object.", 0, 0, 3, "file", 0, "", &ODDValue[4], 0, 0, NULL}, {"in", "Name of the input token table.", 1, 1, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"ic", "Token code.", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"n", "Numerical token code.", 0, 0, 1, "", -1, "", &ODDValue[4], 0, 0, NULL}, {"p", "Name of production to be linked.", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"t", "Name of task that if results in forced parsing.", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"count", "", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"var", "", 0, 0, 6, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"file", "Symbolic name of the input file.", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"share", "Symbolic name file that shares physical file.", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"select", "Selects token with specified count number. \nThe value 0 selects all tokens \n(only in combination with \"count\").\n", 0, 0, 1, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"c", "", 0, 0, 6, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"name", "Name of ouput token table.", 1, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"name", "Name of ouput token table.", 1, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"len", "", 0, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"len", "", 0, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"len", "", 0, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"c", "token code as a name", 1, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"n", "token code as a number", 0, 0, 1, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"s", "string to be written to the token table.\nIf left unspecified the current match, or current token ($Ct)\nis written.\n", 0, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"c", "token code as a name", 1, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"n", "token code as a number", 0, 0, 1, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"s", "string to be written to the token table.\nIf left unspecified the current match, or current token ($Ct)\nis written.\n", 0, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"c", "token code as a name", 1, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"n", "token code as a number", 0, 0, 1, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"s", "string to be written to the token table.\nIf left unspecified the current match, or current token ($Ct)\nis written.\n", 0, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"s", "String to be written to the token table.", 1, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"s", "String to be written to the token table.", 1, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"s", "String with which current match is to be replaced", 1, 0, 6, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"s", "String with which current match is to be replaced", 1, 0, 6, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"name", "Name of requested token table.", 1, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"flag", "", 0, 0, 2, "", 0, "nocase", &ODDValue[4], 0, 0, NULL}, {"value", "", 1, 0, 6, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"value", "", 1, 0, 6, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 1, "", &ODDValue[4], 0, 0, NULL}, {"value", "", 1, 0, 6, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 2, "", &ODDValue[4], 0, 0, NULL}, {"value", "", 1, 0, 6, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 3, "", &ODDValue[4], 0, 0, NULL}, {"value", "", 1, 0, 6, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 4, "", &ODDValue[4], 0, 0, NULL}, {"value", "", 1, 0, 6, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 5, "", &ODDValue[4], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 1, "", &ODDValue[4], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 2, "", &ODDValue[4], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 3, "", &ODDValue[4], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 4, "", &ODDValue[4], 0, 0, NULL}, {"stack", "", 0, 0, 1, "", 5, "", &ODDValue[4], 0, 0, NULL}, {"val", "", 1, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"val", "", 1, 0, 2, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"name", "Parameter name.", 1, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"set", "", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"name", "Parameter name.", 1, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"set", "", 0, 0, 1, "", 2, "", &ODDValue[4], 0, 0, NULL}, {"name", "Parameter name.", 1, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"set", "", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"name", "Parameter name.", 1, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"set", "", 0, 0, 1, "", 2, "", &ODDValue[4], 0, 0, NULL}, {"name", "Parameter name.", 1, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"name", "Name of environment variable.", 1, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"set", "New string value of the environment variable.", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"cond", "The condition.", 1, 1, 1, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"t", "String to be returned if condition is true.", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"f", "String to be returned if condition is false", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"cond", "The condition.", 1, 1, 1, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"t", "String to be returned if condition is true.", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"f", "String to be returned if condition is false", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"var", "Name of variable used for iteration", 1, 0, 6, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"in", "The list.", 0, 0, 16, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"s", "String to print for each list element", 0, 0, 6, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"sep", "Separator strings to be printed between elements", 0, 0, 6, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"str", "Classical substr function", 1, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"s", "Start posilion inside of string", 0, 1, 1, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"l", "subStr length if ommited - suffix", 0, 0, 1, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"com", "Unix command", 1, 1, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"script", "String (text) that is written to a script and then executed", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"scriptName", "Name of the script that is to be generated.", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"out", "Name of output file (Use 'stdout' for standard output).", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"error", "Name of error output file (Use 'stdout' for standard output).", 0, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"name", "The name of the file; if omitted stdin (for read access mode) \nor stdout (write access mode) are assumed.\n", 1, 0, 9, "", 0, "", &ODDValue[4], 0, 0, NULL}, {"mode", "Access mode for opened file", 0, 0, 1, "", 1, "", &ODDValue[4], 2, 0, NULL}, {"file", "", 1, 0, 3, "file", 0, "", &ODDValue[6], 0, 0, NULL}, {"type", "", 1, 0, 1, "", 1, "", &ODDValue[6], 5, 0, NULL}, {"s", "", 1, 0, 6, "", 0, "", &ODDValue[11], 0, 0, NULL}, {"f", "", 0, 0, 3, "file", 0, "", &ODDValue[11], 0, 0, NULL}, {"mode", "", 0, 0, 1, "", 0, "", &ODDValue[11], 2, 0, NULL}, {"v", "Appends the string to specified string variable.", 0, 0, 6, "", 0, "", &ODDValue[13], 0, 0, NULL}, {"s", "", 1, 0, 6, "", 0, "", &ODDValue[13], 0, 0, NULL}, {"s", "", 1, 0, 6, "", 0, "", &ODDValue[13], 0, 0, NULL}, {"f", "", 0, 0, 3, "file", 0, "", &ODDValue[13], 0, 0, NULL}, {"mode", "", 0, 0, 1, "", 0, "", &ODDValue[13], 2, 0, NULL}, {"v", "Appends the string to specified string variable.", 0, 0, 6, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"s", "", 1, 0, 9, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"label", "Label to be printed at begin of each line.", 0, 0, 9, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"width", "Maximum width of output lines.", 0, 0, 1, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"indent", "Indentation for all lines.", 0, 0, 1, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"firstIndent", "Indentation of first line.", 0, 0, 1, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"n", "", 1, 0, 1, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"val", "", 1, 0, 6, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"list", "", 1, 0, 6, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"switch", "", 1, 0, 1, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"switch", "", 1, 0, 1, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"state", "0: turns skipping white space off
    \n1: turns it on again\n", 1, 0, 1, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"s", "", 0, 0, 9, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"state", "0: turns skipping white space off
    \n1: turns it on again\n", 1, 0, 1, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"s", "", 0, 0, 9, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"prog", "", 1, 0, 9, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"s", "", 1, 0, 9, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"skip", "String containing characters to be removed from ends.\n", 0, 0, 9, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"n", "", 0, 0, 1, "", 1, "", &ODDValue[15], 0, 0, NULL}, {"n", "", 0, 0, 1, "", 2, "", &ODDValue[15], 0, 0, NULL}, {"n", "", 0, 0, 1, "", 3, "", &ODDValue[15], 0, 0, NULL}, {"n", "", 0, 0, 1, "", 4, "", &ODDValue[15], 0, 0, NULL}, {"n", "", 0, 0, 1, "", 5, "", &ODDValue[15], 0, 0, NULL}, {"n", "", 0, 0, 1, "", 6, "", &ODDValue[15], 0, 0, NULL}, {"n", "", 0, 0, 1, "", 7, "", &ODDValue[15], 0, 0, NULL}, {"n", "", 0, 0, 1, "", 8, "", &ODDValue[15], 0, 0, NULL}, {"n", "", 0, 0, 1, "", 9, "", &ODDValue[15], 0, 0, NULL}, {"name", "", 1, 0, 2, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"set", "", 1, 0, 3, "set", 0, "", &ODDValue[15], 0, 0, NULL}, {"q", "", 0, 0, 9, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"init", "", 0, 0, 2, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"db", "", 0, 0, 2, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"group", "", 1, 0, 3, "dbGroup", 0, "", &ODDValue[15], 0, 0, NULL}, {"index", "", 0, 1, 2, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"group", "", 1, 0, 3, "dbGroup", 0, "", &ODDValue[15], 0, 0, NULL}, {"l", "", 0, 0, 2, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"h", "", 0, 0, 2, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"le", "", 0, 0, 1, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"re", "", 0, 0, 1, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"s", "", 0, 0, 9, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"index", "", 0, 1, 2, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"group", "", 1, 0, 3, "dbGroup", 0, "", &ODDValue[15], 0, 0, NULL}, {"op", "", 1, 0, 2, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"s1", "", 0, 0, 3, "set", 0, "", &ODDValue[15], 0, 0, NULL}, {"s2", "", 0, 0, 3, "set", 0, "", &ODDValue[15], 0, 0, NULL}, {"op", "", 1, 0, 2, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"s1", "", 0, 0, 3, "set", 0, "", &ODDValue[15], 0, 0, NULL}, {"s2", "", 0, 0, 3, "set", 0, "", &ODDValue[15], 0, 0, NULL}, {"name", "", 1, 0, 9, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"s", "", 0, 0, 3, "set", 0, "", &ODDValue[15], 0, 0, NULL}, {"name", "", 1, 0, 2, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"fileName", "", 0, 0, 2, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"s", "", 1, 0, 9, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"infile1", "Name of input file with the search probe.", 0, 0, 2, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"infile2", "Name of input file with the data bank.", 0, 0, 2, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"field", "", 1, 0, 9, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"set", "", 0, 0, 9, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"s", "Sequence in which to store the sequence.", 1, 0, 3, "sequence", 0, "", &ODDValue[15], 0, 0, NULL}, {"file", "File object with the sequence.", 1, 0, 3, "file", 0, "", &ODDValue[15], 0, 0, NULL}, {"len", "Length of the sequence to be read.", 0, 0, 1, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"s", "", 1, 0, 3, "sequence", 0, "", &ODDValue[15], 0, 0, NULL}, {"from", "", 0, 0, 1, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"len", "", 0, 0, 1, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"name", "", 1, 0, 9, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"list", "", 0, 0, 3, "sequence", 0, "", &ODDValue[15], 0, 0, NULL}, {"seq", "", 1, 0, 3, "sequence", 0, "", &ODDValue[15], 0, 0, NULL}, {"s", "", 0, 0, 9, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"seq", "", 1, 0, 3, "sequence", 0, "", &ODDValue[15], 0, 0, NULL}, {"seq", "", 1, 0, 3, "sequence", 0, "", &ODDValue[15], 0, 0, NULL}, {"len", "", 0, 0, 1, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"seq", "", 1, 0, 3, "sequence", 0, "", &ODDValue[15], 0, 0, NULL}, {"seq", "", 1, 0, 3, "sequence", 0, "", &ODDValue[15], 0, 0, NULL}, {"s", "The sequence as a string value.", 0, 0, 9, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"name", "", 0, 0, 2, "", 0, "", &ODDValue[15], 0, 0, NULL}, {"format", "", 0, 0, 1, "", 0, "", &ODDValue[15], 8, 0, NULL}, {"width", "", 0, 0, 1, "", 60, "", &ODDValue[23], 0, 0, NULL}, {"op", "", 1, 0, 2, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"l", "", 0, 0, 1, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"r", "", 0, 0, 1, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"s", "", 1, 0, 2, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"s", "", 1, 0, 2, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"s", "", 1, 0, 9, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"v", "", 1, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"s", "", 0, 0, 9, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"s", "", 1, 0, 9, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"from", "", 0, 0, 9, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"to", "", 0, 0, 9, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"s", "", 1, 0, 9, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"from", "", 0, 0, 9, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"to", "", 0, 0, 9, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"s", "", 1, 0, 9, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"s", "", 1, 0, 9, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"s", "Input string.", 1, 0, 9, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"len", "Length of the result string.", 0, 0, 1, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"c", "Character used for padding.", 0, 0, 9, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"thirds", "", 1, 0, 1, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"s", "", 0, 0, 1, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"l", "", 0, 0, 1, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"l", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"r", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"l", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"r", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"l", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"r", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"l", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"r", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"l", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"r", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"l", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"r", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"l", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"r", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"l", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"r", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"l", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"r", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"l", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"r", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"l", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"r", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"l", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"r", "", 0, 0, 6, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"state", "", 1, 0, 1, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"name", "", 1, 0, 9, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"fip", "", 0, 0, 1, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"acc", "", 1, 0, 9, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"db", "", 0, 0, 9, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"seq", "", 1, 0, 9, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"to", "", 0, 0, 1, "", -2, "", &ODDValue[23], 0, 0, NULL}, {"uncertain", "", 0, 0, 1, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"feature", "", 1, 0, 1, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"expr", "", 1, 0, 9, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"db", "", 0, 0, 9, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"shift", "", 0, 0, 1, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"left", "", 0, 0, 1, "", 0, "", &ODDValue[23], 0, 0, NULL}, {"right", "", 0, 0, 1, "", 0, "", &ODDValue[23], 0, 0, NULL} }; IARGoCOM IARGCOM[] = { {"_prog", "IopProg_", 0, "", 2, 8, "", 0, "", &IARGVALUE[0], 0, NULL, 0, 0, NULL}, {"_opnd", "IopOpnd_", 0, "", 6, 8, "", 0, "", &IARGVALUE[0], 2, NULL, 0, 0, NULL}, {"_list", "IopList_", 0, "", 6, 8, "", 0, "", &IARGVALUE[2], 0, NULL, 0, 0, NULL}, {"_assoc", "IopAssoc_", 0, "", 6, 8, "", 0, "", &IARGVALUE[2], 2, NULL, 0, 0, NULL}, {"_binop", "IopBinop_", 0, "", 6, 8, "", 0, "", &IARGVALUE[4], 3, NULL, 0, 0, NULL}, {"_strmake", "IopStrMake_", 0, "", 6, 8, "", 0, "", &IARGVALUE[7], 0, NULL, 0, 0, NULL}, {"_makearg", "IopMakeArg_", 0, "", 6, 8, "", 0, "", &IARGVALUE[7], 2, NULL, 0, 0, NULL}, {"_select", "IopSelect_", 0, "", 6, 8, "", 0, "", &IARGVALUE[9], 3, NULL, 0, 0, NULL}, {"_setwrt", "IopSetWrite_", 0, "", 6, 8, "", 0, "", &IARGVALUE[12], 1, NULL, 0, 0, NULL}, {"_func", "IopFunc_", 0, "", 6, 8, "", 0, "", &IARGVALUE[13], 0, NULL, 0, 0, NULL}, {"_body", "IopBody_", 0, "", 6, 8, "", 0, "", &IARGVALUE[13], 0, NULL, 0, 0, NULL}, {"_ref", "IopRef_", 0, "", 6, 8, "", 0, "", &IARGVALUE[13], 2, NULL, 0, 0, NULL}, {"_file", "IopFile_", 0, "", 6, 8, "", 0, "", &IARGVALUE[15], 1, NULL, 0, 0, NULL}, {"_pre", "IopPre_", 0, "", 6, 8, "", 0, "", &IARGVALUE[16], 1, NULL, 0, 0, NULL}, {"_init", "IopInit_", 0, "", 6, 8, "", 0, "", &IARGVALUE[17], 1, NULL, 0, 0, NULL}, {"_for", "IopFor_", 0, "", 6, 8, "", 0, "", &IARGVALUE[18], 4, NULL, 0, 0, NULL}, {"_foreach", "IopForeach_", 0, "", 6, 8, "", 0, "", &IARGVALUE[22], 3, NULL, 0, 0, NULL}, {"_while", "IopWhile_", 0, "", 6, 8, "", 0, "", &IARGVALUE[25], 2, NULL, 0, 0, NULL}, {"_if", "IopIf_", 0, "", 6, 8, "", 0, "", &IARGVALUE[27], 0, NULL, 0, 0, NULL}, {"_prod", "IopProd_", 0, "", 3, 8, "node", 0, "", &IARGVALUE[27], 0, NULL, 0, 0, NULL}, {"_endProd", "IopEndProd_", 0, "", 6, 8, "", 0, "", &IARGVALUE[27], 2, NULL, 0, 0, NULL}, {"_expr", "IopExpr_", 0, "", 3, 8, "node", 0, "", &IARGVALUE[29], 0, NULL, 0, 0, NULL}, {"_term", "IopTerm_", 0, "", 3, 8, "node", 0, "", &IARGVALUE[29], 0, NULL, 0, 0, NULL}, {"_regexp", "IopRegexp_", 0, "", 3, 8, "node", 0, "", &IARGVALUE[29], 1, NULL, 0, 0, NULL}, {"_literal", "IopLiteral_", 0, "", 3, 8, "node", 0, "", &IARGVALUE[30], 1, NULL, 0, 0, NULL}, {"_makeOpt", "IopMakeOpt_", 0, "", 3, 8, "node", 0, "", &IARGVALUE[31], 2, NULL, 0, 0, NULL}, {"_nodeProg", "IopNodeProg_", 0, "", 3, 8, "node", 0, "", &IARGVALUE[33], 2, NULL, 0, 0, NULL}, {"_prodName", "IopProdName_", 0, "", 3, 8, "node", 0, "", &IARGVALUE[35], 2, NULL, 0, 0, NULL}, {"_doCom", "IopCommand_", 0, "", 3, 8, "node", 0, "", &IARGVALUE[37], 0, NULL, 0, 0, NULL}, {"_doInputEnd", "IopInputEnd_", 0, "", 3, 8, "node", 0, "", &IARGVALUE[37], 0, NULL, 0, 0, NULL}, {"_nullNode", "IopNullNode_", 0, "", 3, 8, "node", 0, "", &IARGVALUE[37], 0, NULL, 0, 0, NULL}, {"_push", "IopPush_", 0, "", 2, 8, "", 0, "", &IARGVALUE[37], 2, NULL, 0, 0, NULL}, {"_push1", "IopPush_", 0, "", 2, 8, "", 0, "", &IARGVALUE[39], 2, NULL, 0, 0, NULL}, {"_push2", "IopPush_", 0, "", 2, 8, "", 0, "", &IARGVALUE[41], 2, NULL, 0, 0, NULL}, {"_push3", "IopPush_", 0, "", 2, 8, "", 0, "", &IARGVALUE[43], 2, NULL, 0, 0, NULL}, {"_push4", "IopPush_", 0, "", 2, 8, "", 0, "", &IARGVALUE[45], 2, NULL, 0, 0, NULL}, {"_push5", "IopPush_", 0, "", 2, 8, "", 0, "", &IARGVALUE[47], 2, NULL, 0, 0, NULL}, {"_pop", "IopPop_", 0, "", 6, 8, "", 0, "", &IARGVALUE[49], 1, NULL, 0, 0, NULL}, {"_pop1", "IopPop_", 0, "", 6, 8, "", 0, "", &IARGVALUE[50], 1, NULL, 0, 0, NULL}, {"_pop2", "IopPop_", 0, "", 6, 8, "", 0, "", &IARGVALUE[51], 1, NULL, 0, 0, NULL}, {"_pop3", "IopPop_", 0, "", 6, 8, "", 0, "", &IARGVALUE[52], 1, NULL, 0, 0, NULL}, {"_pop4", "IopPop_", 0, "", 6, 8, "", 0, "", &IARGVALUE[53], 1, NULL, 0, 0, NULL}, {"_pop5", "IopPop_", 0, "", 6, 8, "", 0, "", &IARGVALUE[54], 1, NULL, 0, 0, NULL}, {"Break", "IopBreak", 1, "", 2, 6, "", 0, "", &IARGVALUE[55], 3, NULL, 0, 0, NULL}, {"break", "IopBreak", 0, "", 2, 2, "", 0, "", &IARGVALUE[58], 2, NULL, 0, 0, NULL}, {"next", "IopNext", 1, "", 2, 8, "", 0, "", &IARGVALUE[60], 0, NULL, 0, 0, NULL}, {"cont", "IopContinue", 1, "", 2, 8, "", 0, "", &IARGVALUE[60], 0, NULL, 0, 0, NULL}, {"tree", "IopTree", 1, "", 2, 8, "", 0, "", &IARGVALUE[60], 0, NULL, 0, 0, NULL}, {"TestMode", "IopTestMode", 1, "", 1, 8, "", 0, "", &IARGVALUE[60], 0, NULL, 0, 0, NULL}, {"prod", "IopProd", 0, "", 2, 8, "", 0, "", &IARGVALUE[60], 1, NULL, 0, 0, NULL}, {"Prod", "IopProd", 1, "", 2, 8, "", 0, "", &IARGVALUE[61], 1, NULL, 0, 0, NULL}, {"CDefine", "IopCDefine", 0, "", 2, 8, "", 0, "", &IARGVALUE[62], 2, NULL, 0, 0, NULL}, {"test", "IopTest", 0, "Test command.", 1, 8, "", 0, "", &IARGVALUE[64], 3, NULL, 0, 0, NULL}, {"printProd", "IopPrintProduction", 0, "Prints a production.", 1, 8, "", 0, "", &IARGVALUE[67], 1, NULL, 0, 0, NULL}, {"Parse", "IopParse", 1, "Parses a string.", 2, 8, "", 0, "", &IARGVALUE[68], 9, NULL, 0, 0, NULL}, {"JobNew", "IopJobNew", 1, "Creates a new parsing job and associates it with a syntax and\nthe input. Use $JobTokens to start the parsing (lazy parsing) and\n$JobNext to move to the next job in the input stream.\n", 3, 8, "job", 0, "", &IARGVALUE[77], 8, NULL, 0, 0, NULL}, {"Fail", "IopFail", 1, "Can be used only in an action symbol (like x{...}). If called the action node reports\na parsing error which is treated in the same way as a 'normal' parsing\nerror from, eg, a literal. \n", 2, 8, "", 0, "", &IARGVALUE[85], 0, NULL, 0, 0, NULL}, {"JobHasInput", "IopJobHasInput", 1, "Returns TRUE if the input file of the job is not \n finished\n", 1, 8, "", 0, "", &IARGVALUE[85], 1, NULL, 0, 0, NULL}, {"JobNext", "IopJobNext", 1, "", 2, 8, "", 0, "", &IARGVALUE[86], 5, NULL, 0, 0, NULL}, {"JobHasInput", "IopJobHasInput", 1, "Returns TRUE if the input file of the job is not \n finished\n", 1, 8, "", 0, "", &IARGVALUE[91], 1, NULL, 0, 0, NULL}, {"JobKill", "IopJobEnd", 1, "", 2, 8, "", 0, "", &IARGVALUE[92], 1, NULL, 0, 0, NULL}, {"JobTokens", "IopJobTokens", 1, "", 1, 8, "", 0, "", &IARGVALUE[93], 8, NULL, 0, 0, NULL}, {"In", "IopIn", 1, "Sets the input token table for parsing. \nControls the lazy parsing execution by defining the connections\nbetween productions \n", 1, 6, "", 0, "", &IARGVALUE[101], 11, NULL, 0, 0, NULL}, {"Out", "IopOut", 1, "Sets the output table for all writing of tokens for the \ncurrent production and its dependants.\n", 2, 6, "", 0, "", &IARGVALUE[112], 1, NULL, 0, 0, NULL}, {"out", "IopOut", 0, "Sets the output table for all writing of tokens for the \ncurrent production and its dependants.\n", 2, 6, "", 0, "", &IARGVALUE[113], 1, NULL, 0, 0, NULL}, {"Getc", "IopGetc", 0, "Defines $Ct to be a token starting at the current position\nand with the given length. Moves the current position, as if\n the given number of characters would have been really parsed\n", 2, 8, "", 1, "", &IARGVALUE[114], 1, NULL, 0, 0, NULL}, {"Len", "IopRestrictLength", 0, "Limits the parsing to stop after 'len' characters\nMust be the last command in a production. See also $Mov\n", 2, 12, "", 1, "", &IARGVALUE[115], 1, NULL, 0, 0, NULL}, {"Mov", "IopMove", 1, "Skips the next 'len' characters while parsing \n", 2, 4, "", 1, "", &IARGVALUE[116], 1, NULL, 0, 0, NULL}, {"Wrt", "IopWrt", 1, "This function can be called inside an action attached to the symbol of\na production. It writes the match of the current symbol or a specified\nstring into the output table specified by the most recent call of $out.\n", 2, 8, "", 1, "", &IARGVALUE[117], 3, NULL, 0, 0, NULL}, {"wrt", "IopWrt", 0, "This function can be called inside an action attached to the symbol of\na production. It writes the match of the current symbol or a specified\nstring into the output table specified by the most recent call of $out.\n", 2, 8, "", 1, "", &IARGVALUE[120], 3, NULL, 0, 0, NULL}, {"Uniq", "IopUniq", 1, "Exactly as $Wrt but writes the token only into the table if it does\nnot already exist. Unique here means that both the token string as the\ntoken code are used for comparison.\n", 2, 8, "", 1, "", &IARGVALUE[123], 3, NULL, 0, 0, NULL}, {"App", "IopApp", 1, "Appends the string token to the output token table\n", 2, 8, "", 1, "", &IARGVALUE[126], 1, NULL, 0, 0, NULL}, {"app", "IopApp", 0, "Old syntax, see $App\n", 2, 8, "", 1, "", &IARGVALUE[127], 1, NULL, 0, 0, NULL}, {"Rep", "IopRep", 1, "Replaces the current token ($Ct) in case of a symbol match. The\ninput cursor is moved after the replaced string. \n", 2, 8, "", 0, "", &IARGVALUE[128], 1, NULL, 0, 0, NULL}, {"rep", "IopRep", 0, "Old syntax, see $Rep \n", 2, 8, "", 0, "", &IARGVALUE[129], 1, NULL, 0, 0, NULL}, {"Not", "IopNot", 1, "The rest of the production matches only if the preceding \nterminal doesn't match. (see $Probe) The parsing position \n(cursor) is not moved when matching the preceding terminal \n", 2, 2, "", 0, "", &IARGVALUE[130], 0, NULL, 0, 0, NULL}, {"not", "IopNot", 0, "", 2, 2, "", 0, "", &IARGVALUE[130], 0, NULL, 0, 0, NULL}, {"Probe", "IopProbe", 1, "The rest of the production matches only if the preceding \nterminal matches. (see $Not) The parsing position \n(cursor) is not moved when matching the preceding terminal \n", 2, 2, "", 0, "", &IARGVALUE[130], 0, NULL, 0, 0, NULL}, {"Noskip", "IopNoskip", 1, "Inactivates skipping of white space\n", 2, 2, "", 0, "", &IARGVALUE[130], 0, NULL, 0, 0, NULL}, {"noskip", "IopNoskip", 0, "", 2, 2, "", 0, "", &IARGVALUE[130], 0, NULL, 0, 0, NULL}, {"Request", "IopRequest", 1, "Activates the lazy parsing chain producing the \nrequested token table, but doesn't connect the input \nto it. (see $In)\n", 2, 8, "", 0, "", &IARGVALUE[130], 1, NULL, 0, 0, NULL}, {"Nocase", "IcaOpSetFlag", 1, "", 2, 8, "", 0, "", &IARGVALUE[131], 1, NULL, 0, 0, NULL}, {"push", "IopPush", 0, "", 2, 8, "", 0, "", &IARGVALUE[132], 2, NULL, 0, 0, NULL}, {"push1", "IopPush", 0, "", 2, 8, "", 0, "", &IARGVALUE[134], 2, NULL, 0, 0, NULL}, {"push2", "IopPush", 0, "", 2, 8, "", 0, "", &IARGVALUE[136], 2, NULL, 0, 0, NULL}, {"push3", "IopPush", 0, "", 2, 8, "", 0, "", &IARGVALUE[138], 2, NULL, 0, 0, NULL}, {"push4", "IopPush", 0, "", 2, 8, "", 0, "", &IARGVALUE[140], 2, NULL, 0, 0, NULL}, {"push5", "IopPush", 0, "", 2, 8, "", 0, "", &IARGVALUE[142], 2, NULL, 0, 0, NULL}, {"pop", "IopPop", 0, "", 6, 8, "", 0, "", &IARGVALUE[144], 1, NULL, 0, 0, NULL}, {"pop1", "IopPop", 0, "", 6, 8, "", 0, "", &IARGVALUE[145], 1, NULL, 0, 0, NULL}, {"pop2", "IopPop", 0, "", 6, 8, "", 0, "", &IARGVALUE[146], 1, NULL, 0, 0, NULL}, {"pop3", "IopPop", 0, "", 6, 8, "", 0, "", &IARGVALUE[147], 1, NULL, 0, 0, NULL}, {"pop4", "IopPop", 0, "", 6, 8, "", 0, "", &IARGVALUE[148], 1, NULL, 0, 0, NULL}, {"pop5", "IopPop", 0, "", 6, 8, "", 0, "", &IARGVALUE[149], 1, NULL, 0, 0, NULL}, {"Exit", "IopExit", 1, "", 2, 8, "", 0, "", &IARGVALUE[150], 1, NULL, 0, 0, NULL}, {"exit", "IopExit", 0, "", 2, 8, "", 0, "", &IARGVALUE[151], 1, NULL, 0, 0, NULL}, {"parStr", "IopParStr", 0, "Returns the value of a 'string' parameter or sets its value if \".set\" is \ndefined.\n", 9, 8, "", 0, "", &IARGVALUE[152], 2, NULL, 0, 0, NULL}, {"parInt", "IopParInt", 0, "Returns the value of an 'int' parameter or sets its value if \".set\" is \ndefined.\n", 1, 8, "", 0, "", &IARGVALUE[154], 2, NULL, 0, 0, NULL}, {"ParStr", "IopParStr", 1, "Returns the value of a 'string' parameter or sets its value if \".set\" is \ndefined.\n", 9, 8, "", 0, "", &IARGVALUE[156], 2, NULL, 0, 0, NULL}, {"ParInt", "IopParInt", 1, "Returns the value of an 'int' parameter or sets its value if \".set\" is \ndefined.\n", 1, 8, "", 0, "", &IARGVALUE[158], 2, NULL, 0, 0, NULL}, {"ParDel", "IopParDel", 1, "Deletes the parameter with specified name.\n", 2, 8, "", 0, "", &IARGVALUE[160], 1, NULL, 0, 0, NULL}, {"Env", "IopEnv", 1, "Optionally sets and returns the value an environment variable.\n", 9, 8, "", 0, "", &IARGVALUE[161], 2, NULL, 0, 0, NULL}, {"AltStr", "IopAltStr", 0, "Returns one of two strings depending whether condition is \ntrue or false.\n", 9, 8, "", 0, "", &IARGVALUE[163], 3, NULL, 0, 0, NULL}, {"Alt", "IopAltStr", 1, "Returns one of two strings depending whether condition is \ntrue or false.\n", 9, 8, "", 0, "", &IARGVALUE[166], 3, NULL, 0, 0, NULL}, {"Foreach", "IopPrintForeach", 1, "prints each element in the list with specified separators.\n", 9, 8, "", 0, "", &IARGVALUE[169], 4, NULL, 0, 0, NULL}, {"subStr", "IcaOpSubStr", 0, "", 9, 8, "", 0, "", &IARGVALUE[173], 3, NULL, 0, 0, NULL}, {"System", "IopSystem", 0, "", 9, 8, "", 0, "", &IARGVALUE[176], 5, NULL, 0, 0, NULL}, {"FileOpen", "IopFileOpen", 1, "", 3, 8, "file", 0, "", &IARGVALUE[181], 2, NULL, 0, 0, NULL}, {"FileClose", "IopFileClose", 1, "", 2, 8, "", 0, "", &IARGVALUE[183], 1, NULL, 0, 0, NULL}, {"FileName", "IopFileName", 1, "", 9, 8, "", 0, "", &IARGVALUE[184], 1, NULL, 0, 0, NULL}, {"Print", "IopPrint", 1, "Prints a string.", 2, 8, "", 0, "", &IARGVALUE[185], 4, NULL, 0, 0, NULL}, {"dp", "IopDebugPrint", 1, "Printing within the debugger", 2, 8, "", 0, "", &IARGVALUE[189], 1, NULL, 0, 0, NULL}, {"print", "IopPrint", 0, "Prints a string.", 2, 8, "", 0, "", &IARGVALUE[190], 4, NULL, 0, 0, NULL}, {"StrFormat", "IopPrintFormat", 0, "Prints a string with the specified format.\n", 9, 8, "", 0, "", &IARGVALUE[194], 5, NULL, 0, 0, NULL}, {"It", "IopInToken", 1, "Returns the input token (token which serves as input for \nthe current production through the $In command)\n", 9, 8, "", 0, "", &IARGVALUE[199], 1, NULL, 0, 0, NULL}, {"itc", "IopInTokenCode", 0, "", 9, 8, "", 0, "", &IARGVALUE[200], 0, NULL, 0, 0, NULL}, {"Itc", "IopInTokenCode", 1, "Returns the token code of the input token (see $It)\n", 9, 8, "", 0, "", &IARGVALUE[200], 0, NULL, 0, 0, NULL}, {"ct", "IopCurrToken", 0, "", 9, 8, "", 0, "", &IARGVALUE[200], 0, NULL, 0, 0, NULL}, {"Ct", "IopCurrToken", 1, "Returns the current token (string parsed in the preceding\nparsing block)\n", 9, 8, "", 0, "", &IARGVALUE[200], 0, NULL, 0, 0, NULL}, {"Key", "IopKey", 1, "Returns the symbolic tag associated with the given list element\n", 9, 8, "", 0, "", &IARGVALUE[200], 1, NULL, 0, 0, NULL}, {"IsLast", "IopIsLast", 1, "Returns TRUE if the element is the last in the list.\n", 1, 8, "", 0, "", &IARGVALUE[201], 0, NULL, 0, 0, NULL}, {"IsFirst", "IopIsFirst", 1, "Returns TRUE if the element is the first in the list.\n", 1, 8, "", 0, "", &IARGVALUE[201], 0, NULL, 0, 0, NULL}, {"ListLen", "IopListLen", 1, "Returns the number of elements in the list\n", 1, 8, "", 0, "", &IARGVALUE[201], 1, NULL, 0, 0, NULL}, {"Fip", "IopFip", 1, "Returs the file pointer to the current \nposition in the input file\n", 1, 8, "", 0, "", &IARGVALUE[202], 1, NULL, 0, 0, NULL}, {"fip", "IopFip", 0, "", 1, 8, "", 0, "", &IARGVALUE[203], 1, NULL, 0, 0, NULL}, {"File", "IopFile", 1, "Returns the file object of the currrent job.\n", 3, 8, "file", 0, "", &IARGVALUE[204], 0, NULL, 0, 0, NULL}, {"skip", "IopSetSkip", 0, "Controls skipping of white space during parsing which is\nactive by default.\n", 2, 8, "", 0, "", &IARGVALUE[204], 2, NULL, 0, 0, NULL}, {"Skip", "IopSetSkip", 1, "Controls skipping of white space during parsing which is\nactive by default.\n", 2, 8, "", 0, "", &IARGVALUE[206], 2, NULL, 0, 0, NULL}, {"Eval", "IopEval", 1, "", 2, 8, "", 0, "", &IARGVALUE[208], 1, NULL, 0, 0, NULL}, {"Trim", "IopStrTrim", 1, "Cuts leading or trailing white space from the string.", 9, 8, "", 0, "", &IARGVALUE[209], 2, NULL, 0, 0, NULL}, {"1", "IopSubMatch", 1, "Returns the first submatch of the most recent regular expression\nmatching. The submatch is indicated by parentheses within the\nregular expression and the opening parenthesis is used for counting.\n$2, $3 until $9 will return the submatches with the respective\nnumber. $0 returns the entire match.\n", 9, 8, "", 0, "", &IARGVALUE[211], 1, NULL, 0, 0, NULL}, {"2", "IopSubMatch", 0, "", 9, 8, "", 0, "", &IARGVALUE[212], 1, NULL, 0, 0, NULL}, {"3", "IopSubMatch", 0, "", 9, 8, "", 0, "", &IARGVALUE[213], 1, NULL, 0, 0, NULL}, {"4", "IopSubMatch", 0, "", 9, 8, "", 0, "", &IARGVALUE[214], 1, NULL, 0, 0, NULL}, {"5", "IopSubMatch", 0, "", 9, 8, "", 0, "", &IARGVALUE[215], 1, NULL, 0, 0, NULL}, {"6", "IopSubMatch", 0, "", 9, 8, "", 0, "", &IARGVALUE[216], 1, NULL, 0, 0, NULL}, {"7", "IopSubMatch", 0, "", 9, 8, "", 0, "", &IARGVALUE[217], 1, NULL, 0, 0, NULL}, {"8", "IopSubMatch", 0, "", 9, 8, "", 0, "", &IARGVALUE[218], 1, NULL, 0, 0, NULL}, {"9", "IopSubMatch", 0, "", 9, 8, "", 0, "", &IARGVALUE[219], 1, NULL, 0, 0, NULL}, {"SetFunctions", "IopSetFunctions", 0, "", 2, 8, "", 0, "", &IARGVALUE[220], 1, NULL, 0, 0, NULL}, {"SetResult", "QuerySaveResult", 0, "", 2, 8, "", 0, "", &IARGVALUE[221], 2, NULL, 0, 0, NULL}, {"DbGroup", "QueryDBGroup", 0, "", 3, 8, "dbGroup", 0, "", &IARGVALUE[223], 3, NULL, 0, 0, NULL}, {"SetRetrRange", "QueryRangeSearch", 0, "", 3, 8, "set", 0, "", &IARGVALUE[226], 6, NULL, 0, 0, NULL}, {"SetRetrStr", "QueryStrSearch", 0, "", 3, 8, "set", 0, "", &IARGVALUE[232], 3, NULL, 0, 0, NULL}, {"SetLogOp", "QueryLogOp", 0, "", 3, 8, "set", 0, "", &IARGVALUE[235], 3, NULL, 0, 0, NULL}, {"SetLinkOp", "QueryLinkOp", 0, "", 3, 8, "set", 0, "", &IARGVALUE[238], 3, NULL, 0, 0, NULL}, {"SetAssign", "QuerySetAssign", 0, "", 3, 8, "set", 0, "", &IARGVALUE[241], 2, NULL, 0, 0, NULL}, {"SetGet", "QuerySetGet", 0, "", 3, 8, "set", 0, "", &IARGVALUE[243], 2, NULL, 0, 0, NULL}, {"MakeWild", "QueryOpMakeWild", 0, "", 9, 8, "", 0, "", &IARGVALUE[245], 1, NULL, 0, 0, NULL}, {"GCGwordsearch", "GCGWordsearch", 0, "", 2, 8, "", 0, "", &IARGVALUE[246], 2, NULL, 0, 0, NULL}, {"setFormat", "EntryIopSetFieldFormat", 0, "", 2, 8, "", 0, "", &IARGVALUE[248], 2, NULL, 0, 0, NULL}, {"SeqGet2Bit", "SeqIopGet2Bit", 1, "Reads a sequence in GCG's 2BIT format into supplied sequence object \nwhich can be created by $SeqNew. If the sequence object contains \na sequence already the sequence read is appended. This is useful\nto collect split sequences as found in the GCG formatted sequence\ndatabanks.\n", 2, 8, "", 0, "", &IARGVALUE[250], 3, NULL, 0, 0, NULL}, {"SeqCut", "SeqIopCut", 1, "Cuts away specified part of the sequence\n", 2, 8, "", 0, "", &IARGVALUE[253], 3, NULL, 0, 0, NULL}, {"SeqNew", "SeqIopNew", 1, "Creates a new sequence object.\n", 3, 8, "sequence", 0, "", &IARGVALUE[256], 2, NULL, 0, 0, NULL}, {"SeqApp", "SeqIopApp", 1, "", 3, 8, "sequence", 0, "", &IARGVALUE[258], 2, NULL, 0, 0, NULL}, {"SeqMake", "SeqIopMake", 1, "", 3, 8, "sequence", 0, "", &IARGVALUE[260], 1, NULL, 0, 0, NULL}, {"SeqTrunc", "SeqIopTrunc", 1, "", 3, 8, "sequence", 0, "", &IARGVALUE[261], 2, NULL, 0, 0, NULL}, {"SeqLen", "SeqIopLen", 1, "Returns the length of the sequence.", 1, 8, "", 0, "", &IARGVALUE[263], 1, NULL, 0, 0, NULL}, {"SeqPrint", "SeqIopPrint", 1, "Prints a sequence in various formats.", 2, 8, "", 0, "", &IARGVALUE[264], 5, NULL, 0, 0, NULL}, {"calc", "IopCalc", 0, "", 1, 8, "", 0, "", &IARGVALUE[269], 3, NULL, 0, 0, NULL}, {"strlen", "IopStrlen", 0, "", 1, 8, "", 0, "", &IARGVALUE[272], 1, NULL, 0, 0, NULL}, {"Strlen", "IopStrlen", 0, "", 1, 8, "", 0, "", &IARGVALUE[273], 1, NULL, 0, 0, NULL}, {"StrLen", "IopStrLen", 1, "", 1, 8, "", 0, "", &IARGVALUE[274], 1, NULL, 0, 0, NULL}, {"StrApp", "IopStrApp", 1, "", 2, 8, "", 0, "", &IARGVALUE[275], 2, NULL, 0, 0, NULL}, {"StrTrans", "IopStrTrans", 1, "Translates all characters in the 'from' set to the character\nat the equivalent position in the 'to' set.\n", 9, 8, "", 0, "", &IARGVALUE[277], 3, NULL, 0, 0, NULL}, {"StrReplace", "IopStrReplace", 1, "Translates all occurences of 'from' \nto strings specified by 'to'.\n", 9, 8, "", 0, "", &IARGVALUE[280], 3, NULL, 0, 0, NULL}, {"StrLower", "IopStrLower", 1, "Converts all characters of the input string into lower case.\n", 9, 8, "", 0, "", &IARGVALUE[283], 1, NULL, 0, 0, NULL}, {"StrUpper", "IopStrUpper", 1, "Converts all characters of the input string into upper case.\n", 9, 8, "", 0, "", &IARGVALUE[284], 1, NULL, 0, 0, NULL}, {"StrPad", "IopStrPad", 1, "Pads a string with specified character if input string is \nshorter than requested length. \n", 9, 8, "", 0, "", &IARGVALUE[285], 3, NULL, 0, 0, NULL}, {"HtmlSpace", "IopHtmlSpace", 0, "", 2, 8, "", 0, "", &IARGVALUE[288], 3, NULL, 0, 0, NULL}, {"=", "IopAss", 0, "", 6, 8, "", 0, "", &IARGVALUE[291], 2, NULL, 0, 0, NULL}, {"+", "IopAdd", 0, "", 1, 8, "", 0, "", &IARGVALUE[293], 2, NULL, 0, 0, NULL}, {"<", "IopLT", 0, "", 1, 8, "", 0, "", &IARGVALUE[295], 2, NULL, 0, 0, NULL}, {">", "IopGT", 0, "", 1, 8, "", 0, "", &IARGVALUE[297], 2, NULL, 0, 0, NULL}, {"==", "IopEq", 0, "", 1, 8, "", 0, "", &IARGVALUE[299], 2, NULL, 0, 0, NULL}, {"*", "IopMul", 0, "", 1, 8, "", 0, "", &IARGVALUE[301], 2, NULL, 0, 0, NULL}, {"/", "IopDivide", 0, "", 1, 8, "", 0, "", &IARGVALUE[303], 2, NULL, 0, 0, NULL}, {"!=", "IopNEq", 0, "", 1, 8, "", 0, "", &IARGVALUE[305], 2, NULL, 0, 0, NULL}, {"-", "IopSubt", 0, "", 1, 8, "", 0, "", &IARGVALUE[307], 2, NULL, 0, 0, NULL}, {"+=", "IopAddAss", 0, "", 1, 8, "", 0, "", &IARGVALUE[309], 2, NULL, 0, 0, NULL}, {"&&", "IopLogAnd", 0, "", 1, 8, "", 0, "", &IARGVALUE[311], 2, NULL, 0, 0, NULL}, {"||", "IopLogOr", 0, "", 1, 8, "", 0, "", &IARGVALUE[313], 2, NULL, 0, 0, NULL}, {"debug", "IopSetDebug", 0, "", 2, 8, "", 0, "", &IARGVALUE[315], 1, NULL, 0, 0, NULL}, {"labelAdd", "TemplIcaAddLabel", 0, "", 2, 8, "", 0, "", &IARGVALUE[316], 2, NULL, 0, 0, NULL}, {"SdbRetrieve", "SdbRetrieve", 0, "", 9, 8, "", 0, "", &IARGVALUE[318], 2, NULL, 0, 0, NULL}, {"SdbPop", "SdbPop", 0, "", 2, 8, "", 0, "", &IARGVALUE[320], 0, NULL, 0, 0, NULL}, {"SdbPush", "SdbPush", 0, "", 2, 8, "", 0, "", &IARGVALUE[320], 0, NULL, 0, 0, NULL}, {"SdbEval", "SdbEval", 0, "", 9, 8, "", 0, "", &IARGVALUE[320], 0, NULL, 0, 0, NULL}, {"SdbChunk", "SdbChunk", 0, "", 2, 8, "", 0, "", &IARGVALUE[320], 3, NULL, 0, 0, NULL}, {"SdbFeature", "SdbFeature", 0, "", 2, 8, "", 0, "", &IARGVALUE[323], 1, NULL, 0, 0, NULL}, {"SdbComplement", "SdbComplement", 0, "", 2, 8, "", 0, "", &IARGVALUE[324], 0, NULL, 0, 0, NULL}, {"SdbReplace", "SdbReplace", 0, "", 2, 8, "", 0, "", &IARGVALUE[324], 0, NULL, 0, 0, NULL}, {"SdbJoin", "SdbJoin", 0, "", 2, 8, "", 0, "", &IARGVALUE[324], 0, NULL, 0, 0, NULL}, {"SeqGetFt", "SdbGetFeatureSequence", 0, "", 9, 8, "", 0, "", &IARGVALUE[324], 5, NULL, 0, 0, NULL}, {"SdbFunctions", "SdbFunctions", 0, "", 2, 8, "", 0, "", &IARGVALUE[329], 0, NULL, 0, 0, NULL}, {"", "", 0, "", 2, 8, "", 0, "", &IARGVALUE[329], 0, NULL, 0, 0, NULL} }; #endif NULL, 0, 0, NULL}, {"SdbReplace"srs/src/cursor.c char cursor_ID[] = "$Id: cursor.c,v 1.12 1996/12/04 19:49:28 etzold Exp $"; /* ** ** $RCSfile: cursor.c,v $ ** $Revision: 1.12 $ ** $Date: 1996/12/04 19:49:28 $ ** $Author: etzold $ ** ** $Locker: $ ** $State: Exp $ ** ** ** Copyright by Thure Etzold ** ** Author: Anatoly Ulyanov ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387451 ** Email: ulyanov@embl-heidelberg.de ** */ #include #include #include #include "message.h" #include "futil.h" #include "regexp.h" #include "sm.h" #include "toklist.h" #include "cursor.h" /**api* CursorNew *************************************************** ** ** Create a new cursor object. ** ** INPUT: ** ** RETURNS: cursor object */ CURSORo *CursorNew() { CURSORo *cursor; if( (cursor = (CURSORo *) calloc (sizeof(CURSORo), 1)) == NULL ) _ErrExit2 (e__allocfail, "Cursor object"); return(cursor); } /**api* CursorDelete *************************************************** ** ** Delete the cursor object. ** ** INPUT: address of cursor object [W] ** ** IMPLICIT: ** ** RETURNS: */ void CursorDelete(CURSORo **cursor) { if (*cursor) free (*cursor); *cursor = NULL; } /**api* CursorSave *************************************************** ** ** Copy the content of cursor object. ** ** INPUT: target cursor object [W] ** cursor object to be saved [R] ** ** RETURNS: */ void CursorSave(CURSORo *cursorSave, CURSORo *cursor) { memcpy(cursorSave, cursor, sizeof(CURSORo)); } /**api* CursorRestore *************************************************** ** ** ** Restore the content of cursor object. ** ** INPUT: target cursor object [W] ** cursor object to be restored [R] ** ** RETURNS: */ void CursorRestore(CURSORo *cursor, CURSORo *cursorRestore) { memcpy(cursor, cursorRestore, sizeof(CURSORo)); } /**api* CursorAdvance *************************************************** ** ** Move cursor to the next non space position in input stream. ** ** INPUT: o pointer to the cursor object [R] ** o string of the white space characters [R] ** o white space character represented as a regular ** expression. NULL if it is represented as string ** o flag to suppress skipping [R] ** o flag is set to FALSE when skipping is already done ** ** RETURN: o TRUE if cursor can be proceed ** o FALSE if input is exhausted */ INT4 CursorAdvance(CURSORo *cursor, char *skipChars, regexp *re, INT4 isNoSkip, INT4 *doAdvance) { char *string; INT4 len; /* skip white space AND comments using regular expression */ if (!isNoSkip && *skipChars) { while (cursor->len) { *doAdvance = 0; len = MIN(cursor->len, strspn(cursor->current, skipChars)); cursor->len -= len; cursor->current += len; if (re) { /* test regular expr for comments */ if (RegExec (re, cursor->current) == 1) { len = MIN(cursor->len, (INT4)(re->endp[0] - re->startp[0])); cursor->current += len; cursor->len -= len; continue; } } break; } } if (cursor->len) return(TRUE); else if (!cursor->tokList || !TokGetMore(cursor->tokList, &string, &len)) { return(FALSE); } else { cursor->current = string; cursor->len = len; return(CursorAdvance(cursor, skipChars, re, isNoSkip, doAdvance)); } } /**api* CursorIterate *************************************************** ** ** Move cursor to the next token skipping the rest of the token ** ** INPUT: o pointer to the cursor object [R] ** o string of the white space characters [R] ** o white space character represented as a regular ** expression. NULL if it is represented as string ** o flag to suppress skipping [R] ** o flag is set to FALSE when skipping is already done ** ** RETURN: o TRUE if cursor can be proceed ** o FALSE if input is exhausted */ INT4 CursorIterate(CURSORo *cursor, char *skipChars, regexp *re, INT4 isNoSkip, INT4 *doAdvance) { char *string; INT4 len; if (!TokGetMore(cursor->tokList, &string, &len) ) return(FALSE); else { cursor->current = string; cursor->len = len; return(CursorAdvance(cursor, skipChars, re, isNoSkip, doAdvance)); } } /**api* CursorResetMatch *************************************************** ** ** This function sets match length to zero ** ** INPUT: pointer to the cursor object [R] ** ** RETURN: */ void CursorResetMatch (CURSORo *cursor) { cursor->matchLen = 0; } /**api* CursorIncrement *************************************************** ** ** This function must be called after (not) matches. ** ** INPUT: pointer to the cursor object [R] ** ** RETURN: */ void CursorIncrement(CURSORo *cursor) { if (cursor) { cursor->current += cursor->matchLen; cursor->len -= cursor->matchLen; cursor->matchLen = 0; } } /**api* CursorMove *************************************************** ** ** This function must be called after move statement ** ** INPUT: pointer to the cursor object [R] ** ** RETURN: */ void CursorMove(CURSORo *cursor) { cursor->current += cursor->matchLen; cursor->len -= cursor->matchLen; if( cursor->len < 0 ) cursor->len = 0; cursor->matchLen = 0; } /**api* CursorRestrictLength *********************************************** ** ** Restrict the cursor length to some particular size by temporarily ** string terminator. It is required to find correct biggest regular ** expression. See CursorRestoreChar ** ** INPUT: pointer to the cursor object [R] ** ** RETURN: */ void CursorRestrictLength(CURSORo *cursor) { INT4 length; length = cursor->len; cursor->saveChar = cursor->current[length]; cursor->saveCharPtr = &cursor->current[length]; *cursor->saveCharPtr = '\0'; } /**api* CursorRestrictLength *********************************************** ** ** Restrict the cursor length to some particular size by temporarily ** string terminator. It is required to find correct biggest regular ** expression. See CursorRestoreChar ** ** INPUT: pointer to the cursor object [R] ** ** RETURN: */ Int4 CursorSetTmpLength (CURSORo *cursor, Int4 len) { return (cursor->len = MIN(len, cursor->len)); } Int4 CursorResetLength (CURSORo *cursor, Int4 length) { cursor->len = length; } void CursorReset (CURSORo *cursor) { cursor->len = 0; } Int4 CursorGetLength (CURSORo *cursor) { return cursor->len; } Int4 CursorSetFile (CURSORo *cursor, FILEo *file) { Int4 l; char *s; if (file && (s = FileGetLn (file))) { l = strlen (s); CursorSetString (cursor, s, l); } } Int4 CursorSetString (CURSORo *cursor, char *s, Int4 len) { cursor->current = s; cursor->len = len; } /**api* CursorRestoreChar *********************************************** ** ** Restore the temporal string terminator in the input token ** See CursorRestrictLength ** ** INPUT: pointer to the cursor object [R] ** ** RETURN: */ void CursorRestoreChar(CURSORo *cursor) { *cursor->saveCharPtr = cursor->saveChar; } /**api* CursorDefineAnchor *********************************************** ** ** Set a cursor anchor. The anchor is used for determination of ** global cursor movement. ** ** INPUT: pointer to the cursor object [R] ** ** RETURN: */ void CursorDefineAnchor(CURSORo *cursor, CURSORoANCHOR *anchor) { anchor->begin = cursor->current; anchor->tokListBuff = TokGetBuff (cursor->tokList); } /**api* CursorGetBegin *********************************************** ** ** Get the beginning of the current input token ** ** INPUT: pointer to the cursor object [R] ** ** RETURN: pointer to the beginning of input token */ char *CursorGetBegin(CURSORo *cursor) { return(cursor->begin); } /**api* CursorGetPtr *********************************************** ** ** Get the pointer to the current position the the input token ** ** INPUT: pointer to the cursor object [R] ** ** RETURN: current position the the input token */ char *CursorGetPtr(CURSORo *cursor) { static char *emptyStr = ""; if(cursor->len == 0) return(emptyStr); else return(cursor->current); } /**api* CursorGetMatch *********************************************** ** ** Get the last match and its length ** ** INPUT: pointer to the cursor object [R] ** pointer to the last match [W] ** length of the last match [W] ** ** RETURN: */ void CursorGetMatch(CURSORo *cursor, char **ptr, INT4 *length) { *length = cursor->matchLen; *ptr = cursor->current; } /**api* CursorGetMatchCopy *********************************************** ** ** Get the copy of the current match. It would be store in a static ** buffer until the next call of the function. ** ** INPUT: pointer to the cursor object [R] ** ** RETURN: pointer to copy of the match */ char *CursorGetMatchCopy(CURSORo *cursor) { static SMoBUFF *matchBuff = NULL; matchBuff = BuffInit(matchBuff, TOKxMAXTOKBUFFSIZE); if(cursor->len == 0) return(""); else { BuffCopyNChar(matchBuff, cursor->current, cursor->matchLen); BuffCopyNChar(matchBuff, "\0", 1); return(BuffGetPtr(matchBuff)); } } /**api* CursorSetMatch *********************************************** ** ** Set the match length ** ** INPUT: pointer to the cursor object [W] ** length of the match [R] ** ** RETURN: */ void CursorSetMatch(CURSORo *cursor, INT4 len) { cursor->matchLen = len; } /**api* CursorSetLength *********************************************** ** ** Set the match length ** ** INPUT: pointer to the cursor object [W] ** length of the match [R] ** ** RETURN: */ void CursorSetLength(CURSORo *cursor, INT4 len) { cursor->matchLen = MIN(len, cursor->len); } /**api* CursorReplaceMatch *********************************************** ** ** Replace the match by defined string ** ** INPUT: pointer to the cursor object [W] ** string to replace [R] ** length of the string [R] ** ** RETURN: ** */ void CursorReplaceMatch(CURSORo *cursor, char *newMatch, INT4 newLen) { cursor->current += TokReplaceIn(cursor->tokList, cursor->current, cursor->matchLen, newMatch, newLen); cursor->len += (newLen - cursor->matchLen); cursor->matchLen = newLen; } /**api* CursorSetGlobalMatch *********************************************** ** ** Set the global match ** ** INPUT: pointer to the cursor object [W] ** anchor of the cursor object [R] ** ** RETURN: */ void CursorSetGlobalMatch(CURSORo *cursor, CURSORoANCHOR *anchor) { INT4 len; char *tokListBuff; tokListBuff = TokGetBuff (cursor->tokList); if (tokListBuff && tokListBuff != anchor->tokListBuff) anchor->begin += tokListBuff - anchor->tokListBuff; len = (INT4)(cursor->current - anchor->begin); cursor->matchLen = len; cursor->len += len; cursor->current = anchor->begin; } /**api* CursorLength *********************************************** ** ** Get the the size of the string from current position in the ** token until the end. ** ** INPUT: pointer to the cursor object [W] ** ** RETURN: rest length of input token */ INT4 CursorLength(CURSORo *cursor) { return(cursor->len); } /**api* CursorIsBegin *********************************************** ** ** Check if the cursor is at the beginning of the input token ** ** INPUT: pointer to the cursor object [R] ** ** RETURN: TRUE if cursor points to the token beginning ** FALSE otherwise */ INT4 CursorIsBegin(CURSORo *cursor) { return(cursor->current == cursor->begin); } /**api* CursorIsLineStart *********************************************** ** ** Check if the cursor is at the beginning of the input token ** and if the previous character is the "new line" ** ** INPUT: pointer to the cursor object [R] ** ** RETURN: TRUE if cursor points to the token beginning ** FALSE otherwise */ INT4 CursorIsLineStart(CURSORo *cursor) { return(cursor->begin == cursor->current || cursor->begin[-1] == '\n'); } /**api* CursorIsEnd *********************************************** ** ** Check if the cursor is at the end of the input token ** ** INPUT: pointer to the cursor object [R] ** ** RETURN: TRUE if cursor points to the token end ** FALSE otherwise */ INT4 CursorIsEnd(CURSORo *cursor) { return (cursor->len == 0); } /**api* CursorIsMoved *********************************************** ** ** Check if the cursor is not at the beginning of the input token ** It is opposite to CursorIsBegin function. ** ** INPUT: pointer to the cursor object [R] ** ** RETURN: TRUE if cursor does not point to the token beginning ** FALSE otherwise */ INT4 CursorIsMoved(CURSORo *cursor, CURSORoANCHOR *anchor) { return(cursor->current != anchor->begin); } /**api* CursorIsInstall *********************************************** ** ** Check if the cursor is installed at the beginning of the input token ** ** INPUT: pointer to the cursor object [R] ** ** RETURN: TRUE if cursor installs to the token beginning ** FALSE otherwise */ INT4 CursorIsInstall(CURSORo *cursor) { return(cursor->isInstall); } /**api* CursorInstall *************************************************** ** ** Install the cursor is at the beginning of the input token ** ** INPUT: pointer to the cursor object [W] ** input token [R] ** input token list [R] ** ** RETURN: */ void CursorInstall(CURSORo *cursor, TOKoTOKEN *token, TOKoLIST *tokList) { if(token) { cursor->len = TokGetLength(token); cursor->begin = TokGetString(tokList, token); cursor->isInstall = TRUE; } else { cursor->len = 0; cursor->begin = ""; cursor->isInstall = FALSE; } cursor->current = cursor->begin; cursor->tokList = tokList; } : pointer to the cursor object [W] ** input token [R] ** input token list [R] ** ** RETURN: */ void CursorInstall(CURSORo *cursor, TOKoTOKEN *token, TOKoLIST *tokList) { if(token) { cursor->len = TokGetLength(token); cursor->begin = TokGetString(tokList, token); cursor->isInstall = TRUE; } else { cursor->len = 0; cursor->begin = ""srs/src/cursor.h char *current; INT4 len; INT4 matchLen; char saveChar; char *saveCharPtr; char *begin; TOKoLIST *tokList; INT4 isInstall; } CURSORo; typedef struct CURSORoANCHOR { char *begin; char *tokListBuff; } CURSORoANCHOR; typedef struct regexp *dummytointroducestructtagregexp; CURSORo *CursorNew(); INT4 CursorAdvance(CURSORo *cursor, char *skipChars, struct regexp *re, INT4 isNoSkip, INT4 *doAdvance); INT4 CursorIsBegin(CURSORo *cursor); INT4 CursorIsEnd(CURSORo *cursor); INT4 CursorIsLineStart(CURSORo *cursor); INT4 CursorIsMoved(CURSORo *cursor, CURSORoANCHOR *anchor); INT4 CursorIterate(CURSORo *cursor, char *skipChars, struct regexp *re, INT4 isNoSkip, INT4 *doAdvance); INT4 CursorIsInstall(CURSORo *cursor); INT4 CursorLength(CURSORo *cursor); char *CursorGetPtr(CURSORo *cursor); char *CursorGetBegin(CURSORo *cursor); void CursorDefineAnchor(CURSORo *cursor, CURSORoANCHOR *anchor); void CursorDelete(CURSORo **cursor); void CursorGetMatch(CURSORo *cursor, char **ptr, INT4 *length); void CursorMove(CURSORo *cursor); void CursorIncrement(CURSORo *cursor); void CursorInstall(CURSORo *cursor, TOKoTOKEN *token, TOKoLIST *tokList); void CursorResetMatch(CURSORo *cursor); void CursorRestore(CURSORo *cursor, CURSORo *cursorRestore); void CursorRestoreChar(CURSORo *cursor); void CursorRestrictLength(CURSORo *cursor); void CursorSave(CURSORo *cursorSave, CURSORo *cursor); void CursorSetGlobalMatch(CURSORo *cursor, CURSORoANCHOR *anchor); void CursorSetLength(CURSORo *cursor, INT4 len); void CursorSetMatch(CURSORo *cursor, INT4 len); void CursorReplaceMatch(CURSORo *cursor, char *newMatch, INT4 newLen); char* CursorGetMatchCopy (CURSORo *cursor); sorRestore(CURSORo *cursor, CURSORo *cursorRestore); void CursorRestoreChar(CURSORo *cursrs/src/def.c char def_ID[] = "$Id: def.c,v 1.8 1997/03/19 20:41:40 srs Exp $"; /* ** ** $RCSfile: def.c,v $ ** $Revision: 1.8 $ ** $Date: 1997/03/19 20:41:40 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** module with general purpose functions. ** file has sections for individual programmers ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include "def.h" /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Thure's functions */ /* function is called via _addObj macro */ void *addObj (char **ptr, Int4 *n, Int4 *allocN, Int4 size) { char *tmp; if (*n >= *allocN) { if (!*n) { *allocN = 10; *ptr = malloc (size * *allocN); } else { *allocN *= 2; *ptr = realloc (*ptr, size * *allocN); } } tmp = *ptr + size * (*n)++; memset (tmp, 0, size); return tmp; } void MemMove (char *to, char *from, int len) { #ifdef sun char *tmp; tmp = (char *) malloc (len); memcpy (tmp, from, len); memcpy (to, tmp, len); free (tmp); #else memmove (to, from, len); #endif } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Anatoly's functions */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Giorgio's functions */ /**api* align ************************************************************ ** ** Calculates a Word-aligned offset for a data item ** ** INPUT: the current offset ** the size of the item to be aligned ** RETURNS: the aligned offset for the item */ int align(int pos, int sz) { int off; if (sz>=sizeof(Word)) sz=sizeof(Word); off=pos%sz; return off?(sz-off):0; } /**api* HashGo *********************************************************** ** ** Incremental rehashing macro for hash values calculated with _hash ** This function "rewinds" or "fast forwards" the hash value ** If the n-th last value from which 'sum' was calculated was ** modified, sum can be updated with the formula: ** hashGo(sum,-n); sum^=old_val; ...; sum^=new_val; hashGo(sum, n); ** ** INPUT: [W] the hash value to be modified (32 bit) ** the index of the modified item */ void hashGo(UINT4* s, INT4 index) { UINT4 sum=*s; UINT4 disp=(UINT4)index & 31; disp=(disp<<2+disp)&31; *s=(sum>>disp)^(sum<<(32-disp)); } UINT4 CharHash(char* p) { UINT4 sum=0; char* stop=p+strlen(p); while (p!=stop) _hash(sum,*p++); return sum; } UINT4 CharHashLen(char* p, int len) { UINT4 sum=0; char* stop=p+len; while (p!=stop) _hash(sum,tolower(*p++)); return sum; } char MPtrBuffer[100]; void stopProg(char *msg) { printf(msg); printf("\n"); exit(1); } void checkProg(char *msg) { printf(msg); printf("\n"); } srs/src/def.h ** ** $RCSfile: def.h,v $ ** $Revision: 1.8 $ ** $Date: 1997/03/17 23:23:58 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** this file is included by all SRS modules. ** sections exist for each programmer to insert definitions they ** think should be visible to all modules ** */ #ifndef DEF #define DEF typedef char *ID; typedef char *IDo; typedef unsigned char *IDPTR; typedef unsigned long ULONG; #ifdef dos typedef long INT4; typedef long Int4; typedef unsigned long UINT4; typedef unsigned long Uint4; #else typedef int INT4; typedef int Int4; typedef unsigned int UINT4; typedef unsigned int Uint4; #endif typedef UINT4 FIP; typedef UINT4 Fip; #ifndef TRUE # define TRUE 1 # define FALSE 0 #endif #ifndef NULL # define NULL 0L #endif typedef INT4 (*FUNC)(); typedef INT4 (*Func)(); typedef void (*VFUNC)(); typedef struct SMoBUFF *(*BFUNC)(); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Thure's definitions */ void *addObj (char **ptr, Int4 *n, Int4 *allocN, Int4 size); #define _addObj(x, n, allocN, type)\ (type *) addObj ((char **) &x, &n, &allocN, sizeof (type)) #define _Index(x,y) ( ((x)-'a'+1) << 5) +((y)-'a'+1) void MemMove (char *to, char *from, int len); #ifndef sun # define _MemMove(x,y,l) memmove ((x),(y),(l)) /* _tolower returns uppercase letter if initially lowercase - on irix64!*/ # define _ToLower(x) tolower (x); # define _ToUpper(x) toupper (x) #else # define _MemMove(x,y,l) MemMove ((x),(y),(l)) # define _ToLower(x) tolower (x) # define _ToUpper(x) toupper (x) #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Anatoly's definitions */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Giorgio's definitions */ /********************************************* ** MACHINE-DESCRIBING DEFINITIONS */ /* UNIX */ /* description of the register width of the machine ** WORD= int type exactly fitting in one register ** WORD_BITS= number of bits of the register ** also used for alignement purposes */ #ifndef WORD #define WORD unsigned long #define Word unsigned long #define WORD_BITS 32 #endif /* definition of the type which can contain both a pointer ** and an integer value */ typedef WORD IntOrPtr; /********************************************* ** BASIC TYPE DEFINITIONS */ /* the type containing a logical variable ** in bit-fields, the use of unsigned is mandatory */ #ifndef BOOL #define BOOL unsigned int #endif /* good when casting/shifting bits */ #ifndef BYTE #define BYTE unsigned char #endif /* the iterator type, hiding implementation in the ** various data structures... as much as it is efficient */ /* typedef IntOrPtr Iter */ typedef void* Iter; /********************************************* ** LOW-LEVEL UTILITIES */ /* useful for making type-casts in complex pointer expressions ** a bit more readable */ #define cast(ptr,type) ((type)(ptr)) /* makes calls to function pointers more readable */ #define call(funcPtr) (*(funcPtr)) /* makes allocation of structs easier and more readable */ /**api* macro ************************************************************ ** ** Incremental hashing macro ** Rotates right sum by 5 bits (*index) and xores with num ** ** INPUT: [W] the hash value to be modified (32 bit) ** an unsigned integer (32 bit) to be added to ** the hash value */ #define _hash(sum, num) sum=(sum>>5)^(sum<<27)^num void hashGo(UINT4* sum, INT4 index); #define _talloc(type) ((type*)malloc(sizeof(type))) /* returns the pointer moved of the specified number of bytes ** and casts it to the required type. */ #define _ptrMove(ptr,nbyte,type) cast(cast(ptr,char*)+nbyte,type) /* returns the difference in bytes between 2 pointers */ #define _ptrDiff(ptr1, ptr2) (cast(ptr1, char*)-cast(ptr2, char*)) /* returns the offset of a certain attribute within a struct, ** cl=struct name, attr=name of the attribute ** can only be used in function bodies (cc complains) */ extern char MPtrBuffer[]; #define _attrOffs(cl, attr) displ(&cast(MPtrBuffer,cl*)->attr, MPtrBuffer) /* function to allocate aligned byte offset of attributes in a struct ** given: ** offset of the end of the struct ** the number of bytes to allocate to the new attribute ** returns: ** the offset where the new attribute starts */ int align(int currOffs, int allocSize); UINT4 CharHash (char* p); UINT4 CharHashLen (char *p, int len); /****************************** ** OLD macros ******************************/ #define typeAlloc(type) _talloc(type) #define offset(ptr,nbyte,type) _ptrMove(ptr,nbyte,type) #define displ(ptr1, ptr2) _ptrDiff(ptr1, ptr2) #define mPtr(cl, attr) _attrOffs(cl,attr) /*********************************************************************** ** DEBUGGING SUPPORT ** ** this macro generate debugging code if DEBUG ** is defined, else they do nothing ***********************************************************************/ /* the function used to stop the program when an exception is thrown. ** Set a breakpoint here if you want to see where the exception comes from */ void stopProg(char *msg); /* throws an exception */ #ifndef THROW #define THROW(except) \ (void)Message (6, f__exception, MSGxEXIT, (except), __FILE__, __LINE__) #endif /* if the condition specified is false, throws an exception */ #ifndef ASSERT #define ASSERT(cond,except) ((cond)? (void)0:THROW(except)) #endif /* prints a debug message */ #ifndef TRACE #define TRACE(cmd) ((void)0) #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #endif comes from */ void stopProg(char *msg); /* throws an exception */ #ifndef THROW #define THROW(except) \ (void)Message (6, f__exception, MSGxEXIT, (except), __FILE__, __LINE__) #endif /* if the condition specified is false, throws an exception */ #ifndef ASSERT #define ASSERT(cond,except) ((cond)? (void)0:THROW(except)) #endif /* #include /*********************************************************************** ** DICTIONARY size management */ UINT4 primes[]= { 1U,3U,7U,17U,31U,61U,127U,257U,509U, 1021U,2053U,4093U,8191U,16381U,32771U,65537U,131071U, 262147U,524287U,1048573U,2097143U,4194301U,8388617U,16777213U,33554467U, 67108859U,134217689U,268435459U,536870909U,1073741827U,2147483647U,4294967291U }; int numPrimes=32; UINT4 FindNextPrime(UINT4 num) { /* performs a range search on the prime number array */ int bott,top,curr; bott=0; top=numPrimes; while (top-bott>1) { curr=bott+((top-bott)>>1); if (num==primes[curr]) return primes[curr+1]; if (num1) { curr=bott+((top-bott)>>1); if (num==primes[curr]) return primes[curr-1]; if (numtab; currtab+dict->dim; curr++) *curr=NULL; dict->num=0; } DICTv DictCopyImpl(DICTv dict) { int size=sizeof(DICTo)+sizeof(DictElem)*(dict->dim-1); DICTv d=(DICTv)malloc(size); memcpy(d, dict, size); d->usage=1; return d; } DictElem* DictAddImpl (DICTv dict, void* key) { int dim=dict->dim; DictElem* curr=dict->tab+call(dict->myClass->hash)(key,dim); DictElem* last=dict->tab+dim; while (*curr) if (++curr==last) curr=dict->tab; return curr; } /* get element with same key if present, else add */ DictElem* DictSetImpl(DICTv dict, void* key) { CLASSoDICT* cl=dict->myClass; ValComparer equal=cl->equal; KeyAccessor toKey=cl->toKey; IntOrPtr toKeyInfo=cl->toKeyInfo; int dim=dict->dim; DictElem* curr=dict->tab+call(cl->hash)(key,dim); DictElem* last=dict->tab+dim; while (*curr && !call(equal)(key, toKey(curr, toKeyInfo))) { if (++curr==last) curr=dict->tab; } return curr; } /*********************************************************************/ int DictCreateDim=7; /**API* DictCreate ********************************************************* ** ** Creates a new empty DICTv ** ** INPUT: a dictionary class (CLASSoDICT structure) ** IMPLICIT: o the variable DictCreateDim (default=7) storing the ** initial size of the dictionary ** RETURNS: a dictionary */ DICTv DictCreate(CLASSoDICT* c) { DICTv d=(DICTv)malloc(sizeof(DICTo)+sizeof(DictElem)*(DictCreateDim-1)); d->myClass=c; d->dim=DictCreateDim; d->usage=1; DictClearImpl(d); return d; } /**API* DictDestroy ********************************************************* ** ** Destroys a dictionary. It does'nt destroy the dictionary class ** ** INPUT: [W] a DICTv */ void DictDestroy(DICTv dict) { if (dict && !--dict->usage) { DictClearImpl(dict); free(dict); } } /**API* DictCopy ********************************************************* ** ** Creates a dictionary copying another one. ** ** INPUT: a DICTv ** RETURNS: a new dictionary */ DICTv DictCopy(DICTv dict) { if (dict) dict->usage++; return dict; } /**API* DictOffset ********************************************************* ** ** Offsets all valid pointers inside a dictionary by a specified amount. ** Useful when the dictionary is used to index positions in a memory ** buffer which is being reallocated. The user can use this function ** to switch indexing to the new buffer. If not all entries in the DICTv ** are pointing to the buffer, DictOffsetWithin should be used. ** ** INPUT: [W] a DICTv ** a memory offset */ void DictOffset (DICTv dict, int offs) { DictElem* curr; for (curr=dict->tab; currtab+dict->dim; curr++) if (*curr) *(BYTE**)curr+=offs; } /**API* DictOffsetWithin ********************************************************* ** ** Offsets all pointers in a given address range inside a dictionary ** by a specified amount ** Useful when some entries in dictionary index positions in a memory ** buffer which is being reallocated. The user can use this function ** to switch indexing to the new buffer. If all valid entries in the DICTv ** are pointing to the buffer, DictOffset should be used. ** ** INPUT: [W] a DICTv ** the starting address of the memory range ** the length in bytes of the memory range ** the destination address ** */ void DictOffsetWithin(DICTv dict, DictElem buf, int len, DictElem newBuf) { DictElem* curr; DictElem elem; int offs=displ(newBuf,buf); for (curr=dict->tab; currtab+dict->dim; curr++) { elem=*curr; if (elem && elem>=buf && elemmyClass; KeyAccessor toKey=cl->toKey; IntOrPtr toKeyInfo=cl->toKeyInfo; d->myClass=cl; d->num=old->num; d->dim=newDim; d->usage=1; ASSERT(d->numtab; currtab+newDim; curr++) *curr=NULL; for (curr=old->tab; currtab+old->dim; curr++) { /* move value to new place */ if (*curr) *DictAddImpl(d, toKey(curr, toKeyInfo))=*curr; } DictDestroy(old); *dict=d; } /* insertion/removal */ /**API* DictAddGrow ********************************************************* ** ** Allocates a new entry, given the key where to insert. If ** the dictionary class allows repetitions, then more than one ** entry can have the same key. See also DictWith, DictNextWith ** ** INPUT: [W] a pointer to DICTv ** the pointer to the key value ** RETURNS: o the pointer to the entry (a void*) to be assigned ** to the structure to be inserted */ DictElem* DictAddGrow(DICTv* dict,void* key) { DICTv d=*dict; if (d->usage>1) { DictResize(dict,FindNextPrime(d->dim)); d=*dict; } if (d->myClass->repetitions) { if (++d->num>(d->dim*3>>2)) DictResize(dict,FindNextPrime(d->dim)); return DictAddImpl(*dict,key); } else { DictElem* el=DictSetGrow(dict, key); ASSERT(!*el, "DuplicateKey"); return el; } } /**API* DictSetGrow ********************************************************* ** ** Given a key, allocates a new entry if the key is not found, ** else returns the first entry which has the same key. Useful when ** adding a new element with the same key must replace the old element. ** See also DictAdd ** ** INPUT: [W] a pointer to DICTv ** the pointer to the key value ** RETURNS: o the pointer to the new entry (a void*) to be assigned ** if the key is not found, else a pointer to the already ** present entry */ DictElem* DictSetGrow(DICTv* dict, void* key) { DictElem* elem; if ((*dict)->usage>1) *dict=DictCopyImpl(*dict); elem=DictSetImpl(*dict,key); if (!*elem) { int num=++((*dict)->num); int dim=(*dict)->dim; if (num>(dim*3>>2)) { DictResize(dict,FindNextPrime(dim)); return DictAddImpl(*dict,key); } } return elem; } /**API* DictAddPtr ********************************************************* ** ** Adds a new element to the dictionary. The element must contain ** a valid key. While inserted into the dictionary, the key cannot be ** modified nor the structure reallocated. ** If the user to perform such an operation, it must remove the structure ** with DictRemovePtr, do the operation and insert it again with DictAddPtr. ** To reallocate an array of indexed structure, see DictOffsetWithin. ** ** INPUT: [W] a pointer to DICTv ** the pointer to the element ** RETURNS: o an iterator with the position of the inserted element ** the iterator is only valid until the next dictionary-modifying ** operation is performed */ Iter DictAddPtr(DICTv* dict, DictElem elem) { CLASSoDICT* cl=(*dict)->myClass; void* key=call(cl->toKey)(&elem, cl->toKeyInfo); DictElem* e=DictAddGrow(dict,key); *e=cast(elem, DictElem); return e; } /**API* DictSetPtr ********************************************************* ** ** Adds a new element to the dictionary or substitutes an already present ** element with the same key (see DictSetGrow) ** The element must contain a valid key. While inserted into the ** dictionary, the key cannot be modified nor the structure reallocated. ** If the user to perform such an operation, it must remove the structure ** with DictRemovePtr, do the operation and insert it again with DictAddPtr. ** To reallocate an array of indexed structure, see DictOffsetWithin. ** ** INPUT: [W] a pointer to DICTv ** the pointer to the element ** RETURNS: o an iterator with the position of the inserted/replaced element ** the iterator is only valid until the next dictionary-modifying ** operation is performed */ Iter DictSetPtr(DICTv* dict, DictElem elem) { CLASSoDICT* cl=(*dict)->myClass; void* key=call(cl->toKey)(&elem, cl->toKeyInfo); DictElem* e=DictSetGrow(dict,key); *e=cast(elem, DictElem); return e; } /**API* DictRemove ********************************************************* ** ** Removes the element at a given position ** The iterator can be obtained by using DictAddPtr, DictSetPtr, ** DictWith, DictWithPtr, DictFirst, DictNext, DictNextWith. ** ** INPUT: [W] a pointer to DICTv ** the iterator of the element */ void DictRemove (DICTv* dict, Iter i) { DICTv d=*dict; BOOL shared=d->usage>1; int dim=d->dim; DictElem* hole=(DictElem*)i; DictElem sharedVal; ASSERT(hole && *hole, "NoSuchElem"); if ((--d->num)<(dim>>2) || shared) { sharedVal=*hole; *hole=NULL; DictResize(dict, dim=FindPrevPrime(dim)); if (shared) *hole=sharedVal; /* revert value for shared*/ } else { CLASSoDICT* dc=d->myClass; ValHasher hash=dc->hash; KeyAccessor toKey=dc->toKey; IntOrPtr toKeyInfo=dc->toKeyInfo; DictElem* curr=hole+1; DictElem* last=d->tab+dim; if (curr==last) curr=d->tab; while (*curr) { DictElem* wanted=d->tab+call(hash)(toKey(curr,toKeyInfo),dim); if ((holecurr): (wanted<=hole && wanted>curr)) { *hole=*curr; hole=curr; } if (++curr==last) curr=d->tab; } *hole=NULL; } } /**API* DictRemoveWith ********************************************************* ** ** Removes the elements having a given key value ** ** INPUT: [W] a pointer to DICTv ** the pointer to the key value */ void DictRemoveWith (DICTv* dict, void* key) { Iter i; while (i=DictWith(*dict,key)) DictRemove(dict,i); } /**API* DictRemovePtr ********************************************************* ** ** Removes a certain element (identified by it's memory pointer) ** ** INPUT: [W] a pointer to DICTv ** the pointer to the element */ void DictRemovePtr (DICTv* dict, DictElem elem) { DictRemove(dict,DictWithPtr(*dict, elem)); } /**API* DictClear ********************************************************* ** ** Removes all the elements of the dictionary without reallocating it ** ** INPUT: [W] a pointer to DICTv */ void DictClear(DICTv* dict) { DICTv d=*dict; if (d->usage==1) DictClearImpl(d); else { d->usage--; *dict=DictCreate(d->myClass); } } /* access */ /**API* DictAtImpl ********************************************************* ** ** Accesses the element at a given key. If repetitions are allowed, ** a run-time check for unicity of the key value is performed. ** A NotSuchElement exception is thrown if the key is not found. ** ** INPUT: a DICTv ** a pointer to the key value ** RETURNS: a pointer to the element */ DictElem* DictAtImpl (DICTv dict, void* key) { Iter i=DictWith(dict, key); ASSERT(i, "NoSuchElement"); if (dict->myClass->repetitions) { Iter next=i; DictNextWith(dict, key, &next); ASSERT(!next, "AmbigousAssociation"); } return (DictElem*)i; } /**API* DictKey ********************************************************* ** ** Accesses the key at a given position. The iterator must be valid ** ** INPUT: a DICTv ** an iterator ** RETURNS: a pointer to the key value */ void* DictKey(DICTv dict, Iter i) { CLASSoDICT* cl=dict->myClass; return call(cl->toKey)(*cast(i, DictElem*),cl->toKeyInfo); } /* iterator support */ /**API* DictWith ********************************************************* ** ** Retrieves the iterator position of the first element ** with a given key value. If the key value does'nt ** exist, returns NULL. Useful also for testing the ** presence of a key in the dictionary. The successive elements ** with the same key value can be obtained using DictNextWith. ** ** ** INPUT: a DICTv ** a pointer to the key value ** RETURNS: the iterator */ Iter DictWith (DICTv dict, void* key) { CLASSoDICT* cl=dict->myClass; ValComparer equal=cl->equal; KeyAccessor toKey=cl->toKey; IntOrPtr toKeyInfo=cl->toKeyInfo; int dim=dict->dim; DictElem* curr=dict->tab+call(cl->hash)(key,dim); DictElem* last=dict->tab+dim; while (*curr) { if (call(equal)(key, toKey(curr, toKeyInfo))) return curr; if (++curr==last) curr=dict->tab; } return NULL; } /**API* DictWithPtr ********************************************************* ** ** Retrieves the iterator position given the memory ** pointer to the element. The element must have been ** inserted in the dictionary. ** ** INPUT: a DICTv ** a pointer to the element ** RETURNS: the iterator */ Iter DictWithPtr(DICTv dict, DictElem elem) { CLASSoDICT* cl=dict->myClass; void* key=call(cl->toKey)(&elem,cl->toKeyInfo); DictElem* i=(DictElem*)DictWith(dict, key); if (!i) return NULL; while (*i!=elem) { i++; if (!*i) return NULL; } return i; } /**API* DictFirst ********************************************************* ** ** Retrieves an iterator for scanning the dictionary sequentially. ** No specific ordering is given for the iteration, and the dictionary ** should not be modified while iterating. ** ** INPUT: a DICTv ** RETURNS: the iterator */ Iter DictFirst(DICTv dict) { Iter i=NULL; DictNext(dict,&i); return i; } /**API* DictNext ********************************************************* ** ** Retrieves an iterator for scanning the dictionary sequentially. ** No specific ordering is given for the iteration, and the dictionary ** should not be modified while iterating. The iterator is set to NULL ** when there are no more elements. ** ** INPUT: a DICTv ** [W] a pointer to an iterator */ void DictNext (DICTv dict, Iter* i) { if (*i) (*cast(i, DictElem**))++; else *i=dict->tab; while (*i!=dict->tab+dict->dim) { if (*cast(*i, DictElem*)) return; (*cast(i, DictElem**))++; } *i=NULL; } Iter DictLast (DICTv dict) { Iter i=NULL; DictPrev(dict, &i); return i; } void DictPrev (DICTv dict, Iter* i) { if (*i) (*cast(i, DictElem**))--; else *i=dict->tab+dict->dim; while (*i!=dict->tab-1) { if (*cast(*i, DictElem*)) return; (*cast(i, DictElem**))--; } *i=NULL; } /**API* DictNextWith ********************************************************* ** ** Retrieves an iterator for scanning all insterted elements having ** a given key value. The order of the elements is the insertion order. ** The first element can be obtained using the DictWith function. ** The iterator is set to NULL when there are no more elements. ** ** INPUT: a DICTv ** a pointer to the key value ** [W] a pointer to an iterator */ void DictNextWith (DICTv dict, void* key, Iter* i) { int dim=dict->dim; DictElem* curr=*i; CLASSoDICT* cl=dict->myClass; ValComparer equal=cl->equal; KeyAccessor toKey=cl->toKey; IntOrPtr toKeyInfo=cl->toKeyInfo; if (curr) { curr++; if (curr==dict->tab+dict->dim) curr=dict->tab; } else curr=dict->tab+call(cl->hash)(key,dim); while (*curr) { if (call(equal)(key, toKey(curr, toKeyInfo))) { *i=curr; return; } curr++; if (curr==dict->tab+dict->dim) curr=dict->tab; } *i=NULL; } /* information */ /**API* DictCard ********************************************************* ** ** Returns the number of elements in the dictionary ** ** INPUT: a DICTv ** RETURNS: the number of elements */ int DictCard (DICTv dict) { return dict->num; } /**API* DictCardWith ********************************************************* ** ** Returns the number of elements in the dictionary with a given key value ** ** INPUT: a DICTv ** a pointer to the key value ** RETURNS: the number of elements */ int DictCardWith(DICTv dict, void* key) { Iter i; int num=0; for (i=DictWith(dict, key);i;DictNextWith(dict, key, &i)) num++; return num; } /**API* DictEmpty ********************************************************* ** ** Tells whether a dictionary is empty. ** ** INPUT: a DICTv ** RETURNS: TRUE if the dictionary is empty */ BOOL DictEmpty(DICTv dict) { return dict->num!=0; } /**API* DictHas ********************************************************* ** ** Tells weather a dictionary contains an element with the given key. ** See also DictWith ** ** INPUT: a DICTv ** a pointer to a key value ** RETURNS: TRUE if the dictionary contains the key */ BOOL DictHas (DICTv dict, void* key) { return DictWith(dict, key)!=NULL; } /*************************************************************************/ /**API* PolyStrEqual ********************************************************* ** ** Compares 2 pointers to STRv for equality ** ** INPUT: a pointer to STRv ** a pointer to STRv ** RETURNS: TRUE if the STRv's are equal */ BOOL PolyStrEqual(void* s1, void* s2) { return StrEqual(*cast(s1, STRv*), *cast(s2, STRv*)); } /**API* PolyStrHash ********************************************************* ** ** Hashes the STRv identified by a pointer to STRv ** ** INPUT: a pointer to STRv ** RETURNS: an hash value */ int PolyStrHash(void* s, int max) { return StrHash(*cast(s, STRv*), max); } /**API* PolyIntEqual ********************************************************* ** ** Compares 2 pointers to int for equality ** ** INPUT: a pointer to int ** a pointer to int ** RETURNS: TRUE if the int's are equal */ BOOL PolyIntEqual(void* i1, void* i2) { return *cast(i1, int*)==*cast(i2, int*); } /**API* PolyIntHash ********************************************************* ** ** Hashes the int identified by a pointer to int ** ** INPUT: a pointer to int ** RETURNS: an hash value */ int PolyIntHash(void* i, int max) { return *cast(i, int*)%max; } /**API* PolyPtrEqual ********************************************************* ** ** Compares 2 pointers to pointer for equality ** ** INPUT: a pointer to pointer ** a pointer to pointer ** RETURNS: TRUE if the pointed pointers are equal */ BOOL PolyPtrEqual(void* p1, void* p2) { return *cast(p1, void**)==*cast(p2, void**); } /**API* PolyPtrHash ********************************************************* ** ** Hashes the pointer identified by a pointer to pointer ** ** INPUT: a pointer to pointer ** RETURNS: an hash value */ int PolyPtrHash(void* p, int max) { return *cast(p, IntOrPtr*)%max; } #include /**API* strhash ********************************************************* ** ** Hashes a C string ** ** INPUT: a char* ** RETURNS: an hash value */ int strhash(char* s, int max) { WORD h=0, g; while (*s) { h=(h << 4 | (h&0xf0000000L)>>28) ^ *s++; } return h%max; } /**API* strequal ********************************************************* ** ** compares 2 C strings ** ** INPUT: a char* ** a char* ** RETURNS: TRUE if equal */ BOOL strequal(char* s1,char* s2) { return strcmp(s1,s2)==0; } /**API* PtrEqual ********************************************************* ** ** compares 2 pointers ** ** INPUT: a pointer ** a pointer ** RETURNS: TRUE if equal */ BOOL PtrEqual(void* p1, void* p2) { return p1==p2; } /**API* PtrHash ********************************************************* ** ** Hashes a pointer ** ** INPUT: a pointer ** RETURNS: an hash value */ int PtrHash(void* p, int max) { return cast(p, WORD)%max; } /**API* KeyItself ********************************************************* ** ** Used in definitions of dictionary classes, used with DictCreate. ** Defines the dictionary to be a set, so that the entire value of ** elements that are inserted is the key of the dictionary. ** ** INPUT: a pointer to the element (a pointer inside the dictionary) ** RETURNS: a pointer to the key */ void* KeyItself(DictElem* entry) { return *entry; } /**API* KeyOffset ********************************************************* ** ** Used in definitions of dictionary classes, used with DictCreate. ** Defines the dictionary to be a dictionary of structures in which ** one attribute is the key. ** ** INPUT: a pointer to the element (a pointer inside the dictionary) ** RETURNS: a pointer to the key */ void* KeyOffset(DictElem* entry, int offs) { return offset(*entry, offs, void*); } void* KeyOffsetDeref(DictElem* entry, int offs) { return *offset(*entry,offs,void**); } /**API* DictDebug ********************************************************* ** ** Prints the status of the dictionary. Especially useful if the ** dictionary class has been defined using the functions provided ** by this module. ** ** INPUT: a DICTv */ void DictDebug(DICTv d) { printf("DICTv:%p", d); if (d) { DictElem* curr; CLASSoDICT* info=d->myClass; printf("[num:%d dim:%d", d->num, d->dim); if (d->usage!=1) printf(" shared:%d",d->usage-1); printf("\n"); for (curr=d->tab; currtab+d->dim; curr++) if (*curr) { void* key=call(info->toKey)(curr, info->toKeyInfo); ValComparer equal=info->equal; printf("\t[ix:%d elem:%p ", curr-d->tab, *curr); if (equal==(ValComparer)strequal) printf("key:%s", (char*)key); else if (equal==PtrEqual) printf("key:%p", key); else if (equal==PolyStrEqual) printf("key:%s", Str(*(STRv*)key)); else if (equal==PolyIntEqual) printf("key:%d", *(int*)key); else if (equal==PolyPtrEqual) printf("key:%p", *(void**)key); else printf("key: DontKnow"); printf(" hash:%d ]\n", call(info->hash)(key, d->dim)); } printf("]"); } printf("\n"); } /******************************************************************* ** PROPERTY MANAGEMENT */ DICTv AccessMethods=NULL; DICTv Properties=NULL; typedef struct AccessMethod { KeyAccessor toKey; DICTv accessInfo; } AccessMethod; KeyAccessor* AccessMethodToKey(AccessMethod** entry) { return &(*entry)->toKey; } BOOL PropertyCompare(Prop prop1, Prop prop2) { if (prop1==prop2) return TRUE; else if (prop1->toKey==prop2->toKey && prop1->toKeyInfo==prop2->toKeyInfo && prop1->equal==prop2->equal && prop1->hash==prop2->hash && prop1->repetitions==prop2->repetitions) return TRUE; return FALSE; } int PropertyHash(Prop p, int max) { int val=(cast(p->toKey, WORD)+cast(p->equal, WORD)+cast(p->hash, WORD)+ p->toKeyInfo+p->repetitions)%max; return val; } void InitProperties() { Prop cl=typeAlloc(CLASSoDICT); cl->toKey=(KeyAccessor)AccessMethodToKey; cl->toKeyInfo=NULL; cl->equal=(ValComparer)PolyPtrEqual; cl->hash=(ValHasher)PolyPtrHash; cl->repetitions=FALSE; AccessMethods=DictCreate(cl); cl=typeAlloc(CLASSoDICT); cl->toKey=(KeyAccessor)KeyItself; cl->toKeyInfo=NULL; cl->equal=(ValComparer)PropertyCompare; cl->hash=(ValHasher)PropertyHash; cl->repetitions=FALSE; Properties=DictCreate(cl); } AccessId RegisterAccessMethod(KeyAccessor toKey, ValComparer toKeyInfoEqual, ValHasher toKeyInfoHash) { AccessMethod** am; AccessMethod* m; ASSERT (AccessMethods, "NotInitialized"); am =&DictSet(&AccessMethods, toKey, AccessMethod*); m =*am; if (!m) { Prop p=typeAlloc(CLASSoDICT); p->toKey=(KeyAccessor)KeyItself; p->toKeyInfo=NULL; p->equal=(ValComparer)toKeyInfoEqual; p->hash=(ValHasher)toKeyInfoHash; m=typeAlloc(AccessMethod); m->toKey=toKey; m->accessInfo=DictCreate(p); *am=m; } else { Prop p=m->accessInfo->myClass; ASSERT(p->equal==toKeyInfoEqual && p->hash==toKeyInfoHash, "InconsistentIdMethods"); } return m; } void RegisterAccessInfo(AccessId how, void** info) { void** i=&DictSet(&how->accessInfo, info, void*); if (*i) { free (*info); *info=*i; } else *i=*info; } void RegisterProperty(Prop* property) { Prop* p; ASSERT (Properties, "NotInitialized"); p=&DictSet(&Properties, *property, Prop); if (!*p) *p=*property; else { free(*property); *property=*p; } } BOOL RegisteredProp(Prop property) { return DictWith(Properties, property)!=NULL; } void* GetProp(Prop p, DictElem* elem) { return call(p->toKey)(elem, p->toKeyInfo); } /***********************************************************************************/ DICTv DictCreateKeyStr(int offs, BOOL repetitions) { CLASSoDICT* cl=typeAlloc(CLASSoDICT); cl->equal=(ValComparer)PolyStrEqual; cl->hash=(ValHasher)PolyStrHash; cl->toKey=(KeyAccessor)KeyOffset; cl->toKeyInfo=offs; cl->repetitions=repetitions; return DictCreate(cl); } DICTv DictCreateKeyInt(int offs, BOOL repetitions) { CLASSoDICT* cl=typeAlloc(CLASSoDICT); cl->equal=(ValComparer)PolyIntEqual; cl->hash=(ValHasher)PolyIntHash; cl->toKey=(KeyAccessor)KeyOffset; cl->toKeyInfo=offs; cl->repetitions=repetitions; return DictCreate(cl); } void DictDestroyWithClass(DICTv d) { free(d->myClass); DictDestroy(d); } CLASSoDICT* DictCreateClassStrKey(KeyAccessor toKey, IntOrPtr toKeyInfo, BOOL repetitions) { CLASSoDICT* cl=typeAlloc(CLASSoDICT); cl->equal=(ValComparer)PolyStrEqual; cl->hash=(ValHasher)PolyStrHash; if (toKey) cl->toKey=toKey; else cl->toKey=(KeyAccessor)KeyOffset; cl->toKeyInfo=toKeyInfo; cl->repetitions=repetitions; return cl; } /**API* function ************************************************************* ** ** Creates a new dictionary for 0 terminated strings within structs. ** For accessing the key either the second or the third argument must ** be defined. ** ** INPUT: function to access the key within the item [R] ** offset of the key within the item [R] (use mPtr) or NULL ** flag if repetitions of values are allowed [R] or NULL ** ** RETURNS: the new dictionary class */ CLASSoDICT* DictCreateClassStrZKey (KeyAccessor toKey, IntOrPtr toKeyInfo, BOOL repetitions) { CLASSoDICT* cl=typeAlloc(CLASSoDICT); cl->equal=(ValComparer)strequal; cl->hash=(ValHasher)strhash; if (toKey) cl->toKey=toKey; else cl->toKey=(KeyAccessor)KeyOffsetDeref; cl->toKeyInfo=toKeyInfo; cl->repetitions=repetitions; return cl; } CLASSoDICT* DictCreateClassIntKey(KeyAccessor toKey, IntOrPtr toKeyInfo, BOOL repetitions) { CLASSoDICT* cl=typeAlloc(CLASSoDICT); cl->equal=(ValComparer)PolyIntEqual; cl->hash=(ValHasher)PolyIntHash; if (toKey) cl->toKey=toKey; else cl->toKey=(KeyAccessor)KeyOffset; cl->toKeyInfo=toKeyInfo; cl->repetitions=repetitions; return cl; } /**API* function ************************************************************* ** ** Creates a new dictionary for pointers within structs. ** For accessing the key either the second or the third argument must ** be defined. ** ** INPUT: function to access the key within the item [R] ** offset of the key within the item [R] (use mPtr) or NULL ** flag if repetitions of values are allowed [R] or NULL ** ** RETURNS: the new dictionary class */ CLASSoDICT* DictCreateClassPtrKey(KeyAccessor toKey, IntOrPtr toKeyInfo, BOOL repetitions) { CLASSoDICT* cl=typeAlloc(CLASSoDICT); cl->equal=(ValComparer)PolyPtrEqual; cl->hash=(ValHasher)PolyPtrHash; if (toKey) cl->toKey=toKey; else cl->toKey=(KeyAccessor)KeyOffset; cl->toKeyInfo=toKeyInfo; cl->repetitions=repetitions; return cl; } /**API* function ************************************************************* ** ** Creates a new dictionary where they key is the address of the item ** itself ** ** INPUT: flag if repetitions of values are allowed [R] or NULL ** ** RETURNS: the new dictionary class */ CLASSoDICT* DictCreateClassSelfPtrKey (BOOL repetitions) { CLASSoDICT* cl=typeAlloc(CLASSoDICT); cl->equal=(ValComparer)PtrEqual; cl->hash=(ValHasher)PtrHash; cl->toKey=(KeyAccessor)KeyItself; cl->repetitions=repetitions; return cl; } *************************** ** ** Creates a new dictionary where they key is the address of the item ** itself ** ** INPUT: flag if repetitions of values are allowed [R] or NULL ** ** RETURNS: the new dictionary class */ CLASSoDICT* DictCreateClassSelfPtrKey (BOOL repetitions) { CLASSoDICT* cl=typeAlloc(CLASSoDICT); cl->equal=(ValComparer)PtrEqual; cl->hash=(ValHasher)PtrHsrs/src/dict.h #define _DICT_H /******************************************************************************* ** DICTIONARY data structure ** associates values with other values *******************************************************************************/ /* Dictionary is an index built on some other (owning) data structure It is composed by aliases to the indexed values (hmmm. bad, should always be notified on changes on the index in the indexed value) */ typedef void* DictElem; typedef void* (*KeyAccessor)(DictElem* entry, IntOrPtr info); typedef BOOL (*ValComparer)(void* val1, void* val2); typedef int (*ValHasher) (void* val, int N); typedef struct CLASSoDICT { ValComparer equal; /* key compare */ ValHasher hash; /* key hash */ KeyAccessor toKey; IntOrPtr toKeyInfo; BOOL repetitions; } CLASSoDICT; typedef struct DICTo { CLASSoDICT* myClass; int dim; int num; int usage; /* num of hashed elements */ DictElem tab[1]; } DICTo; typedef DICTo* DICTv; /* dictionary value is polymorphic */ /* creation/deletion */ DICTv DictCreate(CLASSoDICT* cl); void DictDestroy(DICTv dict); DICTv DictCopy(DICTv dict); void DictOffset(DICTv dict, int offs); void DictOffsetWithin(DICTv dict, DictElem buf, int len, DictElem newBuf); /* insertion/removal */ DictElem* DictAddGrow(DICTv* dict, void* key); DictElem* DictSetGrow(DICTv* dict, void* key); #define DictAdd(dict, key, type) (*cast(DictAddGrow(dict,key), type*)) #define DictSet(dict, key, type) (*cast(DictSetGrow(dict,key), type*)) Iter DictAddPtr(DICTv* dict, DictElem elem); Iter DictSetPtr(DICTv* dict, DictElem elem); void DictRemove (DICTv* dict, Iter i); void DictRemoveWith (DICTv* dict, void* key); void DictRemovePtr (DICTv* dict, DictElem elem); void DictClear (DICTv* dict); /* access */ DictElem* DictAtImpl (DICTv dict, void* key); DictElem* DictInImpl (DICTv dict, Iter i); #define DictAt(dict, key, type) (*(type*)DictAtImpl(dict, key)) #define DictIn(iter, type) (*(ASSERT(iter, "Undefined"), cast(iter,type*))) /* iterator support */ Iter DictWith (DICTv dict, void* key); Iter DictWithPtr(DICTv dict, DictElem elem); void DictNextWith (DICTv dict, void* key, Iter* i); Iter DictFirst(DICTv dict); void DictNext (DICTv dict, Iter* i); Iter DictLast (DICTv dict); void DictPrev (DICTv dict, Iter* i); /* information */ int DictCard (DICTv dict); int DictCardWith(DICTv dict, void* key); BOOL DictEmpty(DICTv dict); BOOL DictHas (DICTv dict, void* key); void* DictKey(DICTv dict, Iter i); /********************************************************* ** Useful support functions */ BOOL PolyStrEqual(void* s1, void* s2); int PolyStrHash(void* s, int max); BOOL PolyIntEqual(void* i1, void* i2); int PolyIntHash(void* i, int max); BOOL PolyPtrEqual(void* p1, void* p2); int PolyPtrHash(void* p, int max); int strhash(char* s, int max); BOOL strequal(char* s1,char* s2); BOOL PtrEqual(void* p1, void* p2); int PtrHash(void* p, int max); void* KeyItself(DictElem* entry); void* KeyOffset(DictElem* entry, int offs); /********************************************************** ** Dictionary class management */ typedef CLASSoDICT* Prop; typedef struct AccessMethod* AccessId; void InitProperties(); AccessId RegisterAccessMethod(KeyAccessor toKey, ValComparer toKeyInfoEqual, ValHasher toKeyInfoHash); void RegisterAccessInfo(AccessId how, void** info); void RegisterProperty(Prop* property); BOOL RegisteredProp(Prop property); void* GetProp(Prop p, DictElem* elem); /********************************************************* ** Useful dictionary constructors/destructors */ DICTv DictCreateKeyStr(int offs, BOOL repetitions); DICTv DictCreateKeyInt(int offs, BOOL repetitions); void DictDestroyWithClass(DICTv d); /******************************************************** ** CLASSoDICT creators ** if toKey is null, then it is assumed that: ** - the dictionary contains pointers to struct ** - toKeyInfo is the offset to the key attribute *******************************************************/ CLASSoDICT* DictCreateClassStrKey(KeyAccessor toKey, IntOrPtr toKeyInfo, BOOL repetitions); CLASSoDICT* DictCreateClassStrZKey(KeyAccessor toKey, IntOrPtr toKeyInfo, BOOL repetitions); CLASSoDICT* DictCreateClassIntKey(KeyAccessor toKey, IntOrPtr toKeyInfo, BOOL repetitions); CLASSoDICT* DictCreateClassPtrKey(KeyAccessor toKey, IntOrPtr toKeyInfo, BOOL repetitions); CLASSoDICT* DictCreateClassSelfPtrKey (BOOL repetitions); #endif the key attribute *******************************************************/ CLASSoDICT* DictCreateClassStrKey(KeyAccessor toKey, IntOrPtr toKeyInfo, BOOL repetitions); CLASSoDICT* DictCreateClassStrZKey(KeyAccessor toKey, IntOrPtr toKeyInfo, BOOL repetitions); CLASSoDICT* DictCreateClassIntKey(KeyAccessor toKey, IntOrPtr toKeyInfo, BOOL repetitions); CLASSoDICT* DictCreateClassPtrKey(KeyAccessor toKey, IntOrPtr toKeyInfo, BOOL repetitions); CLASSoDICT* DictCreateClassSelfPtrsrs/src/entry.c char entry_ID[] = "$Id: entry.c,v 1.26 1997/03/03 18:20:29 srs Exp $"; /* ** ** $RCSfile: entry.c,v $ ** $Revision: 1.26 $ ** $Date: 1997/03/03 18:20:29 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port by Lukas Rosenthaler and Reinhard ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** D-69012 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** functions open flat files and indices for read access only - compare ** time stamps and retrieve entry information from ID-indices ** ** Global Parameters: ** "printf" ** "parseTest" ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include "message.h" #include "sm.h" #include "strv.h" #include "dict.h" #include "tm.h" #include "futil.h" #include "par.h" #include "id.h" #include "idx.h" #include "set.h" #include "library.h" #include "field.h" #include "entry.h" #include "toklist.h" #include "variable.h" #include "icarus.h" #include "templ.h" #include "view.h" #include "query.h" #include "regexp.h" #include "binpack.h" #define _SRS #define _SLB #include SRSINCLUDE /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Describes an entry in a flat file opened for read access. All ** different sections (eg, text, data) can be opened simultaneously. */ typedef struct ENTRYo { struct IDoENTRY *id; /* pointer to ID-object */ struct SLBo *lib; /* (API) address of library object */ char entry_nm[132]; /* unique entry name */ char file_nm[132]; /* complete or partial file name */ char full_nm[132]; /* unique entry name */ FIP fip[2]; /* file ptr to the section in flat file */ Int4 fileX[2]; /* file index for each file type */ struct FILEo *file[2]; /* file descriptor for a section */ struct SLBoFIELD *field; struct TOKoLIST **tokList; /* token list with the "field" tokens */ Int4 tokListN; Int4 tokListAllocN; DICTv tokListDict; UINT4 indexTime; UINT4 fileCreTime[2]; Int4 partNo; /* current library part number */ } ENTRYo; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** private functions */ static FILEo *EntryJobNextFile (char *symName, void* data); static FILEo *EntryJobFile (char *symName, void* data); static void EntryEmptyViewInTable (VIEWoLIB *vlib, Int4 rowN); static void EntryPrintTableField (ENTRYo *entry, SLBoFIELD *field, LIBoFieldFormat *format, Int4 rowN); static INT4 EntryViewInTable (ENTRYo *entry, VIEWo *view, VIEWoLIB *vlib, Int4 entryNo, Int4 isRoot, Int4 rowN); static void EntryViewInList (ENTRYo *entry, VIEWo *view, VIEWoLIB *vlib, Int4 entryNum, Int4 isRoot); static void EntrySetJob (ENTRYo *entry, ICAoJOB *job); static void EntrySetInputNames (ENTRYo *entry); void EntryIdRecordUnpack (ENTRYv entry, char *buff); static char *EntryGetFileName (ENTRYo *entry); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** extern or module wide variables */ static FILE *outFile=NULL; #ifdef sun extern INT4 printf (); #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** default function for printing lines */ static INT4 EntryPrintF (char *formatStr, ...) { va_list ap; va_start (ap, formatStr); vfprintf (outFile, formatStr, ap); va_end (ap); if (formatStr[strlen (formatStr) -1] != '\n') fprintf (outFile, "\n"); return 1; } static void EntrySetInputNames (ENTRYo *entry) { SRSoFILTYP *ft; Int4 k, c; for (k=0, c=0; (ft=LibNextFileType (EntryGetLib (entry), &c)); k++) { IcaSetLogicStream (EntryGetJob (entry), LibGetFileTypeName (ft)); } } /**API* EntryOpen ************************************************************* ** ** Creates and returns an entry object which ** is a 'handle' to the 'real' entry ** contained in the flat file ** which can be accessed using functions such as ** EntryPrint, EntryPritntFields. To destroy the entry object again use ** EntryClose. ** ** INPUT: address of ID-object (see SetGetID) [R] ** IMPLICIT: ** ** RETURNS: new entry-object ** NULL if there is a problem with the ID or the ID index */ ENTRYo *EntryOpen (IDoENTRY *id) { LIBoINDEX *libInx; SLBo *lib; ICAoJOB *job; ENTRYo *entry; entry = (ENTRYo *) calloc (1, sizeof (ENTRYo)); if (!(lib = (SLBo *) LibObjById ("library", id->lib_x))) { _ErrMsg2 (e__libidnotknown, id->lib_x); EntryClose(&entry); /*PURIFY*/ return NULL; } entry->lib = lib; entry->id = id; /* get information how to access entry within the library flat file */ if (!(libInx = LibIndexOpen (lib, LibGetIdField (lib), 0))) _ErrExit (e__error); EntryIdRecordUnpack (entry, IdxRecordGet (libInx->idx, id->fip)); if (IdIsSub (id)) { entry->lib = LibGetSubEntryLib (entry->lib, IdGetSubN (id)); sprintf (entry->entry_nm, "%s_%d", entry->entry_nm, IdGetSubN (id)); } entry->fileX[1] = entry->fileX[0]; if (!EntryGetJob (entry)) { ParDefNum ("fromSrs", 1); /* turn off debugging in .is file */ job = IcaCreateJob (entry->lib->form->syntax); IcaSetInputStreamer (job, EntryJobFile); EntrySetJob (entry, job); EntrySetInputNames (entry); } else job = EntryGetJob (entry); IcaSetInputStreamerData (job, (void*)entry); IcaJobNext (job); return entry; } /**api* function ************************************************************** ** ** Writes an entry record into a buffer which can then be appended to ** the IDX file. ** ** INPUT: address entry-object [R] ** address of write buffer (must be allocated) [W] */ void EntryIdRecordPack (ENTRYv entry, char *buff) { SLBo *lib=EntryGetLib (entry); Int4 len; _BinPackFip (buff, EntryGetFip (entry, 0)); _BinPackFip (buff, EntryGetFip (entry, 1)); _BinPackNum (buff, EntryGetFileX (entry)); _BinPackFixStr (buff, EntryGetName (entry), LibGetMaxNameLength (lib)); if ((len=LibGetSaveNameLength (lib))) { switch (LibGetSaveNameType (lib)) { case LIBxFILE: _BinPackFixStr (buff, FileGetName (IcaJobGetFile (EntryGetJob (entry)), "file"), len); break; case LIBxNAME: _BinPackFixStr (buff, FileGetName (IcaJobGetFile (EntryGetJob (entry)), "name"), len); break; case LIBxPATH: _BinPackFixStr (buff, FileGetName (IcaJobGetFile (EntryGetJob (entry)), "path"), len); break; } } } /**api* function ************************************************************** ** ** Reads an entry record which must be obtained from an IDX file and ** translates and stores its contents as attribtutes in the entry ** object. ** ** INPUT: address entry-object [W] ** address of write buffer [R] */ void EntryIdRecordUnpack (ENTRYv entry, char *buff) { SLBo *lib=EntryGetLib (entry); Int4 len; _BinUnpackFip (buff, entry->fip[0]); _BinUnpackFip (buff, entry->fip[1]); _BinUnpackNum (buff, entry->fileX[0]); _BinUnpackFixStr (buff, entry->entry_nm, LibGetMaxNameLength (lib)); if (len=LibGetSaveNameLength (lib)) _BinUnpackFixStr (buff, entry->file_nm, len); } /**API* EntryClose ************************************************************ ** ** Closes an entry object by deleting it. Sets entry pointer ** to NULL to prevent freeing it a second time. ** ** INPUT: address of pointer to entry-object [W] */ void EntryClose (ENTRYo **entry) { if ((*entry)->tokList) free ((*entry)->tokList); if ((*entry)->tokListDict) DictDestroy ((*entry)->tokListDict); if (*entry) { free(*entry); *entry = NULL; } } void EntryClosePtr (ENTRYo *entry) { free(entry); } Fip EntryGetFip (ENTRYo *entry, Int4 index) { return entry->fip[index]; } Int4 EntryGetFileX (ENTRYo *entry) { return entry->fileX[0]; } SLBoFIELD *EntryTokenToField (ENTRYo *entry, TOKoLIST *tokList, TOKoTOKEN *token) { TOKoTOKEN *tok; SLBoFIELD *field; SLBo *lib; char tokName[200]; Int4 c; sprintf (tokName, "%s|%s", TokListGetName (tokList), TokCodeToStr (TokGetCode (tok))); lib = EntryGetLib (entry); for (c=0; (field=LibNextField (lib, &c));) if (SmEqs (tokName, "")) return field; return NULL; } TOKoLIST *EntryNextTokList (ENTRYo *entry, Int4 *c) { if (*c >= entry->tokListN) { *c = 0; return NULL; } else return entry->tokList[(*c)++]; } /**API* function ************************************************************* ** ** Returns the token table with the specified name. This function may ** initiate the parsing of the entry. ** ** INPUT: entry object [W] ** name of the token table [R] ** ** RETURNS: token table object */ TOKoLIST *EntryGetTokList (ENTRYo *entry, char *name) { TOKoLIST *tokList, **tokListPtr; Iter i; if (!entry->tokListDict) { entry->tokListDict = DictCreate (DictCreateClassStrZKey ((KeyAccessor) TokListPtrGetName, NULL, FALSE)); } tokListPtr = &DictSet (&entry->tokListDict, name, TOKoLIST*); tokList = *tokListPtr; if (!tokList) { tokList = IcaGetTokenList (EntryGetJob (entry), name); *tokListPtr = tokList; *(_addObj (entry->tokList, entry->tokListN, entry->tokListAllocN, TOKoLIST*)) = tokList; } return tokList; } STRv EntryNextFieldToken (ENTRYo *entry, SLBoFIELD **fieldPtr, Int4 isOnlyActive, Int4 *c) { static TOKoLIST *tokList; static Int4 tokC, tokListC; TOKoTOKEN *tok; SLBoFIELD *field, *tmp; SLBo *lib=EntryGetLib (entry); STRv s=NULL; char *name; Int4 k, c2, doPrint=0; if (!(*c)++) { VarSetInt (EntryGetIcarusVar (entry, "subEntryN"), IdIsSub (entry->id) ? IdGetSubN (entry->id) : 0); /* request all token tables */ for (k=0; (field = LibNextField (lib, &k));) { if (!FieldIs (field, "show") || (isOnlyActive && !FieldIs (field, "active"))) continue; if (*(name = FieldGetTokListName (field, "field"))) EntryGetTokList (entry, name); if ((tmp = FieldInherits (field))) if (*(name = FieldGetTokListName (tmp, "field"))) /* contents will not be printed */ tokList = IcaGetTokenList (EntryGetJob (entry), name); } tokList = NULL; tokListC = 0; } *fieldPtr = NULL; while (1) { if (tokList && (tok = TokNext (tokList, &tokC))) { for (c2=0, doPrint=0; (field=FieldNextFromToken (lib, tokList, tok, &c2));) { if (isOnlyActive && !FieldIs (field, "active")) continue; else if (!isOnlyActive || FieldIs (field, "active")) { *fieldPtr = field; doPrint=1; break; } } if (!isOnlyActive || doPrint) { s = TokGetStrv (tokList, tok); break; } } else { if ((tokList = EntryNextTokList (entry, &tokListC))) { tokC = 0; } else { *c = 0; break; } } } return s; } /**API* EntryPrint ****************************************************** ** ** Prints entire entry using the "printField" function (see also ** EntryPrintFields). ** ** INPUT: o address of entry object [W] ** o pointer to user data to be given to print function [R] ** (or NULL). ** ** RETURNS: 1 if success ** e__filnotok + ** e__badfile */ void EntryPrint (ENTRYo *entry, void *data) { SLBoFIELD *field; char *com; STRv s; INT4 c, (*print)(char *,...) = (INT4(*)(char *,...)) ParGetFunction ("printField"); IcaSetTask (EntryGetJob (entry), "hl", ParGetBool ("isHTMLFormat")); IcaSetTask (EntryGetJob (entry), "html", ParGetBool ("isHTMLFormat")); ParDefBool ("printEntireEntry", 1); VarSetStr (EntryGetIcarusVar (entry, "libName"), SmEdit (LibName (EntryGetLib (entry)), SMxLOWCASE)); for (c=0; (s = EntryNextFieldToken (entry, &field, 0, &c));) { if (field && FieldIs (field, "formatted")) { if ((com = FieldGetFormatEval (field))) { VarSetStrv (EntryGetIcarusVar (entry, "token"), s); IcaEvalInJob (com, EntryGetJob (entry)); } } else if (StrLen (s)) { print (_Str (s), field, data); StrDel (s); } } } /**API* EntryPrintFields ****************************************************** ** ** Prints one ore more of the entry's fields using the "printField" ** parameter function (prints to STDOUT if not defined). ** ** INPUT: o address of entry object [W] ** o pointer to user data to be given to print function [R] ** (or NULL). ** ** RETURNS: 1 if success ** e__filnotok + ** e__badfile */ INT4 EntryPrintFields (ENTRYo *entry, void *data) { SLBoFIELD *field; VARo *var; char *com; STRv s; INT4 c, (*print)(char *,...) = (INT4(*)(char *,...)) ParGetFunction ("printField"); IcaSetTask (EntryGetJob (entry), "hl", ParGetBool ("isHTMLFormat")); IcaSetTask (EntryGetJob (entry), "html", ParGetBool ("isHTMLFormat")); LibSetActiveFields (entry->lib); /** activate fields to be printed */ VarSetStr (EntryGetIcarusVar (entry, "libName"), SmEdit (LibName (EntryGetLib (entry)), SMxLOWCASE)); for (c=0; (s = EntryNextFieldToken (entry, &field, TRUE, &c));) { if (field && FieldIs (field, "formatted")) { if ((com = FieldGetFormatEval (field))) { if ((var = EntryGetIcarusVar (entry, "token"))) VarSetStrv (var, s); IcaEvalInJob (com, EntryGetJob (entry)); } } else if (StrLen (s)) { print (_Str (s), field, data); StrDel (s); } } } /**API* EntryGetField ******************************************************** ** ** Retrieves the specfied field from the entries record using the ** table token. ** If the table token for the field is not specified then it selects ** a table and a printing format itself. ** ** INPUT: entry object [W] ** field object [R] ** address of iteration variable [W] or NULL ** IMPLICIT: ** ** RETURNS: pointer to the string containing the field */ STRv EntryGetField (ENTRYo *entry, SLBoFIELD *field, INT4 *c) { static TOKoLIST *tokList; SLBoFIELD *tmp; TOKoTOKEN *tok; STRv s=NULL; char *tokListName, *name; INT4 rv, code, cDummy; if (!c) c = &cDummy; if (!entry->tokList) { IcaSetTask (EntryGetJob (entry), "hl", ParGetBool ("isHTMLFormat")); IcaSetTask (EntryGetJob (entry), "html", ParGetBool ("isHTMLFormat")); } VarSetInt (EntryGetIcarusVar (entry, "subEntryN"), IdIsSub (entry->id) ? IdGetSubN (entry->id) : 0); if (*(tokListName = FieldGetTokListName (field, "table"))) code = FieldGetTokCode (field, "table"); else if (*(tokListName = FieldGetTokListName (field, "index"))) { code = FieldGetTokCode (field, "index"); if ((FieldIs (field, "num") || FieldIs (field, "real")) && !FieldGetTableFormat (NULL, field)) FieldSetTableFormat (field, LIBxRIGHT); } else { tokListName = FieldGetTokListName (field, "fields"); code = FieldGetTokCode (field, "fields"); } /* activate token of inherited field */ if ((tmp = FieldInherits (field))) if (*(name = FieldGetTokListName (tmp, "field"))) /* contents will not be printed */ tokList = IcaGetTokenList (EntryGetJob (entry), name); tokList = IcaGetTokenList (EntryGetJob (entry), tokListName); if ((tok = TokNextWithCode (tokList, code, c))) s = TokGetStrv (tokList, tok); return s; } void EntryViewEntryNamePrint (VIEWo *view, ENTRYo *entry, Int4 entryNo, Int4 rowN, Int4 isRoot) { TemplPrint (isRoot ? "rootName" : "leafName", EntryGetFullName (entry)); } /**API* EntryView ************************************************************ ** ** Print a single entry with selected root library ** fields, links with leaf libraries and prints leaf ** library entries with selected fields in a tabular format. ** Needs the "view" from Www?. ** ** INPUT: entry object [W] ** view object [R] */ void EntryView (ENTRYo *entry, struct VIEWo *view) { static Int4 entryNum=0; SETo *set; IDoENTRY id; ENTRYo *leafEntry; VIEWoLIB *vlib; VIEWoLEAFSET *leaves[50], *leaf; INT4 n, i, maxEntryN=1, leafLibsN=0, isTable=ViewIsTable (view); if (!view->entryNamePrint) /* improve !!!te*/ ViewSetEntryNamePrint (view, EntryViewEntryNamePrint); ViewTemplateBegin (view); /* do the link to the leaf libs and collect the resulting sets */ for (n=0; (vlib = ViewGetNextLeafLib (view, &n)); ) { set = Query (ViewGetLeafQuery (vlib, entry), NULL); leaf = (VIEWoLEAFSET *) malloc (sizeof (VIEWoLEAFSET)); leaf->vlib = vlib; leaf->set = set; leaf->entryN = set ? SetGetSize (set) : 0; if (leaf->entryN > maxEntryN && !ViewLeafIsOnlyEntryN (leaf->vlib)) maxEntryN = leaf->entryN; leaves[leafLibsN++] = leaf; } leaves[leafLibsN] = NULL; /* print the root entry */ for (i=0, vlib=NULL; (vlib = ViewGetNextRootLib (view, &i));) if (EntryGetLib (entry) == vlib->lib) break; if (isTable) EntryViewInTable (entry, view, vlib, ++entryNum, 1, maxEntryN); else EntryViewInList (entry, view, vlib, ++entryNum, 1); /* print the leaf entries */ if (!maxEntryN) TemplPrint ("tail"); else { for (n=1; n <= maxEntryN; n++) { for (i=0; (leaf = leaves[i]); i++) { if (n > leaf->entryN) { if (isTable && n==1) /* no linked entries */ EntryEmptyViewInTable (leaf->vlib, maxEntryN); continue; } if (ViewLeafIsOnlyEntryN (leaf->vlib)) { ViewLeafEntryNPrint (view, leaf, entry, maxEntryN); leaf->entryN = 0; /* prevent printing of more entries from set */ } else { SetGetID (leaf->set, n, &id); leafEntry = EntryOpen (&id); if (isTable) EntryViewInTable (leafEntry, view, leaf->vlib, entryNum, 0, n==leaf->entryN ? maxEntryN-n+1 : 1); else EntryViewInList (leafEntry, view, leaf->vlib, entryNum, 0); EntryClose (&leafEntry); } } TemplPrint ("tail"); } } SetClean (); /* remove temp. sets */ ViewTemplateEnd (view); } /****** WwwViewEntryInTable *************************************************** ** ** Prints an entry view inside a table. ** ** INPUT: entry object [R] ** view object [R] ** ** RETURNS: number of fields printed for the entry */ static INT4 EntryViewInTable (ENTRYo *entry, VIEWo *view, VIEWoLIB *vlib, Int4 entryNo, Int4 isRoot, Int4 rowN) { SLBoFIELD *field; INT4 k, fieldsN; ViewEntryNamePrint (view, entry, entryNo, rowN, isRoot); for(k=0, fieldsN=1; (field = ViewGetNextField (vlib, &k)); fieldsN++) { TemplWith (ViewGetTemplate (view), "value"); EntryPrintTableField (entry, field, FieldIs (field, "formatted") ? ViewGetFieldFormat (vlib, field) : NULL, rowN); TemplEndWith (); } return fieldsN; } /****** EntryEmptyViewInTable ************************************************ ** ** Prints an empty entry inside a table. ** ** INPUT: view library object [R] ** number of rows entry should span [R] */ static void EntryEmptyViewInTable (VIEWoLIB *vlib, Int4 rowN) { SLBoFIELD *field; INT4 k; TemplPrint ("emptyValue", rowN); for(k=0; (field = ViewGetNextField (vlib, &k));) TemplPrint ("emptyValue", rowN); } void EntryViewPrintEnvelope (ENTRYo *entry, char *option) { if (option[0] == 'h') {/* head */ switch (entry->lib->form->printFormat) { case LIBxTOPICLIST: TemplPrint ("$entry.inList.envelope.head.topicList"); break; case LIBxTABLE: TemplPrint ("$entry.inList.envelope.head.table"); break; case LIBxTABLE2: TemplPrint ("$entry.inList.envelope.head.table2"); break; case LIBxTEXT: TemplPrint ("$entry.inList.envelope.head.text"); break; default: TemplPrint ("$entry.inList.envelope.head.preformatted"); } } else /* tail */ switch (entry->lib->form->printFormat) { case LIBxTOPICLIST: TemplPrint ("$entry.inList.envelope.tail.topicList"); break; case LIBxTABLE: TemplPrint ("$entry.inList.envelope.tail.table"); break; case LIBxTABLE2: TemplPrint ("$entry.inList.envelope.tail.table2"); break; case LIBxTEXT: TemplPrint ("$entry.inList.envelope.tail.text"); break; default: TemplPrint ("$entry.inList.envelope.tail.preformatted"); } } /****** EntryViewInList ****************************************************** ** ** Prints an entry view inside a list. ** ** INPUT: template object [W] ** entry object [R] ** */ static void EntryViewInList (ENTRYo *entry, VIEWo *view, VIEWoLIB *vlib, Int4 entryNo, Int4 isRoot) { LIBoFieldFormat *format; SLBoFIELD *field; INT4 k; if (ViewIsEntryNamePrinting (view)) ViewEntryNamePrint (view, entry, entryNo, 1, isRoot); ParDefStr ("fieldList", "reset"); for(k=0; (field = ViewGetNextField (vlib, &k));) { ParDefStr ("fieldList", LibGetFieldName (field)); if (FieldIs (field, "formatted")) { format = ViewGetFieldFormat (vlib, field); LibSelectFieldFormat (field->type, format->name); } } EntryViewPrintEnvelope (entry, "head"); EntryPrintFields (entry, NULL); EntryViewPrintEnvelope (entry, "tail"); ParDefStr ("fieldList", "reset"); } /****** WwwPrintTableField **************************************************** ** ** Prints a data field inside a table. ** ** INPUT: entry object [R] ** field object [R] ** the field format object [R] or NULL ** number of rows the cell should span [R} */ static void EntryPrintTableField (ENTRYo *entry, SLBoFIELD *field, LIBoFieldFormat *format, Int4 rowN) { STRv s; INT4 c, type, l, k; if (!(type = FieldGetTableFormat (entry->lib, field))) type = LIBxLISTING; for (c=0, k=0; (s=EntryGetField (entry, field, &c)) || !k; k++) { if (!k) /* must print format here: EntryGetField decides the format! */ switch (type) { case LIBxLEFT: TemplPrint ("leftAlign", rowN); break; case LIBxRIGHT: TemplPrint ("rightAlign", rowN); break; case LIBxCENTER: TemplPrint ("center", rowN); break; case LIBxLISTING: TemplPrint ("listing", rowN); break; case LIBxPREFORMAT: TemplPrint ("preformat", rowN); break; } else TemplPrint ("next"); if (s) { /* if a token was found */ if (format) { char *com; if ((com = format->eval)) { VarSetStrv (EntryGetIcarusVar (entry, "token"), s); IcaEvalInJob (com, EntryGetJob (entry)); } } else { StrCutLF (&s); TemplPrint ("value", _Str (s)); } } else /* print empty token */ TemplPrint ("empty"); StrDel (s); } TemplPrint ("tail"); } /**api* EntrySourceName ******************************************************* ** ** returns the name of the entry source...is resolved in the following ** order: the logical name of the flatfile (GCG), the logical name of ** the whole library, just the library name ** ** INPUT: address of entry objcect [R] ** address of output string receiving the source name [W] ** IMPLICIT: ** ** RETURNS: */ void EntrySourceName (ENTRYo *entry, char *source_nm) { char *name; if (*(name = (entry->lib->fil[ entry->fileX[0] ].lnam)) || *(name = entry->lib->lnam[0]) || (name = entry->lib->nam)) strcpy (source_nm, name); } FILEo *EntryGetNextJobFile (ENTRYo *entry, char *name) { } /**api* EntryJobFile ********************************************************** ** ** Opens the file to access access the current entry. ** ** INPUT: entry object [R] ** symbolic file name [R] ** ** RETURNS: file object ** NULL: end of input stream */ static FILEo *EntryJobFile (char *symName, void* data) { ENTRYo *entry=(ENTRYo*)data; SRSoFILTYP *ft, *ftShares; FILEo **file; Int4 ftX, rv, ftXShares; if (!(ft=LibGetFileType (EntryGetLib (entry), symName, &ftX))) _ErrExit3 (e__objectunknown, "input file type", symName); file = &entry->file[ftX]; if (ftShares = LibGetFileTypeSharesFile (entry->lib, ft, &ftXShares)) { ft = ftShares; } /* single file per entry */ if (LibIsFilePerEntry (entry->lib)) { if (ftShares) return entry->file[ftXShares]; else if (LibOpenEntryFile (EntryGetLib (entry), file, ft, EntryGetFileName (entry))) return *file; else return NULL; } /* entry is in flat file */ else { if (!(*file = LibOpenFlatFile (entry->lib, entry->fileX[ftX], ft, &rv))) _ErrExit2 (rv, FileGetName (*file, "full")); FileSeek (*file, entry->fip[ftX]); return *file; } } /**api* EntryJobNextFile ***************************************************** ** ** Opens the next entry file mathing some criterion. To be used only ** as argument for IcaSetInputStreamer and for databanks where entries ** reside in separate files. See also EntryJobFile. ** ** INPUT: entry object [R] ** symbolic file name [R] ** ** RETURNS: file object ** NULL: end of input stream */ FILEo *EntryJobNextFile (char *symName, void* data) { ENTRYo *entry=(ENTRYo*)data; SLBo *lib=EntryGetLib (entry); FILEo **file; SRSoFILTYP *ft, *ftShares; Int4 ftX, rv, ftXShares; if (!(ft=LibGetFileType (lib, symName, &ftX))) _ErrExit3 (e__objectunknown, "input file type", symName); file = &entry->file[ftX]; if (ftShares = LibGetFileTypeSharesFile (lib, ft, &ftXShares)) ft = ftShares; /* single file per entry */ if (LibIsFilePerEntry (lib)) { if (ftShares) return entry->file[ftXShares]; else if (LibOpenNextEntryFile (lib, file, ft)) { strcpy (entry->entry_nm, FileGetName (*file, "name")); return *file; } } /* entry is in flat file */ else { if (!(rv = LibOpenNextFlatFile (lib, file, ft, &entry->fileX[ftX]))) return NULL; else if (rv == -1) _ErrExit2 (e__filnotok, FileGetName (*file, "full")); else if (rv == 1) return *file; else if (rv == 2) { _ErrMsg2 (i__processing, FileGetName (*file, "full")); FileSetGetFip (*file, 1); return *file; } } return NULL; } /**API* EntryOpenStream ******************************************************* ** ** Opens an entry stream. Entries can be read in sequential order with ** "EntryNext" ** ** INPUT: address of library object [R] ** IMPLICIT: ** ** RETURNS: entry object */ ENTRYo *EntryOpenStream (SLBo *lib) { ENTRYo *entry; if ((entry = (ENTRYo *) calloc (1, sizeof (ENTRYo))) == NULL) _ErrExit2 (e__allocfail, "entry-object"); if ((entry->id = (IDoENTRY *) calloc (1, sizeof (IDoENTRY))) == NULL) _ErrExit2 (e__allocfail, "id-object"); entry->id->idType = (IDoTYPE*) LibObjByName ("idtype", "Entry-ID"); entry->lib = lib; ParDefNum ("fromSrs", 1); /* turn off debugging in .is file */ EntrySetJob (entry, IcaCreateJob (lib->form->syntax)); entry->lib->allEntryCnt=0; IcaSetInputStreamer (EntryGetJob (entry), EntryJobNextFile); IcaSetInputStreamerData (EntryGetJob (entry), (void*)entry); EntrySetInputNames (entry); entry->fileX[0] = -1; entry->fileX[1] = -1; return entry; } /**API* EntryIsPartBegin ****************************************************** ** ** Checks if the entry stream opend with EntryOpenStream and processed ** with EntryNext is currently at a part begin. A part is a subsection of ** the databank which is independently indexed for a later merge. **
    ** In case the databank is not partioned the function returns TRUE only ** for the first entry. ** ** INPUT: address of entry object object [R] ** ** RETURNS: TRUE or FALSE */ Int4 EntryIsPartBegin (ENTRYo *entry) { SLBo *lib; Int4 partSize, rv; lib = EntryGetLib (entry); if (LibIs (lib, "partitioned")) { if (partSize = LibGetPartSize (lib)) rv = !((lib->allEntryCnt-1) % partSize) ? 1 : 0; } else rv = entry->lib->allEntryCnt == 1 ? 1 : 0; if (rv) entry->partNo++; return rv; } Int4 EntryGetPartNo (ENTRYo *entry) { return entry->partNo; } /**API* EntryNext ************************************************************* ** ** Opens next entry in the entry stream (opened by "EntryOpenStream"). ** ** INPUT: address of entry object [W] ** IMPLICIT: ** ** RETURNS: 1 if success ** 0 if all entries have been accessed */ INT4 EntryNext (ENTRYo *entry) { ICAoJOB *job=EntryGetJob (entry); if (IcaIsInputEnd (job)) { IcaEndJob (job); return 0; } IcaJobNext (job); if (entry->tokListDict) DictClear (&entry->tokListDict); entry->tokListN = 0; /* if (!job->file) IcaSetInputFile (job, NULL, NULL); */ entry->lib->allEntryCnt++; return 1; } /**API* EntryGetName ******************************************************* ** ** Returns the plain entry name without the library name prefixed. ** ** INPUT: address of entry object [R] ** ** RETURNS: entry name */ char *EntryGetName (ENTRYo *entry) { return entry->entry_nm; } /**API* EntryGetFullName ***************************************************** ** ** Returns the full entry name: databank name ':' entry name. ** ** INPUT: address of entry object [R] ** ** RETURNS: address of entry name */ char *EntryGetFullName (ENTRYo *entry) { if (!*entry->full_nm) sprintf (entry->full_nm, "%s:%s", LibName (entry->lib), entry->entry_nm); return entry->full_nm; } /**api* function ************************************************************** ** ** Returns the entry's file name or entry name if it has not been ** defined. ** ** INPUT: address of entry object [R] ** ** RETURNS: address of entry file name */ static char *EntryGetFileName (ENTRYo *entry) { return *entry->file_nm ? entry->file_nm : entry->entry_nm; } /**API* EntryGetGCGName ******************************************************* ** ** Returns the full entry name in GCG style. ** ** INPUT: address of entry object [R] ** ** RETURNS: address of entry name */ char *EntryGetGCGName (ENTRYo *entry) { static char name[200]; char libName[40]; EntrySourceName (entry, libName); sprintf (name, "%s:%s", libName, EntryGetName (entry)); return name; } /**API* EntryGetLib *********************************************************** ** ** Returns the library object of entry's source databank; ** ** INPUT: address of entry object [R] ** ** RETURNS: library object */ SLBo *EntryGetLib (ENTRYo *entry) { return entry->lib; } /**api* function ************************************************************** ** ** Returns job object for entry; ** ** INPUT: address of entry object [R] ** ** RETURNS: job object */ ICAoJOB *EntryGetJob (ENTRYo *entry) { SLBo *lib; lib = (LibIs (entry->lib, "subentries")) ? LibGetParentLib (entry->lib) : entry->lib; return lib->job; } /**api* function ************************************************************** ** ** Sets a job object for entry. ** ** INPUT: entry object [W] ** job object [R] ** ** RETURNS: library object */ static void EntrySetJob (ENTRYo *entry, ICAoJOB *job) { SLBo *lib; lib = (LibIs (entry->lib, "subentries")) ? LibGetParentLib (entry->lib) : entry->lib; lib->job = job; } /**API* function ************************************************************** ** ** Returns the subentry number of an entry and 0 if it is not a subentry. ** ** INPUT: address of entry object [R] ** ** RETURNS: 0: entry is not a subentry ** number greater 0: subentry number */ Int4 EntryGetSubEntryNo (ENTRYo *entry) { return IdIsSub (entry->id) ? IdGetSubN (entry->id) : 0; } /**API* EntryGetIcarusVar ***************************************************** ** ** Returns an Icarus variable with the specified name that is created ** during parsing of the entry. Access the value of the variable ** with VarGetInt, VarGetStrV, VarGetObject etc. ** ** INPUT: address of entry object [R] ** name of the variable [R] ** ** RETURNS: a variable object */ VARo *EntryGetIcarusVar (ENTRYo *entry, char *name) { ICAoJOB *job=EntryGetJob (entry); return VarGet (&job->scope, name); } /**api* EntryParse *********************************************************** ** ** Forces parsing of the field productions for all file sources of the ** entry. ** ** INPUT: address of entry object [R] ** ** RETURNS: 1: success ** 0: parsing unsuccessful */ Int4 EntryParse (ENTRYo *entry) { SRSoFILTYP *ft; Int4 c, k; for (c=0, k=0; (ft=LibNextFileType (EntryGetLib (entry), &c)); k++) { IcaGetTokenList (EntryGetJob (entry), LibGetFileTypeTokenTableName (ft)); entry->fip[k] = VarGetInt (EntryGetIcarusVar (entry, LibGetFileTypeFipName (ft))); } } /**API* EntryGetId *********************************************************** ** ** Returns the entry's ID object. ** ** INPUT: address of entry object [R] ** ** RETURNS: ID object */ IDoENTRY *EntryGetId (ENTRYo *entry) { return entry->id; } /**API* EntryGetAuxInfo ******************************************************* ** ** Returns auxilliary information about an entry. ** ** INPUT: address of entry object [R] ** ** RETURNS: buffer object */ SMoBUFF *EntryGetAuxInfo (ENTRYo *entry) { static SMoBUFF *buff=NULL; buff = BuffInit (buff, 100); LibGetEntryAuxInfo (entry->id->fip, entry->lib, buff); return buff; } void EntryIopSetFieldFormat (Int4 runTime, STRv fieldName, STRv formatName) { LIBoFieldFormat *format; SRSoFLD *fieldType; Int4 c, k, isFound; if (runTime) IargGetArgs ("field|set", &fieldName, &formatName); if (!StrLen(fieldName) || !StrLen(formatName)) return; /* return if empty strings */ for (k=0, isFound=0; (fieldType = LibNextFieldType (_Str(fieldName), &k));){ for (c=0; (format = LibNextFieldFormat (fieldType, &c));) { if (SmEqs (format->name, _Str(formatName))) { isFound=1; format->isSelected = 1; } else format->isSelected = 0; } } if (!isFound) _ErrExit3 (e__unknownformat, _Str(fieldName), _Str(formatName)); StrDel (fieldName); StrDel (formatName); } (!StrLen(fieldName) || !StrLen(formatName)) return; /* return if empty strings */ for (k=0, isFound=0; (fieldType = LibNextFieldType (_Str(fieldName), srs/src/entry.h ** ** $RCSfile: entry.h,v $ ** $Revision: 1.8 $ ** $Date: 1996/11/20 16:35:57 $ ** $Author: etzold $ ** ** $Locker: $ ** $State: Exp $ ** ** SRS V3.0 Copyright by Thure Etzold ** */ typedef struct ENTRYo *ENTRYv; typedef struct VIEWo *dummytointroducestructtagVIEWo; typedef struct IDoENTRY *dummytointroducestructtagIDoENTRY; #ifndef _SLBo typedef struct SLBo *dummytointroducestructtagSLBo; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of exported functions */ /* accessing an entry */ ENTRYv EntryOpen (struct IDoENTRY *id); INT4 EntryOpenText (ENTRYv entry); INT4 EntryOpenData (ENTRYv entry); void EntryClose (ENTRYv *entry); INT4 EntryBeginSub (ENTRYv entry); INT4 EntryNextSub (ENTRYv entry); ENTRYv EntryOpenStream (struct SLBo *lib); INT4 EntryNext (ENTRYv entry); struct SLBoFIELD *EntryNextField (ENTRYv entry, INT4 doLabelRemove, INT4 doNotReadLine); struct STRo *EntryGetField (ENTRYv entry, struct SLBoFIELD *field, INT4 *c); /* printing and parsing entries */ Int4 EntryParse (ENTRYv entry); struct TOKoLIST *EntryGetTokList (ENTRYv entry, char *name); void EntryPrint (ENTRYv entry, void *data); INT4 EntryPrintFields (ENTRYv entry, void *data); void EntryView (ENTRYv entry, struct VIEWo *view); /* get entry information */ INT4 EntryIsSub (); INT4 EntryIsEndLine (ENTRYv entry); void EntrySourceName (ENTRYv entry, char *source_nm); char* EntryGetFullName (ENTRYv entry); char* EntryGetName (ENTRYv entry); char* EntryGetGCGName (ENTRYv entry); struct SLBo* EntryGetLib (ENTRYv entry); struct SMoBUFF* EntryGetAuxInfo (ENTRYv entry); struct TOKoLIST* EntryGetTokList (ENTRYv entry, char *name); struct VARo* EntryGetIcarusVar (ENTRYv entry, char *name); struct ICAoJOB* EntryGetJob (ENTRYv entry); struct IDoENTRY* EntryGetId (ENTRYv entry); Fip EntryGetFip (ENTRYv entry, Int4 index); Int4 EntryGetFileX (ENTRYv entry); Int4 EntryGetSubEntryNo (ENTRYv entry); har* EntryGetGCGName (ENTRYv entry); struct SLBo* EntryGetLib (ENTRYv entry); struct SMoBUFF* EntryGetAuxInfo (ENTRYv entry); struct TOKoLIST* EntryGetTokList (ENTRYv entry, char *name); struct VARo* EntryGetIcarusVar (ENTRYv entry, char *name); struct ICAoJOB* EntryGetJob (ENTRYv entry); stsrs/src/error.c #include #include #include "message.h" #include "futil.h" #include "sm.h" #include "toklist.h" #include "cursor.h" #include "error.h" /******* ErrPop *************************************************** ** */ static ERRo *ErrPop(ERRoSTACK *errStack) { if(errStack->current > errStack->top) return(--errStack->current); else return(NULL); } /******* ErrPush *************************************************** ** */ static ERRo *ErrPush(ERRoSTACK *errStack) { if(errStack->current <= errStack->bottom) return(errStack->current++); else return(NULL); } /******* ErrNewStack *************************************************** ** */ ERRoSTACK *ErrNewStack() { ERRoSTACK *errStack; if( (errStack = (ERRoSTACK *)malloc(sizeof(ERRoSTACK))) == NULL ) _ErrExit2 (e__allocfail, "Error object"); memset(errStack, NULL, sizeof(ERRoSTACK)); errStack->top = errStack->error; errStack->bottom = errStack->error+1-1; /* maxstacksize not needed any more?*/ errStack->current = errStack->top; return(errStack); } /******* ErrErase *************************************************** ** */ void *ErrErase(ERRoSTACK *errStack) { errStack->current = errStack->top; /* printf("*********** ERASE **********************\n"); */ return; } /******* ErrIsFound *************************************************** ** */ INT4 ErrIsFound(ERRoSTACK *errStack, INT4 code) { ERRo *error; error = errStack->top; while(error <= errStack->current && error->code != code) error++; error--; return(errStack->current != error); } /******* ErrThrow *************************************************** ** */ void *ErrThrow(ERRoSTACK *errStack, char *pattern, INT4 code) { ERRo *error; if( (error = ErrPush(errStack)) ) { error->pattern = pattern; error->code = code; /* printf("Throw error now\t\t%s\n", pattern); */ } /* else */ /* _ErrMsg2 (e__overflowstack, MAXSTACKSIZE); */ return; } /******* ErrCatch *************************************************** ** */ ERRo *ErrCatch(ERRoSTACK *errStack, INT4 code) { ERRo *error; while( (error = ErrPop(errStack)) && code != error->code) ; return(error); } /******* ErrPrint *************************************************** ** */ void *ErrPrint(ERRoSTACK *errStack, char *name, INT4 code) { static char line[ERRxMAXPRINTSIZE+1], dots[ERRxMAXPRINTSIZE+1]; char *begin, *position, *ptr; INT4 len; ERRo *error; memset(line, NULL, ERRxMAXPRINTSIZE); memset(dots, NULL, ERRxMAXPRINTSIZE); begin = CursorGetBegin(Cursor); position = CursorGetPtr(Cursor); ptr = position; len = 0; while(ptr > begin && len < ERRxMAXPRINTSIZE/2 && *ptr != '\n') { len++; ptr--; } if(*ptr == '\n' && len) { ptr++; len--; } if(len) { strncpy(line, ptr, len); memset(dots, '.', len); } strcat(dots, "^"); ptr = position; len = 1; while(ptrcode, name, line, dots); do { printf(" |%s|\n", error->pattern); } while( error = ErrCatch(errStack, code) ); printf(" did not succeed to fit.\n"); } return; } #ifdef MAIN /* USAGE: cc -g -L /home/srs/srs5/bin/irix -I/home/srs/srs5/src -DSRSINCLUDE=\"srswin.h\" -DMAIN error.c */ static char *Test1 = "1234567890 Test String #1"; static char *Test2 = "1234567890 Test Long Long Long Long Long Long Long Long Long Long Long Long Long Long Long Long String #2"; static char *Test3 = "\n1234567890 Empty Test String #3"; static char *Test4 = "1234567890\nTest String with NewLine \n Continue #4"; char *ErrStrBegin, *ErrStrPtr; CURSORo *Cursor = NULL; /******make SRS happy*****/ char *CursorGetBegin(CURSORo *cursor){ return(ErrStrBegin); } char *CursorGetPtr(CURSORo *cursor){ return(ErrStrPtr); } INT4 Message (INT4 i, INT4 j, INT4 k, ...){ printf("Mess: %d %d %d\n",i,j,k); } FUNC SDL_fnct[1]; main() { ERRoSTACK *errStack; errStack = ErrNewStack(); printf("******* Test1 *******\n"); ErrStrBegin = Test1; ErrStrPtr = Test1 + 5; ErrErase(errStack); ErrThrow(errStack, "err1.1", 1); ErrThrow(errStack, "err1.2", 1); ErrThrow(errStack, "err1.3", 1); ErrThrow(errStack, "err1.4", 1); if(ErrIsFound(errStack, 1)) ErrPrint(errStack, "Dummy", 1); printf("******* Test2 *******\n"); ErrStrBegin = Test2; ErrStrPtr = Test2 + 80; ErrErase(errStack); ErrThrow(errStack, "err2.1", 1); ErrThrow(errStack, "err2.2", 2); ErrThrow(errStack, "err2.3", 1); ErrThrow(errStack, "err2.4", 2); ErrPrint(errStack, "Dummy", 2); printf("******* Test3 *******\n"); ErrStrBegin = Test3; ErrStrPtr = Test3; ErrErase(errStack); ErrThrow(errStack, "err3.1", 3); ErrThrow(errStack, "err3.2", 1); ErrThrow(errStack, "err3.3", 1); ErrThrow(errStack, "err3.4", 1); ErrPrint(errStack, "Dummy", 3); printf("******* Test4 *******\n"); ErrStrBegin = Test4; ErrStrPtr = Test4 + 9; ErrErase(errStack); ErrThrow(errStack, "err4.1", 1); ErrThrow(errStack, "err4.2", 1); ErrThrow(errStack, "err4.3", 1); ErrThrow(errStack, "err4.4", 4); ErrPrint(errStack, "Dummy", 4); printf("******* Test5 *******\n"); ErrStrBegin = Test1; ErrStrPtr = Test1+4; ErrErase(errStack); ErrThrow(errStack, "err4.1", 1); ErrThrow(errStack, "err4.2", 1); ErrThrow(errStack, "err4.3", 1); ErrThrow(errStack, "err4.4", 1); if( ErrIsFound(errStack, 5) ) ErrPrint(errStack, "Dummy", 5); else printf("No error level 5 was detected\n"); } #endif rThrow(errStack, "err4.2", 1); ErrThrow(errStack, "err4.3", 1); ErrThrow(errStack, "err4.4", 4); ErrPrint(errStack, "Dummy", 4); printf("******* Test5 *******\n"); ErrStrBegin = Test1; ErrStrPtr = Test1+4; ErrErase(errStack); ErrThrow(errStack, "err4.1", 1); ErrThrow(errStack, "ersrs/src/error.h ** ** $RCSfile: error.h,v $ ** $Revision: 1.2 $ ** $Date: 1996/05/06 19:20:33 $ ** $Author: etzold $ ** ** $Locker: $ ** $State: Exp $ ** ** ** Copyright by Thure Etzold ** ** Author: Anatoly Ulyanov ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387451 ** Email: ulyanov@embl-heidelberg.de ** */ #define ERRxMAXPRINTSIZE 72 typedef struct ERRo { char *pattern; /* patternt that does not fit */ INT4 code; /* error code */ } ERRo; typedef struct ERRoSTACK { ERRo error[1]; /* not needed any more ? */ ERRo *top; ERRo *bottom; ERRo *current; } ERRoSTACK; /* prototypes and external */ extern CURSORo *Cursor; ERRoSTACK *ErrNewStack(); void *ErrErase(ERRoSTACK *errStack); void *ErrThrow(ERRoSTACK *errStack, char *pattern, INT4 code); ERRo *ErrCatch(ERRoSTACK *errStack, INT4 code); void *ErrPrint(ERRoSTACK *errStack, char *name, INT4 code); INT4 ErrIsFound(ERRoSTACK *errStack, INT4 code); ERRo; typedef struct ERRoSTACK { ERRo error[1]; /* not needed any more ? */ ERRo *top; ERRo *bottom; ERRo *current; } ERRoSTACK; /* prototypes and external */ extern CURSORo *Cursor; ERRoSTACK *ErrNewStack(); void *ErrErase(ERRoSTACK *errStack); void *ErrThrow(ERRoSTACK *errStack, char *pattern, INT4 code); ERRo *ErrCatch(ERRoSTACK *errStasrs/src/field.c char field_ID[] = "$Id: field.c,v 1.4 1997/03/03 18:20:30 srs Exp $"; /* ** ** $RCSfile: field.c,v $ ** $Revision: 1.4 $ ** $Date: 1997/03/03 18:20:30 $ ** $Author: srs $ ** ** SRS Copyright by Thure Etzold ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** Requires: message, file, sm ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include "message.h" #include "futil.h" #include "sm.h" #include "strv.h" #include "toklist.h" #include "dict.h" #include "library.h" #include "field.h" #define _SRS #define _SLB #include SRSINCLUDE /**API* function ************************************************************** ** ** supersedes: LibIsField
    ** Returns 1 if the specified characteristic is true for the specified ** data-field. ** ** INPUT: o address of field object [R] ** o type: "index", "ID", "link", "show", "num", "real" ** "doquery", "group", "active", "system" "subentry" ** "formatted", "header" [R] ** ** RETURNS: 1: specified characteristic is true ** 0: not */ Int4 FieldIs (FIELDv field, char *option) { if (!field) return 0; switch (_Index (tolower(option[0]), tolower (option[1]))) { case _Index('i','n'): /* index */ return (field->index == SRSxID || field->index == SRSxKEY || field->index == SRSxNUM || field->index == SRSxREAL) ? 1 : 0; case _Index('i','d'): /* ID */ return (field->index == SRSxID) ? 1 : 0; case _Index('l','i'): /* link */ return (field->index == SRSxLINK) ? 1 : 0; case _Index('h','e'): /* header */ return (field->type->ityp == SRSxHEADER) ? 1 : 0; case _Index('s','h'): /* show */ return (field->type->isGroup ? 0 : 1); case _Index('d','o'): /* doquery */ return (field->index == SRSxID || field->index == SRSxKEY || field->index == SRSxNUM || field->index == SRSxREAL || field->type->isGroup) ? 1 : 0; case _Index('n', 'u'): /* num */ return (field->index == SRSxNUM) ? 1 : 0; case _Index('r','e'): /* real */ return (field->index == SRSxREAL) ? 1 : 0; case _Index('g','r'): /* group */ return (field->type->isGroup) ? 1 : 0; case _Index('a','c'): /* active */ return (ParGetBool (field->type->nam) || field->do_f); case _Index('s','y'): /* system */ return field->isSystem; case _Index('s','u'): /* subentry */ return !field->indexId ? 0 : ((field->indexId->siz == 6) ? 1 : 0); case _Index('f','o'): /* formatted */ return field->type->formatN ? 1 : 0; default: _ErrExit2 (e__unknownoption, option); } return 0; } /**api* function ************************************************************* ** ** Returns the name of a the token table that contains the specified ** tokens. Use FieldGetTokCode to get their token code. ** ** INPUT: field object [R] ** option: "fields", "index", "table" ** IMPLICIT: ** ** RETURNS: name of token table */ char *FieldGetTokListName (FIELDv field, char *option) { switch (tolower (option[0])) { case 'f': /* field */ if (field->code && *field->code) return "fields"; else return field->token; case 'i': /* index */ return field->indexToken[0]; case 't': /* table */ return field->tableToken; default: _ErrExit2 (e__unknownoption, option); } } /**api* function ************************************************************* ** ** Use FieldGetTokListName to get the token table name. ** ** INPUT: field object [R] ** option: "fields", "index", "table" ** IMPLICIT: ** ** RETURNS: token code */ Int4 FieldGetTokCode (FIELDv field, char *option) { Int4 k=0; switch (tolower (option[0])) { case 'f': /* field */ if (field->fieldTokCode == 0 && *field->code) field->fieldTokCode = TokStrToCode (field->code); return field->fieldTokCode; case 'i': /* index */ return field->indexTokCode[0]; case 't': /* table */ return field->tableTokCode; default: _ErrExit2 (e__unknownoption, option); } } /**api* function ************************************************************** ** ** Returns the format for printing the field inside a table. ** ** INPUT: library object [R] or NULL ** field object [R] ** ** RETURNS: table print format */ INT4 FieldGetTableFormat (SLBo *lib, SLBoFIELD *field) { Int4 format; if ((format = field->tableFormat)) return format; else if (lib && (format = lib->form->tableFormat)) return format; return 0; } /**api* function ************************************************************** ** ** Sets the table printing format for a field. ** ** INPUT: field object [W] ** format code ** */ void FieldSetTableFormat (SLBoFIELD *field, Int4 format) { field->tableFormat = format; } /**api* function ************************************************************* ** ** Returns the name of a data-field. Returns "unknown" if the field ** name could not be found. See also LibGetFieldTypeName. ** ** INPUT: address of field object [R] ** IMPLICIT: ** ** RETURNS: field name */ char *FieldGetName (FIELDv field) { static char unknown[30] = "unknown field"; if (field && field->type) { if (field->type->ityp == SRSxHEADER) return (field->name); else return field->type->nam; } else return unknown; } /**API* function ************************************************************** ** ** Returns the short name of a data-field. ** ** INPUT: address of field object [R] ** IMPLICIT: ** ** RETURNS: short field name */ char *FieldGetShortName (FIELDv field) { if (field->type->ityp == SRSxHEADER) return (field->name); else return field->type->shortn; } /**API* function ************************************************************** ** ** Returns the index type of a field as string. ** ** INPUT: address of field object [R] ** IMPLICIT: ** ** RETURNS: field name ** NULL */ char *FieldGetIndexType (FIELDv field) { static char *fieldIType[10]={"", "id", "index", "link", "show", "tree", "num", "real", "group"}; return fieldIType[field->index]; } /**api* function ************************************************************** ** ** Returns for a field object the object describing its type. See also ** LibGetFieldType. ** ** INPUT: field object [R] ** ** RETURNS: field type object */ SRSoFLD *FieldGetType (FIELDv field) { return field->type; } static int FieldTokenHash (FIELDv field, int max) { UINT4 sum; sum = CharHash (FieldGetTokListName (field, "field")); _hash (sum, (UINT4) FieldGetTokCode (field, "field")); return sum%max; } static Int4 FieldTokenEqual (FIELDv a, FIELDv b) { if (SmEqs (FieldGetTokListName (a, "field"), FieldGetTokListName (b, "field")) && FieldGetTokCode (a, "field") == FieldGetTokCode (b, "field")) return 1; else return 0; } /**api* function ************************************************************** ** ** Exchanges a "field" token for one or more field objects that match ** both token table name and code. ** ** INPUT: library object [W] ** token table from which the token is [R] ** token [R] ** ** RETURNS: field object */ FIELDv FieldNextFromToken (struct SLBo *lib, struct TOKoLIST *tokList, struct TOKoTOKEN *tok, Int4 *c) { static CLASSoDICT cl={(ValComparer)FieldTokenEqual, (ValHasher)FieldTokenHash, (KeyAccessor)KeyItself, 0, TRUE}; static Iter i=NULL; SLBoFIELD fieldKey; FIELDv *fieldPtr, field; Int4 k; if (!lib->form->tokenDict) { lib->form->tokenDict = DictCreate (&cl); for (k=0; (field=LibNextField (lib, &k));) { fieldPtr = &DictAdd (&lib->form->tokenDict, field, FIELDv); *fieldPtr = field; } } field = NULL; fieldKey.fieldTokCode = TokGetCode (tok); fieldKey.token = TokListGetName (tokList); fieldKey.code = ""; if (!i || !(*c)++) { if (i=DictWith (lib->form->tokenDict, &fieldKey)) field = DictIn (i, FIELDv); } else { DictNextWith (lib->form->tokenDict, &fieldKey, &i); if (i) field = DictIn (i, FIELDv); else { field = NULL; *c = 0; } } return field; } /**api* function ************************************************************** ** ** Gets an Icarus eval statement for a field. ** ** INPUT: the field object [R] ** ** RETURNS: string with Icarus statement */ char *FieldGetFormatEval (FIELDv field) { SRSoFLD *fieldType = field->type; Int4 k; if (!fieldType->formatN) return NULL; for (k=0; kformatN; k++) if (fieldType->format[k].isSelected) return fieldType->format[k].eval; if (*field->format) return (FieldGetFormat (field, field->format))->eval; else return field->type->format[0].eval; /* first in list is default */ } /**api* FieldGetFormat ******************************************************** ** ** Returns the field format object if there is the field has a format with ** the specified name. if an empty name is specified then the first ** format in the list is returned (default format). ** ** INPUT: address of field object [R] ** format name (or NULL or empty string) [R] ** ** RETURNS: data-field format object */ LIBoFieldFormat *FieldGetFormat (FIELDv field, char *name) { LIBoFieldFormat *format; Int4 c; for (c=0; (format = LibNextFieldFormat (field->type, &c));) if (!name || !*name || SmEqs (format->name, name)) return format; _ErrExit3 (e__objectunknown, "field format", name); return NULL; } Int4 FieldIsKeyConvert (FIELDv field) { return field->keyConvert; } /**api* function ************************************************************** ** ** Only for fields of subentries. Returns the "parent" field of a field ** which may be optionally specified. ** ** INPUT: address of field object [R] ** ** RETURNS: parent field object ** NULL: not specified */ FIELDv FieldInherits (FIELDv field) { return field->parent; } nknown, "field format", name); return NULL; } Int4 FieldIsKeyConvert (FIELDv field) { return field->keyConvert; } /**api* function ************************************************************** ** ** Only for fields of subentries. Returns the "parent" field of a field ** which may be optionally specified. ** ** INPUT: address of field object [R] ** ** srs/src/field.h ** ** $RCSfile: field.h,v $ ** $Revision: 1.5 $ ** $Date: 1997/03/03 18:20:30 $ ** $Author: srs $ ** ** ** SRS Copyright by Thure Etzold ** */ typedef struct SLBoFIELD *FIELDv; typedef struct TOKoTOKEN *dummytointroducestructtagTOKoTOKENfield; typedef struct TOKoLIST *dummytointroducestructtagTOKoLISTfield; typedef struct SLBoFIELD *dummytointroducestructtagSLBoFIELDfield; typedef struct SLBo *dummytointroducestructtagSLBofield; /* get attributes */ Int4 FieldIs (FIELDv field, char *option); char* FieldGetTokListName (FIELDv field, char *option); char* FieldGetName (FIELDv field); char* FieldGetShortName (FIELDv field); char* FieldGetIndexType (FIELDv field); struct SRSoFLD* FieldGetType (FIELDv field); char* FieldGetFormatEval (FIELDv field); struct LIBoFieldFormat* FieldGetFormat (FIELDv field, char *name); Int4 FieldIsKeyConvert (FIELDv field); FIELDv FieldInherits (FIELDv field); /* iteration */ FIELDv FieldNextFromToken (struct SLBo *lib, struct TOKoLIST *tokList, struct TOKoTOKEN *tok, Int4 *c); (FIELDv field); char* FieldGetIndexType (FIELDv field); struct SRSoFLD* FieldGetType (FIELDv field); char* FieldGetFormatEval (FIELDv field); struct LIBoFieldFormat* FieldGetFormat (FIELDv field, char *nasrs/src/futil.c char file_srs_ID[] = "$Id: futil.c,v 1.19 1997/03/03 18:20:31 srs Exp $"; /* ** ** $RCSfile: futil.c,v $ ** $Revision: 1.19 $ ** $Date: 1997/03/03 18:20:31 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port: This module has been modified in major parts ** by Lukas Rosenthaler and Reinhard ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** Requires: sm, message ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** contains routines for opening files, testing filenames; ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include "message.h" #include "regexp.h" #ifdef dos #else # ifdef VMS # include # include # include # include "rtl.h" # else # include # include # include # include # include # define TMPSTR_LEN 256 # endif #endif #include "futil.h" #include "sm.h" #include "strv.h" /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** defining file with variable record length under VMS */ #ifdef VMS # define VARFILE , "rat=cr", "rfm=var" # define READ "r" #else # define VARFILE # define READ "rb" #endif #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** objectwide variables */ #ifndef VMS static char *FilTranslate (char *, INT4); char *(*filTranslate)(char *, INT4) = FilTranslate; static FILEo *FilePipeOpen (FILEo *file); # define PATH_BUF_LEN 132 /* maximal length of pathname */ /**api* FilTranslate ********************************************************** ** ** called using the macro _FilLN; ** converts a name containing logicals into the expanded name, works ** with both VMS and UNIX syntax; overwrites input name!!! and ** assumes that input character array is large enough to handle output; ** ** INPUT: o address of file name string [W] ** o TRUE if output should not overwrite input - instead ** functions own static array is used - be sure you ** don't need output name after next call! [R] ** ** RETURNS: address of translated string - same address as input */ static char *FilTranslate (char *fileName, int isTemp) { static int count=0; static char tmpNames[5][PATH_BUF_LEN+1], *tmp; extern int LogNameTranslate (char *name, char *trans_name, int len); tmp = tmpNames[count++%5]; LogNameTranslate (fileName, tmp, PATH_BUF_LEN); if (!isTemp) { strcpy (fileName, tmp); return fileName; } else return tmp; } #endif /**api* FilOpenR ************************************************************** ** ** open file for read access; has the "b" option for opening binary files ** under DOS; ** ** INPUT: address of file name [R] ** address of error code [W] or NULL ** e__filnotok ** IMPLICIT: ** ** RETURNS: file pointer ** ...NULL if not successfull */ FILE *FilOpenR (char *fnam, int *errCode) { FILE *fptr; if ((fptr = fopen (_FilTempLN (fnam), "rb")) == NULL) { _ErrSet (errCode, e__filnotok); return NULL; } rewind (fptr); _ErrSet (errCode, 1); return fptr; } /**api* FilOpenRF ************************************************************* ** ** open file for read access; has the "b" option for opening binary files ** under DOS + varible record format under VMS; ** ** INPUT: address of file name [R] ** address of error code [W] or NULL ** e__filnotok ** IMPLICIT: ** ** RETURNS: file pointer ** ...NULL if not successfull */ FILE *FilOpenRF (char *fnam, int *errCode) { FILE *fptr; if ((fptr = fopen (_FilTempLN (fnam), READ)) == NULL) { _ErrSet (errCode, e__filnotok); return NULL; } rewind (fptr); _ErrSet (errCode, 1); return fptr; } /**api* FilOpenWV ************************************************************* ** ** open file in variable record format for write access ** ** INPUT: address of file name [R] ** address of error code [W] or NULL ** e__filnotok ** IMPLICIT: ** ** RETURNS: file pointer ** ...NULL if not successfull */ FILE *FilOpenWV (char *fileName, int *errCode) { FILE *file_d; if ((file_d = fopen (_FilTempLN (fileName), "w" VARFILE)) == NULL) { _ErrSet (errCode, e__filnotok); return NULL; } rewind (file_d); _ErrSet (errCode, 1); return file_d; } /**api* FilOpenW ************************************************************* ** ** open file for write access ** ** INPUT: address of file name [R] ** address of error code [W] or NULL ** e__filnotok ** IMPLICIT: ** ** RETURNS: file pointer ** ...NULL if not successfull */ FILE *FilOpenW (char *fileName, int *errCode) { FILE *file_d; if ((file_d = fopen (_FilTempLN (fileName), "wb+")) == NULL) { _ErrSet (errCode, e__filnotok); return NULL; } rewind (file_d); _ErrSet (errCode, 1); return file_d; } /**api* FilOpenU ************************************************************* ** ** open file for write access ** ** INPUT: address of file name [R] ** address of error code [W] or NULL ** e__filnotok ** IMPLICIT: ** ** RETURNS: file pointer ** ...NULL if not successfull */ FILE *FilOpenU (char *fileName, int *errCode) { FILE *file_d; if ((file_d = fopen (_FilTempLN (fileName), "r+")) == NULL) { _ErrSet (errCode, e__filnotok); return NULL; } fseek (file_d, 0, 2); _ErrSet (errCode, 1); return file_d; } /**api* FilTestW ************************************************************** ** ** tests whether a file can be opened (created) for write access; ** tests also a directory specification; ** ** INPUT: address of file name [R] ** ** RETURNS: 1 if ok ** e__invalofn */ INT4 FilTestW (char *fileName) { FILE *fil; char tmpName[FILxXNAM+1], testName[FILxXNAM+1]; char tmp2Name[256]; strcpy (testName, _FilTempLN (fileName)); if ((fil = fopen (testName, "w")) == NULL) return e__invalofn; #ifdef VMS fgetname (fil, tmpName, 1); /* delete correct file */ fclose( fil); if (delete (tmpName) != 0) return e__invalofn; #else fclose (fil); unlink (testName); #endif if (!FilParse (tmpName, tmp2Name, FILxNAME)) return e__invalofn; return 1; } /**api* FilTestDirW *********************************************************** ** ** tests whether a directory can be opened for write access; ** ** INPUT: address of file name [R] ** name option: FILxNAME, FILxDEST [R] ** ** RETURNS: 1 if ok ** e__invalofn */ INT4 FilTestDirW (char *fileName) { FILE *fil; char tmpName[FILxXNAM+1], testName[FILxXNAM+1]; char tmp2Name[256]; if (!FilParse (_FilTempLN (fileName), testName, FILxDEST)) return e__invalofn; strcat(testName, "x.x"); /** conv. to ordinary filspec */ FilParse (testName, tmp2Name, FILxNAME); if ((fil = fopen (testName, "w")) == NULL) return e__invalofn; #ifdef VMS fgetname (fil, tmpName, 1); /* delete correct file */ fclose( fil); if (delete (tmpName) != 0) return e__invalofn; #else fclose (fil); unlink (testName); #endif if (!FilParse (tmpName, tmp2Name, FILxNAME)) return e__invalofn; return 1; } /**api* FilTestR ************************************************************** ** ** tests whether a file can be accessed for reading; ** ** INPUT: name of file ** ** RETURNS: 1 if ok ** e__invalifn */ INT4 FilTestR(char *fileName) { if (access (_FilTempLN (fileName), 4) == EOF) return e__invalifn; return 1; } /**api* FilParse ************************************************************** ** ** parses a file name and returns: ** FILxNODE, FILxDEV, FILxROOT, FILxDIR, FILxNAME, FILxTYPE, FILxVERS ** ** INPUT: address of file name [R] ** address where to put part of file name [W] ** type (see above) [R] ** ** RETURNS: 1 if successful ** 0 if specified part was not found */ INT4 FilParse(char *innam, char *outnam, INT4 typ) { #ifdef VMS struct itemdesc { unsigned short len; unsigned short code; char *item; } itemd[8]; INT4 k, ret, len; itemd[FILxNODE].code = FSCN$_NODE; itemd[FILxDEV].code = FSCN$_DEVICE; itemd[FILxROOT].code = FSCN$_ROOT; itemd[FILxDIR].code = FSCN$_DIRECTORY; itemd[FILxNAME].code = FSCN$_NAME; itemd[FILxTYPE].code = FSCN$_TYPE; itemd[FILxVERS].code = FSCN$_VERSION; itemd[7].len = 0; /* longword at end of list = 0 */ itemd[7].code = 0; ret = sys$filescan ( _Psi(innam), itemd, 0); _StopIfEven(ret); if (typ == FILxDEST) { for (k = FILxDEV; k <= FILxNAME && itemd[k].item == NULL; k++) ; if (k == FILxNAME) return 0; len = itemd[FILxDEV].len + itemd[FILxROOT].len + itemd[FILxDIR].len; strncpy(outnam, itemd[k].item, len); } else if (typ == FILxSPEC) { for (k = FILxNAME; k <= FILxVERS && itemd[k].item == NULL; k++) ; if (k == FILxVERS) return 0; len = itemd[FILxNAME].len + itemd[FILxTYPE].len; strncpy(outnam, itemd[k].item, len); } else { if (itemd[typ].item == NULL) return 0; len = itemd[typ].len; strncpy(outnam, itemd[typ].item, len); } outnam[len] = '\0'; #else #define DIR_LEN 256 char cwd[DIR_LEN], t_innam[DIR_LEN]; INT4 i; strcpy (t_innam, innam); (void) getcwd (cwd, DIR_LEN); switch (typ) { /* ** return node name only (void on UNIX) */ case FILxNODE : { (void) strcpy (outnam, ""); break; } /* ** return device (void on UNIX) */ case FILxDEV : { (void) strcpy (outnam, ""); break; } /* * return root directory (current working directory on UNIX) */ case FILxROOT : { (void) strcpy (outnam, cwd); break; } /* * get directory path of file */ case FILxDIR : { for (i = strlen (_FilLN (t_innam)) - 1; (i >= 0) && (t_innam[i] != '/'); i--); if (t_innam[0] != '/') { /* * relative path, add absolute path of current working directory */ strcpy (outnam, cwd); strcat (outnam, "/"); if (i > 0) strncat (outnam, t_innam, i); } else { /* * absolute path */ (void) strncpy (outnam, t_innam, i); outnam[i] = '\0'; } break; } /* * return filename only without extension */ case FILxNAME : { for (i = strlen (t_innam) - 1; (i >= 0) && !strchr ("/:", t_innam[i]); i--) ; strcpy (outnam, &(t_innam[i+1])); for (i = strlen (outnam) - 1; (i >= 0) && (outnam[i] != '.'); i--); outnam[i] = '\0'; break; } /* * return file type (extension of the form file.ext) * ^^^ */ case FILxTYPE : { /* * scan file name from tail. If a '.' or a '/' is encountered, stop! */ for (i = strlen (t_innam) - 1; (i >= 0) && (t_innam[i] != '.') && (t_innam[i] != '/'); i--) ; if ((i <= 0) || (t_innam[i] == '/')) { /* no "file type"... */ (void) strcpy (outnam, ""); } else { (void) strcpy (outnam, &(t_innam[i+1])); /* o.k, "file type" found */ } break; } /* * file version (void on UNIX) */ case FILxVERS : { (void) strcpy (outnam, ""); break; } /* * full directory path */ case FILxDEST : { for (i = strlen (t_innam) - 1; (i >= 0) && (t_innam[i] != '/'); i--) ; if (t_innam[0] != '/') { /* relative path */ strcpy (outnam, cwd); strcat (outnam, "/"); if (i > 0) strncat (outnam, t_innam, i - 1); } else { if (i > 1) { (void) strncpy (outnam, t_innam, i); outnam[i] = '\0'; } else { (void) strncpy (outnam, t_innam, 1); outnam[1] = '\0'; } } break; } /* * full file name with extension (but without preceeding directory) */ case FILxSPEC : { for (i = strlen (t_innam) - 1; (i >= 0) && (t_innam[i] != '/'); i--); if (i >= 0) { (void) strcpy (outnam, &(t_innam[i+1])); } else { (void) strcpy (outnam, ""); } break; } } #endif return 1; } /**api* FilReadLn ************************************************************* ** ** reads a line and discards new line character; ** ** INPUT: address of file pointer ** address of output string ** max number of characters to be read ** ** RETURNS: 1 if success ** e__filnotok if not */ INT4 FilReadLn(FILE *fil, char *ln, INT4 nchar) { INT4 len; if (fgets(ln, nchar, fil) == NULL) return e__filnotok; len = strlen(ln); if (ln[len-1] == '\n') ln[len-1] = '\0'; return 1; } /**api* FilUOpen ************************************************************** ** ** opens file for read access and allocates an array that is to hold ** the lines read and reads first line ** ** INPUT: address of FILo ** address of file name ** max line length ** file type: FILxSTREAM or FILxVAR ** ** RETURNS 1 if success ** e__filopenerr ** e__allocfail ** e__eof ** e__filnotok ** e__ltoolong if line len > max len ** */ INT4 FilUOpen (FILo *file, char *fileName, INT4 len, INT4 ft) { INT4 rv; if (ft == FILxVAR) { if ((file->fil = fopen (_FilTempLN (fileName), READ)) == NULL) return e__filnotok; } else if ((file->fil = fopen (_FilTempLN (fileName), READ)) == NULL) return e__filopenerr; rewind (file->fil); if ((file->ln = malloc(len)) == 0) return e__allocfail; (void) strcpy (file->nam, _FilTempLN (fileName)); file->n = 0; file->len = len; file->eof = FALSE; file->c_s = 0; file->isPipe = 0; /* ** read first line of file...if that fails free the buffer for the ** current line and return error */ rv = FilURead (file); /* read first line */ _ErrIf (rv) free (file->ln); return rv; } /**api* FilUOpenPipe ********************************************************** ** ** opens a pipe for read access and allocates an array that is to hold ** the lines read and reads first line ** ** INPUT: address of FILo ** address of file name ** max line length ** file type: FILxSTREAM or FILxVAR ** ** RETURNS 1 if success ** e__filopenerr ** e__allocfail ** e__eof ** e__filnotok ** e__ltoolong if line len > max len ** */ INT4 FilUOpenPipe (FILo *file, char *fileName, char *comFormat, INT4 maxLen) { INT4 rv; char com[500]; sprintf (com, comFormat, _FilTempLN (fileName)); #ifndef VMS if (!(file->fil = popen (com , "r"))) return e__filopenerr; #endif if ((file->ln = malloc (maxLen)) == 0) return e__allocfail; (void) strcpy (file->nam, _FilTempLN (fileName)); file->n = 0; file->len = maxLen; file->eof = FALSE; file->c_s = 0; file->isPipe = 1; /* ** read first line of file...if that fails free the buffer for the ** current line and return error */ rv = FilURead (file); /* read first line */ _ErrIf (rv) free (file->ln); return rv; } /**api* FilUOpen2 ************************************************************* ** ** should become obsolete! ** Allocates file-descriptor, ** opens file for read access and allocates an array that is to hold ** the lines read and reads first line ** ** ** INPUT: address of pointer to FILo [W] ** address of file name [R] ** max line length [R] ** file type: FILxSTREAM or FILxVAR [R] ** ** RETURNS 1 if success ** e__filopenerr ** e__allocfail ** e__eof ** e__filnotok ** e__ltoolong if line len > max len ** */ INT4 FilUOpen2 (FILo **file_p, char *fileName, INT4 len, INT4 ft) { FILo *file; INT4 rv; if ((file = malloc (sizeof (FILo))) == 0) { return e__allocfail; } if (ft == FILxVAR) { if ((file->fil = fopen (_FilTempLN (fileName), READ)) == NULL) return e__filnotok; } else if ((file->fil = fopen (_FilTempLN (fileName), READ)) == NULL) { free (file); return e__filopenerr; } rewind (file->fil); if ((file->ln = malloc(len)) == 0) return e__allocfail; (void) strcpy (file->nam, fileName); file->n = 0; file->len = len; file->eof = FALSE; file->svn = 0; file->c_s = '\0'; file->isPipe = 0; *file_p = file; /* ** read first line of file...if that fails free the buffer for the ** current line and return error */ rv = FilURead (file); /* read first line */ _ErrIf (rv) free (file->ln); return rv; } /**api* FilUClose ************************************************************* ** ** closes file opened with FilUOpen and frees again the line buffer; ** ** INPUT: address of file descr. (FILo) ** ** RETURNS: 1 if ok ** e__freefail + */ INT4 FilUClose (FILo *file) { if (file == NULL) return 1; if (file->fil != NULL) { #ifndef VMS if (file->isPipe) pclose (file->fil); else #endif fclose (file->fil); file->fil = NULL; } if (file->ln) free (file->ln); return 1; } /**api* FilUClose2 ************************************************************ ** ** should become obsolete! ** closes file opened with FilUOpen and frees again the line buffer; ** frees storage used by FILo; ** ** INPUT: address of file descr. (FILo) ** ** RETURNS: 1 if ok ** e__freefail + */ INT4 FilUClose2 (FILo *file) { if (file == NULL) return 1; if (file->fil != NULL) fclose (file->fil); free (file->ln); free (file); file = NULL; return 1; } /**api* FilURead ************************************************************** ** ** reads a line in file; input and output ATTRIBUTEs are contained in ** FILo; checks whether read line ends with a '\n' if not ** error is reported and f->n is not incremented; ** ** INPUT: address of FILo ** ** RETURNS: e__eof <> ** e__filnotok <> ** e__ltoolong <> ** 1 if successful */ INT4 FilURead (FILo *f) { INT4 rv = 1; f->crfdd = ftell(f->fil); /* save file address */ if (fgets(f->ln, f->len, f->fil) == NULL) { if (feof(f->fil) != 0) { f->eof = TRUE; *f->ln = '\n'; *(f->ln+1) = '\0'; f->l = f->ln; return e__eof; } return e__filnotok; } /* if (f->ln[strlen(f->ln) - 1] != '\n') rv = e__ltoolong; */ f->l = f->ln; if (rv == 1) (f->n)++; return rv; } /**api* FilUSave ************************************************************** ** ** saves info about current line + offset so that it can be restored ** again with FilUBack ** ** INPUT: address of FILo ** address of FILoL_S ** ** RETURNS: 1 */ INT4 FilUSave (FILo *f, FILoL_S *svl) { svl->svfdd = f->crfdd; svl->svoff = f->l - &(f->ln)[0]; svl->svn = f->n; return 1; } /**api* FilUSave2 ************************************************************* ** ** should be removed again! ** saves info about current line + offset so that it can be restored ** again with FilUBack ** ** INPUT: address of FILo [W] ** ** RETURNS: 1 */ INT4 FilUSave2 (FILo *f) { f->svfdd = f->crfdd; f->svoff = f->l - &(f->ln)[0]; f->svn = f->n; return 1; } /**api* FilUBack ************************************************************** ** ** restores line saved by FilUSave - i.e. goes back in the file ** ** INPUT: address of FILo ** address of FILoL_S ** ** RETURNS: 1 ** e__lnotsaved if info is missing */ INT4 FilUBack (FILo *f, FILoL_S *svl) { INT4 rv; if (svl->svn == 0) return e__lnotsaved; if (svl->svn != f->n) { fseek(f->fil, svl->svfdd, 0); rv = FilURead(f); _ErrRet(rv); f->n = svl->svn; } f->l = f->ln + svl->svoff; return 1; } /**api* FilUBack2 ************************************************************* ** ** should be removed again! ** restores line saved by FilUSave - i.e. goes back in the file ** ** INPUT: address of FILo ** ** RETURNS: 1 ** e__lnotsaved if info is missing */ INT4 FilUBack2 (FILo *f) { INT4 rv; if (f->svn == 0) return e__lnotsaved; if (f->svn != f->n) { fseek(f->fil, f->svfdd, 0); rv = FilURead(f); _ErrRet(rv); f->n = f->svn; } f->l = f->ln + f->svoff; return 1; } /**api* FilEof **************************************************************** ** ** checks whether end of file has been reached and sets f->eof flag to ** FALSE; ** ** INPUT: address of FILo ** ** RETURNS: TRUE (EOF) ** FALSE */ INT4 FilEof(FILo *f) { if (f->eof) { f->eof = FALSE; return TRUE; } return FALSE; } #ifndef dos /**api* FilSearch ************************************************************* ** ** returns full specification for a file - if name has a wildcard ** then the first is found and context is returned for further calls; ** ** INPUT: address of input name [R] ** address of output name [W] or NULL ** address of search context [W] (0 if first call) or NULL ** IMPLICIT: ** ** RETURNS: 1 if name contains no wildcard ** 2 if yes ** 0 if no more file found */ INT4 FilSearch (char *wildfileName, char *efileName, UINT4 *c) #ifdef VMS { char fileName[FILxXNAM+1]; UINT4 c2=0; INT4 k, rv; if (efileName == NULL) efileName = fileName; if (c == NULL) c = &c2; rv = lib$find_file ( _Psi (wildfileName), _Pso (efileName), c); if (rv == RMS$_NMF) { lib$find_file_end ( c); return 0; } else if (rv%2 == 0) /** file not found */ return 0; for (k=0; efileName[k] != ' '; k++) ; efileName[k] = '\0'; if (strpbrk (wildfileName, "%*") == NULL) return 1; else return 2; } #else /* ** UNIX implementation */ { regexp *regExp; char dirName[DIR_LEN], fil_str[DIR_LEN], regexp_str[DIR_LEN]; char twildfileName[DIR_LEN], tmp_nm[DIR_LEN]; static char fileName[FILxXNAM+1]; static DIR *dirStream = NULL; struct dirent *dirEntry; INT4 i; if (efileName == NULL) efileName = fileName; strcpy (twildfileName, wildfileName); /* ** first get the directory part of "twildfileName"; ** if it is a relative path (does not start with '/') then add the ** absolute path of the current working directory */ for (i=strlen (_FilLN (twildfileName)) - 1; (i >= 0) && (twildfileName[i] != '/'); i--); if (twildfileName[0] != '/') { (void) getcwd (dirName, DIR_LEN); if (i > 0) { if ((i - 1) > 0) { (void) strcat (dirName, "/"); (void) strncat (dirName, twildfileName, i); } } } else { /** absolute path */ if (i > 0) { (void) strncpy (dirName, twildfileName, i); dirName[i] = '\0'; } else { (void) strcpy (dirName, "/"); } } /* ** now get file part (including wildcarts a la regexp) */ for (i=strlen (twildfileName) - 1; (i >= 0) && (twildfileName[i] != '/'); i--); if ((i > 0) || (strpbrk (twildfileName, "?*") != NULL)) { (void) strcpy (fil_str, &(twildfileName[i+1])); } else { (void) strcpy (fil_str, twildfileName); /** used to be "./" ??? */ } RegWildToRegexp (fil_str, regexp_str, 1); regExp = RegComp (regexp_str); if (regExp == NULL) _ErrRet2 (e__regerror, "regcomp failure"); /* ** open directory, read all file names and compare each name to the ** regular expression - if match then construct the complete file name ** and return; ** */ if (!c || *c == 0) { if ((dirStream = opendir (dirName)) == NULL) { return (0); } if (c) *c = 1; } while ((dirEntry = readdir (dirStream)) != NULL) { strcpy(tmp_nm, dirEntry->d_name); if (!RegExec (regExp, tmp_nm)) continue; /** get next entry */ strcpy (efileName, dirName); /** construct complete file name */ if (dirName[strlen (dirName) - 1] != '/') strcat (efileName, "/"); strcat (efileName, tmp_nm); if (!c) closedir (dirStream); return (strpbrk (twildfileName, "?*") == NULL) ? 1 : 2; } /* no more matching files can be found */ if (c) *c = 0; closedir (dirStream); free (regExp); return (0); } #endif #endif /**api* FilCutLn ************************************************************** ** ** makes a line look shorter as is - line can be restored to full ** length by FilRestoreLn - line can be cut at both ends; ** ** INPUT: address of file-dsc [W] ** begin of cut line [R] first col=1 ** length of cut line [R] ** IMPLICIT: ** ** RETURNS: 1 ** 0 if beg + length is greater than actual line ** e__novalnum + */ INT4 FilCutLn (FILo *file, INT4 beg, INT4 len) { INT4 ln_z; ln_z = strlen (file->ln); if (ln_z < beg) _ErrRet2 (e__novalnum, beg); file->l = &(file->ln[--beg]); if (strlen (file->ln) < beg + len) return 0; file->c_sp = &(file->ln[beg+len]); file->c_s = *file->c_sp; *(file->c_sp) = '\0'; file->n_s = file->n; return 1; } /**api* FilUSeek ************************************************************** ** ** goes to file address and reads first line; current line number (FILo.n) ** is set to 0 (-> of no use any more) ** ** INPUT: address of file descriptor [W] ** file address [R] ** IMPLICIT: ** ** RETURNS: 1 */ INT4 FilUSeek (FILo *file, UINT4 fadd) { if (!file->isPipe) { fseek (file->fil, fadd, 0); file->n = 0; return FilURead (file); } return 0; } /**api* FilRestoreLn ********************************************************** ** ** restores cut line to full length line - does not if context (line nr.) ** different. ** ** INPUT: address of file->dsc [W] ** IMPLICIT: ** ** RETURNS: 1 if restored ** 0 if not */ INT4 FilRestoreLn (FILo *file) { if (file->n != file->n_s) return 0; *(file->c_sp) = file->c_s; file->c_s = 0; return 0; } /****** FilMsg **************************************************************** ** ** forms string for error message containg erroneous line + position wher; ** ** INPUT: address of FILo ** ** RETURNS: pointer to message string */ char *FilMsg (FILo *file) { static char msgLine[2*MSGxXLN+2]; char spacer[MSGxXLN+1]; INT4 len; len = strlen (file->ln) - strlen (file->l); SmFill(spacer, len MSGxXLN) file->ln[MSGxXLN]='\0'; sprintf (msgLine, "%s%s^\n", file->ln, spacer); SmEdit (msgLine, SMxDETAB); return &msgLine[0]; } /****** FilChMod ************************************************************** ** ** changes file mod to executable...function ignores second argument... ** expandable; ** ** INPUT: file name [R] ** mode specifier [R] ...ignored ** ** RETURNS: */ void FilChMod (char *fileName, char *mode) { #ifndef VMS chmod (_FilTempLN(fileName), 00744); /* no need to do that under VMS */ #endif } /**API* FilSetTranslate ******************************************************* ** ** Sets a new function for the translation of filenames of the ** form "someName:fileName" where "someName" is an environment ** variable or a logical name defining a directory location. File ** names in this format render SRS independent of the different naming ** conventions of the operating systems supported. ** ** ** INPUT: o address of the function to supersede the default ** function [W] ** ** RETURNS: */ void FilSetTranslate (char *(*translate)(char *, INT4)) { #ifndef vms if (translate) filTranslate = translate; #endif } /*****************************************************************************/ /*******the better futil starts from here! ***********************************/ /*****************************************************************************/ #define _Index(x,y) ( ((x)-'a'+1) << 5) +((y)-'a'+1) static void FileInitNames (FILEo *file); /**api* FileNew *************************************************************** ** ** Creates a new file object. Use FileOpen to open the file, FileClose ** to close it again and FileDelete to delete the object. **
    The file name is optional and can be also set with FileSetName. ** ** INPUT: o the file name (or NULL, stdin/stdout (see FileOpen) will ** be assumed) [R] ** ** RETURNS: the new file object ** */ FILEo *FileNew (char *fileName) { FILEo *file; if (!(file = (FILEo *) calloc (1, sizeof (FILEo)))) _ErrExit2 (e__allocfail, "file object"); file->isRead = 1; file->fullName = BuffNew (0); file->dirName = BuffNew (0); file->fileName = BuffNew (0); file->extName = BuffNew (0); file->name = BuffNew (0); file->ln = NULL; file->lnMaxLength = 2000; file->fd = -1; if (fileName) BuffCopyString (file->fullName, fileName); return file; } /**api* FileSetMaxLine ******************************************************** ** ** Sets the size of the longest line in the file for read operations. ** ** INPUT: the file object [W] ** the maximum line length [R] ** ** RETURNS: the file object ** */ FILEo *FileSetMaxLine (FILEo *file, INT4 length) { file->lnMaxLength = length; return file; } /**api* FileSetName *********************************************************** ** ** Sets the entire ("full") or specified part of the name for the file. ** See also FileGetName. ** ** INPUT: file object [W] ** option: "full", "dir", "file", "name", "ext" ** the name [R] ** */ void FileSetName (FILEo *file, char *opt, char *name) { ASSERT (name, "no name specified"); switch (_Index (tolower(opt[0]), tolower (opt[1]))) { case _Index('f','u'): /* full */ BuffReset (file->fullName); BuffCopyString (file->fullName, name); break; case _Index('d','i'): /* dir */ BuffReset (file->dirName); BuffCopyString (file->dirName, name); if (BuffMatch (file->dirName, "[^/]$")) BuffCopyString (file->dirName, "/"); break; case _Index('f','i'): /* file */ BuffReset (file->fileName); BuffCopyString (file->fileName, name); break; case _Index('e','x'): /* ext */ BuffReset (file->extName); BuffCopyString (file->extName, name); break; case _Index('n','a'): /* name */ BuffReset (file->fileName); BuffReset (file->name); BuffCopyString (file->name, name); break; default: _ErrExit2 (e__unknownoption, opt); } file->isNameInit = 0; } /**api* FileSetMode *********************************************************** ** ** Sets the access mode for the file. The mode is specified as a ** string with 9 letters for owner, group and world access. ** The first in a triple must be 'r' (read) followed by 'w' (write) and ** 'x' (execute). Missing characteristics must be indicated by '-'. ** Eg, "rw-r--r--" or "rwxr-x--x" ** ** INPUT: the file object [W] ** the mode string [R] ** */ void FileSetMode (FILEo *file, char *mode) { strcpy (file->mode, mode); } /**api* FileOpen ************************************************************** ** ** Opens a file described by the file object created by FileNew. ** The file object can be further described or modified before opening ** with FileSetName, FileSetUpdate, FileSetWrite, FileSetMaxLine, ** FileSetGetFip, FileSetUnixIo, FileSetWrite. ** If the input file name is not defined, stdin/stdout is assumed depending on the access mode. ** ** INPUT: the file object [W] ** ** RETURNS: the file object ** NULL: if not successful ** */ FILEo *FileOpen (FILEo *file) { char *fileName, *optStr; Int4 option; if (!file->isNameInit) FileInitNames (file); FileClose (file); /* in case object is reused */ if (!file->ln) if (!(file->ln = (char *) malloc (file->lnMaxLength+1))) _ErrExit2 (e__allocfail, "file line"); *file->ln = '\0'; fileName = FileGetName (file, "path"); if (file->isUnixIo) { if (file->isRead && file->isWrite) option = O_RDWR; else if (file->isWrite) option = O_WRONLY | O_CREAT | O_TRUNC; else option = O_RDONLY; if ((file->fd = open (fileName, option, 0666)) == -1) return NULL; } else if (file->pipeCom) { /* open pipe for reading */ FilePipeOpen (file); } else { if (!*fileName) file->file = file->isWrite ? stdout : stdin; else { if (file->isRead && file->isWrite) optStr = "r+"; else if (file->isWrite) optStr = "w"; else optStr = "r"; if (!(file->file = fopen (fileName, optStr))) return NULL; } } return file; } static FILEo *FilePipeOpen (FILEo *file) { STRv com=StrNew (); StrPrintf (&com, _Str(file->pipeCom), FileGetName (file, "path")); if (!(file->file = popen (_Str (com) , "r"))) { StrDel (com); return NULL; } StrDel (com); return file; } /**api* FileReadLn ************************************************************ ** ** ** INPUT: the file object [W] ** ** RETURNS: the address of the line just read. ** */ char *FileReadLn (FILEo *file) { if (file->doGetFip) file->fip = ftell (file->file); if (fgets (file->ln, file->lnMaxLength, file->file) == NULL) { if (feof (file->file) != 0) file->isEof = 1; *file->ln = '\0'; return NULL; } file->lnN++; return file->ln; } /**api* FileWrite ************************************************************* ** ** Writes specified number of bytes to the stream. ** ** INPUT: the file object [W] ** the input buffer [R] ** the number of bytes to write [R] ** */ void FileWrite (FILEo *file, char *buff, Int4 nBytes) { Int4 nWriteBytes; if (file->isUnixIo) write (file->fd, buff, nBytes); else nWriteBytes = fwrite (buff, 1, nBytes, file->file); } /**api* FileRead ************************************************************** ** ** Reads specified number of bytes from the stream. ** ** INPUT: the file object [W] ** the output buffer [W] ** the number of bytes to read [R] ** ** RETURNS: 1 if the read operation was successful ** 0 if at the end of the file ** */ char *FileRead (FILEo *file, char *buff, Int4 nBytes) { Int4 nReadBytes; if (file->isUnixIo) nReadBytes = read (file->fd, buff, nBytes); else nReadBytes = fread (buff, 1, nBytes, file->file); if (!nReadBytes) file->isEof = 1; return file->isEof ? NULL : buff; } /**api* FileIsEof ************************************************************* ** ** ** INPUT: a ** ** RETURNS: 1 or 0 ** */ INT4 FileIsEof (FILEo *file) { return file->isEof; } /**api* FileDelete ************************************************************ ** ** Deletes a file object created with FileNew and closes it if ** the file object describes a still opened file. ** ** INPUT: the file object [W] ** ** RETURNS: NULL ** */ FILEo *FileDelete (FILEo *file) { if (file->ln) free (file->ln); BuffDelete (&file->fullName); BuffDelete (&file->dirName); BuffDelete (&file->fileName); FileClose (file); free (file); return NULL; } /**api* FileClose ************************************************************* ** ** Closes the file but checks first if there is a file to be closed ** at all. ** ** INPUT: file object [W] */ void FileClose (FILEo *file) { if (file->isUnixIo) { if (!(file->fd == -1)){ close (file->fd); file->fd = -1; } } else if (file->file && file->pipeCom) { /* consume file - otherwise 'broken pipe' */ if (!FileIsEof (file)) while (fgets (file->ln, file->lnMaxLength, file->file)) ; pclose (file->file); file->file = NULL; } else if (file->file) { fclose (file->file); file->file = NULL; } file->lnN = 0; file->fip = 0; file->fd = -1; file->isEof = FALSE; if (*file->mode) /* improve !!!te*/ chmod (FileGetName (file, "path"), 00755); } /**api* FileGetLn ************************************************************* ** ** Returns the most recently read line. ** ** INPUT: file object [R] ** ** RETURNS: the current line */ char *FileGetLn (FILEo *file) { return file->ln; } /**api* FileGetName *********************************************************** ** ** Returns the full file name or optionally parses it and returns parts ** of it. Use "path" to get the real name where all logical names are ** translated. ** ** INPUT: file object [R] ** option: "full", "dir", "file", "name", "ext", "path" ** ** RETURNS: the requested name */ char *FileGetName (FILEo *file, char *opt) { if (!file->isNameInit) FileInitNames (file); switch (_Index (tolower(opt[0]), tolower (opt[1]))) { case _Index('f','u'): /* full */ return BuffGetPtr (file->fullName); case _Index('p','a'): /* path */ return _FilTempLN (BuffGetPtr (file->fullName)); case _Index('d','i'): /* dir */ BuffMatch (file->fullName, "^(.+/)[^/]+$"); return BuffGetMatch (1); case _Index('f','i'): /* file */ BuffMatch (file->fullName, "^(.+/)?([^/]+)$"); return BuffGetMatch (2); case _Index('e','x'): /* ext */ BuffMatch (file->fullName, "^.+/[^\\.]+\\.([^/]+)$"); return BuffGetMatch (1); case _Index('n','a'): /* name */ BuffMatch (file->fullName, "^.+/([^\\.]+)\\.[^/]+$"); return BuffGetMatch (1); default: _ErrExit2 (e__unknownoption, opt); return NULL; } } /**api* FileGetTime ********************************************************** ** ** Returns various times (in seconds after 1.jan 1970) for a file ** which must have been opened with FileOpen. ** the "create" time corresponds to the "status change" time returned ** by fstat. ** ** INPUT: the file object [R] ** option: "create", "mod", "access". ** ** RETURNS: the time of specified type ** */ Int4 FileGetTime (FILEo *file, char *option) { struct stat buff; Int4 fileNo; fileNo = fileno (file->file); fstat (fileNo, &buff); switch (option[0]) { case 'c': /* create */ return buff.st_ctime; case 'm': /* mod */ return buff.st_mtime; case 'a': /* access - last access */ return buff.st_atime; default: _ErrExit3 (e__novalopt, option, "FileGetTime"); } return 0; } /**api* FileGetFile *********************************************************** ** ** Returns the 'real' file descriptor as returned by fopen. ** ** INPUT: the file object [R] ** ** RETURNS: the stdio ('FILE') file descriptor ** */ FILE *FileGetFile (FILEo *file) { return file->file; } /**api* FileGetFileN ********************************************************** ** ** Returns the number of a file during an iteration with FileNext. ** ** INPUT: the file object [R] ** ** RETURNS: the iteration number ** */ INT4 FileGetFileN (FILEo *file) { return file->fileN; } /**api* FileGetFileN ********************************************************** ** ** Returns the number of the last line read from the file. ** ** INPUT: file object [W] ** ** RETURNS: the line number ** */ INT4 FileGetLineN (FILEo *file) { return file->lnN; } /**api* FileGetFip ************************************************************ ** ** Returns the file pointer to the position in the file BEFORE the ** last line read. ** ** INPUT: file object ** ** RETURNS: the current file pointer ** */ FIP FileGetFip (FILEo *file) { return file->fip; } /**api* FileSetPipe *********************************************************** ** ** Sets a command to be opened as a pipe. The command must have up ** to three "%s" wherever the file name should be inserted. ** ** INPUT: file object [W] ** the pipe command [R] ** */ void FileSetPipe (FILEo *file, char *command) { if (!file->pipeCom) file->pipeCom = StrNew (); StrSetS (&file->pipeCom, command); } /**api* FileSetGetFip ********************************************************* ** ** Selects whether the file pointer should be memorized after each ** reading a line from the file. ** ** INPUT: file object [W] ** true or false [R] ** */ void FileSetGetFip (FILEo *file, INT4 flag) { if (file && !file->pipeCom) file->doGetFip = flag; } /**api* FileSetWrite ********************************************************** ** ** Selects write access for the file. ** ** INPUT: file object [W] ** ** RETURNS: the file object */ FILEo *FileSetWrite (FILEo *file) { file->isRead = 0; file->isWrite = 1; return file; } /**api* FileSetUpdate ********************************************************* ** ** Selects "update" access for the file. ** ** INPUT: file object [W] ** ** RETURNS: the file object */ FILEo *FileSetUpdate (FILEo *file) { file->isRead = 1; file->isWrite = 1; return file; } /**api* FileSetUnixIo ********************************************************* ** ** Selects the file to be opened with UNIX/IO functions. ** ** INPUT: file object [W] ** ** RETURNS: the file object */ FILEo *FileSetUnixIo (FILEo *file) { file->isUnixIo = 1; return file; } /**api* FileNext ************************************************************** ** ** Opens the next file that matches a file name that may ** contain '*' and '?' as wildcards. ** ** INPUT: the file object [W} ** ** RETURNS: the number of the file found ** 0: no more files found */ INT4 FileNext (FILEo *file) { struct dirent *dirEntry; char reStr[512], *tmp; if (file->fileN && !file->isWildFile) return 0; if (!file->isNameInit) { FileInitNames (file); if (file->regExp) { free (file->regExp); file->regExp = NULL; } BuffReset (file->dirName); BuffCopyString (file->dirName, FileGetName (file, "dir")); BuffReset (file->fileName); BuffCopyString (file->fileName, FileGetName (file, "file")); if (RegWildToRegexp (BuffGetPtr (file->fileName), reStr, 1)) { file->isWildFile = 1; } } if (!file->regExp && file->isWildFile) { file->fileN = 0; RegWildToRegexp (BuffGetPtr (file->fileName), reStr, 1); if (!(file->regExp = RegComp (reStr))) { _ErrMsg2 (e__regerror, "regcomp failure"); return 0; } tmp = BuffGetPtr (file->dirName); if (!(file->dirStream = opendir (*tmp ? tmp : "./"))) { _ErrMsg2 (e__filopenerr, BuffGetPtr (file->dirName)); return 0; } } if (file->isWildFile) { while ((dirEntry = readdir ((DIR *) file->dirStream))) { if (!RegExec (file->regExp, dirEntry->d_name)) continue; BuffReset (file->fullName); BuffPrintF (file->fullName, "%s%s", BuffGetPtr (file->dirName), dirEntry->d_name); FileOpen (file); return ++file->fileN; } closedir (file->dirStream); } else { file->fileN = 1; if (!FileOpen (file)) _ErrExit2 (e__filnotok, FileGetName (file, "path")); return 1; } return 0; } /****** FileInitNames ********************************************************* ** ** ** INPUT: a ** ** RETURNS: 1 ** */ static void FileInitNames (FILEo *file) { if (BuffLength (file->dirName)) { BuffReset (file->fullName); BuffCat (file->fullName, file->dirName); } if (BuffLength (file->fileName)) BuffCat (file->fullName, file->fileName); else { if (BuffLength (file->name)) BuffCat (file->fullName, file->name); if (BuffLength (file->extName)) { BuffCopyString (file->fullName, "."); BuffCat (file->fullName, file->extName); } } file->isNameInit = 1; } /**api* FileSeek ************************************************************** ** ** Sets the file pointer to file address. ** The current line number is set to 0. ** ** INPUT: file object [W] ** file address relative from file start [R] ** ** RETURNS: 1 ** */ void FileSeek (FILEo *file, FIP fip) { if (file->isUnixIo) lseek (file->fd, fip, 0); else if (!file->pipeCom) fseek (file->file, fip, 0); file->fip = fip; file->ln[0] = '\0'; file->lnN=0; file->isEof = 0; } /**api* FileSeekEnd *********************************************************** ** ** ** INPUT: file object [W] ** file address relative from file start [R] ** ** RETURNS: 1 ** */ void FileSeekEnd (FILEo *file, FIP fip) { if (file->isUnixIo) lseek (file->fd, fip, 2); else if (!file->pipeCom) fseek (file->file, fip, 2); file->fip = fip; file->ln[0] = '\0'; } eek (file->file, fip, 0); file->fip = fip; file->ln[0] = '\0'; file->lnN=0; file->isEof = 0; } /**api* FileSeekEnd *********************************************************** ** ** ** INPUT: file object [W] ** file address relative from file start [R] ** ** srs/src/futil.h ** ** $RCSfile: futil.h,v $ ** $Revision: 1.7 $ ** $Date: 1997/03/03 18:20:32 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port: Lukas Rosenthaler and Reinhard Doelz ** */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** different parts of the file name; ** DEST = NODE+DEV+ROOT+DIR, SPEC = NAME+TYPE+VERS */ enum fil_nametag {FILxNODE=0, FILxDEV, FILxROOT, FILxDIR, FILxNAME, FILxTYPE, FILxVERS, FILxDEST, FILxSPEC}; #define FILxXNAM 132 /* max size of a file name */ #define FILxVAR 1 /* variable record format */ #define FILxSTREAM 2 /* c-stream file */ #define FILxWRITE 1 #define FILxREAD 2 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** macro that calls FilLogicName on UNIX but not on VMS */ #ifndef VMS extern char * (*filTranslate)(char *, INT4); # define _FilLN(x) (char *) (*filTranslate) (x, 0) # define _FilTempLN(x) (char *) (*filTranslate) (x, 1) #else # define _FilLN(x) x # define _FilTempLN(x) x #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** descriptor of a file opened with FilUOpen */ typedef struct FILo { FILE *fil; /* C-lib file descriptor */ char nam[FILxXNAM+1]; /* file name */ char *ln; /* current line = line buffer */ char *l; /* read pointer within current line */ INT4 n; /* no of lines */ INT4 len; /* length of line buffer */ UINT4 crfdd; /* current file address */ char eof; /* flag if eof has been reached */ char c_s; /* saved character at CUT position */ char *c_sp; /* pointer to CUT position */ INT4 n_s; /* line no of CUT line */ UINT4 svfdd; /* saved file offset of line */ INT4 svoff; /* saved offset within saved line */ INT4 svn; /* saved line no */ INT4 isPipe; /* flag if file was opened as pipe */ } FILo; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** structure to save a read position within a file opened by FilUSave */ typedef struct { UINT4 svfdd; /* saved file offset of line */ INT4 svoff; /* saved offset within saved line */ INT4 svn; /* saved line no */ } FILoL_S; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of exported functions */ FILE *FilOpenW (char *, int *errCode); FILE *FilOpenU (char *, int *errCode); FILE *FilOpenR (char *, int *errCode); FILE *FilOpenRF (char *, int *errCode); FILE *FilOpenWV (char *, int *errCode); INT4 FilUOpen (FILo *f, char *fil_nm, INT4 len, INT4 ft); INT4 FilUOpen2 (FILo **f, char *fil_nm, INT4 len, INT4 ft); INT4 FilURead (FILo *f); INT4 FilUSeek (FILo *file, UINT4 fip); INT4 FilUClose (FILo *f); INT4 FilUClose2 (FILo *f); INT4 FilEof(FILo *f); void FilChMod (char *fileName, char *mode); INT4 FilSearch (char *wildfil_nm, char *efil_nm, UINT4 *cntxt); INT4 FilParse (char *innam, char *outnam, INT4 typ); INT4 FilUSave (FILo *f, FILoL_S *svl); INT4 FilUSave2 (FILo *f); INT4 FilUBack (FILo *f, FILoL_S *svl); INT4 FilUBack2 (FILo *f); char *FilMsg (FILo *file); INT4 FilCutLn (FILo *file, INT4 beg, INT4 len); INT4 FilRestoreLn (FILo *file); void FilSetTranslate (char *(*translate)(char *, INT4)); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** descriptor of a file opened with FilNew/FilOpen */ typedef struct FILEo { FILE *file; /* C-lib file descriptor */ Int4 fd; struct SMoBUFF *fullName; struct SMoBUFF *dirName; struct SMoBUFF *fileName; struct SMoBUFF *extName; struct SMoBUFF *name; struct STRo *pipeCom; struct regexp *regExp; void *dirStream; char *ln; /* line buffer */ INT4 lnMaxLength; /* max length of line read from file */ INT4 lnN; /* no of lines currently read */ INT4 fileN; /* number of file in 'search' context */ FIP fip; /* file address of current line */ char isEof; /* flag if eof has been reached */ char isPipe; /* flag if file was opened as pipe */ char isWildFile; char isNameInit; char isWrite; char isRead; char isUnixIo; char doGetFip; char mode[20]; } FILEo; /* create, set and delete files */ FILEo* FileNew (char *fileName); FILEo* FileOpen (FILEo *file); void FileClose (FILEo *file); FILEo* FileDelete (FILEo *file); INT4 FileNext (FILEo *file); /* set characteristics */ FILEo* FileSetWrite (FILEo *file); FILEo* FileSetUpdate (FILEo *file); FILEo* FileSetMaxLine (FILEo *file, INT4 length); void FileSetPipe (FILEo *file, char *pipeCommand); void FileSetName (FILEo *file, char *opt, char *name); FILEo* FileSetUnixIo (FILEo *file); /* read and write and set position */ char* FileReadLn (FILEo *file); char* FileRead (FILEo *file, char *buff, Int4 nBytes); void FileWrite (FILEo *file, char *buff, Int4 nBytes); void FileSeek (FILEo *file, FIP fip); /* get info */ INT4 FileIsEof (FILEo *file); INT4 FileGetFileN (FILEo *file); char* FileGetName (FILEo *file, char *opt); void FileSetGetFip (FILEo *file, INT4 flag); FIP FileGetFip (FILEo *file); INT4 FileGetLineN (FILEo *file); Int4 FileGetTime (FILEo *file, char *option); FILE* FileGetFile (FILEo *file); char* FileGetLn (FILEo *file); #ifdef ready void FileSetTranslate (); void FileChangeMod (); #endif (FILEo *file, char *buff, Int4 nBytes); void FileSeek (FILEo *file, FIP fip); /* get info */ INT4 FileIsEof (FILEo *file); INT4 FileGetFileN (FILEo *file); char* FileGetName (FILEo *file, char *opt); void FileSetGetFip (FILEo *file, INT4 flag); FIP FileGetFip (FILEo *file); INT4 FileGetLsrs/src/gd.c char gd_ID[] = "$Id: gd.c,v 1.1 1996/05/06 15:16:31 srs Exp $"; /* ** ** $RCSfile: gd.c,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:16:31 $ ** ** $Locker: $ ** $State: Exp $ ** ** ** Written by Tom Boutell, 5/94. ** Copyright 1994, Cold Spring Harbor Labs. ** Permission granted to use this code in any fashion provided ** that this notice is retained and any alterations are ** labeled as such. It is requested, but not required, that ** you share extensions to this module with us so that we ** can incorporate them into new versions. ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** The original file "gd.c" was modified ...it now contains also gdfontl.c ** gdfonts.c and mtables.c by thure etzold, March 10, 1995 */ #include #include #include #include #include #include "gd.h" /* begin of gdfontl.c */ char gdFontLargeData[] = { 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,1,0,0,0, 0,0,1,1,1,0,0,0, 0,0,1,1,1,0,0,0, 0,0,1,1,1,0,0,0, 0,0,1,1,1,0,0,0, 0,0,1,1,1,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,1,1,1,0,0,0, 0,0,0,1,0,0,0,0, 0,1,1,0,1,1,0,0, 0,1,1,0,1,1,0,0, 0,0,1,0,0,1,0,0, 0,0,1,0,0,1,0,0, 0,1,0,0,1,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,1,0,0,1,0, 0,0,0,1,0,0,1,0, 0,0,0,1,0,0,1,0, 0,1,1,1,1,1,1,1, 0,0,1,0,0,1,0,0, 0,0,1,0,0,1,0,0, 0,0,1,0,0,1,0,0, 0,0,1,0,0,1,0,0, 0,0,1,0,0,1,0,0, 1,1,1,1,1,1,1,0, 0,1,0,0,1,0,0,0, 0,1,0,0,1,0,0,0, 0,1,0,0,1,0,0,0, 0,1,0,0,1,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,1,1,1,0,0,0, 0,1,0,1,0,1,0,0, 1,0,0,1,0,0,1,0, 1,0,0,1,0,1,1,0, 1,0,0,1,0,0,0,0, 0,1,0,1,0,0,0,0, 0,0,1,1,1,0,0,0, 0,0,0,1,0,1,0,0, 0,0,0,1,0,0,1,0, 1,1,0,1,0,0,1,0, 1,0,0,1,0,0,1,0, 1,0,0,1,0,1,0,0, 0,1,1,1,1,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,0,0,0,1,0, 0,1,1,0,0,0,1,0, 1,0,0,1,0,1,0,0, 1,0,0,1,0,1,0,0, 1,0,0,1,0,1,0,0, 1,0,0,1,1,0,0,0, 0,1,1,0,1,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,1,0,1,1,0,0, 0,0,1,1,0,0,1,0, 0,1,0,1,0,0,1,0, 0,1,0,1,0,0,1,0, 0,1,0,1,0,0,1,0, 1,0,0,0,1,1,0,0, 1,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,0,0,0,0, 0,1,0,0,1,0,0,0, 0,1,0,0,1,0,0,0, 0,1,0,0,1,0,0,0, 0,1,0,1,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,1,1,1,0, 0,1,0,1,0,1,0,0, 0,1,0,1,0,1,0,0, 1,0,0,1,0,1,0,0, 1,0,0,0,1,0,0,0, 1,0,0,0,1,1,0,0, 0,1,1,1,0,0,1,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,0,0,0,0,0, 1,1,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 1,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,1,0, 0,0,0,0,0,1,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,0,1,0,0, 0,0,0,0,0,0,1,0, 1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,1,0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,1,1,1,0,0,0, 1,0,0,1,0,0,1,0, 1,1,0,1,0,1,1,0, 0,0,1,1,1,0,0,0, 1,1,0,1,0,1,1,0, 1,0,0,1,0,0,1,0, 0,0,1,1,1,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 1,1,1,1,1,1,1,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,0,0,0,0,0, 1,1,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 1,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 1,1,1,0,0,0,0,0, 1,1,1,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,1,0, 0,0,0,0,0,0,1,0, 0,0,0,0,0,1,0,0, 0,0,0,0,0,1,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,1,1,0,0,0, 0,0,1,0,0,1,0,0, 0,0,1,0,0,1,0,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,0,1,0,0,1,0,0, 0,0,1,0,0,1,0,0, 0,0,0,1,1,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,1,0,0,0,0, 0,1,1,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,1,1,1,1,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,1,1,0,0,0, 0,0,1,0,0,1,0,0, 0,1,0,0,0,0,1,0, 0,1,1,0,0,0,1,0, 0,0,0,0,0,0,1,0, 0,0,0,0,0,1,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,1,1,1,1,1,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,1,0,0,0, 0,1,0,0,0,1,0,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 0,0,0,0,0,0,1,0, 0,0,0,0,0,1,0,0, 0,0,1,1,1,0,0,0, 0,0,0,0,0,1,0,0, 0,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 0,1,0,0,0,1,0,0, 0,0,1,1,1,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,1,1,0,0,0, 0,0,1,0,1,0,0,0, 0,0,1,0,1,0,0,0, 0,1,0,0,1,0,0,0, 0,1,0,0,1,0,0,0, 1,0,0,0,1,0,0,0, 1,0,0,0,1,0,0,0, 1,1,1,1,1,1,1,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,1,1,1,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,1,1,1,0,0, 1,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 1,0,1,1,1,0,0,0, 1,1,0,0,0,1,0,0, 1,0,0,0,0,0,1,0, 0,0,0,0,0,0,1,0, 0,0,0,0,0,0,1,0, 1,1,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 0,1,0,0,0,1,0,0, 0,0,1,1,1,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,1,1,0,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,1,1,0, 1,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 1,0,1,1,1,0,0,0, 1,1,0,0,0,1,0,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 0,1,0,0,0,1,0,0, 0,0,1,1,1,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 0,0,0,0,0,1,0,0, 0,0,0,0,0,1,0,0, 0,0,0,0,0,1,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,1,0,0,0, 0,1,0,0,0,1,0,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 0,1,0,0,0,1,0,0, 0,0,1,1,1,0,0,0, 0,1,0,0,0,1,0,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 0,1,0,0,0,1,0,0, 0,0,1,1,1,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,1,0,0,0, 0,1,0,0,0,1,0,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 0,1,0,0,0,1,1,0, 0,0,1,1,1,0,1,0, 0,0,0,0,0,0,1,0, 0,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 0,1,0,0,0,1,0,0, 0,0,1,1,1,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,1,0,0,0, 0,0,1,1,1,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,1,0,0,0, 0,0,1,1,1,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,1,0,0,0, 0,0,1,1,1,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,1,0,0,0, 0,0,1,1,1,0,0,0, 0,0,0,1,1,0,0,0, 0,0,0,1,0,0,0,0, 0,0,1,1,0,0,0,0, 0,0,0,0,0,0,1,0, 0,0,0,0,0,1,0,0, 0,0,0,0,0,1,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,0,1,0,0, 0,0,0,0,0,1,0,0, 0,0,0,0,0,0,1,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,1,0,0,0, 0,1,0,0,0,1,0,0, 1,0,0,0,0,0,1,0, 1,1,0,0,0,0,1,0, 0,0,0,0,0,0,1,0, 0,0,0,0,0,1,0,0, 0,0,0,0,0,1,0,0, 0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,1,1,1,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,1,1,0,0, 0,1,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,1,1,0,1,0, 1,0,1,0,0,1,1,0, 1,0,1,0,0,0,1,0, 1,0,1,0,0,0,1,0, 1,0,1,0,0,0,1,0, 1,0,1,0,0,1,1,0, 1,0,0,1,1,0,1,0, 1,0,0,0,0,0,0,0, 0,1,0,0,0,0,1,0, 0,0,1,1,1,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,1,0,1,0,0,0, 0,0,1,0,1,0,0,0, 0,0,1,0,1,0,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,1,1,1,1,1,0,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,1,0,0,0,1,1,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,1,1,0,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,1,0,0, 0,1,1,1,1,0,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 1,1,1,1,1,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,1,0,1,0, 0,1,0,0,0,1,1,0, 0,1,0,0,0,0,1,0, 1,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 1,0,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,0,1,1,1,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,1,1,0,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 1,1,1,1,1,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,0,0, 0,1,0,0,1,0,0,0, 0,1,0,0,1,0,0,0, 0,1,1,1,1,0,0,0, 0,1,0,0,1,0,0,0, 0,1,0,0,1,0,0,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 1,1,1,1,1,1,1,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,0,0, 0,1,0,0,1,0,0,0, 0,1,0,0,1,0,0,0, 0,1,1,1,1,0,0,0, 0,1,0,0,1,0,0,0, 0,1,0,0,1,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 1,1,1,1,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,1,1,0,1,0, 0,0,1,0,0,1,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 1,0,0,0,1,1,1,1, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,1,0,0,1,1,0, 0,0,0,1,1,0,1,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,0,0,1,1,1, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,1,1,1,1,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 1,1,1,0,0,1,1,1, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 1,1,1,1,1,1,1,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,1,1,1,1,1, 0,0,0,0,0,0,1,0, 0,0,0,0,0,0,1,0, 0,0,0,0,0,0,1,0, 0,0,0,0,0,0,1,0, 0,0,0,0,0,0,1,0, 0,0,0,0,0,0,1,0, 0,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 0,1,0,0,0,1,0,0, 0,0,1,1,1,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,0,0,1,1,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,1,0,0,0, 0,1,0,0,1,0,0,0, 0,1,1,1,0,0,0,0, 0,1,0,1,0,0,0,0, 0,1,0,0,1,0,0,0, 0,1,0,0,1,0,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,0,1,0, 1,1,1,0,0,0,1,1, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,1,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 1,1,1,1,1,1,1,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,0,0,0,0,0,1,0, 1,1,0,0,0,1,1,0, 1,0,1,0,1,0,1,0, 1,0,1,0,1,0,1,0, 1,0,1,0,1,0,1,0, 1,0,0,1,0,0,1,0, 1,0,0,1,0,0,1,0, 1,0,0,1,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,1,0,0,0,1,1,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,0,0,0,0,1,1,1, 1,1,0,0,0,0,1,0, 1,0,1,0,0,0,1,0, 1,0,1,0,0,0,1,0, 1,0,1,0,0,0,1,0, 1,0,0,1,0,0,1,0, 1,0,0,1,0,0,1,0, 1,0,0,1,0,0,1,0, 1,0,0,0,1,0,1,0, 1,0,0,0,1,0,1,0, 1,0,0,0,1,0,1,0, 1,0,0,0,0,1,1,0, 1,1,0,0,0,0,1,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,1,0,0,0, 0,1,0,0,0,1,0,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 0,1,0,0,0,1,0,0, 0,0,1,1,1,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,1,1,0,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,1,0,0, 0,1,1,1,1,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 1,1,1,1,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,1,0,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,1,1,1,0,1,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,0,1,1,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,0,1,1,0, 0,0,0,0,0,0,0,0, 1,1,1,1,1,0,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,1,0,0, 0,1,1,1,1,0,0,0, 0,1,0,0,1,0,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,0,1,0, 1,1,1,0,0,0,1,1, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,0,1,0,0, 0,1,0,0,1,1,0,0, 1,0,0,0,0,1,0,0, 1,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 0,1,1,0,0,0,0,0, 0,0,0,1,1,0,0,0, 0,0,0,0,0,1,0,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,1,0,0,0,1,0,0, 1,0,1,1,1,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,0, 1,0,0,1,0,0,1,0, 1,0,0,1,0,0,1,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,1,1,1,1,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,0,0,1,1,1, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,0,1,1,1,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,0,0,0,1,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,0,1,0,1,0,0,0, 0,0,1,0,1,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,0,0,0,1,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,1,0,0,1,0, 1,0,0,1,0,0,1,0, 1,0,0,1,0,0,1,0, 1,0,1,0,1,0,1,0, 1,0,1,0,1,0,1,0, 1,0,1,0,1,0,1,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,0,1,1,1,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,0,1,0,1,0,0,0, 0,0,1,0,1,0,0,0, 0,0,0,1,0,0,0,0, 0,0,1,0,1,0,0,0, 0,0,1,0,1,0,0,0, 0,0,1,0,1,0,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 1,0,0,0,0,0,1,0, 1,1,0,0,0,1,1,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,0,0,0,1,1,0, 1,0,0,0,0,0,1,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,0,1,0,1,0,0,0, 0,0,1,0,1,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,1,1,1,1,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,0, 1,0,0,0,0,1,0,0, 1,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,1,1,1,1,1,1,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,1,1,1,1,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,1,1,1,0, 0,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,0,1,0,0, 0,0,0,0,0,1,0,0, 0,0,0,0,0,0,1,0, 0,0,0,0,0,0,1,0, 0,0,0,0,0,0,0,0, 1,1,1,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 1,1,1,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,1,0,1,0,0,0, 0,1,0,0,0,1,0,0, 1,0,0,0,0,0,1,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,0, 0,0,1,1,0,0,0,0, 0,0,1,1,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,1,1,0,0, 0,1,0,0,0,0,1,0, 0,0,0,0,0,0,1,0, 0,0,1,1,1,1,1,0, 0,1,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,1,1,0, 0,1,1,1,1,0,1,1, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,1,1,1,0,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,1,0,0, 0,1,1,1,1,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,1,0,1,0, 0,1,0,0,0,1,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 1,0,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,0,1,1,1,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,1,1,0, 0,0,0,0,0,1,0,0, 0,0,0,0,0,1,0,0, 0,0,0,0,0,1,0,0, 0,0,1,1,1,1,0,0, 0,1,0,0,0,1,0,0, 1,0,0,0,0,1,0,0, 1,0,0,0,0,1,0,0, 1,0,0,0,0,1,0,0, 1,0,0,0,0,1,0,0, 1,0,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,0,1,1,1,1,1,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,1,0,0,0, 0,1,0,0,0,1,0,0, 1,0,0,0,0,0,1,0, 1,1,1,1,1,1,1,0, 1,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0, 1,0,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,0,1,1,1,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,1,1,1,0, 0,0,0,1,0,0,0,1, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 1,1,1,1,1,1,1,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,1,1,1,1,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,1,0,1,1, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,0,1,1,1,0,0,0, 0,1,0,0,0,0,0,0, 0,1,1,1,1,0,0,0, 1,0,0,0,0,1,0,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 0,1,1,1,1,1,0,0, 0,0,0,0,0,0,0,0, 1,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,1,1,1,0,0, 0,1,1,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 1,1,1,0,0,1,1,1, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,1,1,0,0,0, 0,0,0,1,1,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,1,1,1,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,1,1,0, 0,0,0,0,0,1,1,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,1,1,1,0, 0,0,0,0,0,0,1,0, 0,0,0,0,0,0,1,0, 0,0,0,0,0,0,1,0, 0,0,0,0,0,0,1,0, 0,0,0,0,0,0,1,0, 0,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 0,1,0,0,0,1,0,0, 0,0,1,1,1,0,0,0, 0,0,0,0,0,0,0,0, 1,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,1,0,0, 0,1,0,0,1,0,0,0, 0,1,0,1,1,0,0,0, 0,1,1,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 1,1,1,0,0,0,1,1, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,1,1,1,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,1,1,0,1,1,0,0, 1,0,0,1,0,0,1,0, 1,0,0,1,0,0,1,0, 1,0,0,1,0,0,1,0, 1,0,0,1,0,0,1,0, 1,0,0,1,0,0,1,0, 1,0,0,1,0,0,1,0, 1,0,0,1,0,0,1,0, 1,1,0,1,1,0,1,1, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,0,1,1,1,0,0, 0,1,1,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 1,1,1,0,0,1,1,1, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,1,0,0,0, 0,1,0,0,0,1,0,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 0,1,0,0,0,1,0,0, 0,0,1,1,1,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,1,1,0,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,1,0,0, 0,1,1,1,1,0,0,0, 0,1,0,0,0,0,0,0, 0,1,0,0,0,0,0,0, 1,1,1,1,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,1,1,1,0, 0,1,0,0,0,1,0,0, 1,0,0,0,0,1,0,0, 1,0,0,0,0,1,0,0, 1,0,0,0,0,1,0,0, 1,0,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,0,1,1,1,1,0,0, 0,0,0,0,0,1,0,0, 0,0,0,0,0,1,0,0, 0,0,0,1,1,1,1,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,0,1,1,0,0, 0,0,1,1,0,0,1,0, 0,0,1,0,0,0,1,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 1,1,1,1,1,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,1,0,1,0, 0,1,0,0,0,1,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,0,0, 0,0,1,1,1,1,0,0, 0,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 1,1,0,0,0,0,1,0, 1,0,1,1,1,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 1,1,1,1,1,1,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,1,0, 0,0,1,0,0,0,1,0, 0,0,0,1,1,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,0,0,0,1,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,1,1,0, 0,0,1,1,1,0,0,1, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,0,0,0,1,1,0, 1,0,0,0,0,0,1,0, 1,0,0,0,0,0,1,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,0,1,0,1,0,0,0, 0,0,1,0,1,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,0,0,1,0,0,1,0, 1,0,0,1,0,0,1,0, 1,0,0,1,0,0,1,0, 1,0,0,1,0,0,1,0, 1,0,1,0,1,0,1,0, 1,0,1,0,1,0,1,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,1,0,0,0,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,0,1,1,1,0, 0,1,0,0,0,1,0,0, 0,0,1,0,1,0,0,0, 0,0,1,0,1,0,0,0, 0,0,0,1,0,0,0,0, 0,0,1,0,1,0,0,0, 0,0,1,0,1,0,0,0, 0,1,0,0,0,1,0,0, 1,1,1,0,1,1,1,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,1,1,0,0,1,1,1, 0,1,0,0,0,0,1,0, 0,0,1,0,0,0,1,0, 0,0,1,0,0,1,0,0, 0,0,0,1,0,1,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0, 1,0,0,1,0,0,0,0, 1,0,1,0,0,0,0,0, 0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,1,1,1,1,1,1,0, 0,1,0,0,0,1,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,1,0,0,0,1,0, 0,1,0,0,0,0,1,0, 1,1,1,1,1,1,1,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,1,1,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,0,0,1,1,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0, 1,1,0,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,0,1,0,0,0,0, 0,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 0,0,1,0,0,0,0,0, 1,1,0,0,0,0,0,0, 0,1,1,0,0,0,0,0, 1,0,0,1,0,0,1,0, 0,0,0,0,1,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0 }; gdFont gdFontLargeRep = { 96, 32, 8, 16, gdFontLargeData }; gdFontPtr gdFontLarge = &gdFontLargeRep; /* end of gdfontl.c */ /* begin of gdfonts.c */ char gdFontSmallData[] = { 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,0,0,0,0, 0,0,1,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,0,1,0,0, 0,1,0,1,0,0, 0,1,0,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,0,1,0,0, 1,1,1,1,1,0, 0,1,0,1,0,0, 0,1,0,1,0,0, 1,1,1,1,1,0, 0,1,0,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,1,0,0,0, 0,1,1,1,0,0, 1,0,1,0,1,0, 1,0,1,0,0,0, 0,1,1,1,0,0, 0,0,1,0,1,0, 1,0,1,0,1,0, 0,1,1,1,0,0, 0,0,1,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,1,1,1,1,0, 1,1,0,0,1,0, 0,0,0,1,0,0, 0,0,1,0,0,0, 0,1,0,0,0,0, 1,0,0,1,1,0, 1,0,0,1,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,0,0,0,0, 1,0,1,0,0,0, 1,0,1,0,0,0, 0,1,0,0,0,0, 1,0,1,0,1,0, 1,0,0,1,0,0, 0,1,1,0,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,0,0,0, 0,1,1,0,0,0, 1,1,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,1,0, 0,0,0,1,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,0,1,0,0, 0,0,0,0,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,0,0,0,0, 0,1,0,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,1,0,0,0,0, 1,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,1,0,0,0, 1,0,1,0,1,0, 0,1,1,1,0,0, 0,0,1,0,0,0, 0,1,1,1,0,0, 1,0,1,0,1,0, 0,0,1,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 1,1,1,1,1,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,0,0,0, 0,1,1,0,0,0, 1,1,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,1,1,1,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,0,0,0, 0,1,1,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,1,0, 0,0,0,1,0,0, 0,0,1,0,0,0, 0,1,0,0,0,0, 1,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,1,0,0, 1,0,0,0,1,0, 1,0,0,1,1,0, 1,0,1,0,1,0, 1,1,0,0,1,0, 1,0,0,0,1,0, 0,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,1,0,0,0, 0,1,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,1,0,0, 1,0,0,0,1,0, 0,0,0,0,1,0, 0,0,0,1,0,0, 0,0,1,0,0,0, 0,1,0,0,0,0, 1,1,1,1,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,1,0,0, 1,0,0,0,1,0, 0,0,0,0,1,0, 0,0,1,1,0,0, 0,0,0,0,1,0, 1,0,0,0,1,0, 0,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,1,0,0, 0,0,1,1,0,0, 0,1,0,1,0,0, 1,0,0,1,0,0, 1,1,1,1,1,0, 0,0,0,1,0,0, 0,0,0,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,1,1,1,1,0, 1,0,0,0,0,0, 1,1,1,1,0,0, 0,0,0,0,1,0, 0,0,0,0,1,0, 1,0,0,0,1,0, 0,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,1,1,0,0, 0,1,0,0,0,0, 1,0,0,0,0,0, 1,1,1,1,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 0,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,1,1,1,1,0, 0,0,0,0,1,0, 0,0,0,1,0,0, 0,0,0,1,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,1,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 0,1,1,1,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 0,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,1,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 0,1,1,1,1,0, 0,0,0,0,1,0, 0,0,0,1,0,0, 0,1,1,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,0,0,0, 0,1,1,0,0,0, 0,0,0,0,0,0, 0,1,1,0,0,0, 0,1,1,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,0,0,0, 0,1,1,0,0,0, 0,0,0,0,0,0, 0,1,1,0,0,0, 0,1,1,0,0,0, 1,1,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,1,0,0, 0,0,1,0,0,0, 0,1,0,0,0,0, 0,0,1,0,0,0, 0,0,0,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,1,1,1,1,0, 0,0,0,0,0,0, 1,1,1,1,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,0,0,0,0, 0,0,1,0,0,0, 0,0,0,1,0,0, 0,0,1,0,0,0, 0,1,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,1,0,0, 1,0,0,0,1,0, 0,0,0,1,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,0,0,0,0, 0,0,1,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,1,0,0, 1,0,0,0,1,0, 1,0,1,1,1,0, 1,0,1,0,1,0, 1,0,1,1,1,0, 1,0,0,0,0,0, 0,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,1,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,1,1,1,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,1,1,1,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,1,1,1,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,1,0,0, 1,0,0,0,1,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 1,0,0,0,1,0, 0,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,1,1,1,0,0, 0,1,0,0,1,0, 0,1,0,0,1,0, 0,1,0,0,1,0, 0,1,0,0,1,0, 0,1,0,0,1,0, 1,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,1,1,1,1,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 1,1,1,1,0,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 1,1,1,1,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,1,1,1,1,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 1,1,1,1,0,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,1,0,0, 1,0,0,0,1,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 1,0,0,1,1,0, 1,0,0,0,1,0, 0,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,1,1,1,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,1,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,1,0, 0,0,0,0,1,0, 0,0,0,0,1,0, 0,0,0,0,1,0, 0,0,0,0,1,0, 1,0,0,0,1,0, 0,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,0,0,1,0, 1,0,0,1,0,0, 1,0,1,0,0,0, 1,1,0,0,0,0, 1,0,1,0,0,0, 1,0,0,1,0,0, 1,0,0,0,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 1,1,1,1,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,0,0,1,0, 1,1,0,1,1,0, 1,0,1,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,1,0,0,1,0, 1,0,1,0,1,0, 1,0,0,1,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,1,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 0,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,1,1,1,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,1,1,1,0,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,1,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,1,0,1,0, 1,0,0,1,0,0, 0,1,1,0,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,1,1,1,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,1,1,1,0,0, 1,0,1,0,0,0, 1,0,0,1,0,0, 1,0,0,0,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,1,0,0, 1,0,0,0,1,0, 1,0,0,0,0,0, 0,1,1,1,0,0, 0,0,0,0,1,0, 1,0,0,0,1,0, 0,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,1,1,1,1,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 0,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 0,1,0,1,0,0, 0,1,0,1,0,0, 0,0,1,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,1,0,1,0, 1,1,0,1,1,0, 1,0,0,0,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 0,1,0,1,0,0, 0,0,1,0,0,0, 0,1,0,1,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 0,1,0,1,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,1,1,1,1,0, 0,0,0,0,1,0, 0,0,0,1,0,0, 1,1,1,1,1,0, 0,1,0,0,0,0, 1,0,0,0,0,0, 1,1,1,1,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,1,1,1,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,1,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,0,0,0,0, 0,1,0,0,0,0, 0,0,1,0,0,0, 0,0,0,1,0,0, 0,0,0,0,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,1,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 1,1,1,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,1,0,0,0, 0,1,0,1,0,0, 1,0,0,0,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,1,1,1,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,1,1,0,0, 0,0,1,1,0,0, 0,0,0,1,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,1,0,0, 0,0,0,0,1,0, 0,1,1,1,1,0, 1,0,0,0,1,0, 0,1,1,1,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 1,1,1,1,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,1,0,0, 1,0,0,0,1,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 0,1,1,1,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,1,0, 0,0,0,0,1,0, 0,1,1,1,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 0,1,1,1,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,1,0,0, 1,0,0,0,1,0, 1,1,1,1,0,0, 1,0,0,0,0,0, 0,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,1,1,0,0, 0,1,0,0,1,0, 0,1,0,0,0,0, 1,1,1,0,0,0, 0,1,0,0,0,0, 0,1,0,0,0,0, 0,1,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,1,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 0,1,1,1,1,0, 0,0,0,0,1,0, 0,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 1,1,1,1,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,1,0,0,0, 0,0,0,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,1,0, 0,0,0,0,0,0, 0,0,0,0,1,0, 0,0,0,0,1,0, 0,0,0,0,1,0, 0,0,0,0,1,0, 1,0,0,0,1,0, 0,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 1,0,0,0,1,0, 1,0,0,1,0,0, 1,1,1,0,0,0, 1,0,0,1,0,0, 1,0,0,0,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,1,0,1,0,0, 1,0,1,0,1,0, 1,0,1,0,1,0, 1,0,1,0,1,0, 1,0,1,0,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,1,1,0,0, 1,1,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,1,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 0,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,1,1,1,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,1,1,1,0,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,1,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 0,1,1,1,1,0, 0,0,0,0,1,0, 0,0,0,0,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,1,1,0,0, 1,1,0,0,1,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,1,1,0, 1,0,0,0,0,0, 0,1,1,1,0,0, 0,0,0,0,1,0, 1,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 1,1,1,1,1,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,0,1,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 0,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 0,1,0,1,0,0, 0,0,1,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,1,0,1,0, 1,0,1,0,1,0, 0,1,0,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,0,0,1,0, 0,1,0,1,0,0, 0,0,1,0,0,0, 0,1,0,1,0,0, 1,0,0,0,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 0,1,0,1,0,0, 0,0,1,0,0,0, 0,1,0,0,0,0, 1,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,1,1,1,1,0, 0,0,0,1,0,0, 0,1,1,1,0,0, 0,1,0,0,0,0, 1,1,1,1,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,1,0, 0,0,0,1,0,0, 0,0,0,1,0,0, 0,0,0,1,0,0, 0,0,1,0,0,0, 0,0,0,1,0,0, 0,0,0,1,0,0, 0,0,0,1,0,0, 0,0,0,0,1,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,1,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,0,0,0,0, 0,1,0,0,0,0, 0,1,0,0,0,0, 0,1,0,0,0,0, 0,0,1,0,0,0, 0,1,0,0,0,0, 0,1,0,0,0,0, 0,1,0,0,0,0, 1,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,1,1,0,1,0, 1,0,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 1,0,0,0,0,0, 1,0,0,0,0,0, 1,1,1,1,0,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,0,0,0,1,0, 1,1,1,1,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,0,0,0 }; gdFont gdFontSmallRep = { 96, 32, 6, 12, gdFontSmallData }; gdFontPtr gdFontSmall = &gdFontSmallRep; /* end of gdfonts.c */ /* begin of mtables.c */ #define costScale 1024 int cost[] = { 1024, 1023, 1023, 1022, 1021, 1020, 1018, 1016, 1014, 1011, 1008, 1005, 1001, 997, 993, 989, 984, 979, 973, 968, 962, 955, 949, 942, 935, 928, 920, 912, 904, 895, 886, 877, 868, 858, 848, 838, 828, 817, 806, 795, 784, 772, 760, 748, 736, 724, 711, 698, 685, 671, 658, 644, 630, 616, 601, 587, 572, 557, 542, 527, 512, 496, 480, 464, 448, 432, 416, 400, 383, 366, 350, 333, 316, 299, 282, 265, 247, 230, 212, 195, 177, 160, 142, 124, 107, 89, 71, 53, 35, 17, 0, -17, -35, -53, -71, -89, -107, -124, -142, -160, -177, -195, -212, -230, -247, -265, -282, -299, -316, -333, -350, -366, -383, -400, -416, -432, -448, -464, -480, -496, -512, -527, -542, -557, -572, -587, -601, -616, -630, -644, -658, -671, -685, -698, -711, -724, -736, -748, -760, -772, -784, -795, -806, -817, -828, -838, -848, -858, -868, -877, -886, -895, -904, -912, -920, -928, -935, -942, -949, -955, -962, -968, -973, -979, -984, -989, -993, -997, -1001, -1005, -1008, -1011, -1014, -1016, -1018, -1020, -1021, -1022, -1023, -1023, -1024, -1023, -1023, -1022, -1021, -1020, -1018, -1016, -1014, -1011, -1008, -1005, -1001, -997, -993, -989, -984, -979, -973, -968, -962, -955, -949, -942, -935, -928, -920, -912, -904, -895, -886, -877, -868, -858, -848, -838, -828, -817, -806, -795, -784, -772, -760, -748, -736, -724, -711, -698, -685, -671, -658, -644, -630, -616, -601, -587, -572, -557, -542, -527, -512, -496, -480, -464, -448, -432, -416, -400, -383, -366, -350, -333, -316, -299, -282, -265, -247, -230, -212, -195, -177, -160, -142, -124, -107, -89, -71, -53, -35, -17, 0, 17, 35, 53, 71, 89, 107, 124, 142, 160, 177, 195, 212, 230, 247, 265, 282, 299, 316, 333, 350, 366, 383, 400, 416, 432, 448, 464, 480, 496, 512, 527, 542, 557, 572, 587, 601, 616, 630, 644, 658, 671, 685, 698, 711, 724, 736, 748, 760, 772, 784, 795, 806, 817, 828, 838, 848, 858, 868, 877, 886, 895, 904, 912, 920, 928, 935, 942, 949, 955, 962, 968, 973, 979, 984, 989, 993, 997, 1001, 1005, 1008, 1011, 1014, 1016, 1018, 1020, 1021, 1022, 1023, 1023 }; #define sintScale 1024 int sint[] = { 0, 17, 35, 53, 71, 89, 107, 124, 142, 160, 177, 195, 212, 230, 247, 265, 282, 299, 316, 333, 350, 366, 383, 400, 416, 432, 448, 464, 480, 496, 512, 527, 542, 557, 572, 587, 601, 616, 630, 644, 658, 671, 685, 698, 711, 724, 736, 748, 760, 772, 784, 795, 806, 817, 828, 838, 848, 858, 868, 877, 886, 895, 904, 912, 920, 928, 935, 942, 949, 955, 962, 968, 973, 979, 984, 989, 993, 997, 1001, 1005, 1008, 1011, 1014, 1016, 1018, 1020, 1021, 1022, 1023, 1023, 1024, 1023, 1023, 1022, 1021, 1020, 1018, 1016, 1014, 1011, 1008, 1005, 1001, 997, 993, 989, 984, 979, 973, 968, 962, 955, 949, 942, 935, 928, 920, 912, 904, 895, 886, 877, 868, 858, 848, 838, 828, 817, 806, 795, 784, 772, 760, 748, 736, 724, 711, 698, 685, 671, 658, 644, 630, 616, 601, 587, 572, 557, 542, 527, 512, 496, 480, 464, 448, 432, 416, 400, 383, 366, 350, 333, 316, 299, 282, 265, 247, 230, 212, 195, 177, 160, 142, 124, 107, 89, 71, 53, 35, 17, 0, -17, -35, -53, -71, -89, -107, -124, -142, -160, -177, -195, -212, -230, -247, -265, -282, -299, -316, -333, -350, -366, -383, -400, -416, -432, -448, -464, -480, -496, -512, -527, -542, -557, -572, -587, -601, -616, -630, -644, -658, -671, -685, -698, -711, -724, -736, -748, -760, -772, -784, -795, -806, -817, -828, -838, -848, -858, -868, -877, -886, -895, -904, -912, -920, -928, -935, -942, -949, -955, -962, -968, -973, -979, -984, -989, -993, -997, -1001, -1005, -1008, -1011, -1014, -1016, -1018, -1020, -1021, -1022, -1023, -1023, -1024, -1023, -1023, -1022, -1021, -1020, -1018, -1016, -1014, -1011, -1008, -1005, -1001, -997, -993, -989, -984, -979, -973, -968, -962, -955, -949, -942, -935, -928, -920, -912, -904, -895, -886, -877, -868, -858, -848, -838, -828, -817, -806, -795, -784, -772, -760, -748, -736, -724, -711, -698, -685, -671, -658, -644, -630, -616, -601, -587, -572, -557, -542, -527, -512, -496, -480, -464, -448, -432, -416, -400, -383, -366, -350, -333, -316, -299, -282, -265, -247, -230, -212, -195, -177, -160, -142, -124, -107, -89, -71, -53, -35, -17 }; /* end of mtables.c */ static void gdImageBrushApply(/* gdImagePtr im, int x, int y */); static void gdImageTileApply(/* gdImagePtr im, int x, int y */); gdImagePtr gdImageCreate(sx, sy) int sx; int sy; { int i; gdImagePtr im; im = (gdImage *) malloc(sizeof(gdImage)); im->pixels = (unsigned char **) malloc(sizeof(unsigned char *) * sx); im->polyInts = 0; im->polyAllocated = 0; im->brush = 0; im->tile = 0; im->style = 0; for (i=0; (ipixels[i] = (unsigned char *) calloc( sy, sizeof(unsigned char)); } im->sx = sx; im->sy = sy; im->colorsTotal = 0; im->transparent = (-1); im->interlace = 0; return im; } void gdImageDestroy(im) gdImagePtr im; { int i; for (i=0; (isx); i++) { free(im->pixels[i]); } free(im->pixels); if (im->polyInts) { free(im->polyInts); } if (im->style) { free(im->style); } free(im); } int gdImageColorClosest(im, r, g, b) gdImagePtr im; int r; int g; int b; { int i; long rd, gd, bd; int ct = (-1); long mindist; for (i=0; (i<(im->colorsTotal)); i++) { long dist; if (im->open[i]) { continue; } rd = (im->red[i] - r); gd = (im->green[i] - g); bd = (im->blue[i] - b); dist = rd * rd + gd * gd + bd * bd; if ((i == 0) || (dist < mindist)) { mindist = dist; ct = i; } } return ct; } int gdImageColorExact(im, r, g, b) gdImagePtr im; int r; int g; int b; { int i; for (i=0; (i<(im->colorsTotal)); i++) { if (im->open[i]) { continue; } if ((im->red[i] == r) && (im->green[i] == g) && (im->blue[i] == b)) { return i; } } return -1; } int gdImageColorAllocate(im, r, g, b) gdImagePtr im; int r; int g; int b; { int i; int ct = (-1); for (i=0; (i<(im->colorsTotal)); i++) { if (im->open[i]) { ct = i; break; } } if (ct == (-1)) { ct = im->colorsTotal; if (ct == gdMaxColors) { return -1; } im->colorsTotal++; } im->red[ct] = r; im->green[ct] = g; im->blue[ct] = b; im->open[ct] = 0; return ct; } void gdImageColorDeallocate(im, color) gdImagePtr im; int color; { /* Mark it open. */ im->open[color] = 1; } void gdImageColorTransparent(im, color) gdImagePtr im; int color; { im->transparent = color; } void gdImageSetPixel(im, x, y, color) gdImagePtr im; int x; int y; int color; { int p; switch(color) { case gdStyled: if (!im->style) { /* Refuse to draw if no style is set. */ return; } else { p = im->style[im->stylePos++]; } if (p != (gdTransparent)) { gdImageSetPixel(im, x, y, p); } im->stylePos = im->stylePos % im->styleLength; break; case gdStyledBrushed: if (!im->style) { /* Refuse to draw if no style is set. */ return; } p = im->style[im->stylePos++]; if ((p != gdTransparent) && (p != 0)) { gdImageSetPixel(im, x, y, gdBrushed); } im->stylePos = im->stylePos % im->styleLength; break; case gdBrushed: gdImageBrushApply(im, x, y); break; case gdTiled: gdImageTileApply(im, x, y); break; default: if (gdImageBoundsSafe(im, x, y)) { im->pixels[x][y] = color; } break; } } static void gdImageBrushApply(im, x, y) gdImagePtr im; int x; int y; { int lx, ly; int hy; int hx; int x1, y1, x2, y2; int srcx, srcy; if (!im->brush) { return; } hy = gdImageSY(im->brush)/2; y1 = y - hy; y2 = y1 + gdImageSY(im->brush); hx = gdImageSX(im->brush)/2; x1 = x - hx; x2 = x1 + gdImageSX(im->brush); srcy = 0; for (ly = y1; (ly < y2); ly++) { srcx = 0; for (lx = x1; (lx < x2); lx++) { int p; p = gdImageGetPixel(im->brush, srcx, srcy); /* Allow for non-square brushes! */ if (p != gdImageGetTransparent(im->brush)) { gdImageSetPixel(im, lx, ly, im->brushColorMap[p]); } srcx++; } srcy++; } } static void gdImageTileApply(im, x, y) gdImagePtr im; int x; int y; { int srcx, srcy; int p; if (!im->tile) { return; } srcx = x % gdImageSX(im->tile); srcy = y % gdImageSY(im->tile); p = gdImageGetPixel(im->tile, srcx, srcy); /* Allow for transparency */ if (p != gdImageGetTransparent(im->tile)) { gdImageSetPixel(im, x, y, im->tileColorMap[p]); } } int gdImageGetPixel(im, x, y) gdImagePtr im; int x; int y; { if (gdImageBoundsSafe(im, x, y)) { return im->pixels[x][y]; } else { return 0; } } /* Bresenham as presented in Foley & Van Dam */ void gdImageLine(im, x1, y1, x2, y2, color) gdImagePtr im; int x1; int y1; int x2; int y2; int color; { int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag; dx = abs(x2-x1); dy = abs(y2-y1); if (dy <= dx) { d = 2*dy - dx; incr1 = 2*dy; incr2 = 2 * (dy - dx); if (x1 > x2) { x = x2; y = y2; ydirflag = (-1); xend = x1; } else { x = x1; y = y1; ydirflag = 1; xend = x2; } gdImageSetPixel(im, x, y, color); if (((y2 - y1) * ydirflag) > 0) { while (x < xend) { x++; if (d <0) { d+=incr1; } else { y++; d+=incr2; } gdImageSetPixel(im, x, y, color); } } else { while (x < xend) { x++; if (d <0) { d+=incr1; } else { y--; d+=incr2; } gdImageSetPixel(im, x, y, color); } } } else { d = 2*dx - dy; incr1 = 2*dx; incr2 = 2 * (dx - dy); if (y1 > y2) { y = y2; x = x2; yend = y1; xdirflag = (-1); } else { y = y1; x = x1; yend = y2; xdirflag = 1; } gdImageSetPixel(im, x, y, color); if (((x2 - x1) * xdirflag) > 0) { while (y < yend) { y++; if (d <0) { d+=incr1; } else { x++; d+=incr2; } gdImageSetPixel(im, x, y, color); } } else { while (y < yend) { y++; if (d <0) { d+=incr1; } else { x--; d+=incr2; } gdImageSetPixel(im, x, y, color); } } } } /* As above, plus dashing */ #define dashedSet \ { \ dashStep++; \ if (dashStep == gdDashSize) { \ dashStep = 0; \ on = !on; \ } \ if (on) { \ gdImageSetPixel(im, x, y, color); \ } \ } void gdImageDashedLine(im, x1, y1, x2, y2, color) gdImagePtr im; int x1; int y1; int x2; int y2; int color; { int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag; int dashStep = 0; int on = 1; dx = abs(x2-x1); dy = abs(y2-y1); if (dy <= dx) { d = 2*dy - dx; incr1 = 2*dy; incr2 = 2 * (dy - dx); if (x1 > x2) { x = x2; y = y2; ydirflag = (-1); xend = x1; } else { x = x1; y = y1; ydirflag = 1; xend = x2; } dashedSet; if (((y2 - y1) * ydirflag) > 0) { while (x < xend) { x++; if (d <0) { d+=incr1; } else { y++; d+=incr2; } dashedSet; } } else { while (x < xend) { x++; if (d <0) { d+=incr1; } else { y--; d+=incr2; } dashedSet; } } } else { d = 2*dx - dy; incr1 = 2*dx; incr2 = 2 * (dx - dy); if (y1 > y2) { y = y2; x = x2; yend = y1; xdirflag = (-1); } else { y = y1; x = x1; yend = y2; xdirflag = 1; } dashedSet; if (((x2 - x1) * xdirflag) > 0) { while (y < yend) { y++; if (d <0) { d+=incr1; } else { x++; d+=incr2; } dashedSet; } } else { while (y < yend) { y++; if (d <0) { d+=incr1; } else { x--; d+=incr2; } dashedSet; } } } } int gdImageBoundsSafe(im, x, y) gdImagePtr im; int x; int y; { return (!(((y < 0) || (y >= im->sy)) || ((x < 0) || (x >= im->sx)))); } void gdImageChar(im, f, x, y, c, color) gdImagePtr im; gdFontPtr f; int x; int y; int c; int color; { int cx, cy; int px, py; int fline; cx = 0; cy = 0; if ((c < f->offset) || (c >= (f->offset + f->nchars))) { return; } fline = (c - f->offset) * f->h * f->w; for (py = y; (py < (y + f->h)); py++) { for (px = x; (px < (x + f->w)); px++) { if (f->data[fline + cy * f->w + cx]) { gdImageSetPixel(im, px, py, color); } cx++; } cx = 0; cy++; } } void gdImageCharUp(im, f, x, y, c, color) gdImagePtr im; gdFontPtr f; int x; int y; char c; int color; { int cx, cy; int px, py; int fline; cx = 0; cy = 0; if ((c < f->offset) || (c >= (f->offset + f->nchars))) { return; } fline = (c - f->offset) * f->h * f->w; for (py = y; (py > (y - f->w)); py--) { for (px = x; (px < (x + f->h)); px++) { if (f->data[fline + cy * f->w + cx]) { gdImageSetPixel(im, px, py, color); } cy++; } cy = 0; cx++; } } void gdImageString(im, f, x, y, s, color) gdImagePtr im; gdFontPtr f; int x; int y; char *s; int color; { int i; int l; l = strlen(s); for (i=0; (iw; } } void gdImageStringUp(im, f, x, y, s, color) gdImagePtr im; gdFontPtr f; int x; int y; char *s; int color; { int i; int l; l = strlen(s); for (i=0; (iw; } } /* s and e are integers modulo 360 (degrees), with 0 degrees being the rightmost extreme and degrees changing clockwise. cx and cy are the center in pixels; w and h are the horizontal and vertical diameter in pixels. Nice interface, but slow, since I don't yet use Bresenham (I'm using an inefficient but simple solution with too much work going on in it; generalizing Bresenham to ellipses and partial arcs of ellipses is non-trivial, at least for me) and there are other inefficiencies (small circles do far too much work). */ void gdImageArc(im, cx, cy, w, h, s, e, color) gdImagePtr im; int cx; int cy; int w; int h; int s; int e; int color; { int i; int smod, emod; int lx, ly; int w2, h2; w2 = w/2; h2 = h/2; while (e < s) { e += 360; } for (i=s; (i <= e); i++) { int x, y; x = ((long)cost[i % 360] * (long)w2 / costScale) + cx; y = ((long)sint[i % 360] * (long)h2 / sintScale) + cy; if (i != s) { gdImageLine(im, lx, ly, x, y, color); } lx = x; ly = y; } } #if 0 /* Bresenham octant code, which I should use eventually */ int x, y, d; x = 0; y = w; d = 3-2*w; while (x < y) { gdImageSetPixel(im, cx+x, cy+y, color); if (d < 0) { d += 4 * x + 6; } else { d += 4 * (x - y) + 10; y--; } x++; } if (x == y) { gdImageSetPixel(im, cx+x, cy+y, color); } #endif void gdImageFillToBorder(im, x, y, border, color) gdImagePtr im; int x; int y; int border; int color; { int lastBorder; /* Seek left */ int leftLimit, rightLimit; int i; leftLimit = (-1); if (border < 0) { /* Refuse to fill to a non-solid border */ return; } for (i = x; (i >= 0); i--) { if (gdImageGetPixel(im, i, y) == border) { break; } gdImageSetPixel(im, i, y, color); leftLimit = i; } if (leftLimit == (-1)) { return; } /* Seek right */ rightLimit = x; for (i = (x+1); (i < im->sx); i++) { if (gdImageGetPixel(im, i, y) == border) { break; } gdImageSetPixel(im, i, y, color); rightLimit = i; } /* Look at lines above and below and start paints */ /* Above */ if (y > 0) { lastBorder = 1; for (i = leftLimit; (i <= rightLimit); i++) { int c; c = gdImageGetPixel(im, i, y-1); if (lastBorder) { if ((c != border) && (c != color)) { gdImageFillToBorder(im, i, y-1, border, color); lastBorder = 0; } } else if ((c == border) || (c == color)) { lastBorder = 1; } } } /* Below */ if (y < ((im->sy) - 1)) { lastBorder = 1; for (i = leftLimit; (i <= rightLimit); i++) { int c; c = gdImageGetPixel(im, i, y+1); if (lastBorder) { if ((c != border) && (c != color)) { gdImageFillToBorder(im, i, y+1, border, color); lastBorder = 0; } } else if ((c == border) || (c == color)) { lastBorder = 1; } } } } void gdImageFill(im, x, y, color) gdImagePtr im; int x; int y; int color; { int lastBorder; int old; int leftLimit, rightLimit; int i; old = gdImageGetPixel(im, x, y); if (color == gdTiled) { /* Tile fill -- got to watch out! */ int p, tileColor; int srcx, srcy; if (!im->tile) { return; } /* Refuse to flood-fill with a transparent pattern -- I can't do it without allocating another image */ if (gdImageGetTransparent(im->tile) != (-1)) { return; } srcx = x % gdImageSX(im->tile); srcy = y % gdImageSY(im->tile); p = gdImageGetPixel(im->tile, srcx, srcy); tileColor = im->tileColorMap[p]; if (old == tileColor) { /* Nothing to be done */ return; } } else { if (old == color) { /* Nothing to be done */ return; } } /* Seek left */ leftLimit = (-1); for (i = x; (i >= 0); i--) { if (gdImageGetPixel(im, i, y) != old) { break; } gdImageSetPixel(im, i, y, color); leftLimit = i; } if (leftLimit == (-1)) { return; } /* Seek right */ rightLimit = x; for (i = (x+1); (i < im->sx); i++) { if (gdImageGetPixel(im, i, y) != old) { break; } gdImageSetPixel(im, i, y, color); rightLimit = i; } /* Look at lines above and below and start paints */ /* Above */ if (y > 0) { lastBorder = 1; for (i = leftLimit; (i <= rightLimit); i++) { int c; c = gdImageGetPixel(im, i, y-1); if (lastBorder) { if (c == old) { gdImageFill(im, i, y-1, color); lastBorder = 0; } } else if (c != old) { lastBorder = 1; } } } /* Below */ if (y < ((im->sy) - 1)) { lastBorder = 1; for (i = leftLimit; (i <= rightLimit); i++) { int c; c = gdImageGetPixel(im, i, y+1); if (lastBorder) { if (c == old) { gdImageFill(im, i, y+1, color); lastBorder = 0; } } else if (c != old) { lastBorder = 1; } } } } #ifdef TEST_CODE void gdImageDump(im) gdImagePtr im; { int i, j; for (i=0; (i < im->sy); i++) { for (j=0; (j < im->sx); j++) { printf("%d", im->pixels[j][i]); } printf("\n"); } } #endif /* Code drawn from ppmtogif.c, from the pbmplus package ** ** Based on GIFENCOD by David Rowley . A ** Lempel-Zim compression based on "compress". ** ** Modified by Marcel Wijkstra ** ** Copyright (C) 1989 by Jef Poskanzer. ** ** Permission to use, copy, modify, and distribute this software and its ** documentation for any purpose and without fee is hereby granted, provided ** that the above copyright notice appear in all copies and that both that ** copyright notice and this permission notice appear in supporting ** documentation. This software is provided "as is" without express or ** implied warranty. ** ** The Graphics Interchange Format(c) is the Copyright property of ** CompuServe Incorporated. GIF(sm) is a Service Mark property of ** CompuServe Incorporated. */ /* * a code_int must be able to hold 2**GIFBITS values of type int, and also -1 */ typedef int code_int; #ifdef SIGNED_COMPARE_SLOW typedef unsigned long int count_int; typedef unsigned short int count_short; #else /*SIGNED_COMPARE_SLOW*/ typedef long int count_int; #endif /*SIGNED_COMPARE_SLOW*/ static int colorstobpp(/* int colors */); static void BumpPixel (/* void */); static int GIFNextPixel (/* gdImagePtr im */); static void GIFEncode (/* FILE* fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int* Red, int* Green, int* Blue, gdImagePtr im */); static void Putword (/* int w, FILE* fp */); static void compress (/* int init_bits, FILE* outfile, gdImagePtr im */); static void output (/* code_int code */); static void cl_block (/* void */); static void cl_hash (/* count_int hsize */); static void char_init (/* void */); static void char_out (/* int c */); static void flush_char (/* void */); /* Allows for reuse */ static void init_statics(/* void */); void gdImageGif(im, out) gdImagePtr im; FILE *out; { int interlace, transparent, BitsPerPixel; interlace = im->interlace; transparent = im->transparent; BitsPerPixel = colorstobpp(im->colorsTotal); /* Clear any old values in statics strewn through the GIF code */ init_statics(); /* All set, let's do it. */ GIFEncode( out, im->sx, im->sy, interlace, 0, transparent, BitsPerPixel, im->red, im->green, im->blue, im); } static int colorstobpp( colors ) int colors; { int bpp; if ( colors <= 2 ) bpp = 1; else if ( colors <= 4 ) bpp = 2; else if ( colors <= 8 ) bpp = 3; else if ( colors <= 16 ) bpp = 4; else if ( colors <= 32 ) bpp = 5; else if ( colors <= 64 ) bpp = 6; else if ( colors <= 128 ) bpp = 7; else if ( colors <= 256 ) bpp = 8; return bpp; } /***************************************************************************** * * GIFENCODE.C - GIF Image compression interface * * GIFEncode( FName, GHeight, GWidth, GInterlace, Background, Transparent, * BitsPerPixel, Red, Green, Blue, gdImagePtr ) * *****************************************************************************/ #define TRUE 1 #define FALSE 0 static int Width, Height; static int curx, cury; static long CountDown; static int Pass = 0; static int Interlace; /* * Bump the 'curx' and 'cury' to point to the next pixel */ static void BumpPixel() { /* * Bump the current X position */ ++curx; /* * If we are at the end of a scan line, set curx back to the beginning * If we are interlaced, bump the cury to the appropriate spot, * otherwise, just increment it. */ if( curx == Width ) { curx = 0; if( !Interlace ) ++cury; else { switch( Pass ) { case 0: cury += 8; if( cury >= Height ) { ++Pass; cury = 4; } break; case 1: cury += 8; if( cury >= Height ) { ++Pass; cury = 2; } break; case 2: cury += 4; if( cury >= Height ) { ++Pass; cury = 1; } break; case 3: cury += 2; break; } } } } /* * Return the next pixel from the image */ static int GIFNextPixel( im ) gdImagePtr im; { int r; if( CountDown == 0 ) return EOF; --CountDown; r = gdImageGetPixel(im, curx, cury); BumpPixel(); return r; } /* public */ static void GIFEncode( fp, GWidth, GHeight, GInterlace, Background, Transparent, BitsPerPixel, Red, Green, Blue, im ) FILE* fp; int GWidth, GHeight; int GInterlace; int Background; int Transparent; int BitsPerPixel; int Red[], Green[], Blue[]; gdImagePtr im; { int B; int RWidth, RHeight; int LeftOfs, TopOfs; int Resolution; int ColorMapSize; int InitCodeSize; int i; Interlace = GInterlace; ColorMapSize = 1 << BitsPerPixel; RWidth = Width = GWidth; RHeight = Height = GHeight; LeftOfs = TopOfs = 0; Resolution = BitsPerPixel; /* * Calculate number of bits we are expecting */ CountDown = (long)Width * (long)Height; /* * Indicate which pass we are on (if interlace) */ Pass = 0; /* * The initial code size */ if( BitsPerPixel <= 1 ) InitCodeSize = 2; else InitCodeSize = BitsPerPixel; /* * Set up the current x and y position */ curx = cury = 0; /* * Write the Magic header */ fwrite( Transparent < 0 ? "GIF87a" : "GIF89a", 1, 6, fp ); /* * Write out the screen width and height */ Putword( RWidth, fp ); Putword( RHeight, fp ); /* * Indicate that there is a global colour map */ B = 0x80; /* Yes, there is a color map */ /* * OR in the resolution */ B |= (Resolution - 1) << 5; /* * OR in the Bits per Pixel */ B |= (BitsPerPixel - 1); /* * Write it out */ fputc( B, fp ); /* * Write out the Background colour */ fputc( Background, fp ); /* * Byte of 0's (future expansion) */ fputc( 0, fp ); /* * Write out the Global Colour Map */ for( i=0; i= 0 ) { fputc( '!', fp ); fputc( 0xf9, fp ); fputc( 4, fp ); fputc( 1, fp ); fputc( 0, fp ); fputc( 0, fp ); fputc( Transparent, fp ); fputc( 0, fp ); } /* * Write an Image separator */ fputc( ',', fp ); /* * Write the Image header */ Putword( LeftOfs, fp ); Putword( TopOfs, fp ); Putword( Width, fp ); Putword( Height, fp ); /* * Write out whether or not the image is interlaced */ if( Interlace ) fputc( 0x40, fp ); else fputc( 0x00, fp ); /* * Write out the initial code size */ fputc( InitCodeSize, fp ); /* * Go and actually compress the data */ compress( InitCodeSize+1, fp, im ); /* * Write out a Zero-length packet (to end the series) */ fputc( 0, fp ); /* * Write the GIF file terminator */ fputc( ';', fp ); } /* * Write out a word to the GIF file */ static void Putword( w, fp ) int w; FILE* fp; { fputc( w & 0xff, fp ); fputc( (w / 256) & 0xff, fp ); } /*************************************************************************** * * GIFCOMPR.C - GIF Image compression routines * * Lempel-Ziv compression based on 'compress'. GIF modifications by * David Rowley (mgardi@watdcsu.waterloo.edu) * ***************************************************************************/ /* * General DEFINEs */ #define GIFBITS 12 #define HSIZE 5003 /* 80% occupancy */ #ifdef NO_UCHAR typedef char char_type; #else /*NO_UCHAR*/ typedef unsigned char char_type; #endif /*NO_UCHAR*/ /* * * GIF Image compression - modified 'compress' * * Based on: compress.c - File compression ala IEEE Computer, June 1984. * * By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas) * Jim McKie (decvax!mcvax!jim) * Steve Davies (decvax!vax135!petsd!peora!srd) * Ken Turkowski (decvax!decwrl!turtlevax!ken) * James A. Woods (decvax!ihnp4!ames!jaw) * Joe Orost (decvax!vax135!petsd!joe) * */ #include #define ARGVAL() (*++(*argv) || (--argc && *++argv)) static int n_bits; /* number of bits/code */ static int maxbits = GIFBITS; /* user settable max # bits/code */ static code_int maxcode; /* maximum code, given n_bits */ static code_int maxmaxcode = (code_int)1 << GIFBITS; /* should NEVER generate this code */ #ifdef COMPATIBLE /* But wrong! */ # define MAXCODE(n_bits) ((code_int) 1 << (n_bits) - 1) #else /*COMPATIBLE*/ # define MAXCODE(n_bits) (((code_int) 1 << (n_bits)) - 1) #endif /*COMPATIBLE*/ static count_int htab [HSIZE]; static unsigned short codetab [HSIZE]; #define HashTabOf(i) htab[i] #define CodeTabOf(i) codetab[i] static code_int hsize = HSIZE; /* for dynamic table sizing */ /* * To save much memory, we overlay the table used by compress() with those * used by decompress(). The tab_prefix table is the same size and type * as the codetab. The tab_suffix table needs 2**GIFBITS characters. We * get this from the beginning of htab. The output stack uses the rest * of htab, and contains characters. There is plenty of room for any * possible stack (stack used to be 8000 characters). */ #define tab_prefixof(i) CodeTabOf(i) #define tab_suffixof(i) ((char_type*)(htab))[i] #define de_stack ((char_type*)&tab_suffixof((code_int)1< 0 ) goto probe; nomatch: output ( (code_int) ent ); ++out_count; ent = c; #ifdef SIGNED_COMPARE_SLOW if ( (unsigned) free_ent < (unsigned) maxmaxcode) { #else /*SIGNED_COMPARE_SLOW*/ if ( free_ent < maxmaxcode ) { /* } */ #endif /*SIGNED_COMPARE_SLOW*/ CodeTabOf (i) = free_ent++; /* code -> hashtable */ HashTabOf (i) = fcode; } else cl_block(); } /* * Put out the final code. */ output( (code_int)ent ); ++out_count; output( (code_int) EOFCode ); } /***************************************************************** * TAG( output ) * * Output the given code. * Inputs: * code: A n_bits-bit integer. If == -1, then EOF. This assumes * that n_bits =< (long)wordsize - 1. * Outputs: * Outputs code to the file. * Assumptions: * Chars are 8 bits long. * Algorithm: * Maintain a GIFBITS character long buffer (so that 8 codes will * fit in it exactly). Use the VAX insv instruction to insert each * code in turn. When the buffer fills up empty it and start over. */ static unsigned long cur_accum = 0; static int cur_bits = 0; static unsigned long masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF }; static void output( code ) code_int code; { cur_accum &= masks[ cur_bits ]; if( cur_bits > 0 ) cur_accum |= ((long)code << cur_bits); else cur_accum = code; cur_bits += n_bits; while( cur_bits >= 8 ) { char_out( (unsigned int)(cur_accum & 0xff) ); cur_accum >>= 8; cur_bits -= 8; } /* * If the next entry is going to be too big for the code size, * then increase it, if possible. */ if ( free_ent > maxcode || clear_flg ) { if( clear_flg ) { maxcode = MAXCODE (n_bits = g_init_bits); clear_flg = 0; } else { ++n_bits; if ( n_bits == maxbits ) maxcode = maxmaxcode; else maxcode = MAXCODE(n_bits); } } if( code == EOFCode ) { /* * At EOF, write the rest of the buffer. */ while( cur_bits > 0 ) { char_out( (unsigned int)(cur_accum & 0xff) ); cur_accum >>= 8; cur_bits -= 8; } flush_char(); fflush( g_outfile ); if( ferror( g_outfile ) ) exit(1); } } /* * Clear out the hash table */ static void cl_block () /* table clear for block compress */ { cl_hash ( (count_int) hsize ); free_ent = ClearCode + 2; clear_flg = 1; output( (code_int)ClearCode ); } static void cl_hash(hsize) /* reset code table */ register count_int hsize; { register count_int *htab_p = htab+hsize; register long i; register long m1 = -1; i = hsize - 16; do { /* might use Sys V memset(3) here */ *(htab_p-16) = m1; *(htab_p-15) = m1; *(htab_p-14) = m1; *(htab_p-13) = m1; *(htab_p-12) = m1; *(htab_p-11) = m1; *(htab_p-10) = m1; *(htab_p-9) = m1; *(htab_p-8) = m1; *(htab_p-7) = m1; *(htab_p-6) = m1; *(htab_p-5) = m1; *(htab_p-4) = m1; *(htab_p-3) = m1; *(htab_p-2) = m1; *(htab_p-1) = m1; htab_p -= 16; } while ((i -= 16) >= 0); for ( i += 16; i > 0; --i ) *--htab_p = m1; } /****************************************************************************** * * GIF Specific routines * ******************************************************************************/ /* * Number of characters so far in this 'packet' */ static int a_count; /* * Set up the 'byte output' routine */ static void char_init() { a_count = 0; } /* * Define the storage for the packet accumulator */ static char accum[ 256 ]; /* * Add a character to the end of the current packet, and if it is 254 * characters, flush the packet to disk. */ static void char_out( c ) int c; { accum[ a_count++ ] = c; if( a_count >= 254 ) flush_char(); } /* * Flush the packet to disk, and reset the accumulator */ static void flush_char() { if( a_count > 0 ) { fputc( a_count, g_outfile ); fwrite( accum, 1, a_count, g_outfile ); a_count = 0; } } static void init_statics() { /* Some of these are properly initialized later. What I'm doing here is making sure code that depends on C's initialization of statics doesn't break when the code gets called more than once. */ Width = 0; Height = 0; curx = 0; cury = 0; CountDown = 0; Pass = 0; Interlace = 0; a_count = 0; cur_accum = 0; cur_bits = 0; g_init_bits = 0; g_outfile = 0; ClearCode = 0; EOFCode = 0; free_ent = 0; clear_flg = 0; offset = 0; in_count = 1; out_count = 0; hsize = HSIZE; n_bits = 0; maxbits = GIFBITS; maxcode = 0; maxmaxcode = (code_int)1 << GIFBITS; } /* +-------------------------------------------------------------------+ */ /* | Copyright 1990, 1991, 1993, David Koblas. (koblas@netcom.com) | */ /* | Permission to use, copy, modify, and distribute this software | */ /* | and its documentation for any purpose and without fee is hereby | */ /* | granted, provided that the above copyright notice appear in all | */ /* | copies and that both that copyright notice and this permission | */ /* | notice appear in supporting documentation. This software is | */ /* | provided "as is" without express or implied warranty. | */ /* +-------------------------------------------------------------------+ */ #define MAXCOLORMAPSIZE 256 #define TRUE 1 #define FALSE 0 #define CM_RED 0 #define CM_GREEN 1 #define CM_BLUE 2 #define MAX_LWZ_BITS 12 #define INTERLACE 0x40 #define LOCALCOLORMAP 0x80 #define BitSet(byte, bit) (((byte) & (bit)) == (bit)) #define ReadOK(file,buffer,len) (fread(buffer, len, 1, file) != 0) #define LM_to_uint(a,b) (((b)<<8)|(a)) static struct { unsigned int Width; unsigned int Height; unsigned char ColorMap[3][MAXCOLORMAPSIZE]; unsigned int BitPixel; unsigned int ColorResolution; unsigned int Background; unsigned int AspectRatio; } GifScreen; static struct { int transparent; int delayTime; int inputFlag; int disposal; } Gif89 = { -1, -1, -1, 0 }; static int ReadColorMap ( /* FILE *fd, int number, gdImagePtr im, int *flag */); static int DoExtension (/* FILE *fd, int label */); static int GetDataBlock (/* FILE *fd, unsigned char *buf */); static int GetCode (/* FILE *fd, int code_size, int flag */); static int LWZReadByte (/* FILE *fd, int flag, int input_code_size */); static void ReadImage (/* gdImagePtr im, FILE *fd, int len, int height, int interlace, int ignore */); int ZeroDataBlock; gdImagePtr gdImageCreateFromGif(fd) FILE *fd; { int imageNumber; int BitPixel; int ColorResolution; int Background; int AspectRatio; int Transparent = (-1); unsigned char buf[16]; unsigned char c; unsigned char ColorMap[3][MAXCOLORMAPSIZE]; unsigned char localColorMap[3][MAXCOLORMAPSIZE]; int imw, imh; int useGlobalColormap; int bitPixel; int imageCount = 0; char version[4]; gdImagePtr im; ZeroDataBlock = FALSE; imageNumber = 1; if (! ReadOK(fd,buf,6)) { return 0; } if (strncmp((char *)buf,"GIF",3) != 0) { return 0; } strncpy(version, (char *)buf + 3, 3); version[3] = '\0'; if ((strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0)) { return 0; } if (! ReadOK(fd,buf,7)) { return 0; } BitPixel = 2<<(buf[4]&0x07); ColorResolution = (((buf[4]&0x70)>>3)+1); Background = buf[5]; AspectRatio = buf[6]; if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */ if (ReadColorMap(fd, BitPixel, ColorMap)) { return 0; } } for (;;) { if (! ReadOK(fd,&c,1)) { return 0; } if (c == ';') { /* GIF terminator */ int i; if (imageCount < imageNumber) { return 0; } /* Check for open colors at the end, so we can reduce colorsTotal and ultimately BitsPerPixel */ for (i=((im->colorsTotal-1)); (i>=0); i--) { if (im->open[i]) { im->colorsTotal--; } else { break; } } return im; } if (c == '!') { /* Extension */ if (! ReadOK(fd,&c,1)) { return 0; } DoExtension(fd, c, &Transparent); continue; } if (c != ',') { /* Not a valid start character */ continue; } ++imageCount; if (! ReadOK(fd,buf,9)) { return 0; } useGlobalColormap = ! BitSet(buf[8], LOCALCOLORMAP); bitPixel = 1<<((buf[8]&0x07)+1); imw = LM_to_uint(buf[4],buf[5]); imh = LM_to_uint(buf[6],buf[7]); if (!(im = gdImageCreate(imw, imh))) { return 0; } im->interlace = BitSet(buf[8], INTERLACE); if (! useGlobalColormap) { if (ReadColorMap(fd, bitPixel, localColorMap)) { return 0; } ReadImage(im, fd, imw, imh, localColorMap, BitSet(buf[8], INTERLACE), imageCount != imageNumber); } else { ReadImage(im, fd, imw, imh, ColorMap, BitSet(buf[8], INTERLACE), imageCount != imageNumber); } if (Transparent != (-1)) { gdImageColorTransparent(im, Transparent); } } } static int ReadColorMap(fd,number,buffer) FILE *fd; int number; unsigned char buffer[3][MAXCOLORMAPSIZE]; { int i; unsigned char rgb[3]; for (i = 0; i < number; ++i) { if (! ReadOK(fd, rgb, sizeof(rgb))) { return TRUE; } buffer[CM_RED][i] = rgb[0] ; buffer[CM_GREEN][i] = rgb[1] ; buffer[CM_BLUE][i] = rgb[2] ; } return FALSE; } static int DoExtension(fd, label, Transparent) FILE *fd; int label; int *Transparent; { static char buf[256]; switch (label) { case 0xf9: /* Graphic Control Extension */ (void) GetDataBlock(fd, (unsigned char*) buf); Gif89.disposal = (buf[0] >> 2) & 0x7; Gif89.inputFlag = (buf[0] >> 1) & 0x1; Gif89.delayTime = LM_to_uint(buf[1],buf[2]); if ((buf[0] & 0x1) != 0) *Transparent = buf[3]; while (GetDataBlock(fd, (unsigned char*) buf) != 0) ; return FALSE; default: break; } while (GetDataBlock(fd, (unsigned char*) buf) != 0) ; return FALSE; } static int GetDataBlock(fd, buf) FILE *fd; unsigned char *buf; { unsigned char count; if (! ReadOK(fd,&count,1)) { return -1; } ZeroDataBlock = count == 0; if ((count != 0) && (! ReadOK(fd, buf, count))) { return -1; } return count; } static int GetCode(fd, code_size, flag) FILE *fd; int code_size; int flag; { static unsigned char buf[280]; static int curbit, lastbit, done, last_byte; int i, j, ret; unsigned char count; if (flag) { curbit = 0; lastbit = 0; done = FALSE; return 0; } if ( (curbit+code_size) >= lastbit) { if (done) { if (curbit >= lastbit) { /* Oh well */ } return -1; } buf[0] = buf[last_byte-2]; buf[1] = buf[last_byte-1]; if ((count = GetDataBlock(fd, &buf[2])) == 0) done = TRUE; last_byte = 2 + count; curbit = (curbit - lastbit) + 16; lastbit = (2+count)*8 ; } ret = 0; for (i = curbit, j = 0; j < code_size; ++i, ++j) ret |= ((buf[ i / 8 ] & (1 << (i % 8))) != 0) << j; curbit += code_size; return ret; } static int LWZReadByte(fd, flag, input_code_size) FILE *fd; int flag; int input_code_size; { static int fresh = FALSE; int code, incode; static int code_size, set_code_size; static int max_code, max_code_size; static int firstcode, oldcode; static int clear_code, end_code; static int table[2][(1<< MAX_LWZ_BITS)]; static int stack[(1<<(MAX_LWZ_BITS))*2], *sp; register int i; if (flag) { set_code_size = input_code_size; code_size = set_code_size+1; clear_code = 1 << set_code_size ; end_code = clear_code + 1; max_code_size = 2*clear_code; max_code = clear_code+2; GetCode(fd, 0, TRUE); fresh = TRUE; for (i = 0; i < clear_code; ++i) { table[0][i] = 0; table[1][i] = i; } for (; i < (1< stack) return *--sp; while ((code = GetCode(fd, code_size, FALSE)) >= 0) { if (code == clear_code) { for (i = 0; i < clear_code; ++i) { table[0][i] = 0; table[1][i] = i; } for (; i < (1< 0) ; if (count != 0) return -2; } incode = code; if (code >= max_code) { *sp++ = firstcode; code = oldcode; } while (code >= clear_code) { *sp++ = table[1][code]; if (code == table[0][code]) { /* Oh well */ } code = table[0][code]; } *sp++ = firstcode = table[1][code]; if ((code = max_code) <(1<= max_code_size) && (max_code_size < (1< stack) return *--sp; } return code; } static void ReadImage(im, fd, len, height, cmap, interlace, ignore) gdImagePtr im; FILE *fd; int len, height; unsigned char cmap[3][MAXCOLORMAPSIZE]; int interlace, ignore; { unsigned char c; int v; int xpos = 0, ypos = 0, pass = 0; int i; /* Stash the color map into the image */ for (i=0; (ired[i] = cmap[CM_RED][i]; im->green[i] = cmap[CM_GREEN][i]; im->blue[i] = cmap[CM_BLUE][i]; im->open[i] = 1; } /* Many (perhaps most) of these colors will remain marked open. */ im->colorsTotal = gdMaxColors; /* ** Initialize the Compression routines */ if (! ReadOK(fd,&c,1)) { return; } if (LWZReadByte(fd, TRUE, c) < 0) { return; } /* ** If this is an "uninteresting picture" ignore it. */ if (ignore) { while (LWZReadByte(fd, FALSE, c) >= 0) ; return; } while ((v = LWZReadByte(fd,FALSE,c)) >= 0 ) { /* This how we recognize which colors are actually used. */ if (im->open[v]) { im->open[v] = 0; } gdImageSetPixel(im, xpos, ypos, v); ++xpos; if (xpos == len) { xpos = 0; if (interlace) { switch (pass) { case 0: case 1: ypos += 8; break; case 2: ypos += 4; break; case 3: ypos += 2; break; } if (ypos >= height) { ++pass; switch (pass) { case 1: ypos = 4; break; case 2: ypos = 2; break; case 3: ypos = 1; break; default: goto fini; } } } else { ++ypos; } } if (ypos >= height) break; } fini: if (LWZReadByte(fd,FALSE,c)>=0) { /* Ignore extra */ } } void gdImageRectangle(im, x1, y1, x2, y2, color) gdImagePtr im; int x1; int y1; int x2; int y2; { gdImageLine(im, x1, y1, x2, y1, color); gdImageLine(im, x1, y2, x2, y2, color); gdImageLine(im, x1, y1, x1, y2, color); gdImageLine(im, x2, y1, x2, y2, color); } void gdImageFilledRectangle(im, x1, y1, x2, y2, color) gdImagePtr im; int x1; int y1; int x2; int y2; int color; { int x, y; for (y=y1; (y<=y2); y++) { for (x=x1; (x<=x2); x++) { gdImageSetPixel(im, x, y, color); } } } void gdImageCopy(dst, src, dstX, dstY, srcX, srcY, w, h) gdImagePtr dst; gdImagePtr src; int dstX; int dstY; int srcX; int srcY; int w; int h; { int c; int x, y; int tox, toy; int i; int colorMap[gdMaxColors]; for (i=0; (ired[c], src->green[c], src->blue[c]); } if (nc == (-1)) { /* No, so try to allocate it */ nc = gdImageColorAllocate(dst, src->red[c], src->green[c], src->blue[c]); /* If we're out of colors, go for the closest color */ if (nc == (-1)) { nc = gdImageColorClosest(dst, src->red[c], src->green[c], src->blue[c]); } } colorMap[c] = nc; } gdImageSetPixel(dst, tox, toy, colorMap[c]); tox++; } toy++; } } #ifdef xxx /* missing function 'floor' */ void gdImageCopyResized(dst, src, dstX, dstY, srcX, srcY, dstW, dstH, srcW, srcH) gdImagePtr dst; gdImagePtr src; int dstX; int dstY; int srcX; int srcY; int dstW; int dstH; int srcW; int srcH; { int c; int x, y; int tox, toy; int ydest; int i; int colorMap[gdMaxColors]; /* Stretch vectors */ int *stx; int *sty; /* We only need to use floating point to determine the correct stretch vector for one line's worth. */ double accum; stx = (int *) malloc(sizeof(int) * srcW); sty = (int *) malloc(sizeof(int) * srcH); accum = 0; for (i=0; (i < srcW); i++) { int got; accum += (double)dstW/(double)srcW; got = floor(accum); stx[i] = got; accum -= got; } accum = 0; for (i=0; (i < srcH); i++) { int got; accum += (double)dstH/(double)srcH; got = floor(accum); sty[i] = got; accum -= got; } for (i=0; (ired[c], src->green[c], src->blue[c]); } if (nc == (-1)) { /* No, so try to allocate it */ nc = gdImageColorAllocate(dst, src->red[c], src->green[c], src->blue[c]); /* If we're out of colors, go for the closest color */ if (nc == (-1)) { nc = gdImageColorClosest(dst, src->red[c], src->green[c], src->blue[c]); } } colorMap[c] = nc; } for (i=0; (i < stx[x - srcX]); i++) { gdImageSetPixel(dst, tox, toy, colorMap[c]); tox++; } } toy++; } } free(stx); free(sty); } #endif int gdGetWord(result, in) int *result; FILE *in; { int r; r = getc(in); if (r == EOF) { return 0; } *result = r << 8; r = getc(in); if (r == EOF) { return 0; } *result += r; return 1; } void gdPutWord(w, out) int w; FILE *out; { putc((unsigned char)(w >> 8), out); putc((unsigned char)(w & 0xFF), out); } int gdGetByte(result, in) int *result; FILE *in; { int r; r = getc(in); if (r == EOF) { return 0; } *result = r; return 1; } gdImagePtr gdImageCreateFromGd(in) FILE *in; { int sx, sy; int x, y; int i; gdImagePtr im; if (!gdGetWord(&sx, in)) { goto fail1; } if (!gdGetWord(&sy, in)) { goto fail1; } im = gdImageCreate(sx, sy); if (!gdGetByte(&im->colorsTotal, in)) { goto fail2; } if (!gdGetWord(&im->transparent, in)) { goto fail2; } if (im->transparent == 257) { im->transparent = (-1); } for (i=0; (ired[i], in)) { goto fail2; } if (!gdGetByte(&im->green[i], in)) { goto fail2; } if (!gdGetByte(&im->blue[i], in)) { goto fail2; } } for (y=0; (ypixels[x][y] = ch; } } return im; fail2: gdImageDestroy(im); fail1: return 0; } void gdImageGd(im, out) gdImagePtr im; FILE *out; { int x, y; int i; int trans; gdPutWord(im->sx, out); gdPutWord(im->sy, out); putc((unsigned char)im->colorsTotal, out); trans = im->transparent; if (trans == (-1)) { trans = 257; } gdPutWord(trans, out); for (i=0; (ired[i], out); putc((unsigned char)im->green[i], out); putc((unsigned char)im->blue[i], out); } for (y=0; (y < im->sy); y++) { for (x=0; (x < im->sx); x++) { putc((unsigned char)im->pixels[x][y], out); } } } gdImagePtr gdImageCreateFromXbm(fd) FILE *fd; { gdImagePtr im; int bit; int w, h; int bytes; int ch; int spaceat; int i, x, y; int bits; char *sp; char s[161]; if (!fgets(s, 160, fd)) { return 0; } sp = &s[0]; /* Skip #define */ sp = strchr(sp, ' '); if (!sp) { return 0; } /* Skip width label */ sp++; sp = strchr(sp, ' '); if (!sp) { return 0; } /* Get width */ w = atoi(sp + 1); if (!w) { return 0; } if (!fgets(s, 160, fd)) { return 0; } sp = s; /* Skip #define */ sp = strchr(sp, ' '); if (!sp) { return 0; } /* Skip height label */ sp++; sp = strchr(sp, ' '); if (!sp) { return 0; } /* Get height */ h = atoi(sp + 1); if (!h) { return 0; } /* Skip declaration line */ if (!fgets(s, 160, fd)) { return 0; } bytes = (w * h / 8) + 1; im = gdImageCreate(w, h); gdImageColorAllocate(im, 255, 255, 255); gdImageColorAllocate(im, 0, 0, 0); x = 0; y = 0; for (i=0; (i < bytes); i++) { char h[3]; int b; /* Skip spaces, commas, CRs, 0x */ while(1) { ch = getc(fd); if (ch == EOF) { goto fail; } if (ch == 'x') { break; } } /* Get hex value */ ch = getc(fd); if (ch == EOF) { goto fail; } h[0] = ch; ch = getc(fd); if (ch == EOF) { goto fail; } h[1] = ch; h[2] = '\0'; sscanf(h, "%x", &b); for (bit = 1; (bit <= 128); (bit = bit << 1)) { gdImageSetPixel(im, x++, y, b & bit); if (x == im->sx) { x = 0; y++; if (y == im->sy) { return im; } } } } /* Shouldn't happen */ fprintf(stderr, "Error: bug in gdImageCreateFromXbm!\n"); return 0; fail: gdImageDestroy(im); return 0; } void gdImagePolygon(im, p, n, c) gdImagePtr im; gdPointPtr p; int n; int c; { int i; int lx, ly; if (!n) { return; } lx = p->x; ly = p->y; gdImageLine(im, lx, ly, p[n-1].x, p[n-1].y, c); for (i=1; (i < n); i++) { p++; gdImageLine(im, lx, ly, p->x, p->y, c); lx = p->x; ly = p->y; } } int gdCompareInt(/* int *a, int *b */); void gdImageFilledPolygon(im, p, n, c) gdImagePtr im; gdPointPtr p; int n; int c; { int i; int y; int y1, y2; int ints; if (!n) { return; } if (!im->polyAllocated) { im->polyInts = (int *) malloc(sizeof(int) * n); im->polyAllocated = n; } if (im->polyAllocated < n) { while (im->polyAllocated < n) { im->polyAllocated *= 2; } im->polyInts = (int *) realloc(im->polyInts, sizeof(int) * im->polyAllocated); } y1 = p[0].y; y2 = p[0].y; for (i=1; (i < n); i++) { if (p[i].y < y1) { y1 = p[i].y; } if (p[i].y > y2) { y2 = p[i].y; } } for (y=y1; (y <= y2); y++) { int interLast; int dirLast; int interFirst = 1; ints = 0; for (i=0; (i <= n); i++) { int x1, x2; int y1, y2; int dir; int ind1, ind2; if ((i == n) || (!i)) { ind1 = n-1; ind2 = 0; } else { ind1 = i-1; ind2 = i; } y1 = p[ind1].y; y2 = p[ind2].y; if (y1 < y2) { y1 = p[ind1].y; y2 = p[ind2].y; x1 = p[ind1].x; x2 = p[ind2].x; dir = -1; } else if (y1 > y2) { y2 = p[ind1].y; y1 = p[ind2].y; x2 = p[ind1].x; x1 = p[ind2].x; dir = 1; } else { /* Horizontal; just draw it */ gdImageLine(im, p[ind1].x, y1, p[ind2].x, y1); continue; } if ((y >= y1) && (y <= y2)) { int inter = (y-y1) * (x2-x1) / (y2-y1) + x1; /* Only count intersections once except at maxima and minima */ if (!interFirst) { if (inter == interLast) { if (dir == dirLast) { continue; } } } if (i > 0) { im->polyInts[ints++] = inter; } dirLast = dir; interLast = inter; interFirst = 0; } } qsort(im->polyInts, ints, sizeof(int), gdCompareInt); for (i=0; (i < (ints-1)); i+=2) { gdImageLine(im, im->polyInts[i], y, im->polyInts[i+1], y, c); } } } int gdCompareInt(a, b) int *a; int *b; { return *a - *b; } void gdImageSetStyle(im, style, noOfPixels) gdImagePtr im; int *style; int noOfPixels; { if (im->style) { free(im->style); } im->style = (int *) /* used to be unsigned int ...fixed by Thure Etzold */ malloc(sizeof(int) * noOfPixels); memcpy(im->style, style, sizeof(unsigned int) * noOfPixels); im->styleLength = noOfPixels; im->stylePos = 0; } void gdImageSetBrush(im, brush) gdImagePtr im; gdImagePtr brush; { int i; im->brush = brush; for (i=0; (i < gdImageColorsTotal(brush)); i++) { int index; index = gdImageColorExact(im, gdImageRed(brush, i), gdImageGreen(brush, i), gdImageBlue(brush, i)); if (index == (-1)) { index = gdImageColorAllocate(im, gdImageRed(brush, i), gdImageGreen(brush, i), gdImageBlue(brush, i)); if (index == (-1)) { index = gdImageColorClosest(im, gdImageRed(brush, i), gdImageGreen(brush, i), gdImageBlue(brush, i)); } } im->brushColorMap[i] = index; } } void gdImageSetTile(im, tile) gdImagePtr im; gdImagePtr tile; { int i; im->tile = tile; for (i=0; (i < gdImageColorsTotal(tile)); i++) { int index; index = gdImageColorExact(im, gdImageRed(tile, i), gdImageGreen(tile, i), gdImageBlue(tile, i)); if (index == (-1)) { index = gdImageColorAllocate(im, gdImageRed(tile, i), gdImageGreen(tile, i), gdImageBlue(tile, i)); if (index == (-1)) { index = gdImageColorClosest(im, gdImageRed(tile, i), gdImageGreen(tile, i), gdImageBlue(tile, i)); } } im->tileColorMap[i] = index; } } void gdImageInterlace(im, interlaceArg) gdImagePtr im; int interlaceArg; { im->interlace = interlaceArg; } gdImageRed(tile, i), gdImageGreen(tile, i), gdImageBlue(tile, i)); if (index == (-1)) { index = gdImageColorAllocate(im, gdImageRed(tile, i), gdImageGreen(tile, i), gdImageBlue(tile, i)); if (index == (-1)) { index = gdImageColorClosest(im, gdImageRed(tile, i),srs/src/gd.h ** ** $RCSfile: gd.h,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:16:32 $ ** ** $Locker: $ ** $State: Exp $ ** ** ** ** gd.h: declarations file for the gifdraw module. ** ** Written by Tom Boutell, 5/94. ** Copyright 1994, Cold Spring Harbor Labs. ** Permission granted to use this code in any fashion provided ** that this notice is retained and any alterations are ** labeled as such. It is requested, but not required, that ** you share extensions to this module with us so that we ** can incorporate them into new versions. ** ** ** this file was modified so that it now contains also the include files ** gdfonts.h and gdfontl.h by thure etzold, March 10, 1995 */ /* This can't be changed, it's part of the GIF specification. */ #define gdMaxColors 256 /* Image type. See functions below; you will not need to change the elements directly. Use the provided macros to access sx, sy, the color table, and colorsTotal for read-only purposes. */ typedef struct gdImageStruct { unsigned char ** pixels; int sx; int sy; int colorsTotal; int red[gdMaxColors]; int green[gdMaxColors]; int blue[gdMaxColors]; int open[gdMaxColors]; int transparent; int *polyInts; int polyAllocated; struct gdImageStruct *brush; struct gdImageStruct *tile; int brushColorMap[gdMaxColors]; int tileColorMap[gdMaxColors]; int styleLength; int stylePos; int *style; int interlace; } gdImage; typedef gdImage * gdImagePtr; typedef struct { /* # of characters in font */ int nchars; /* First character is numbered... (usually 32 = space) */ int offset; /* Character width and height */ int w; int h; /* Font data; array of characters, one row after another. Easily included in code, also easily loaded from data files. */ char *data; } gdFont; /* Text functions take these. */ typedef gdFont *gdFontPtr; /* For backwards compatibility only. Use gdImageSetStyle() for MUCH more flexible line drawing. Also see gdImageSetBrush(). */ #define gdDashSize 4 /* Special colors. */ #define gdStyled (-2) #define gdBrushed (-3) #define gdStyledBrushed (-4) #define gdTiled (-5) /* NOT the same as the transparent color index. This is used in line styles only. */ #define gdTransparent (-6) /* Functions to manipulate images. */ gdImagePtr gdImageCreate(/* int sx, int sy */); gdImagePtr gdImageCreateFromGif(/* FILE *fd */); gdImagePtr gdImageCreateFromGd(/* FILE *fd */); gdImagePtr gdImageCreateFromXbm(/* FILE *fd */); void gdImageDestroy(/* gdImagePtr im */); void gdImageSetPixel(/* gdImagePtr im, int x, int y, int color */); int gdImageGetPixel(/* gdImagePtr im, int x, int y */); void gdImageLine(/* gdImagePtr im, int x1, int y1, int x2, int y2, int color */); /* For backwards compatibility only. Use gdImageSetStyle() for much more flexible line drawing. */ void gdImageDashedLine(/* gdImagePtr im, int x1, int y1, int x2, int y2, int color */); /* Corners specified (not width and height). Upper left first, lower right second. */ void gdImageRectangle(/* gdImagePtr im, int x1, int y1, int x2, int y2, int color */); /* Solid bar. Upper left corner first, lower right corner second. */ void gdImageFilledRectangle(/* gdImagePtr im, int x1, int y1, int x2, int y2, int color */); int gdImageBoundsSafe(/* gdImagePtr im, int x, int y */); void gdImageChar(/* gdImagePtr im, gdFontPtr font, int x, int y, int c, int color */); void gdImageCharUp(/* gdImagePtr im, gdFontPtr font, int x, int y, int c, int color */); void gdImageString(/* gdImagePtr im, gdFontPtr font, int x, int y, char *s, int color */); void gdImageStringUp(/* gdImagePtr im, gdFontPtr font, int x, int y, char *s, int color */); /* Point type for use in polygon drawing. */ typedef struct { int x, y; } gdPoint, *gdPointPtr; void gdImagePolygon(/* gdImagePtr im, gdPointPtr p, int pointsTotal, int color */); void gdImageFilledPolygon(/* gdImagePtr im, gdPointPtr p, int pointsTotal, int color */); int gdImageColorAllocate(/* gdImagePtr im, int r, int g, int b */); int gdImageColorClosest(/* gdImagePtr im, int r, int g, int b */); int gdImageColorExact(/* gdImagePtr im, int r, int g, int b */); void gdImageColorDeallocate(/* gdImagePtr im, int color */); void gdImageColorTransparent(/* gdImagePtr im, int color */); void gdImageGif(/* gdImagePtr im, FILE *out */); void gdImageGd(/* gdImagePtr im, FILE *out */); void gdImageArc(/* gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color */); void gdImageFillToBorder(/* gdImagePtr im, int x, int y, int border, int color */); void gdImageFill(/* gdImagePtr im, int x, int y, int color */); void gdImageCopy(/* gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h */); /* Stretches or shrinks to fit, as needed */ void gdImageCopyResized(/* gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int destw, int desth, int srcw, int srch */); void gdImageSetBrush(/* gdImagePtr im, gdImagePtr brush */); void gdImageSetTile(/* gdImagePtr im, gdImagePtr tile */); void gdImageSetStyle(/* gdImagePtr im, int *style, int noOfPixels */); /* On or off (1 or 0) */ void gdImageInterlace(/* gdImagePtr im, int interlace */); /* Macros to access information about images. READ ONLY. Changing these values will NOT have the desired result. */ #define gdImageSX(im) ((im)->sx) #define gdImageSY(im) ((im)->sy) #define gdImageColorsTotal(im) ((im)->colorsTotal) #define gdImageRed(im, c) ((im)->red[(c)]) #define gdImageGreen(im, c) ((im)->green[(c)]) #define gdImageBlue(im, c) ((im)->blue[(c)]) #define gdImageGetTransparent(im) ((im)->transparent) #define gdImageGetInterlaced(im) ((im)->interlace) /* formerly gdfontl.h */ /* 8x16 font derived from a public domain font in the X distribution. Only contains the 96 standard ascii characters, sorry. Feel free to improve on this. */ extern gdFontPtr gdFontLarge; /* formerly gdfonts.h */ /* 6x12 font derived from a public domain font in the X distribution. Only contains the 96 standard ascii characters, sorry. Feel free to improve on this. */ extern gdFontPtr gdFontSmall; e gdImageGetInterlaced(im) ((im)->interlace) /* formerly gdfontl.h */ /* 8x16 font derived from a public domain font in the X distribution. Only contains the 96 standard ascii characters, sorry. Feel free to improve on this. */ extern gdFontPtr gdFontLarge; /* formerly gdfonts.h */ /* 6x12 font derived from a public domain font in the X distribution. Only contains the 96 standardsrs/src/getz.c char getz_ID[] = "$Id: getz.c,v 1.10 1997/03/18 17:20:18 srs Exp $"; /* ** $RCSfile: getz.c,v $ ** $Revision: 1.10 $ ** $Date: 1997/03/18 17:20:18 $ ** $Author: srs $ ** ** Copyright by Thure Etzold ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include "srs.h" static VIEWo *BuildView (SETo *set); int main(int argc, char **argv) { ARGoLIST *argList; TEMPLv templ; SETo *set; VIEWo *view=NULL; ENTRYv entry; IDoENTRY id; char *tmp; INT4 i; SrsEnv (); LibOpen (); LibInitHyperLinks (); MsgSetFnct ((FUNC)IcaPrintMessage); templ = TemplOpen ("SRSICA:ascii.it", NULL); /* process command line */ argList = (ARGoLIST*) LibObjByName ("arglist", "getz"); argc = ArgGet (argList, argc, argv); if (ParGetNum ("printLibInfo") && argc == 2) { /* print only info ? */ LibPrintInfo (argv[1]); exit (0); } else if (ParGetNum ("printLibs")) { LibPrintLibs (); exit (0); } else if (ParGetNum ("getStartupInfo")) { LibPrintStartupInfo (); exit (0); } else if (argc != 2) { ArgUsage (argList); exit (0); } /* do the query */ TemplWith (templ, "$queryReport"); if ((set = Query (argv[1], "Q1"))) { if (*ParGetStr ("viewFieldList")) view = BuildView (set); else if (*(tmp=ParGetStr ("viewName"))) if (!(view = ViewGetNamed (tmp))) _ErrExit3 (e__objectunknown, "view", tmp); /* iterate over elements in the retrieved set */ for (i=1; i <= set->n; i++) { SetGetID (set, i, &id); entry = EntryOpen (&id); if (view) EntryView (entry, view); else if (ParGetBool ("printEntireEntry")) EntryPrint (entry, NULL); else if (*ParGetStr ("fieldList")) EntryPrintFields (entry, NULL); else printf ("%s\n", EntryGetFullName (entry)); EntryClose (&entry); } } TemplEndWith (); exit (0); } static VIEWo *BuildView (SETo *set) { VIEWo *view; SRSoFLD *ft; char *libName, *name, *tmp; Int4 k; if (*(tmp = ParGetStr ("viewFieldList"))) { view = ViewNew (1, "getz"); ViewSetFormat (view, "table"); for (k=0; SetGetNextLibStat (SetGetName (set), &libName, &k);) ViewAddRootLib (view, LibObjByName ("library", libName)); while ((name = strtok (tmp, " "))) { tmp = NULL; if (!(ft = LibGetFieldType (libName, name))) _ErrExit3 (e__objectunknown, "data-field", name); ViewAddRootField (view, ft); } } else view=NULL; return view; } k; if (*(tmp = ParGetStr ("viesrs/src/hash.c char hash_srs_ID[] = "$Id: hash.c,v 1.1 1996/05/06 15:16:33 srs Exp $"; /* ** ** $RCSfile: hash.c,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:16:33 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.1 Copyright by Thure Etzold ** Unix port by Lukas Rosenthaler and Reinhard ** ** Author: Gerald Schaefer ** EMBL, Meyerhofstrasse 1 ** D-69012 Heidelberg, Germany ** Tel: 06221 387372 ** Email: schaefer@embl-heidelberg.de ** ** ** Requires: ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** implementation of a hash table used for generating indices ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include /* #include SRSINCLUDE */ #include "message.h" #include "hash.h" #define HSHxDEFHASHSIZE 111 #define HSHxDEFMAXFILL 80 /* ** HSHxHFREE means that this hash table element was never used before ** HSHxHDEL means that the element was used before but deleted now */ #define HSHxHFREE (void*)1L #define HSHxHDEL (void*)0L INT4 (*compare)(void *, void *) = NULL; /**************************************************************** * heap_sort: original by J.F.Korsh, L.J.Garrett * * Data Structures, Algorithms, and Program Style using C * * modification: ascendant order, list contains object pointers * * ****************************************************************/ /* function prototypes */ void heapsort(void **list, INT4 n); void shift(void **list, INT4 root, INT4 last); /* sorts the n elements of list in ascendant order */ void heapsort(void **list, INT4 n) { INT4 root, last; void *temp; list--; /* because the algorithm works from 1 to n */ root = n/2; last = n; while (root > 0) { shift(list, root, last); root--; } root = 1; while (last > 1) { /* interchange(list,1,last) */ temp = list[1]; list[1] = list[last]; list[last] = temp; last--; shift(list, root, last); } } /****************************************************************** * Makes the subtree of the root into a heap (min heap). * The left and right subtrees of root must be heaps. * All subtrees are stored in array list in sequential representation. * Only the nodes between root and last are considered to be * in the subtrees. ******************************************************************/ void shift(void **list, INT4 root, INT4 last) { INT4 ptr, succ; void *rootptr; ptr = root; succ = 2 * ptr; if (succ < last) if (compare(list[succ+1],list[succ]) > 0) /* ascendant order */ succ++; rootptr = list[root]; while ((succ <= last) && (compare(list[succ],rootptr) > 0)) { /* asc. */ list[ptr] = list[succ]; /*copy*/ ptr = succ; succ = 2 * ptr; if (succ < last) if (compare(list[succ+1],list[succ]) > 0) /* ascendant */ succ++; } list[ptr] = rootptr; /*copy*/ } INT4 dummy_func(void *obj) { #if defined (TRACE1) printf("*** dummy function called ***\n"); #endif return 1; } INT4 dummy_func2(void *obj1, void *obj2) { #if defined (TRACE1) printf("*** dummy2 function called ***\n"); #endif return 1; } /****** HshFunc *********************************************************** ** ** computes a hash index for a given string object. ** Needs the hash table manager object ** to get the maximum size of the hash table. ** ** INPUT: address of an existing hash table object [R] ** address of a string object to hash [R] ** IMPLICIT: ** ** RETURNS: the computed hash index */ static INT4 HshFunc (HSHo *table, void *s) { register unsigned long h=0, g; register char *p = (char *) s; while (*p) { h= (h << 4) + *p++; if ((g= (h & 0xf0000000))) h= (h ^ (g >> 24)) ^ g; } #ifdef xxxx while (*s) h = (h<<5) + *s++; /* horner's function ...segdewick */ /* h = (h << 1) ^ *s++; */ #endif return (INT4) h % table->max_hash_elem; } /**api* HshNewTable ******************************************************** ** ** creates and initializes a hash table manager object for a new ** hash table and allocates memory for an array, later used to ** store addresses of objects. ** ** INPUT: maximum size of hash table [R] ** maximum fill in percentage [R] ** address of a hash function [R] ** address of a compare function [R] ** address of a print function [R] ** address of a delete function [R] ** IMPLICIT: ** ** RETURNS: address of the hash table manager object on success, ** NULL otherwise */ HSHo *HshNewTable(INT4 size, INT4 fill, INT4 (*hash_func)(HSHo *, void *), INT4 (*compare_func)(void *, void *), INT4 (*print_func) (void *), INT4 (*delete_func) (void *) ) { INT4 i; HSHo *table = (HSHo*) malloc(sizeof(HSHo)); if (!table) return NULL; /* error handling ... */ /* ** initialize hash table */ if (size > 0) table->max_hash_elem = size; else table->max_hash_elem = HSHxDEFHASHSIZE; if (fill>=50 && fill<=100) table->max_fill = fill; else table->max_fill = HSHxDEFMAXFILL; table->hash_list = (void**)malloc(table->max_hash_elem*sizeof(void*)); if (!table->hash_list) { free(table); return NULL; /* error handling ... */ } table->cur_hash_elem = 0; for (i=0; i < table->max_hash_elem; i++) table->hash_list[i] = HSHxHFREE; table->hash_f = hash_func ? hash_func : HshFunc; table->compare_f = compare_func ? compare_func : dummy_func2; table->print_f = print_func ? print_func : dummy_func; table->delete_f = delete_func ? delete_func : dummy_func; /* ** allow insert and search operations (after compressing ** and sorting disabled !) */ table->insert_search_allowed = 1; return table; } /****** HshHashObject ********************************************************* ** ** puts an existing object into the hash table. ** If there exists a collision with the hash index the next free ** position will be occupied (round robin). ** ** INPUT: address of an existing hash table object [R] ** address of an existing object [R] ** IMPLICIT: ** modifies hash table ** ** RETURNS: 1 */ static INT4 HshHashObject(HSHo *table, void *obj) { INT4 i; INT4 hash_index; /* get hash index */ hash_index = (*table->hash_f)(table, obj); #if defined(TRACE1) printf("hash_index is %d\n", hash_index); #endif /* search for next free place */ for (i=hash_index; imax_hash_elem; i++) if (table->hash_list[i] <= HSHxHFREE) { table->hash_list[i] = obj; /* no entry yet */ table->cur_hash_elem++; return 1; } /* if no free slot until end ...try from begin of table */ for (i=0; ihash_list[i] <= HSHxHFREE) { table->hash_list[i] = obj; /* no entry yet */ table->cur_hash_elem++; return 1; } return 1; } /**api* HshInsertObject **************************************************** ** ** inserts the new object into the hash table. ** If the hash table is not big enough, it will be doubled before ** hashing objects. ** ** INPUT: address of an existing hash table manager object [R] ** address of the new object [R] ** IMPLICIT: ** modifies hash table ** ** RETURNS: 1 if the object has been successfully inserted, ** 0 otherwise */ INT4 HshInsertObject(HSHo *table, void *obj) { INT4 i, rv=1; void **old_hash_list = table->hash_list; INT4 old_max_hash_elem = table->max_hash_elem; if (!table || !obj) { printf("ERROR: hash table or object is NULL\n"); return 0; } /* be sure that hash table is big enough */ if (table->cur_hash_elem > table->max_hash_elem * table->max_fill / 100) { void **tmp; /* extend hash table and rehash all elements in list */ table->max_hash_elem = table->max_hash_elem * 2 + 7; #if defined(TRACE2) printf("*** INFO: Expanding hash table from %d to %d elements ***\n", old_max_hash_elem, table->max_hash_elem); #endif tmp = (void**) malloc(table->max_hash_elem * sizeof(void*)); if (!tmp) return 0; /* no errror message to keep list module independent from other modules */ table->hash_list = tmp; /* use new array */ /* mark all elements as unused */ for (i=0; i < table->max_hash_elem; i++) table->hash_list[i] = HSHxHFREE; table->cur_hash_elem = 0; /* hash all already used old elements */ for (i = 0; i < old_max_hash_elem; i++) if (old_hash_list[i] > HSHxHFREE) /* NULL check would fail */ rv &= HshHashObject(table, old_hash_list[i]); free(old_hash_list); /* free old array */ } /* hash new object */ rv &= HshHashObject(table, obj); return rv; } /**api* HshSearchObject *************************************************** ** ** checks if an object with the same key value as the specified object ** is already in the hash table. ** Passes the address of the found object back to the calling function. ** ** INPUT: address of an existing hash table manager object [R] ** address of an object to search for duplicate [R] ** IMPLICIT: ** ** RETURNS: address of an existing object, if found ** 0 otherwise */ void *HshSearchObject(HSHo *table, void *obj) { void* tmp; INT4 i; INT4 stop_search = 0; INT4 hash_index; if (!table || !obj) { printf("ERROR: hash table or object is NULL\n"); return 0; } /* get hash index for the specified object */ hash_index = (*table->hash_f)(table, obj); #if defined(TRACE1) printf("hash_index is %d\n", hash_index); #endif /* search for object in hash table beginning with hash index */ for (i=hash_index; imax_hash_elem; i++) { tmp = table->hash_list[i]; if (tmp == HSHxHFREE) {stop_search = 1; break;} if (tmp == HSHxHDEL) continue; if (!(*table->compare_f)(tmp, obj)) { /* object found */ return tmp; } } if (!stop_search) for (i=0; ihash_list[i]; if (tmp == HSHxHFREE) {stop_search = 1; break;} if (tmp == HSHxHDEL) continue; if (!(*table->compare_f)(tmp, obj)) { /* object found */ return tmp; } } return 0; /* duplicate object not found */ } /**api* HshRehash ****************************************************** ** ** rehashes a (e.g. sorted) hash table. Inserting of and searching ** for objects is possible again, afterwards. ** ** INPUT: address of an existing hash table manager object [R] ** IMPLICIT: ** modifies hash table ** ** RETURNS: 1 on success, ** 0 otherwise */ INT4 HshRehash(HSHo *table) { INT4 i, rv=1; void **old_hash_list = table->hash_list; INT4 old_max_hash_elem = table->max_hash_elem; void **tmp; if (!table) { printf("*** ERROR: hash table does not exist !!! \n"); return 0; } tmp = (void**) malloc(table->max_hash_elem * sizeof(void*)); if (!tmp) return 0; /* no errror message to keep list module independent from other modules */ table->hash_list = tmp; /* use new array */ /* mark all elements as unused */ for (i=0; i < table->max_hash_elem; i++) table->hash_list[i] = HSHxHFREE; table->cur_hash_elem = 0; /* hash all old elements */ for (i = 0; i < old_max_hash_elem; i++) if (old_hash_list[i]) rv &= HshHashObject(table, old_hash_list[i]); /* ** enable insert and search operations after successful rehashing */ if (rv) { table->insert_search_allowed = 1; free(old_hash_list); /* free old array */ } else { table->hash_list = old_hash_list; free(tmp); } return rv; } /**api* HshCompress ***************************************************** ** ** compresses the specified hash table. Inserting of and searching ** for objects is not possible before rehashing. ** ** INPUT: address of an existing hash table manager object [R] ** IMPLICIT: ** ** RETURNS: 1 on success ** 0 otherwise */ INT4 HshCompress(HSHo *table) { INT4 i,j; void **list; if (!table) { printf("*** ERROR: hash table does not exist !!! \n"); return 0; } /* ** compress hash table */ list = table->hash_list; for (i=0,j=table->max_hash_elem-1; i HSHxHFREE) i++; while (list[j] <= HSHxHFREE) j--; if (i>j) break; list[i] = list[j]; list[j] = NULL; } /* ** disable insert and search operations after compressing */ table->insert_search_allowed = 0; return 1; } /**api* HshSort ********************************************************* ** ** compresses and sorts the specified hash table. ** Inserting of and searching for objects is no more possible. ** ** INPUT: address of an existing hash table manager object [R] ** IMPLICIT: ** ** RETURNS: 1 on success ** 0 otherwise */ INT4 HshSort(HSHo *table) { int rv = 1; if (!table) { printf("*** ERROR: hash table does not exist !!! \n"); return 0; } rv = HshCompress(table); /* ** sort compressed hash table using heap sort */ compare = table->compare_f; /* set global function pointer */ heapsort(table->hash_list, table->cur_hash_elem); /* ** disable insert and search operations after compressing ** and sorting */ table->insert_search_allowed = 0; return rv; } /**api* HshDeleteAll ******************************************************* ** ** HshDeleteAll may be called externally to delete all hashed objects ** inclusive the hash table manager object. A NULL pointer is given back ** to the calling function, so that the old pointer to the hash table ** can not be used anymore. ** ** INPUT: address of an address of an existing hash table object [R,W] ** IMPLICIT: ** ** RETURNS: 1 on success, 0 otherwise */ INT4 HshDeleteAll(HSHo **table_pt) { HSHo *table; INT4 i; if ( !table_pt || !(table = *table_pt) ) { printf("*** ERROR: hash table does not exist !!! \n"); return 0; } /* ** delete all objects in the hash table */ for (i=0; i < table->max_hash_elem; i++) { if (table->hash_list[i] <= HSHxHFREE) continue; (*table->delete_f)(table->hash_list[i]); } /* ** delete the hash table array and the manager object */ free(table->hash_list); /* delete hash table */ free(table); /* delete hash table manager object */ /* ** modify the hash table pointer to signal that the hash table ** has been destroyed */ *table_pt = NULL; return 1; } /**api* HshPrintAll *********************************************************** ** ** Prints the attribute values of the hash table manager object and the ** attribute values of all objects in the hash table. ** ** INPUT: address of an existing hash table manager object [R] ** IMPLICIT: ** ** RETURNS: 1 on success, 0 otherwise */ INT4 HshPrintAll(HSHo *table) { INT4 i; if (!table) { printf("*** ERROR: hash table does not exist !!! \n"); return 0; } printf("********** HASH TABLE DUMP *********************\n"); printf("* Table has %d entries:\n", table->cur_hash_elem); printf("* Table could have %d entries:\n", table->max_hash_elem); printf("* Table will be extended, if more than %d %% of the elements used\n", table->max_fill); /* ** print the attribute values of all objects in the hash table */ for (i=0; i < table->max_hash_elem; i++) { if (table->hash_list[i] <= HSHxHFREE) continue; printf("%8d", i); (*table->print_f)(table->hash_list[i]); } return 1; } /**api* HshLength ******************************************************** ** ** returns the current number of elements if the hash table exists. ** ** INPUT: address of an existing hash table object [R] ** IMPLICIT: ** ** RETURNS: current number of elements on success, 0 otherwise */ INT4 HshLength(HSHo *table) { if (!table) { printf("*** ERROR: hash table does not exist !!! \n"); return 0; } #if defined(TRACE1) printf("*** List has %d entries (max. is %d)***\n", table->cur_hash_elem, table->max_hash_elem); #endif return table->cur_hash_elem; } the hash table exists. ** ** INPUT: address of an existing hash table object [R] ** IMPLICIT: ** ** RETURNS: current number of elements on success, 0 otherwise */ INT4 srs/src/hash.h * File: hash_ind.h * implementation of a hash table used for generating indices * * structures and prototypes * *******************************************************************/ /* ** structure definition of the hash table manager object */ typedef struct HSHo { INT4 max_hash_elem; /* max. number of objects in the hash table */ INT4 cur_hash_elem; /* current number of objects in the hash table */ void **hash_list; /* address of an array of void pointers */ /* pointing to the objects. The array is */ /* automatically doubled, if overflow */ INT4 max_fill; /* determines when hash table should be extended */ INT4 insert_search_allowed; /* insert and search allowed (before sort) */ INT4 (*hash_f)(struct HSHo *, void *); /* pointer to hash function */ INT4 (*compare_f)(void *, void *); /* pointer to compare function */ INT4 (*print_f)(void *); /* pointer to print function for objects */ INT4 (*delete_f)(void *); /* pointer to delete function for objects */ /* INT4 isUnused; e.g. HSHxHFREE INT4 isFreed; e.g. HSHxHDEL */ } HSHo; void *HshSearchObject(HSHo *table, void *obj); INT4 HshInsertObject(HSHo *table, void *obj); HSHo *HshNewTable(INT4 size, INT4 fill, INT4 (*hash_func)(HSHo *, void *), INT4 (*compare_func)(void *, void *), INT4 (*print_func) (void *), INT4 (*delete_func) (void *) ) ; INT4 HshRehash(HSHo *table); INT4 HshLength(HSHo *table); INT4 HshPrintAll(HSHo *table); INT4 HshCompress(HSHo *table); INT4 HshSort(HSHo *table); INT4 HshDeleteAll(HSHo **table_pt); bj); INT4 HshInsertObject(HSHo *table, void *obj); HSHo *HshNewTable(INT4 size, INT4 fill, INT4 (*hash_func)(HSHo *, void *), INT4 (*compare_func)(void *, voisrs/src/ica.c char ica__ID[] = "$Id: ica.c,v 1.2 1996/07/18 09:10:23 ulyanov Exp $"; /* ** ** $RCSfile: ica.c,v $ ** $Revision: 1.2 $ ** $Date: 1996/07/18 09:10:23 $ ** $Author: ulyanov $ ** ** $Locker: $ ** $State: Exp $ ** Author: Anatoly Ulyanov ** EMBL, Meyerhofstrasse 1 ** D-69012 Heidelberg, Germany ** Tel: 06221 387451 ** Email: ulyanov@embl-heidelberg.de ** */ #include #include #include #include "def.h" #include "srs.h" #include "odd.h" #define _INITOBJS #define _CONSTANTS #define _SDL #define _ODD #define _FUNCTION #include "oddclass.h" ICAoSYNTAX *IcaInitSyntax(ICAoSYNTAX *); main(int argc, char **argv) { ARGoLIST *arglist; FILEo *dataFile; ICAoJOB *job; ICAoSYNTAX *syntax; char line[MAXLINESIZE], *tokStr, *name; INT4 printAll, tokCode, c, rv; SrsEnv (); LibOpen ("srs5"); arglist = LibObjByName ("arglist", "try"); argc = ArgGet (arglist, argc, argv); if (argc != 2) { ArgUsage (arglist); _ErrorExit (); } OddInit (def, 1); name = ParGetStr ("syntaxName"); dataFile = FileNew(argv[1]); if( !FileOpen (dataFile) ) _ErrExit2(e__filopenerr, argv[1]); if( !ParGetBool("useIni") ) { syntax = IcaInitSyntax(LibObjByName("syntax", "icarus")); syntax->ign = " \t\n"; job = IcaCreateJob (syntax); IcaNewJob (job, dataFile, NULL); if ( strcmp(name,"") != 0 ) IcaDoJob(job, name); else IcaDoJob(job, "prog"); IcaEndJob (job); VarExec (job->prog); exit(0); } if ( strcmp(name,"") != 0 ) syntax = (ICAoSYNTAX *)LibObjByName ("syntax", name); else syntax = (ICAoSYNTAX*)LibObjByName ("syntax", "icarus"); job = IcaCreateJob (syntax); IcaNewJob (job, dataFile, NULL); IcaGetTokenList ("prog"); IcaEndJob (job); if( job->prog ) VarExec(job->prog); } Icsrs/src/ica2c.c char ica2c_ID[] = "$Id: ica2c.c,v 1.9 1997/03/12 16:17:33 srs Exp $"; /* ** $RCSfile: ica2c.c,v $ ** $Revision: 1.9 $ ** $Date: 1997/03/12 16:17:33 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** Copyright by Thure Etzold ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Module Code: i2c ** ** Description ** =========== ** ** Writes out an icarus program into a C program. ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include "message.h" #include "sm.h" #include "futil.h" #include "templ.h" #include "strv.h" #include "variable.h" #include "icarus.h" #include "icaarg.h" static char* I2cFunctionName (VARo *var); static void I2cStmnt (VARo *var); static void I2cExpr (VARo *var, INT4 type); static void I2cFor (VARo *var); static void I2cCall (VARo *var, INT4 type, Int4 isConvertOK); static void I2cFunc (VARo *var); static INT4 I2cTypeConvert (INT4 type, INT4 newType); static void I2cProtoTypes (); static struct TEMPLo *i2cTempl=NULL; void I2cSetTemplate (struct TEMPLo *templ) { i2cTempl = templ; } void I2cDeclareVariables () { IARGoVALUE* var = (IARGoVALUE*) OddGetObjectPtr (OddGetClass("var"), 0); Int4 varN = OddGetObjectN (OddGetClass("var")); } char *I2cProg (VARo *var) { static INT4 funcN=0; static char funcName[100]; VARo **arg; sprintf (funcName, "IcarusProg%d", ++funcN); TemplPrint ("function.head", funcName); /* the first argument has the program name */ for (arg=VarGetArgs (var) + 1; *arg; arg++) I2cStmnt (*arg); TemplPrint ("function.tail"); return funcName; } char *I2cBody (VARo *var) { static INT4 funcN=0; static char funcName[100]; VARo **arg, **arg2; sprintf (funcName, "IcarusBody%d", ++funcN); TemplWith (i2cTempl, "$prog"); TemplPrint ("body.head", funcName); /* the first argument has the program name */ for (arg=VarGetArgs (var); *arg; arg++) { if ((*arg)->isReadFunction && SmEqs (IcaFunctionName ((*arg)->v.intGet), "IopBody")) { for (arg2=VarGetArgs (*arg); *arg2; arg2++) I2cStmnt (*arg2); /* nested body */ } else I2cStmnt (*arg); } TemplPrint ("body.tail"); TemplEndWith (); return funcName; } static void I2cStmnt (VARo *var) { char *funcName; TemplPrint ("stmnt.head"); funcName = I2cFunctionName (var); if (funcName && SmEqs (funcName, "IopFor")) I2cFor (var); else { I2cExpr (var, 0); TemplPrint ("stmnt.tail"); } } static void I2cExpr (VARo *var, INT4 type) { STRv str; INT4 isConvert=0; if (var->type) isConvert = I2cTypeConvert (var->type, type); if (VarGetCode (var) & IARGxCALL) I2cCall (var, type, isConvert); else if (var->isDelayedType || var->isReadFunction) I2cFunc (var); else switch (var->type) { case VARxINT: TemplPrint ("call.argint", VarGetInt (var)); break; case VARxSTRING: TemplPrint ("call.argstr", VarGetStr (var)); break; case VARxSTRV: str = VarGetStrv (var); TemplPrint ("call.argstrv", _Str (StrEncode (&str))); break; case VARxLIST: case VARxOBJECT: TemplPrint ("call.argstr", "NULL"); break; case VARxALIAS: TemplPrint ("call.argvar", VarGetName (var)); break; default: _ErrExit2 (e__unknownoption, "type in I2cCall"); } if (isConvert) TemplPrint ("convert.tail"); } static void I2cCall (VARo *var, INT4 type, Int4 isConvertOK) { VARo **args=VarGetArgs (var); IARGoCOM *com; IARGoVALUE *arg; char *funcName; INT4 k, isConvert=0; if (!(funcName = I2cFunctionName (var))) return; if (SmEqs (funcName, "IopExecCom")) com = (IARGoCOM *) VarGetObject (NULL, args[0]); else com = (IARGoCOM *) IargFunc2Com (funcName); if (com->returnType && !isConvertOK) isConvert = I2cTypeConvert (com->returnType, type); TemplPrint ("call.name", com->functionName); if (args[0]) IargBuildArgs (com, &args[1], TRUE); for (k=0; k < com->argsN; k++) { if (!(k == com->argsN)) TemplPrint ("call.argsep"); arg = &com->args[k]; if (arg->isSet) I2cExpr (arg->val, arg->type); else /* argument not defined, default value */ switch (arg->type) { case VARxINT: TemplPrint ("call.argint", arg->defInt); break; case VARxSTRING: case VARxSTRV: case VARxLIST: case VARxOBJECT: case VARxVAR: TemplPrint ("call.argval", "NULL"); break; default: _ErrExit2 (e__unknownoption, "type in I2cCall"); } } TemplPrint ("call.tail"); if (isConvert) TemplPrint ("convert.tail"); } static void I2cFunc (VARo *var) { VARo **arg; IARGoCOM *com; char *funcName; INT4 k; funcName = I2cFunctionName (var); com = (IARGoCOM *) IargFunc2Com (funcName); if (com && SmEqs (com->name, "=")) { arg=VarGetArgs (var); I2cExpr (arg[0], com->args[0].type); TemplPrint ("binop.="); I2cExpr (arg[1], com->args[1].type); } else { TemplPrint ("call.name", funcName); for (k=0, arg=VarGetArgs (var); *arg; arg++) { TemplPrint ("call.argsep"); if (com) I2cExpr (*arg, com->args[k++].type); else I2cExpr (*arg, 0); } TemplPrint ("call.tail"); } } static void I2cFor (VARo *var) { ; } #define _cvt(x,y) ((x) << 4) +(y) static INT4 I2cTypeConvert (INT4 type, INT4 newType) { if (!newType || type == newType) return 0; switch (_cvt(type, newType)) { case _cvt (VARxALIAS, VARxVAR): return 0; case _cvt (VARxINT, VARxVAR): return 0; /* TemplPrint ("convert.int.var"); break; */ case _cvt (VARxINT, VARxSTRING): TemplPrint ("convert.int.string"); break; case _cvt (VARxSTRING, VARxVAR): TemplPrint ("convert.int.var"); break; case _cvt (VARxSTRING, VARxSTRV): TemplPrint ("convert.string.strv"); break; case _cvt (VARxSTRV, VARxSTRING): TemplPrint ("convert.strv.string"); break; case _cvt (VARxSTRV, VARxVAR): TemplPrint ("convert.strv.var"); break; case _cvt (VARxOBJECT, VARxVAR): TemplPrint ("convert.object.var"); break; case _cvt (VARxVAR, VARxOBJECT): TemplPrint ("convert.var.object"); break; case _cvt (VARxVAR, VARxSTRV): TemplPrint ("convert.var.strv"); break; case _cvt (VARxVAR, VARxSTRING): /*te!!!!!*/ TemplPrint ("convert.var.strv"); break; case _cvt (VARxALIAS, VARxOBJECT): TemplPrint ("convert.alias.object"); break; case _cvt (VARxALIAS, VARxINT): return 0; case _cvt (VARxALIAS, VARxSTRING): /*te!!!!!*/ return 0; case _cvt (VARxALIAS, VARxSTRV): /*te!!!!!*/ TemplPrint ("convert.var.strv"); break; case _cvt (VARxLIST, VARxALIAS): /*te!!!!!*/ return 0; case _cvt (VARxLIST, VARxVAR): /*te!!!!!*/ return 0; /* TemplPrint ("convert.alias.int"); break; */ default: printf ("conversion is not possible\n"); exit (0); } return 1; } static char *I2cFunctionName (VARo *var) { if (var->isDelayedType) return IcaFunctionName ((FUNC) var->typeGet); else if (var->isReadFunction) return IcaFunctionName (var->v.intGet); return NULL; } void I2cProtoTypes () { } #ifdef ready typedef struct I2CoSyntax { char *name; nodeN nodeN[BNFxNodeTypeN]; } I2CoSyntax; typedef struct I2CoNodeInfo { void *ptr; INT4 index; INT4 progIndex[3]; } I2CoNodeInfo, *I2CvNodeInfo; typedef struct I2CoSyntaxInfo { TEMPLv templ; DICTv niDict; STRv initNodes[9]; I2CoSyntax *syntax; Int4 syntaxN; Int4 syntaxAllocN; } I2CoSyntaxInfo; char *I2cProg (VARo *var, char *name) { I2cSyntaxPrint (si); TemplPrint ("tail"); TemplEndWith (); } void I2cSyntaxPrint (I2CoSyntaxInfo *si) { I2cInitPrint (si->progInit); for (i=2; i < BNFxNodeTypesN; i++) I2cInitPrint (si->progInit[i]); for (i=0; i < 2; i++) I2cInitPrint (si->progInit[i]); I2cInitPrint (si->termReportInit[i]); I2cInitPrint (si->choiceSetInit[i]); } void I2cProdList (VARo *prodList) { VARo *var; Int4 i; /* collect all nodes from BNF tree */ for (i=0; (var = AnyNextInList (prodList, &i)); ) BnfTreeTraverse ((BNFoNODE *)VarGetObject (NULL, var), I2cNodeRegister, 0, syntaxInfo); /* print to buffer the Node initialization arrays */ for (i=0; (var = AnyNextInList (prodList, &i)); ) BnfTreeTraverse ((BNFoNODE *)VarGetObject (NULL, var), I2cNodePrint, 0, syntaxInfo); /* print to buffer the Term reports */ for (i=0; (var = AnyNextInList (prodList, &i)); ) BnfTreeTraverse ((BNFoNODE *)VarGetObject (NULL, var), I2cTermReportPrint, 0, syntaxInfo); /* print to buffer the Choice sets */ for (i=0; (var = AnyNextInList (prodList, &i)); ) BnfTreeTraverse ((BNFoNODE *)VarGetObject (NULL, var), I2cChoiceSetPrint, 0, syntaxInfo); } static void I2cNodeRegister (BNFoNODE *node, Int4 level, void *data) { I2CoSyntaxInfo* si=(I2CoSyntaxInfo*)data; I2CvNode ni, niPtr; STRv s; INT4 i; niPtr = &DictSet(&i2cniDict, &bnfNode, I2CpNode); if (!*ni) { if (node->name) { s = StrCpyS (node->name); StrEncode (&s); bnfNode->name = _Str (s); } ni = typeAlloc (I2CvNode); ni->node = (void *) nodeNode; ni->index = si->nodeN[node->type]++; if (node->type != Term && node->type != Choice) for (i=0; i<3; i++) ni->progIndex[i] = I2cNodeProgs (node->exec[i]); *niPtr = ni; } return; } static void I2cNodePrint (BNFoPRODUCTION *node, INT4 level, void *data) { I2CoSyntaxInfo* si=(I2CoSyntaxInfo*)data; I2CvNodeInfo niImpl, ni; char tmp[1000]; INT4 type; type = node->type; si->syntaxCurr->nodeN[type]++; ni = DictAt (si->niDict, &node, I2CvNode); /* print array header */ if (!StrLen (si->nodeInit[type])) StrCpyS (TemplSPrint (tmp, TemplN (type+1, "head"))); switch (i) { case Production: niImpl = DictAt (si->niDict, &(node->node), I2CvNode); TemplStrPrint (&si->nodeInit[type], "prod.init", node->name, I2cNodeProgs (si, ni->progs), TemplSPrint (tmp, TemplN (node->node->type+1, "arrName")), niImpl->index); break; case ProdName: niImpl=DictAt(si->niDict, &((BNFoPRODNAME *)node)->production, I2CvNode); TemplStrPrint (&si->nodeInit[type], "prodname.init", node->name, I2cNodeProgs (si, ni->progs), TemplSPrint (tmp, TemplN (Production+1, "arrName")), niImpl->index); break; case Literal: case Command: case LineStart: case Regexp: TemplStrPrint (&si->nodeInit[type], TemplN (type+1, "init"), node->name, I2cNodeProgs (si, ni->progs)); break; case Choice: case Term: TemplStrPrint (&si->nodeInit[type], TemplN (type+1, "init"), node->name); break; default: break; } } /****** I2cPrintVarPtr ***************************************************** ** */ static char *I2cPrintVarPtr(INT4 *counter) { static char buff[999]; static char ref[999]; INT4 i; buff[0]='\0'; for(i=0; i<3; i++) { if(*counter == -1) strcat(buff, ", 0"); else { sprintf(ref, ", &%s[%d]", TemplSPrint(s3, TemplN(12, "arrName")), *counter); strcat(buff, ref); } counter++; } return(buff); } static Int4 I2cNodeProgs (I2CoSyntaxInfo *si, VARo *var) { static Int4 varN=-1; if (var) { StrApps (si->varInit, TemplSPrint (tmp, "var.init", I2cBody (var))); return (++varN); } else return -1; } static void I2cPrintTermReport(BNFoNODE *node, INT4 level, void *data) { BNFoREPORT *report; BNFoNODE *tmp; if (node->type == BNFxTerm) { for (report=((BNFoTERM *)node)->factorList; (tmp=report->node); report++){ ni = DictAt (niDict, &nextNode, I2CvNode); TemplStrPrint (&si->reportInit, "report.init", report->counter, TemplSPrint (s, TemplN (tmp->type+1, "arrName")), ni->index); } TemplStrPrint (&si->reportInit, TemplN(10, "arrName"))); } } static void I2cChoiceSetPrint (BNFoNODE *node, INT4 level, void *data) { BNFoNODE **term, *tmp; if (node->type = BNFxChoice) { for (term=((BNFoCHOICE *)node)->termList; (tmp = *term); term++) ni = DictAt (si->niDict, &tmp, I2CvNode); StrAppS (si->nodeInit[BNFxChoice], TemplSPrint(s1, TemplN(11, "format")), TemplSPrint(s2, TemplN(nextNode->type+1, "arrName")), i2cNode->index); } BuffPrintF(i2cChoiceSetBuff, TemplSPrint(s1, TemplN(11, "arrName"))); } } #endif void I2cChoiceSetPrint (BNFoNODE *node, INT4 level, void *data) { BNFoNODE **term, *tmp; if (node->type = BNFxChoice) { for (term=((BNFoCHOICE *)node)->termList; (tmp = *term); term++) ni = DictAt (si->niDict, &tmp, I2CvNode); StrAppS (si->nodeInit[BNFxChoice], TemplSPrint(s1, TemplN(11, "format")), TemplSPsrs/src/ica2c.h ** ** $RCSfile: ica2c.h,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:16:35 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** Copyright by Thure Etzold ** */ void I2cOpen (char *fileName); char *I2cProg (VARo *var); char *I2cBody (VARo *var); ictAt (si->niDict, &tmp, I2CvNode); StrAppS (si->nodeI@Choice], TemplSPrint(s1, TemplN(11, "format")), }plSPsrs/src/icaarg.c char icarg_ID[] = "$Id: icaarg.c,v 1.8 1997/03/19 11:17:26 srs Exp $"; /* ** ** $RCSfile: icaarg.c,v $ ** $Revision: 1.8 $ ** $Date: 1997/03/19 11:17:26 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS Copyright by Thure Etzold ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** 69012 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** The functions in this module let the user define his own commands in ** icarus command lists. ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include "message.h" #include "sm.h" #include "lst.h" #include "dict.h" #include "templ.h" #include "futil.h" #include "toklist.h" #include "strv.h" #include "variable.h" #include "regexp.h" #include "icarus.h" #define _INITOBJS #include "icaarg.h" #undef _INITOBJS #define _SRS #include SRSINCLUDE /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** static functions and modulewide variables */ static void IargAddOrder (IARGoCOM *command, IARGoVALUE *arg); static void* IargToKey (DictElem* e) { return (*(IARGoCOM **)e)->name; } extern ICAoJOB *Job; static IARGoCOM *comCurr=NULL; static VARoSTACK *stack; static DICTv comDict=0; static CLASSoDICT IargDictClass = { (ValComparer)strequal, (ValHasher)strhash, (KeyAccessor)IargToKey, NULL, 0 }; IargComStack (IARGoCOM *com, char *option) { static INT4 count=-1; static IARGoCOM *stack[100]; if (option[1] == 'u') {/* push */ if (count >= 100 - 1) _ErrExit3 (f__limitexceeded, "command objects", 100); stack[++count] = comCurr; comCurr = com; } else comCurr = stack[--count]; } void IargInit () { static INT4 isInit=0; IARGoCOM *com; INT4 k, l; if (isInit) return; comDict = DictCreate (&IargDictClass); for (k=0; (*(com = &IARGCOM[k])->name); k++) { DictSet (&comDict, com->name, IARGoCOM*) = com; com->function = IcaGetFunction (com->functionName); } isInit=1; } /**API* IargSetCom ************************************************************ ** ** Declares a new command or overwrites existing command. ** ** INPUT: command object [R] ** command name [R] ** IMPLICIT: ** comDict (DICTv) ** ** RETURNS: */ void IargSetCom (IARGoCOM *com, char *name) { IargInit (); DictSet (&comDict, name, IARGoCOM*) = com; } /**API* IargGetCom ************************************************************ ** ** Gets the command object for specified command name. ** ** INPUT: command name [R] ** IMPLICIT: ** comDict (DICTv) ** ** RETURNS: command object */ IARGoCOM *IargGetCom (char *name) { IARGoCOM **com; IargInit (); com = (IARGoCOM**) DictWith (comDict, name); return com ? *com : NULL; } char *IargGetComName (IARGoCOM *com) { return com->name; } /**API* IargFunc2Com ************************************************************* ** ** Gets the command object for specified C function name. ** ** INPUT: C-function name [R] ** IMPLICIT: ** comDict (DICTv) ** ** RETURNS: command object ** NULL if not found */ IARGoCOM *IargFunc2Com (char *name) { Iter i; IARGoCOM *com; for (i=DictFirst (comDict); i; DictNext (comDict, &i)) { com = DictIn (i, IARGoCOM*); if (SmEqs (com->functionName, name)) return com; } return NULL; } /**API* IargGetArgs *********************************************************** ** ** This function must be called from the C-function associated to ** an Iargrus command in order to obtain the input parameters. ** The first argument specifies the names and order of the arguments, ** the following arguments are pointers that will be set to the ** respective values. ** ** INPUT: name of command within icarus [R] ** name of C function [R] ** IMPLICIT: ** comCurr (IARGoVALUE) ** ** RETURNS: 1 if success ** 0 if not */ INT4 IargGetArgs (char *orderList, ...) { va_list ap; VARo **var, **list, *varSave; IARGoVALUE *arg; STRv *str, opt; char *argName, *s, tmp[132]; void **p; INT4 k, *i, l; if (!comCurr) _ErrExit (e__fatal); else arg = comCurr->args; /* ** initialize order list */ if (!comCurr->orderN) { strcpy (tmp, orderList); /* SmStrTok modifies string */ while ((argName = SmStrTok (tmp, "|"))) { for (k=0; k < comCurr->argsN; k++) { arg = &comCurr->args[k]; if (SmEqs (argName, arg->name)) break; } if (k == comCurr->argsN) { _ErrMsg3 (e__unknownarg, argName, comCurr->name); return 0; } IargAddOrder (comCurr, arg); } } va_start (ap, orderList); for (k=0; k < comCurr->orderN; k++) { arg = comCurr->order[k]; varSave = arg->val; /* save in case it gets changed by underlying function */ /* execute in case it is 'type executed' */ if (arg->isSet) VarGetType (arg->val); if (arg->isSet) arg->val = VarGetVar (varSave, 1); switch (arg->type) { case VARxSTRING: s = va_arg (ap, char *); if (arg->isSet) strcpy (s, VarGetStr (arg->val)); else *s = '\0'; break; case VARxSTRV: str = va_arg (ap, STRv *); *str = arg->isSet ? VarGetStrv (arg->val) : NULL; break; case VARxINT: i = va_arg (ap, INT4 *); if (arg->valsN && arg->isSet) { for (opt = VarGetStrv (arg->val), l=0; l < arg->valsN; l++) { if (SmEqs (_Str (opt), arg->vals[l].name)) *i = arg->vals[l].n; StrDel (opt); } } else *i = arg->isSet ? VarGetInt (arg->val) : arg->defInt; break; case VARxOBJECT: p = va_arg (ap, void **); *p = arg->isSet ? VarGetObject (NULL, VarFreeze(arg->val)) : NULL; break; case VARxLIST: list = va_arg (ap, VARo **); *list = arg->isSet ? AnyListCpy (arg->val): NULL; break; case VARxVAR: var = va_arg (ap, VARo **); *var = arg->isSet ? arg->val : NULL; break; default: break; } } va_end (ap); return 0; } /**API* IargReturn ************************************************************* ** ** This function must be called from the C-function associated to ** an Icarus command in order to obtain the input parameters. ** The first argument specifies the names and order of the arguments, ** the following arguments are pointers that will be set to the ** respective values. ** ** INPUT: name of command within icarus [R] ** name of C function [R] ** IMPLICIT: ** comCurr (IARGoCOM *) [R] ** stack (IARGoSTACK ** ** RETURNS: 1 if success ** 0 if not */ INT4 IargReturn (char *orderList, ...) { static VARo value; va_list ap; VarReset (&value); va_start (ap, orderList); switch (comCurr->returnType) { case IARGxSTRING: VarSetStr (&value, va_arg (ap, char *)); break; case IARGxINT: VarSetInt (&value, va_arg (ap, INT4)); break; case IARGxOBJECT: VarSetObject (NULL, &value, va_arg (ap, void *)); break; default: break; } va_end (ap); VarPushCopy (stack, &value); return 0; } VARo *iargRetVal; /**api* function ************************************************************* ** ** Can be used from a C function implementing an Icarus command ** to return a value to Icarus. Note that when returning a string value ** it will NOT be copied. ** ** INPUT: type name of the returned value [W] ** the value [R] ** */ INT4 IcaReturn (char *typeName, ...) { static VARo value; STRv str; va_list ap; VarReset (&value); iargRetVal = &value; va_start (ap, typeName); switch (comCurr->returnType) { case VARxSTRING: VarSetStr (&value, va_arg (ap, char *)); break; case VARxSTRV: str = va_arg(ap, STRv); VarSetStrv (&value, str); break; case VARxINT: VarSetInt (&value, va_arg (ap, INT4)); break; case VARxOBJECT: VarSetObject (NULL, &value, va_arg (ap, void *)); break; case VARxVAR: VarSetVar (&value, va_arg (ap, VARo *)); break; default: _ErrExit2 (e__unknownoption, "type in IcaReturn"); break; } va_end (ap); return 0; } /**api* IargNewCommand ********************************************************* ** ** ** INPUT: name of command within icarus [R] ** name of C function [R] ** IMPLICIT: ** comCurr (IARGoCOM *) [W] ** ** RETURNS: */ IARGoCOM *IargNewCommand (char *name, char *funName, IARGoCOM **c) { #ifdef xxx static INT4 classId=0; if(!classId) LstManageClass (&classId, sizeof (IARGoCOM), NULL, NULL, NULL); LstNewNamed ((void **) c, classId, name); command = *c; command->function = IargGetFunction (funName); command->arg = NULL; command->retVal = NULL; command->unNamedArg = NULL; command->orderN = 0; command->orderAllocN = 0; command->order = NULL; #endif return comCurr; } /**api* IargMakeValue ********************************************************** ** ** ** INPUT: type of value: "arg" or "value" [R] ** name of value [R] ** type of value content: "string", "int", "object" [R] ** flag if value can occur unnamed [R] ** flag if value is required [R] ** name of the class (for value type "object") [R] ** IMPLICIT: ** command (IARGoCOM *) [R] ** ** RETURNS: */ void IargAddValue (char *valType, char *name, char *type, INT4 isUnNamed, INT4 isRequired, char *className) { #ifdef xxx static INT4 classId=0; IARGoVALUE *value; if (!command) _ErrExit2 (e__nocurrentcommand, name); if(!classId) LstManageClass (&classId, sizeof (IARGoVALUE), NULL, NULL, NULL); /* ** create a new value and insert in 'arg' or 'return' list */ switch (tolower (valType[0])) { case 'a': /* argument */ LstNewNamed ((void **) &(command->arg), classId, name); value = command->arg; break; case 'r': /* retVal */ LstNewNamed ((void **) &(command->retVal), classId, name); value = command->retVal; break; default: _ErrExit2 (e__unknownoption, type); } /* ** build the value descriptor */ if (isUnNamed) { if (command->unNamedArg) _ErrExit3 (e__onlyoneunnamed, value->name, command->name); command->unNamedArg = value; } value->isRequired = isRequired; switch (tolower (type[0])) { case 's': /* string */ value->type = IARGxSTRING; break; case 'i': /* int */ value->type = IARGxINT; break; case 'o': /* object */ value->type = IARGxOBJECT; strcpy (value->className, className); break; default: _ErrExit2 (e__unknownoption, type); } #endif } /**api* IargBuildArgs ********************************************************* ** ** ** INPUT: command object [W] ** array of pointers to values (last is NULL pointer) [R] ** IMPLICIT: ** comCurr (IARGoCOM *) [W] ** ** RETURNS: */ void IargBuildArgs (IARGoCOM *com, VARo **val, Int4 isInfo) { IARGoVALUE *arg; VARo *tmp; INT4 k; comCurr = com; if (!com->function && !isInfo) if (!(com->function = IcaGetFunction (com->functionName))) _ErrExit3 (e__objectunknown, "Icarus user function", com->functionName); /* initialize all argument values */ for (k=0; k < comCurr->argsN; k++) comCurr->args[k].isSet = 0; /* process arguments on the stack */ while ((tmp = *val++)) { for (k=0; k < comCurr->argsN; k++) { arg = &comCurr->args[k]; if (SmEqs (arg->name, tmp->name)||(*tmp->name == ':' && arg->isUnnamed)) break; } if (k == comCurr->argsN) { _ErrMsg3 (e__unknownarg, tmp->name, comCurr->name); return; } arg->isSet = 1; arg->val = tmp; } } /**api* IargExecCommand ******************************************************** ** ** ** INPUT: name of command within icarus [R] ** name of C function [R] ** IMPLICIT: ** comCurr (IARGoCOM *) [R] ** stack (VARoSTACK *) [W] ** ** RETURNS: */ void IargExecCommand (char *comName, VARoSTACK *s) { IARGoVALUE *arg; VARo *value; INT4 listSize, k; STRv argName; IargInit (); comCurr = DictAt (comDict, comName, IARGoCOM*); stack = s; /* initialize all argument values */ for (k=0; k < comCurr->argsN; k++) comCurr->args[k].isSet = 0; /* process arguments on the stack */ while ((value = VarNextArg (stack, &argName, &listSize))) { for (k=0; k < comCurr->argsN; k++) { arg = &comCurr->args[k]; if (SmEqs (arg->name, _Str(argName)) || (*_Str(argName) == ':' && arg->isUnnamed)) break; } if (k == comCurr->argsN) { _ErrMsg3 (e__unknownarg, _Str(argName), comCurr->name); return; } arg->isSet = 1; arg->val = value; } (*comCurr->function)(); } /**api* IargAddOrder ********************************************************** ** ** Adds a new element to the dynamically growing order list. ** ** INPUT: name of command within icarus [R] ** name of C function [R] ** IMPLICIT: ** ** RETURNS: */ static void IargAddOrder (IARGoCOM *command, IARGoVALUE *arg) { if (!command->orderAllocN) { if ((command->order = (void *) malloc (2 * sizeof (void *))) == NULL) _ErrExit2 (e__allocfail, "command order list"); command->orderN = 0; command->orderAllocN = 2; } else if (command->orderN >= command->orderAllocN) { command->orderAllocN *= 2; if ((command->order= (void *) realloc (command->order, command->orderAllocN * sizeof (void *))) == NULL) _ErrExit2 (e__allocfail, "command order list"); } command->order[command->orderN++] = arg; } /**api* IargPrintInfo ********************************************************* ** ** Prints out information for all Icarus commands. ** */ void IargPrintInfo () { TEMPLv templ; IARGoCOM *com; IARGoVALUE *arg; INT4 k, l, i; templ = TemplOpen ("SRSICA:srswww.i", NULL); TemplWith (templ, "$icarusCommand"); TemplPrint ("title"); for (k=0; (*(com = &IARGCOM[k])->name); k++) { if (!com->isShow) continue; TemplPrint("head", com->name, com->name, com->rem); if (!com->argsN) TemplPrint ("noArgs"); else { TemplWith (templ, "arglist"); for (l=0; largsN; l++) { arg = &com->args[l]; TemplPrint ("name", arg->name); /* argument type */ TemplWith (templ, "type"); if (arg->valsN) { TemplPrint ("enum.head"); for (i=0; i < arg->valsN; i++) TemplPrint ("enum.value", arg->vals[i].name); TemplPrint ("enum.tail"); } else if (arg->type == VARxOBJECT) TemplPrint (TemplN (arg->type, NULL), arg->className); else TemplPrint (TemplN (arg->type, NULL)); TemplEndWith (); TemplPrint (arg->isUnnamed ? "unnamed" : "named"); TemplPrint (arg->isRequired ? "required" : "optional"); /* default value */ if (arg->defInt) TemplPrint ("defaultNum", arg->defInt); else if (*arg->defaultStr) TemplPrint ("defaultStr", arg->defaultStr); else TemplPrint ("empty"); if (*arg->rem) TemplPrint ("comment", arg->rem); else TemplPrint ("empty"); TemplPrint ("tail"); } TemplEndWith (); } TemplWith (templ, "return"); TemplPrint ("head"); if (com->returnType) { TemplPrint ("preType"); /* return value type */ if (com->returnType) { TemplWith (templ, "$icarusCommand.arglist.type"); if (com->returnType == VARxOBJECT) TemplPrint (TemplN (com->returnType, NULL), com->returnClass); else TemplPrint (TemplN (com->returnType, NULL)); TemplEndWith (); TemplPrint ("postType"); } else TemplPrint ("nothing"); TemplEndWith (); TemplPrint ("tail"); } } TemplEndWith (); } nt ("head"); if (com->returnType) { TemplPrint ("preType"); /* return vasrs/src/icaarg.h ** ** $RCSfile: icaarg.h,v $ ** $Revision: 1.2 $ ** $Date: 1996/07/09 20:38:13 $ ** $Author: etzold $ ** ** $Locker: $ ** $State: Exp $ ** ** Copyright by Thure Etzold ** */ #include "builtin.h" #define IARGxCALL 16 #define IARGxINDIRECTCALL 32 #define IARGxODD 1 #define IARGxINIT 2 #define IARGxPRE 4 #define IARGxPOST 8 /* this is now exactly the same as the VARxINT...enum - should be replaced */ typedef enum {IARGxINT=1, IARGxSTRING, IARGxOBJECT, IARGxREAL, IARGxALIAS, IARGxVAR, IARGxANY, IARGxSTRV, IARGxLIST=16} IARGeType; typedef struct IARGoCOM *IARGvCOM; /* API */ INT4 IcaGetArgs (char *orderList, ...); struct IARGoCOM *IargFunc2Com (char *name); /* build time */ IARGvCOM IargGetCom (char *name); char *IargGetComName (struct IARGoCOM *com); void IargSetCom (struct IARGoCOM *com, char *name); struct ICAoCOMMAND *IcaNewCommand (char *name, char *funName, struct ICAoCOMMAND **c); void IcaAddValue (char *valType, char *name, char *type, INT4 isUnNamed, INT4 isRequired, char *className); /* ececution time */ typedef struct VARoSTACK *dummytointroducestructtagVARoSTACK; void IcaExecCommand (struct ICAoCOMMAND *command, struct VARoSTACK *stack); void IargBuildArgs (struct IARGoCOM *com, struct VARo **val, Int4 isInfo); /* the extra arguments are in case variables are defined as parameters */ #define _IargCall(com) (*(com)->function)(1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) void IcaAddValue (char *valType, char *name, char *type, INT4 isUnNamed, INT4 isRequired, char *className); /* ececution time */ typedef struct VARoSTACK *dummytointroducestructtagVARoSTACK; void IcaExecCommand (struct ICAoCOMMAND *command, struct VARoSTACK *stack); void IargBuildArgs (struct IARGoCOM *com, struct VARo **val, Int4 isInfo); /* the extra arguments are in case variables are defined as parameters */ #define _IargCallsrs/src/icabnf.c char icabnf_ID[] = "$Id: icabnf.c,v 1.25 1997/03/18 22:52:30 srs Exp $"; /* ** ** $RCSfile: icabnf.c,v $ ** $Revision: 1.25 $ ** $Date: 1997/03/18 22:52:30 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** Copyright by Thure Etzold ** ** Authors: Anatoly Ulyanov ** Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387451 ** Email: ulyanov@embl-heidelberg.de ** ** ** ** ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include "message.h" #include "regexp.h" #include "futil.h" #include "library.h" #include "sm.h" #include "strv.h" #include "lst.h" #include "variable.h" #include "toklist.h" #include "cursor.h" #include "icatask.h" #include "icarus.h" #include "icaarg.h" #include "icabnf.h" #include "icadebug.h" #define _ErrCheckJump() if(Job->parseError) return(FALSE) #define _ErrThrow(x) Job->parseError = (x) #define _ErrCatch() Job->parseError = 0 #define _SRS #include SRSINCLUDE extern ICAoJOB *Job; extern VARoStack icaStack2[6]; extern INT4 NameListId; extern ICAoSYNTAX *newSyntax; static INT4 TokCode; /* build time curr token code */ static char *BuffPtr; /* build time Ptr to syntax buff */ static char *BuffBegin; /* save the beginnig of syntax buff */ static char TokStr[10000]; /* build time curr token */ ICAoSYNTAX *Syntax; static INT4 BnfCompareLiteral(CURSORo *, INT4, char *); static INT4 BnfCompareRegExp(CURSORo *, regexp *); static void BnfLinkBnfNet(); static void BnfNextToken(); static void BnfPrintTree(BNFoCHOICE *); static void BnfTrace(INT4, char *, char *); void BnfInitRules (ICAoSYNTAX *, INT4); /**api* BnfBuild ************************************************************** ** ** function calls recursively BnfMakeTree function until all the ** parser syntaxes will be obtained. ** ** INPUT: syntax to build up BNF tree */ void BnfBuild(ICAoSYNTAX *syntax) { FILEo *file; ICAoJOB *job; if (*syntax->cmnt && ! syntax->cmntRe) if ((syntax->cmntRe = RegComp (syntax->cmnt)) == NULL) _ErrExit2 (e__regerror, syntax->cmntRe); if (!FileOpen ((file = FileNew (syntax->fileName)))) _ErrExit2 (e__filnotok, syntax->fileName); job = IcaCreateJob ((ICAoSYNTAX *)LibObjByName ("syntax", "icarus")); IcaNewJob (job, file, NULL); IcaGetTokenList (job, "prog"); syntax->prod = VarGet (&job->scope, "rules"); IcaEndJob (job); IcaExecProg (job); syntax->scope = (VARoSCOPE *)VarCopyScope (job->scope); return; } /****** BnfGetProduction ***************************************************** ** ** if a new name ** allocate memory for production and put into ** production list ** else ** return pointer ** INPUT: production name ** IMPLICIT: ** ** RETURNS: */ BNFoPRODUCTION *BnfGetProduction (ICAoSYNTAX *syntax, char *name, enum classtype type ) { BNFoPRODUCTION *production; if (!syntax) syntax = Syntax; if (syntax->prod) { /* level 3 */ VARo *var; if (!(var = AnyGetListAssoc (syntax->prod, name))) production = NULL; else production = VarGetObject (NULL, var); } else if( LstHashSearch((void **) &syntax->prodList, name) ) { if( syntax->prodList->isInit && type == Production) _ErrExit3(e__icabnfGetProd, name, BuffPtr); production = syntax->prodList->pointer; } return(production); } /****** BnfExecTask ************************************************************ ** ** prepare and make local parser task. The parser should parse line ** with instruction and create token list. This list is an input of ** BnfStackProgram ** ** INPUT: string cointains BNF action commands ** corresponding production node pointer ** IMPLICIT: ** ** RETURNS: */ static void BnfExecTask(BNFoPRODUCTION *taskNode) { BNFoPRODUCTION *node; TOKoLIST *inTokList; CURSORo cursorSave; INT4 c; /* output token list of taskNode is input for dependent tasks */ inTokList = taskNode->wrtTokList; for (c=0; (node = TaskNextActiveNode(taskNode->taskLinks, &c));) { CursorSave(&cursorSave, Job->cursor); Job->cursor = CursorNew(); CursorInstall(Job->cursor, TokGetFirst(inTokList), inTokList); BnfParseProdLoop(node); CursorRestore(Job->cursor, &cursorSave); } } /****** BnfParseProduction **************************************************** ** ** parse production: do pre-parsing actions, shift cursor to fist ** non space character, save it position, parse and if the parser ** succeed restore cursor and do post-parsing actions, move cursor ** in new position. ** ** INPUT: production pointer ** IMPLICIT: ** ** RETURNS: TRUE if parser succeed ** FALSE otherwise */ INT4 BnfParseProduction(BNFoPRODUCTION *production) { BNFoNODE *node; CURSORoANCHOR anchor; INT4 rv; Job->currNode = (BNFoNODE *)production; _BnfExecPre (production) if (Job->doAdvance) CursorAdvance(Job->cursor, Job->syntax->ign, Job->syntax->cmntRe, production->action&BNFxNOSKIP, &Job->doAdvance); /* if (!Job->doAdvance || CursorAdvance(Job->cursor, Job->syntax->ign, Job->syntax->cmntRe, production->action&BNFxNOSKIP, &Job->doAdvance) ){ */ CursorDefineAnchor(Job->cursor, &anchor); node = production->node; rv = (*node->parse) (node); if (Job->parseError) switch(Job->parseError) { case(ICAxNEWPARSEERROR): _ErrCatch(); IcaErrPrint(production->name, Job->failPattern, CursorGetBegin(Job->cursor), CursorGetPtr(Job->cursor)); _ErrThrow(ICAxPARSEERROR); /*te!!! why???*/ return(FALSE); break; case(ICAxPARSEERROR): return(FALSE); break; } if( rv == TRUE ) { Job->failPattern = NULL; CursorSetGlobalMatch(Job->cursor, &anchor); _BnfExecPost (production) CursorIncrement(Job->cursor); } if(production->taskLinks) /* should task be executed even if production failed? te!!! */ BnfExecTask(production); return(rv); /* } return(FALSE); */ } /****** BnfParseProdLoop **************************************************** ** ** parse production in loop. It takes corresponded token list ** and parse all the token with corresponded token-coder in it, do ** pre-parsing actions, shift cursor to fist non space character, ** save it position, parse and if the parser succeed restore cursor ** and do post-parsing actions, move cursor in new position. ** ** INPUT: production pointer ** IMPLICIT: ** ** RETURNS: TRUE if all tokens was parsed ** FALSE otherwise */ INT4 BnfParseProdLoop(BNFoPRODUCTION *production) { BNFoNODE *node; CURSORoANCHOR anchor; INT4 rv, isExcept; TokRewindList(production->rdTokList); while (TRUE) { Job->currNode = (BNFoNODE *)production; _BnfExecPre (production) if (Job->parseError) { _ErrCatch(); isExcept = 1; } else isExcept =0; if (isExcept || !Job->cursor->len) return 0; if (Job->doAdvance) CursorAdvance(Job->cursor, Job->syntax->ign, Job->syntax->cmntRe, production->action&BNFxNOSKIP, &Job->doAdvance); CursorDefineAnchor(Job->cursor, &anchor); node = production->node; rv = (*node->parse) (node); if(Job->parseError) switch(Job->parseError) { case(ICAxNEWPARSEERROR): _ErrCatch(); IcaErrPrint(production->name, Job->failPattern, CursorGetBegin(Job->cursor), CursorGetPtr(Job->cursor)); continue; break; default: continue; break; } if( rv == TRUE ) { Job->failPattern = NULL; CursorSetGlobalMatch(Job->cursor, &anchor); Job->currNode = (BNFoNODE *)production; _BnfExecPost (production) CursorIncrement(Job->cursor); if(production->taskLinks) BnfExecTask(production); } } } /****** BnfParseProdName ****************************************************** ** ** parse production name: do pre-parsing actions, shift cursor ** to fist non space character, save it position, call the ** production parser and if the parser succeed restore cursor ** and do post-parsing actions, move cursor in new position. if ** production name is optiinal restore the cursor. ** ** INPUT: production name pointer ** IMPLICIT: ** ** RETURNS: TRUE if parser succeed ** FALSE otherwise */ INT4 BnfParseProdName(BNFoPRODNAME *prodName) { BNFoPRODUCTION *production; CURSORo cursorSave; CURSORoANCHOR anchor; INT4 rv; Job->currNode = (BNFoNODE *)prodName; _BnfExecPre (prodName) if(Job->doAdvance) CursorAdvance(Job->cursor, Job->syntax->ign, Job->syntax->cmntRe, prodName->action&BNFxNOSKIP, &Job->doAdvance); production = prodName->production; if(prodName->optional) { CursorSave(&cursorSave, Job->cursor); Job->isOptional = TRUE; } CursorDefineAnchor(Job->cursor, &anchor); rv = (*production->parse) (production); _ErrCheckJump(); if( rv == TRUE ) { Job->currNode = (BNFoNODE *)prodName; CursorSetGlobalMatch(Job->cursor, &anchor); _BnfExecPost (prodName) CursorIncrement(Job->cursor); } else if(prodName->optional) { Job->isOptional = FALSE; CursorRestore(Job->cursor, &cursorSave); } return(rv); } /****** BnfParseRegExp ******************************************************** ** ** parse regular expression: do pre-parsing actions, shift cursor ** to fist non space character, compare input parsing string with ** the regular expression, and if it fits do post-parsing actions, ** move cursor in new position. The "NOT" action has special treatment. ** ** INPUT: regular expression name pointer ** IMPLICIT: ** ** RETURNS: TRUE if regular expression succeed ** FALSE otherwise ** attention! NOT action reverse RETURN value */ INT4 BnfParseRegExp(BNFoREGEXP *pattern) { INT4 rv; Job->currNode = (BNFoNODE *)pattern; _BnfExecPre (pattern) if(!Job->doAdvance || CursorAdvance(Job->cursor, Job->syntax->ign, Job->syntax->cmntRe, pattern->action&BNFxNOSKIP, &Job->doAdvance) ){ rv = BnfCompareRegExp(Job->cursor, pattern->expression); /* only a probe */ if(pattern->action&(BNFxNOT|BNFxPROBE)) { if (pattern->action & BNFxNOT) rv = !rv; if (rv) { /* braces, macro! te!!! */ _BnfExecPost (pattern) } CursorResetMatch (Job->cursor); return(rv); } if(rv) { Job->regExp = pattern->expression; _BnfExecPost (pattern) if( Job->isTrace & 1 ) BnfTrace(1, "RegExp", pattern->name); CursorIncrement(Job->cursor); Job->doAdvance = 1; } else { Job->doAdvance = Job->cursor->len ? 1 : 1; Job->failPattern = pattern->name; } return(rv); } return(FALSE); } /****** BnfParseLiteral ******************************************************* ** ** parse literal expression: do pre-parsing actions, shift cursor ** to fist non space character, compare input parsing string with ** the literal expression, and if it fits do post-parsing actions, ** move cursor in new position. The "NOT" action has special treatment. ** ** INPUT: literal expression pointer ** IMPLICIT: ** ** RETURNS: TRUE if literal expression succeed ** FALSE otherwise ** attention! NOT action reverse RETURN value */ INT4 BnfParseLiteral(BNFoLITERAL *literal) { INT4 rv; Job->currNode = literal; _BnfExecPre (literal) if (!Job->doAdvance || CursorAdvance(Job->cursor, Job->syntax->ign, Job->syntax->cmntRe, literal->action&BNFxNOSKIP, &Job->doAdvance) ){ rv = BnfCompareLiteral(Job->cursor, literal->action, literal->name); /* only a probe */ if(literal->action&(BNFxNOT|BNFxPROBE)) { if (literal->action & BNFxNOT) rv = !rv; if (rv) { /* braces, macro! te!!! */ _BnfExecPost (literal) } CursorResetMatch (Job->cursor); return rv; } if(rv) { _BnfExecPost (literal) if( Job->isTrace & 1 ) BnfTrace(1, "Literal", literal->name); CursorIncrement(Job->cursor); Job->doAdvance = 1; } else { Job->doAdvance = Job->cursor->len ? 1 : 1; Job->failPattern = literal->name; } return(rv); } return(FALSE); } /****** BnfParseCommand ******************************************************* ** ** parse asterisk expression: do pre-parsing actions do ** post-parsing actions, move cursor in new position. ** ** INPUT: command node pointer ** IMPLICIT: ** ** RETURNS: TRUE if input is expire */ INT4 BnfParseCommand(BNFoNODE *node) { INT4 flag; flag = CursorIsEnd(Job->cursor); Job->currNode = node; _BnfExecPre (node) _BnfExecPost (node) if (Job->parseError) { _ErrCatch(); return 0; } CursorIncrement(Job->cursor); /* program may set a match */ if(flag) return(TRUE); else return( !CursorIsEnd(Job->cursor) ); } /****** BnfParseInputEnd ***************************************************** ** ** check end of the input stream condition. ** It check end of file/token_list ** ** INPUT: end of input node pointer ** IMPLICIT: ** ** RETURNS: TRUE if ther is nothing to read ** FALSE otherwise */ INT4 BnfParseInputEnd(BNFoNODE *node) { Job->currNode = node; if (CursorAdvance(Job->cursor, Job->syntax->ign, Job->syntax->cmntRe, node->action&BNFxNOSKIP, &Job->doAdvance) ){ _ErrThrow(ICAxPARSEERROR); IcaErrPrint(node->name, ENDOFINPUT, CursorGetBegin(Job->cursor), CursorGetPtr(Job->cursor)); return(FALSE); } else { _BnfExecPre (node) _BnfExecPost (node) return(TRUE); } } /****** BnfParseLineStart ***************************************************** ** ** check the cursor position, if it at the beginning of the line do ** pre/post-parsing action. ** ** INPUT: line start node pointer ** IMPLICIT: ** ** RETURNS: TRUE if literal expression succeed ** FALSE otherwise */ INT4 BnfParseLineStart(BNFoNODE *node) { INT4 rv; Job->currNode = node; rv = CursorIsLineStart(Job->cursor); if( rv == TRUE ) { _BnfExecPre (node) _BnfExecPost (node) CursorIncrement(Job->cursor); /* program may set a match */ } return(rv); } /****** BnfParseTerm ********************************************************** ** ** a term node has a list of nodes that should be parsed ** one by one. In the loop it calls all the nodes and checks the ** return value. The return value can be changed depending on the ** type of node. ** ** INPUT: term node pointer ** IMPLICIT: ** ** RETURNS: TRUE if term succeed ** FALSE otherwise */ INT4 BnfParseTerm(BNFoTERM *term) { INT4 rv, trueCount; BNFoREPORT *factor; BNFoNODE *node; enum repeat counter; rv = TRUE; trueCount = 0; factor = term->factorList; while( factor->node != NULL && rv == TRUE) { node = factor->node; counter = factor->counter; rv = (*node->parse) (node); _ErrCheckJump(); if(rv) trueCount++; switch(counter) { case One: if(trueCount >= 1 && !rv) { _ErrThrow(ICAxNEWPARSEERROR); return(FALSE); } break; case ZeroOrOne: rv = TRUE; break; case ZeroOrMore: if( rv == TRUE ) while( (*node->parse)(node) ); _ErrCheckJump(); rv = TRUE; break; case OneOrMore: if(trueCount >= 1 && !rv) { _ErrThrow(ICAxNEWPARSEERROR); return(FALSE); } if( rv == TRUE ) while( (*node->parse)(node) ); _ErrCheckJump(); break; } factor++; } return(rv); } /****** BnfParseChoice ******************************************************** ** ** a choice node has a list of nodes that should be parsed one by ** one until some of them does not succeed. It calls all the nodes ** and checks the return value. If the return value is TRUE - stop ** and return TRUE. If no one node in choise list did not succeed - ** restore the cursor position and return FALSE ** ** INPUT: choice node pointer ** IMPLICIT: ** ** RETURNS: TRUE if choice succeed ** FALSE otherwise */ INT4 BnfParseChoice(BNFoCHOICE *choice) { INT4 rv; CURSORoANCHOR anchor; BNFoNODE *node, **termList; termList = choice->termList; rv = FALSE; CursorDefineAnchor(Job->cursor, &anchor); while(*termList != NULL && rv == FALSE) { node = *termList; rv = (*node->parse) (node); _ErrCheckJump(); termList++; } return(rv); } /****** BnfCompareLiteral ***************************************************** ** ** compare to strings. One defined by cursor the other is given ** as the argument. If "NOCASE" flag sets on case unsensitive ** comparison will be done. ** ** INPUT: pointer to cursor function ** action flag ** string to compare ** IMPLICIT: ** ** RETURNS: TRUE if strings are equal ** FALSE otherwise */ static INT4 BnfCompareLiteral(CURSORo *cursor, INT4 action, char *literal) { char *string1, *string2; INT4 len, l; len = strlen(literal); if( len > CursorLength(cursor) ) return(FALSE); string1 = literal; string2 = CursorGetPtr(cursor); if (BNFxNOCASE&action) { l = 0; while ((toupper(*string1++) == toupper(*string2++)) && l++ <= len) ; if (l != len) return 0; } else if (memcmp(string1, string2, len) != 0) return 0; CursorSetMatch(cursor, len); return 1; } /****** BnfCompareRegExp ****************************************************** ** ** function trys to fit given regular expression to the string ** defined by cursor every time starting from the fist character. ** Every regExp should have ^ at the beginning. To be certain the ** next to last character in the line temporary substitute to NULL. ** ** INPUT: pointer to cursor function ** string to compare ** IMPLICIT: ** ** RETURNS: TRUE if strings are equal ** ** function trys to fit given regular expresiion fo the string defined by cursor. To be certain the next to last character in the line temporary substitude to NULL. ** FALSE otherwise */ static INT4 BnfCompareRegExp(CURSORo *cursor, regexp *regExp) { INT4 rv; CursorRestrictLength(cursor); rv = RegExec(regExp, CursorGetPtr(cursor)); CursorRestoreChar(cursor); if( rv == 1 ) { CursorSetMatch(cursor,(INT4)(regExp->endp[0] - regExp->startp[0])); return(TRUE); } return(FALSE); } /****** BnfTrace ************************************************************** ** ** produce debug output */ static void BnfTrace(INT4 mode, char *tag, char *name) { #define MAXLEN 1000 char *token, *listInName, *listOutName, str[MAXLEN]; INT4 i; token = CursorGetMatchCopy(Job->cursor); i = MIN(MAXLEN-1, strlen(token)); memset(str, 0,MAXLEN); listInName = VarGetStr(VarGet(&Job->scope, VARTOKLISTIN)); listOutName = VarGetStr(VarGet(&Job->scope, VARTOKLISTOUT)); switch(mode) { case 0: printf("Input: %s\n",listInName); break; case 1: printf("Input: %s Output: %s\n", listInName, listOutName); break; } printf("%s shift: %s |%s|\n", tag, name, strncpy(str, token ,i)); } /****** BnfIsNodeActive ******************************************************* ** */ static INT4 BnfIsNodeActive(BNFoNODE *node) { if (node->exec[0] || node->exec[1] || node->exec[2]) return 1; return 0; } /****** BnfPruneTree ********************************************************** ** */ void BnfPruneTree (BNFoNODE **nodePtr, Int4 passN) { BNFoREPORT *report; BNFoNODE **term, *node=*nodePtr; Int4 k; return; switch (node->type) { case Choice: for (term=((BNFoCHOICE *)node)->termList; *term; term++) BnfPruneTree (term, passN); break; case Term: for (k=0, report=((BNFoTERM *)node)->factorList; report->node; report++,k++) BnfPruneTree (&report->node, passN); if (k==1 && passN==1) { /* term list with only one term and no counter */ report--; if (!report->counter) node = report->node; } break; case Production: if (passN == 2) { if (!BnfIsNodeActive (node)) { node = ((BNFoPRODUCTION *) node)->node; } } else { BnfPruneTree (&((BNFoPRODUCTION*) node)->node, passN); LstSetObjCurrent((void **) &Syntax->prodList, node); } break; case ProdName: if (!BnfIsNodeActive (node)) { node = (BNFoNODE*) BnfGetProduction (Syntax, node->name, ProdName); } break; } *nodePtr = node; } /****** BnfLinkBnfNet ********************************************************* ** */ static void BnfLinkBnfNet() { LstFirst((void **) &Syntax->prodList); do { if( !Syntax->prodList->isInit ) _ErrExit2(e__icabnfLinkBnfNet, Syntax->prodList->name); /* BnfPruneTree(Syntax->prodList->pointer); */ } while( LstNext((void **) &Syntax->prodList) ); } /****** BnfPrintTree ********************************************************** ** */ static char *tabs = " "; static INT4 Level = 1; static void BnfPrintTree(BNFoCHOICE *choiceNode) { BNFoREPORT *report; BNFoCHOICE *choice; BNFoTERM *term; BNFoNODE *node, **termList; BNFoPRODUCTION *production, *extendNode; enum repeat counter; char marg[MAXPRINTSIZE], edit[MAXPRINTSIZE]; strcpy(marg, tabs); marg[Level] = '\0'; if(choiceNode->name != NULL) { strcpy(edit,choiceNode->name); SmSwapS(edit,"\n","$"); } printf("%sLevel: %d\n%s%s ", marg, Level, marg, edit); extendNode = (BNFoPRODUCTION *)choiceNode; switch(choiceNode->type) { case ProdName: printf("ProdName\n"); break; case Production: printf("Production\n"); break; case Literal: printf("Literal\n"); break; case Regexp: printf("RegExp\n"); break; case Term: printf("Term\n"); break; case Choice: printf("Choice\n"); break; case Command: printf("Command\n"); break; case LineStart: printf("LineStart\n"); break; default: printf("%s unknown\n" ,marg); break; } Level++; if(choiceNode->type == Production) { production = (BNFoPRODUCTION *)choiceNode; choice = (BNFoCHOICE *)production->node; BnfPrintTree(choice); } else if(choiceNode->type == Choice ) { termList = choiceNode->termList; while( *termList != NULL) { printf("%s======= Choice =======\n", marg); node = *termList; choice = (BNFoCHOICE *)node; BnfPrintTree(choice); termList++; } } else if(choiceNode->type == Term) { term = (BNFoTERM *)choiceNode; report = term->factorList; while( report->node != NULL) { node = report->node; counter = report->counter; switch(counter) { case ZeroOrOne: printf("%s======= ZeroOrOne =======\n", marg); break; case One: printf("%s======= One =======\n", marg); break; case ZeroOrMore: printf("%s======= ZeroOrMore =======\n", marg); break; } choice = (BNFoCHOICE *)node; BnfPrintTree(choice); report++; } } Level--; } /*****************************************************************************/ /* for 2nd bootstrapping of icarus */ /*****************************************************************************/ /******************* making syntax tree **********************************/ static BNFoPRODUCTION *currProduction; INT4 IopBody (VARo *var); BNFoNODE *IopNodeProg_ (Int4 runTime, BNFoNODE *node, VARo *nodeProg) { VARo *prog[3], **stmnt[3], **tmp; INT4 count[3], k, time; if (runTime) IargGetArgs ("node|prog", &node, &nodeProg); /* ** find out how many statements for each execution time ** commands can have multiple execution times! */ count[0]=count[1]=count[2]=0; if (nodeProg) for (tmp = VarGetArgs (nodeProg); *tmp; tmp++){ time = VarGetCode (*tmp); if (time & IARGxINIT) count[0]++; if (time & IARGxPRE) count[1]++; if (time & IARGxPOST || !time) count[2]++; } if (ParGetBool ("icaIsDebug")) { count[1]++; count[2]++; } /* allocate program vars and argument lists */ for (k=0; k < 3; k++) if (count[k]) { prog[k] = VarNew (); stmnt[k] = (VARo **) malloc ((count[k] + 1) * sizeof (void *)); VarSetArgs (prog[k], stmnt[k]); VarSetReadInt (prog[k], (FUNC)IopBody); } else prog[k] = NULL; count[0]=count[1]=count[2]=0; if (ParGetBool ("icaIsDebug")) { stmnt[1][count[1]++] = DbgGetStatement (IARGxPRE); stmnt[2][count[2]++] = DbgGetStatement (IARGxPOST); } /* distribute statements into time specific programs */ if (nodeProg) for (tmp = VarGetArgs (nodeProg); *tmp; tmp++){ time = VarGetCode (*tmp); if (time & IARGxINIT) stmnt[0][count[0]++] = *tmp; if (time & IARGxPRE) stmnt[1][count[1]++] = *tmp; if (time & IARGxPOST || !time) stmnt[2][count[2]++] = *tmp; } for (k=0; k < 3; k++) if (count[k]) stmnt[k][count[k]] = NULL; for (k=0; k < 3; k++) node->exec[k] = prog[k]; if (runTime) IcaReturn ("node", node); else return node; } BNFoNODE *IopProd_ (Int4 runTime) { BNFoPRODUCTION *prod; BNFoNODE *node; prod = (BNFoPRODUCTION *) calloc (sizeof(BNFoPRODUCTION), 1); prod->type = Production; prod->parse = BnfParseProduction; if (runTime) IcaReturn ("node", prod); else return (BNFoNODE*)prod; } VARo *IopEndProd_ (Int4 runTime, BNFoNODE *node, BNFoPRODUCTION *prod) { VARo *var; if (runTime) IargGetArgs ("node|prod", &node, &prod); prod->node = node; var = VarNew (); VarSetObject ("production", var, prod); if (runTime) IcaReturn ("var", var); else return var; } BNFoNODE *IopExpr_ (Int4 runTime) { static VARoStack *stack=NULL; VARo *tmp; BNFoCHOICE *node; INT4 k, l; /* init tmp stack and copy from userstack until NULLNODE is found */ stack = VarStackInit (stack); for (k=0; (tmp = VarPop2 (&icaStack2[3])); k++){ if (((BNFoNODE *) VarGetObject (NULL, VarFreeze(tmp)))->type == NullNode) break; VarPush2 (stack, tmp); } if (k == 1) /* no use creating choice with one node only */ node = (BNFoCHOICE *) VarGetObject (NULL, VarFreeze(VarPop2 (stack))); else { /* create a 'term' node */ node = (BNFoCHOICE *) calloc (sizeof(BNFoCHOICE), 1); node->type = Choice; node->parse = BnfParseChoice; node->termList = malloc ((k+1) * sizeof (BNFoNODE *)); /* pop nodes and assign them to the factor list */ for (l=0; k && (tmp = VarPop2 (stack)); k-- , l++){ node->termList[l] = (BNFoNODE *) VarGetObject (NULL, VarFreeze(tmp)); } node->termList[l] = NULL; } if (runTime) IcaReturn ("node", node); else return (BNFoNODE*)node; } BNFoNODE *IopTerm_ (Int4 runTime) { static VARoStack *stack=NULL; VARo *tmp; BNFoTERM *node; INT4 k, l; /* init tmp stack and copy from userstack until NULLNODE is found */ stack = VarStackInit (stack); for (k=0; (tmp = VarPop2 (&icaStack2[3])); k++){ if (((BNFoNODE *) VarGetObject (NULL, VarFreeze (tmp)))->type == NullNode) break; node = VarGetObject (NULL, VarFreeze(tmp)); VarPush2 (stack, tmp); } if (k == 100000 && !node->counter) /* no use creating term with one node only */ node = (BNFoTERM *) VarGetObject (NULL, VarFreeze(VarPop2 (stack))); else { /* create a 'term' node */ node = (BNFoTERM *) calloc (sizeof(BNFoTERM), 1); node->type = Term; node->parse = BnfParseTerm; node->factorList = malloc ((k+1) * sizeof (BNFoREPORT)); /* pop nodes and assign them to the factor list */ for (l=0; k && (tmp = VarPop2 (stack)); k-- , l++){ tmp->isTypeEval = 1; node->factorList[l].node = (BNFoNODE *) VarGetObject (NULL, VarFreeze(tmp)); node->factorList[l].counter = node->factorList[l].node->counter; } node->factorList[l].node = NULL; } if (runTime) IcaReturn ("node", node); else return (BNFoNODE*)node; } BNFoNODE *IopNullNode_ (Int4 runTime) { static BNFoNODE node; node.type = NullNode; if (runTime) IcaReturn ("node", &node); else return &node; } BNFoNODE *IopProdName_ (Int4 runTime, STRv name, Int4 isLookAhead) { BNFoPRODNAME *node; if (runTime) IargGetArgs ("name|lookahead", &name, &isLookAhead); node = (BNFoPRODNAME *) calloc (sizeof (BNFoPRODNAME), 1); node->name = (char *) malloc (strlen (_Str(name)) + 1); strcpy (node->name, _Str(name)); node->type = ProdName; node->parse= BnfParseProdName; node->optional = isLookAhead; if (runTime) IcaReturn ("node", node); else return (BNFoNODE*)node; } BNFoNODE *IopRegexp_ (Int4 runTime, STRv reStr) { BNFoREGEXP *node; if (runTime) IargGetArgs ("reStr", &reStr); StrDecode (&reStr); node = (BNFoREGEXP *) calloc (sizeof(BNFoREGEXP), 1); node->name = (char *) malloc (strlen (_Str(reStr))+2); node->name[0] = '^'; strcpy (node->name + 1, _Str(reStr)); node->type = Regexp; node->parse = BnfParseRegExp; if ((node->expression = RegComp (node->name)) == NULL) _ErrExit2 (e__regerror, node->name); if (runTime) IcaReturn ("node", node); else return (BNFoNODE*)node; } BNFoNODE *IopLiteral_ (Int4 runTime, STRv litStr) { BNFoLITERAL *node; if (runTime) IargGetArgs ("name", &litStr); StrDecode (&litStr); node = (BNFoLITERAL *) calloc (sizeof (BNFoLITERAL), 1); node->name = (char *) malloc (strlen (_Str(litStr))+1); strcpy (node->name, _Str(litStr)); node->type = Literal; node->parse = BnfParseLiteral; if (runTime) IcaReturn ("node", node); else return (BNFoNODE*)node; } BNFoNODE *IopCommand_ (Int4 runTime) { BNFoNODE *node; node = (BNFoNODE *) calloc (sizeof (BNFoNODE), 1); node->type = Command; node->parse = BnfParseCommand; if (runTime) IcaReturn ("node", node); else return node; } BNFoNODE *IopInputEnd_ (Int4 runTime) { BNFoNODE *node; node = (BNFoNODE *) calloc (sizeof (BNFoNODE), 1); node->type = EndOfInput; node->parse = BnfParseInputEnd; if (runTime) IcaReturn ("node", node); else return node; } BNFoNODE *IopMakeOpt_ (Int4 runTime, BNFoNODE *node, STRv type) { if (runTime) IargGetArgs ("node|t", &node, &type); switch (_Str(type)[2]) { case 'c': /* once */ node->counter = ZeroOrOne; break; case 'l': /* multi */ node->counter = ZeroOrMore; break; case 'e': /* onemore */ node->counter = OneOrMore; break; default: _ErrExit2 (e__unknownoption, _Str(type)); } if (runTime) IcaReturn ("node", node); else return node; } void BnfPrintNode (BNFoNODE *node, INT4 level); void BnfTreeTraverse (BNFoNODE *node, INT4 (*func)(BNFoNODE*, INT4 level), INT4 level) { BNFoPRODUCTION *production; BNFoNODE *nextNode, **term; INT4 k; (*func)((BNFoNODE *) node, level); if (node->type == Choice ) for (term=((BNFoCHOICE *)node)->termList; (nextNode = *term); term++) BnfTreeTraverse (nextNode, func, level+1); else if (node->type == Term) for (k=0; (nextNode = ((BNFoTERM *)node)->factorList[k].node); k++) BnfTreeTraverse (nextNode, func, level+1); else if(node->type == Production) BnfTreeTraverse (((BNFoPRODUCTION *)node)->node, func, level+1); } void BnfLinkProdName (BNFoNODE *node, INT4 level) { BNFoPRODNAME *prodName; Job->currNode = node; /* sets the context for the node programs */ switch (node->type) { case ProdName: prodName = (BNFoPRODNAME *) node; if (!(prodName->production = BnfGetProduction (Syntax, prodName->name, 0))) _ErrMsg3 (e__objectunknown, "production", prodName->name); _BnfExecInit (node) break; case Production: case Literal: case Regexp: case Command: _BnfExecInit (node) break; } } void BnfInitRules (ICAoSYNTAX *syntax, INT4 doPrintTree) { VARo *var; BNFoPRODUCTION *prod; Int4 c; Syntax = syntax; for (c=0; (var = AnyNextInList (syntax->prod, &c)); ) { prod = VarGetObject (NULL, var); prod->name = VarGetName (var); if (doPrintTree) BnfTreeTraverse ((BNFoNODE *) prod, (FUNC)BnfPrintNode, 1); BnfTreeTraverse ((BNFoNODE *) prod, (FUNC)BnfLinkProdName, 1); BnfPruneTree (((BNFoNODE **) &prod), 1); } for (c=0; (var = AnyNextInList (syntax->prod, &c)); ) { prod = VarGetObject (NULL, var); BnfPruneTree (&prod->node, 2); } } INT4 IopParse (Int4 runTime, VARo *prod, STRv str, STRv startName, STRv fileName, Int4 doPrintTree, STRv skip, STRv cmnt) { static ICAoSYNTAX syntax; ICAoSYNTAX *tmp; FILEo *file; BNFoPRODUCTION *start; ICAoJOB *job=NULL; if (runTime) IargGetArgs ("prod|string|start|fileName|tree|skip|comment", &prod, &str, &startName, &fileName, &doPrintTree, &skip, &cmnt); if (fileName) { file = FileNew (_Str(fileName)); if (!FileOpen (file)) _ErrExit2 (e__filnotok, _Str (fileName)); } else file = NULL; if (prod) { memset (&syntax, 0, sizeof (ICAoSYNTAX)); syntax.ign = skip ? _Str (skip) : ""; syntax.ignAlt = ""; syntax.cmnt = cmnt ? _Str (cmnt) : ""; syntax.commandSyntax = (ICAoSYNTAX *) LibObjByName ("syntax", "icarus"); syntax.prod = prod; BnfInitRules (&syntax, doPrintTree); tmp = &syntax; } else tmp = Job->syntax; job = IcaCreateJob (tmp); /* retain variable scope of calling context */ job->scope = Job->scope; job->fileName = IcaGetCurrFileName ("progFlag"); if (str) IcaJobSetString (job, _Str(str)); else if (file) IcaJobSetFile (job, file); else _ErrExit2 (e__error, "IopParse"); if (startName) IcaDoJob (job, _Str(startName)); else _ErrExit2 (e__error, "IopParse"); job->scope = NULL; /* scope was 'borrowed' from parent job */ IcaJobDestroy (&job); StrDel (str); StrDel (startName); StrDel (fileName); StrDel (skip); StrDel (cmnt); } char *BnfNodeString (BNFoNODE *node) { static STRv s=NULL; if (!s) s = StrNew (); else StrClear (&s); switch(node->type) { case ProdName: StrPrintf (&s, "%-10s %s", "ProdName", node->name); break; case Production: StrPrintf (&s, "%-10s %s", "Prod", node->name); break; case Literal: StrPrintf (&s, "%-10s '%s'", "Lit", node->name); break; case Regexp: StrPrintf (&s, "%-10s /%s/", "Regexp", node->name); break; case Term: StrPrintf (&s, "%-10s", "Term"); break; case Choice: StrPrintf (&s, "%-10s", "Choice"); break; case Command: StrPrintf (&s, "%-10s", "Action"); break; default: StrPrintf (&s, "%-10s", "Unknown"); break; } return _Str (StrEncode (&s)); } void IopTree () { printf ("====================================\n"); BnfTreeTraverse ((BNFoNODE *) Job->currNode, (FUNC)BnfPrintNode, 1); printf ("====================================\n"); } /******************* making syntax tree - END ********************************/ INT4 BnfSetOpFunctions () { IcaSetFunction("IopProd_", (Func)IopProd_); IcaSetFunction("IopEndProd_", (Func)IopEndProd_); IcaSetFunction("IopExpr_", (Func)IopExpr_); IcaSetFunction("IopTerm_", (Func)IopTerm_); IcaSetFunction("IopNullNode_", (Func)IopNullNode_); IcaSetFunction("IopRegexp_", (Func)IopRegexp_); IcaSetFunction("IopProdName_", (Func)IopProdName_); IcaSetFunction("IopLiteral_", (Func)IopLiteral_); IcaSetFunction("IopCommand_", (Func)IopCommand_); IcaSetFunction("IopInputEnd_", (Func)IopInputEnd_); IcaSetFunction("IopMakeOpt_", (Func)IopMakeOpt_); IcaSetFunction("IopNodeProg_", (Func)IopNodeProg_); IcaSetFunction("IopParse", (Func)IopParse); IcaSetFunction("IopTree", (Func)IopTree); } IopNullNode_); IcaSetFunction("IopRegexp_", (Func)IopRegexp_); IcaSetFunction("IopProdName_", (Func)IopProdName_); IcaSetFunction("IopLiteral_", (Func)IopLiteral_); IcaSetFunction("IopCommand_srs/src/icabnf.h ** ** $RCSfile: icabnf.h,v $ ** $Revision: 1.7 $ ** $Date: 1996/11/20 16:36:04 $ ** $Author: etzold $ ** ** $Locker: $ ** $State: Exp $ ** ** ** Copyright by Thure Etzold ** ** Author: Anatoly Ulyanov ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387451 ** Email: ulyanov@embl-heidelberg.de ** */ enum repeat {One, ZeroOrMore, ZeroOrOne, OneOrMore}; enum tokCode {BNFxNAM=1, BNFxCOM, BNFxLSTART, BNFxACT, BNFxLIT, BNFxREG, BNFxEQUAL='=', BNFxEOT='.', BNFxEOS=';'}; enum classtype {Production, ProdName, Literal, Regexp, Term, Choice, Command, LineStart, EndOfInput, ProdLoop, NullNode}; enum BNFeClass {BNFxProduction, BNFxProdName, BNFxLiteral, BNFxRegexp, BNFxTerm, BNFxChoice, BNFxCommand, BNFxLineStart, BNFxEndOfInput, BNFxProdLoop, BNFxNodeTypesN}; enum BNFeTime {BNFxBUILDTIME=1, BNFxPREPARSE=2, BNFxPOSTPARSE=4}; #define BNFxNOACTION 0 /* all action is turned off */ #define BNFxACTION 8 /* an action is associated with token */ #define BNFxNOT 16 /* match inversion */ #define BNFxNOSKIP 32 /* do not skip whitespaces till next token */ #define BNFxNOCASE 64 /* disregard case */ #define BNFxUNIQ 128 /* token must be uniq */ #define BNFxPROBE 256 /* like NOT but assertive */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** MACROs for common elements of structures */ #define BASECLASS \ char *name; /* name, literal, regexp ... */ \ enum classtype type; /* Production Regexp Term Choice ... */ \ char dbgBreak; /* for the debugger */ \ enum repeat counter; /* loop counter(), {}, [] or {} */ \ INT4 (*parse)() /* method to parse */ \ #define BASEACTION \ INT4 action; /* action mask */ \ struct TOKoLIST *rdTokList; /* toklist to be read */ \ struct TOKoLIST *wrtTokList; /* toklist where to write */ \ struct PROGo *prog; /* program attached to node */ \ struct VARo *exec[3] /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** definition of main classes */ typedef struct BNFoNODE { BASECLASS; BASEACTION; } BNFoNODE, BNFoLITERAL; typedef struct BNFoPRODUCTION { BASECLASS; BASEACTION; struct BNFoNODE *node; struct TASKoLINKS *taskLinks; Int4 *inCode; Int4 inCodeN; Int4 inCodeAllocN; } BNFoPRODUCTION; typedef struct BNFoPRODNAME { BASECLASS; BASEACTION; struct BNFoPRODUCTION *production; /* pointer to coresponded production */ INT4 optional; /* optinal `?' operation TRUE/FALSE*/ } BNFoPRODNAME; typedef struct BNFoREGEXP { BASECLASS; BASEACTION; struct regexp *expression; } BNFoREGEXP; typedef struct BNFoTERM { BASECLASS; struct BNFoREPORT *factorList; } BNFoTERM; typedef struct BNFoCHOICE { BASECLASS; struct BNFoNODE **termList; } BNFoCHOICE; typedef struct BNFoREPORT { enum repeat counter; /* loop counter(), {}, [] or {} */ struct BNFoNODE *node; } BNFoREPORT; /* module prototypes ***************************************/ void BnfBuild(ICAoSYNTAX *); INT4 BnfParseProduction(BNFoPRODUCTION *); BNFoPRODUCTION *BnfGetProduction (ICAoSYNTAX *syntax, char *, enum classtype); char *BnfNodeString (struct BNFoNODE *node); #define _BnfExecInit(node) \ if ((node)->exec[0]) {\ Job->time=BNFxBUILDTIME; VarExec ((node)->exec[0]);} #define _BnfExecPre(node) \ if (Job->isDebug) IopDebug (BNFxPREPARSE);\ if ((node)->exec[1]) \ {Job->time=BNFxPREPARSE; VarExec ((node)->exec[1]);} #define _BnfExecPost(node) \ if (Job->isDebug) IopDebug (BNFxPOSTPARSE);\ if ((node)->exec[2]) \ {Job->time=BNFxPOSTPARSE; VarExec ((node)->exec[2]);} ; char *BnfNodeString (struct BNFoNODE *node); #define _BnfExecInit(node) \ if (srs/src/icadebug.c #include #include #include "message.h" #include "sm.h" #include "dict.h" #include "strv.h" #include "termio.h" #include "variable.h" #include "icarus.h" #include "icabnf.h" #include "icaarg.h" #define _SRS #include SRSINCLUDE typedef struct IDBGoStatus { ICAoJOB *job; struct DBGoBreak *breaks; Int4 breaksN; Int4 breaksAllocN; Int4 isNext; Int4 isBreak; Int4 isContinue; Int4 time; } DBGoStatus; extern ICAoJOB *Job; static DBGoStatus dbgStatusBuff; static DBGoStatus *dbgStatus=&dbgStatusBuff; void DbgSetNext () { dbgStatus->isBreak = 1; dbgStatus->isContinue = 1; } void DbgSetContinue () { dbgStatus->isBreak = 0; dbgStatus->isContinue = 1; } Int4 DbgIsBreak (DBGoStatus *dbgStatus) { if (dbgStatus->isBreak) { dbgStatus->isBreak = 0; return 1; } else if (dbgStatus->time & dbgStatus->job->currNode->dbgBreak) return 1; else return 0; } Int4 DbgIsContinue (DBGoStatus *dbgStatus) { if (dbgStatus->isContinue) { dbgStatus->isContinue = 0; return 1; } else return 0; } static Int4 DbgIopStatement (VARo *var) { static TERMvLine led=NULL; VARo **arg=VarGetArgs (var); STRv ln; char prompt[500]; Int4 time; if (!led) led = TermNewLineEditor (); time = VarGetInt (arg[0]); dbgStatus->job = Job; dbgStatus->time = time; if (DbgIsBreak (dbgStatus)) { while (!DbgIsContinue (dbgStatus)) { sprintf (prompt, "[%s %s]> ", time == IARGxPRE ? "-" : "+", BnfNodeString (Job->currNode)); ln = TermLineEdit (led, prompt); IcaEvalInJob (_Str (ln), Job); } } } VARo *DbgGetStatement (Int4 time) { VARo **args, *stmnt = VarNew (), *val; /* one argument with execution time */ args = (VARo **) malloc (2*sizeof (void *)); val = VarNew (); VarSetInt (val, time); args[0] = val; args[1] = NULL; VarSetArgs (stmnt, args); VarSetCode (stmnt, IARGxCALL | IARGxPOST); VarSetReadInt (stmnt, (Func)DbgIopStatement); return stmnt; } Bnfsrs/src/icadebug.h rmLineEdit (led, prompt); IcaEvalInJob (_Str (ln), Job); } } } VARo *DbgGetStatement (Int4 time) { VARo **args, *stmnt = VarNew (), *val; /* one argument with execution time */ args = (VARo **) malloc (2*sizeof (void *)); val = VarNew (); VarSetInt (val, time); args[0] = val; args[1] = NULL; VarSetArgs (stmnt, args); VarSetCode (stmnt, IARGxCALL | IARG@ VarSetReadInt (stmnt, (Func)DbgIopStatement); returnX Bnfsrs/src/icainit.c #include #include #include #include #include #define DECLARE_ONLY #define DEFIGNORE " \n\t" #define DEFCOMMENT "^#[^\n]*\n" #include "srs.h" #include "regexp.h" static VARoSCOPE *scope = NULL; extern ICAoJOB *Job; extern ICAoSYNTAX *Syntax; INT4 BnfParseProduction(BNFoPRODUCTION *); INT4 BnfParseProdLoop(BNFoPRODUCTION *); INT4 BnfParseRegExp(BNFoREGEXP *); INT4 BnfParseLiteral(BNFoLITERAL *); INT4 BnfParseCommand(BNFoNODE *); INT4 BnfParseLineStart(BNFoNODE *); INT4 BnfParseInputEnd(BNFoNODE *); INT4 BnfParseTerm(BNFoTERM *); INT4 BnfParseChoice(BNFoCHOICE *); INT4 BnfParseProdName(BNFoPRODNAME *); void BnfPruneTree (BNFoNODE **, Int4 passN); VARo *IopPop_(INT4, INT4); VARo *IopBody_ (Int4 runTime); STRv IopInterpStr_(VARo *var, STRv str, ...); STRv IopInterpStr2(VARo *var, STRv str, ...); STRv IopSubMatch(INT4, INT4); STRv IopCurrToken(); /* Declaration of C variables used by some translated functions */ VARo *a, *b, *c, *d, *e, *u, *i, *str; Int4 opt; void IcarusBody1 () { IopOut (0 , NULL ) ; } void IcarusBody2 () { IopOut (0 , NULL ) ; IopFip (0 , 1 ) ; IopPush_ (0 , IopOpnd_ (0 , NULL , StrCpyS ( "mark" ) ) , 0 ) ; } void IcarusBody3 () { IopProg_ (0 ) ; } void IcarusBody4 () { TemplIcaAddLabel (0 , IopSubMatch (0 , 1 ) , IopFip (0 , 0 ) ) ; } void IcarusBody5 () { IopNoskip (0 ) ; } void IcarusBody6 () { IopProg_ (0 ) ; } void IcarusBody7 () { IopPush_ (0 , IopOpnd_ (0 , IopCurrToken (0 ) , StrCpyS ( "string" ) ) , 1 ) ; } void IcarusBody8 () { b = IopPop_ (0 , 0 ) ; IopPush_ (0 , IopBinop_ (0 , VarGetStrv ( IopPop_ (0 , 1 ) ) , IopPop_ (0 , 0 ) , b ) , 0 ) ; } void IcarusBody9 () { IopOut (0 , NULL ) ; } void IcarusBody10 () { IopOut (0 , NULL ) ; IopPush_ (0 , IopOpnd_ (0 , NULL , StrCpyS ( "mark" ) ) , 0 ) ; } void IcarusBody11 () { IopProg_ (0 ) ; } void IcarusBody12 () { IopPush_ (0 , IopOpnd_ (0 , NULL , StrCpyS ( "mark" ) ) , 0 ) ; } void IcarusBody13 () { IopPush_ (0 , IopBody_ (0 ) , 0 ) ; } void IcarusBody14 () { IopPush_ (0 , IopOpnd_ (0 , IopSubMatch (0 , 1 ) , StrCpyS ( "string" ) ) , 5 ) ; } void IcarusBody15 () { IopPush_ (0 , IopAssoc_ (0 , IopPop_ (0 , 0 ) , IopPop_ (0 , 5 ) ) , 0 ) ; } void IcarusBody16 () { IopPush_ (0 , IopSetWrite_ (0 , IopPop_ (0 , 0 ) ) , 0 ) ; } void IcarusBody17 () { b = IopPop_ (0 , 0 ) ; IopPush_ (0 , IopBinop_ (0 , VarGetStrv ( IopPop_ (0 , 1 ) ) , IopPop_ (0 , 0 ) , b ) , 0 ) ; } void IcarusBody18 () { IopNot (0 ) ; } void IcarusBody19 () { b = IopPop_ (0 , 0 ) ; IopPush_ (0 , IopBinop_ (0 , VarGetStrv ( IopPop_ (0 , 1 ) ) , IopPop_ (0 , 0 ) , b ) , 0 ) ; } void IcarusBody20 () { b = IopPop_ (0 , 0 ) ; IopPush_ (0 , IopBinop_ (0 , VarGetStrv ( IopPop_ (0 , 1 ) ) , IopPop_ (0 , 0 ) , b ) , 0 ) ; } void IcarusBody21 () { IopPush_ (0 , IopOpnd_ (0 , NULL , StrCpyS ( "null" ) ) , 0 ) ; } void IcarusBody22 () { IopPush_ (0 , IopOpnd_ (0 , IopCurrToken (0 ) , StrCpyS ( "str" ) ) , 1 ) ; } void IcarusBody23 () { IopPush_ (0 , IopOpnd_ (0 , IopCurrToken (0 ) , StrCpyS ( "str" ) ) , 1 ) ; } void IcarusBody24 () { IopPush_ (0 , IopOpnd_ (0 , IopCurrToken (0 ) , StrCpyS ( "str" ) ) , 1 ) ; } void IcarusBody25 () { IopPush_ (0 , IopOpnd_ (0 , IopCurrToken (0 ) , StrCpyS ( "str" ) ) , 1 ) ; } void IcarusBody26 () { IopPush_ (0 , IopOpnd_ (0 , IopCurrToken (0 ) , StrCpyS ( "str" ) ) , 1 ) ; } void IcarusBody27 () { IopPush_ (0 , IopOpnd_ (0 , IopCurrToken (0 ) , StrCpyS ( "str" ) ) , 1 ) ; } void IcarusBody28 () { IopPush_ (0 , IopOpnd_ (0 , IopCurrToken (0 ) , StrCpyS ( "str" ) ) , 1 ) ; } void IcarusBody29 () { IopPush_ (0 , IopOpnd_ (0 , NULL , StrCpyS ( "mark" ) ) , 0 ) ; } void IcarusBody30 () { IopPush_ (0 , IopList_ (0 ) , 0 ) ; } void IcarusBody31 () { IopPush_ (0 , IopAssoc_ (0 , IopPop_ (0 , 0 ) , IopPop_ (0 , 5 ) ) , 0 ) ; } void IcarusBody32 () { IopPush_ (0 , IopOpnd_ (0 , IopSubMatch (0 , 1 ) , StrCpyS ( "string" ) ) , 5 ) ; } void IcarusBody33 () { IopPush_ (0 , IopOpnd_ (0 , IopCurrToken (0 ) , StrCpyS ( "real" ) ) , 0 ) ; } void IcarusBody34 () { IopPush_ (0 , IopOpnd_ (0 , IopCurrToken (0 ) , StrCpyS ( "int" ) ) , 0 ) ; } void IcarusBody35 () { IopPush_ (0 , IopOpnd_ (0 , IopCurrToken (0 ) , StrCpyS ( "str" ) ) , 0 ) ; } void IcarusBody36 () { IopSetSkip (0 , 0 , NULL ) ; str = VarSetStrv (VarTemp (), StrCpyS ("") ) ; } void IcarusBody37 () { IopNot (0 ) ; } void IcarusBody38 () { IopStrApp (0 , str , IopCurrToken (0 ) ) ; } void IcarusBody39 () { IopStrApp (0 , str , IopSubMatch (0 , 1 ) ) ; IopPush_ (0 , IopOpnd_ (0 , VarGetStrv ( str ) , StrCpyS ( "lambda" ) ) , 0 ) ; IopSetSkip (0 , 1 , NULL ) ; } void IcarusBody40 () { IopPush_ (0 , IopOpnd_ (0 , IopCurrToken (0 ) , StrCpyS ( "ident" ) ) , 0 ) ; } void IcarusBody41 () { IopPush_ (0 , IopSelect_ (0 , IopOpnd_ (0 , IopCurrToken (0 ) , StrCpyS ( "str" ) ) , NULL , IopPop_ (0 , 0 ) ) , 0 ) ; } void IcarusBody42 () { a = IopPop_ (0 , 0 ) ; IopPush_ (0 , IopSelect_ (0 , a , NULL , IopPop_ (0 , 0 ) ) , 0 ) ; } void IcarusBody43 () { a = IopPop_ (0 , 0 ) ; IopPush_ (0 , IopSelect_ (0 , a , NULL , IopPop_ (0 , 0 ) ) , 0 ) ; } void IcarusBody44 () { a = IopPop_ (0 , 0 ) ; IopPush_ (0 , IopSelect_ (0 , a , NULL , IopPop_ (0 , 0 ) ) , 0 ) ; } void IcarusBody45 () { i = IopPop_ (0 , 0 ) ; IopPush_ (0 , IopSelect_ (0 , NULL , i , IopPop_ (0 , 0 ) ) , 0 ) ; } void IcarusBody46 () { IopPush_ (0 , IopFunc_ (0 ) , 0 ) ; } void IcarusBody47 () { IopPush_ (0 , IopOpnd_ (0 , NULL , StrCpyS ( "mark" ) ) , 0 ) ; } void IcarusBody48 () { IopPush_ (0 , IopMakeArg_ (0 , IopPop_ (0 , 0 ) , IopOpnd_ (0 , StrCpyS (":::::") , StrCpyS ( "str" ) ) ) , 0 ) ; } void IcarusBody49 () { IopPush_ (0 , IopMakeArg_ (0 , IopPop_ (0 , 0 ) , IopOpnd_ (0 , StrCpyS (":::::") , StrCpyS ( "str" ) ) ) , 0 ) ; } void IcarusBody50 () { IopPush_ (0 , IopOpnd_ (0 , IopSubMatch (0 , 1 ) , StrCpyS ( "str" ) ) , 0 ) ; } void IcarusBody51 () { a = IopPop_ (0 , 0 ) ; IopPush_ (0 , IopMakeArg_ (0 , a , IopPop_ (0 , 0 ) ) , 0 ) ; } void IcarusBody52 () { IopPush_ (0 , IopOpnd_ (0 , IopCurrToken (0 ) , StrCpyS ( "str" ) ) , 0 ) ; } void IcarusBody53 () { opt = 1 ; } void IcarusBody54 () { opt = 0 ; } void IcarusBody55 () { IopPush_ (0 , IopRef_ (0 , VarSetStrv (VarTemp (), IopCurrToken (0 ) ) , opt ) , 0 ) ; } void IcarusBody56 () { IopPush_ (0 , IopStrMake_ (0 ) , 0 ) ; } void IcarusBody57 () { IopNot (0 ) ; } void IcarusBody58 () { IopPush_ (0 , IopOpnd_ (0 , NULL , StrCpyS ( "mark" ) ) , 0 ) ; } void IcarusBody59 () { IopSetSkip (0 , 0 , NULL ) ; } void IcarusBody60 () { IopPush_ (0 , IopOpnd_ (0 , IopCurrToken (0 ) , StrCpyS ( "str" ) ) , 0 ) ; } void IcarusBody61 () { IopSetSkip (0 , 1 , NULL ) ; } void IcarusBody62 () { IopNoskip (0 ) ; } void IcarusBody63 () { IopPush_ (0 , IopOpnd_ (0 , IopCurrToken (0 ) , StrCpyS ( "str" ) ) , 0 ) ; } void IcarusBody64 () { IopSetSkip (0 , 0 , NULL ) ; } void IcarusBody65 () { IopSetSkip (0 , 1 , NULL ) ; } void IcarusBody66 () { IopPush_ (0 , IopOpnd_ (0 , IopCurrToken (0 ) , StrCpyS ( "str" ) ) , 0 ) ; } void IcarusBody67 () { IopPush_ (0 , IopOpnd_ (0 , IopCurrToken (0 ) , StrCpyS ( "str" ) ) , 0 ) ; } void IcarusBody68 () { IopPush_ (0 , IopOpnd_ (0 , StrCpyS ("\2") , StrCpyS ( "str" ) ) , 0 ) ; } void IcarusBody69 () { IopPush_ (0 , IopOpnd_ (0 , StrCpyS ("\2") , StrCpyS ( "str" ) ) , 0 ) ; } void IcarusBody70 () { IopPush_ (0 , IopOpnd_ (0 , IopCurrToken (0 ) , StrCpyS ( "str" ) ) , 0 ) ; } void IcarusBody71 () { IopPush_ (0 , IopOpnd_ (0 , StrCpyS ("\n") , StrCpyS ( "str" ) ) , 0 ) ; } void IcarusBody72 () { IopRep (0 , VarSetStrv (VarTemp (), StrCpyS ("\2") ) ) ; } void IcarusBody73 () { IopRep (0 , VarSetStrv (VarTemp (), StrCpyS ("\2") ) ) ; } void IcarusBody74 () { IopSetSkip (0 , 1 , NULL ) ; } void IcarusBody75 () { IopSetSkip (0 , 0 , NULL ) ; } void IcarusBody76 () { IopPush_ (0 , IopOpnd_ (0 , IopSubMatch (0 , 1 ) , StrCpyS ( "ident" ) ) , 0 ) ; } void IcarusBody77 () { IopPush_ (0 , IopFile_ (0 , IopPop_ (0 , 0 ) ) , 0 ) ; } void IcarusBody78 () { IopPush_ (0 , IopPre_ (0 , IopPop_ (0 , 0 ) ) , 0 ) ; } void IcarusBody79 () { IopPush_ (0 , IopInit_ (0 , IopPop_ (0 , 0 ) ) , 0 ) ; } void IcarusBody80 () { a = IopPop_ (0 , 0 ) ; b = IopPop_ (0 , 0 ) ; IopPush_ (0 , IopForeach_ (0 , a , b , IopPop_ (0 , 0 ) ) , 0 ) ; } void IcarusBody81 () { b = IopPop_ (0 , 0 ) ; u = IopPop_ (0 , 0 ) ; c = IopPop_ (0 , 0 ) ; IopPush_ (0 , IopFor_ (0 , IopPop_ (0 , 0 ) , c , u , b ) , 0 ) ; } void IcarusBody82 () { b = IopPop_ (0 , 0 ) ; IopPush_ (0 , IopWhile_ (0 , IopPop_ (0 , 0 ) , b ) , 0 ) ; } void IcarusBody83 () { IopPush_ (0 , IopOpnd_ (0 , NULL , StrCpyS ( "mark" ) ) , 0 ) ; } void IcarusBody84 () { IopPush_ (0 , IopOpnd_ (0 , StrCpyS ("1") , StrCpyS ( "int" ) ) , 0 ) ; } void IcarusBody85 () { IopPush_ (0 , IopIf_ (0 ) , 0 ) ; } void IcarusBody86 () { IopPush_ (0 , VarSetObject (NULL, VarTemp (), (void*) IopProd_ (0 ) ) , 3 ) ; } void IcarusBody87 () { a = IopPop_ (0 , 3 ) ; IopPush_ (0 , IopEndProd_ (0 , VarGetObject (NULL, (void*) a ) , VarGetObject (NULL, (void*) IopPop_ (0 , 3 ) ) ) , 0 ) ; } void IcarusBody88 () { IopPush_ (0 , VarSetObject (NULL, VarTemp (), (void*) IopNullNode_ (0 ) ) , 3 ) ; } void IcarusBody89 () { IopPush_ (0 , VarSetObject (NULL, VarTemp (), (void*) IopExpr_ (0 ) ) , 3 ) ; } void IcarusBody90 () { IopPush_ (0 , VarSetObject (NULL, VarTemp (), (void*) IopNullNode_ (0 ) ) , 3 ) ; } void IcarusBody91 () { IopPush_ (0 , VarSetObject (NULL, VarTemp (), (void*) IopTerm_ (0 ) ) , 3 ) ; } void IcarusBody92 () { IopProbe (0 ) ; } void IcarusBody93 () { IopSetSkip (0 , 1 , NULL ) ; } void IcarusBody94 () { IopSetSkip (0 , 0 , NULL ) ; } void IcarusBody95 () { IopPush_ (0 , VarSetObject (NULL, VarTemp (), (void*) IopRegexp_ (0 , IopCurrToken (0 ) ) ) , 3 ) ; } void IcarusBody96 () { IopSetSkip (0 , 1 , NULL ) ; } void IcarusBody97 () { IopSetSkip (0 , 0 , NULL ) ; } void IcarusBody98 () { IopPush_ (0 , VarSetObject (NULL, VarTemp (), (void*) IopLiteral_ (0 , IopCurrToken (0 ) ) ) , 3 ) ; } void IcarusBody99 () { IopPush_ (0 , VarSetObject (NULL, VarTemp (), (void*) IopCommand_ (0 ) ) , 3 ) ; } void IcarusBody100 () { IopPush_ (0 , VarSetObject (NULL, VarTemp (), (void*) IopInputEnd_ (0 ) ) , 3 ) ; } void IcarusBody101 () { IopPush_ (0 , VarSetObject (NULL, VarTemp (), (void*) IopMakeOpt_ (0 , VarGetObject (NULL, (void*) IopPop_ (0 , 3 ) ) , StrCpyS ( "once" ) ) ) , 3 ) ; } void IcarusBody102 () { IopPush_ (0 , VarSetObject (NULL, VarTemp (), (void*) IopMakeOpt_ (0 , VarGetObject (NULL, (void*) IopPop_ (0 , 3 ) ) , StrCpyS ( "multi" ) ) ) , 3 ) ; } void IcarusBody103 () { IopPush_ (0 , VarSetObject (NULL, VarTemp (), (void*) IopMakeOpt_ (0 , VarGetObject (NULL, (void*) IopPop_ (0 , 3 ) ) , StrCpyS ( "onemore" ) ) ) , 3 ) ; } void IcarusBody104 () { a = 0 ; } void IcarusBody105 () { IopPush_ (0 , VarSetObject (NULL, VarTemp (), (void*) IopNodeProg_ (0 , VarGetObject (NULL, (void*) IopPop_ (0 , 3 ) ) , a ) ) , 3 ) ; } void IcarusBody106 () { IopPush_ (0 , IopOpnd_ (0 , NULL , StrCpyS ( "mark" ) ) , 0 ) ; } void IcarusBody107 () { a = IopBody_ (0 ) ; } void IcarusBody108 () { IopPush_ (0 , VarSetObject (NULL, VarTemp (), (void*) IopProdName_ (0 , IopCurrToken (0 ) , 0 ) ) , 3 ) ; } void IcarusBody109 () { IopPush_ (0 , VarSetObject (NULL, VarTemp (), (void*) IopProdName_ (0 , IopCurrToken (0 ) , 1 ) ) , 3 ) ; } #define PRODNUM 69 #define PRODNNUM 123 #define LITLNUM 69 #define REGNUM 43 #define TERMNUM 166 #define CHOINUM 30 #define COMMNUM 8 #define NAMENUM 8 char *_scopeName [] = { "rules", "b", "str", "a", "i", "opt", "u", "c" }; VARo _var [] = { { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody1}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody2}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody3}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody4}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody5}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody6}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody7}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody8}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody9}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody10}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody11}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody12}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody13}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody14}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody15}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody16}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody17}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody18}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody19}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody20}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody21}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody22}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody23}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody24}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody25}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody26}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody27}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody28}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody29}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody30}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody31}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody32}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody33}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody34}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody35}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody36}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody37}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody38}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody39}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody40}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody41}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody42}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody43}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody44}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody45}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody46}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody47}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody48}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody49}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody50}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody51}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody52}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody53}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody54}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody55}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody56}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody57}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody58}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody59}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody60}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody61}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody62}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody63}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody64}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody65}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody66}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody67}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody68}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody69}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody70}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody71}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody72}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody73}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody74}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody75}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody76}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody77}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody78}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody79}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody80}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody81}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody82}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody83}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody84}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody85}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody86}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody87}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody88}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody89}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody90}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody91}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody92}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody93}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody94}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody95}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody96}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody97}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody98}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody99}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody100}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody101}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody102}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody103}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody104}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody105}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody106}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody107}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody108}, NULL, NULL }, { NULL,1,0,1,1,0,0,0, {(Func) IcarusBody109}, NULL, NULL } }; BNFoLITERAL _lit [] = { {"=",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, &_var [6] }, {"{",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"}",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"(",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {")",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"{",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, &_var [28] }, {"}",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, &_var [29] }, {"~",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"~",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"@{",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, &_var [35] }, {".",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"(",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {")",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, &_var [41] }, {"[",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"]",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, &_var [44] }, {"$",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {":",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, &_var [46] }, {"[",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"]",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"(",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {")",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"@",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"?",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, &_var [52] }, {"\"",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, &_var [58] }, {"\"",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, &_var [60] }, {"|",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, &_var [63] }, {"\n",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, &_var [70] }, {"(",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"($",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {")",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"file",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {":",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"pre",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"init",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"foreach",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {":",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"[",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"in",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {":",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"]",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"for",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {":",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"{",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"}",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"while",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {":",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"if",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {":",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, &_var [82] }, {"elif",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {":",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"else",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, &_var [83] }, {"(",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {")",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"{",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"}",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"[",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"]",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"|",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"(",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {")",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {"/",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, &_var [93] }, {"/",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 }, {".",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, &_var [99] }, {"?",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, &_var [100] }, {"*",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, &_var [101] }, {"+",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, &_var [102] }, {"{",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, &_var [105] }, {"}",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, &_var [106] }, {"_",Literal,0,One, BnfParseLiteral, 0,0,0,0, 0, 0, 0 } }; BNFoREGEXP _reg [] = { {"^\\$([a-zA-Z0-9]+) *= *{",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, &_var [3] }, {"^ *[a-zA-Z0-9]+:| *\\|| *}",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, 0 }, {"^[^\n]*",Regexp,0,One, BnfParseRegExp, 0,0,0,0, &_var [4], 0, 0 }, {"^[^\n]*\n",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, 0 }, {"^[0-9]+\\.[0-9]+",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, 0 }, {"^[a-zA-Z0-9_]+",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, 0 }, {"^[+%-][^=]",Regexp,0,One, BnfParseRegExp, 0,0,0,0, &_var [17], 0, 0 }, {"^(&&|\\|\\|)",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, &_var [21] }, {"^(\\+=|=|-=|\\*=|/=)",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, &_var [22] }, {"^(<=|=<|>=|=>|<|>|==|!=)",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, &_var [23] }, {"^[%+-]",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, &_var [24] }, {"^(\\*|/)",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, &_var [25] }, {"^(\\+\\+|--|\\+)",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, &_var [26] }, {"^(\\+\\+|--)",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, &_var [27] }, {"^([a-zA-Z0-9_]+):",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, 0 }, {"^'(([^']+|\\\\.)*)':",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, 0 }, {"^-?[0-9]+",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, 0 }, {"^[^\n]*}@",Regexp,0,One, BnfParseRegExp, 0,0,0,0, &_var [36], 0, 0 }, {"^([^\n]*)}@",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, &_var [38] }, {"^([a-zA-Z_0-9]+) *:",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, &_var [49] }, {"^[a-zA-Z0-9_]+",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, 0 }, {"^[a-zA-Z_][a-zA-Z0-9_]*",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, &_var [51] }, {"^[^\"'|]",Regexp,0,One, BnfParseRegExp, 0,0,0,0, &_var [56], 0, &_var [57] }, {"^'",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, 0 }, {"^[^'\n]*",Regexp,0,One, BnfParseRegExp, 0,0,0,0, &_var [61], 0, &_var [62] }, {"^'",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, 0 }, {"^[^\n\\$(]+",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, &_var [65] }, {"^\\\\[^\n]",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, &_var [66] }, {"^[($]",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, &_var [69] }, {"^\\\\\n",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, 0 }, {"^[^\n\"\\$(]+",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, 0 }, {"^\\\\.",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, 0 }, {"^\\$([a-zA-Z0-9_]+)",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, &_var [75] }, {"^x[ {\n\t]",Regexp,0,One, BnfParseRegExp, 0,0,0,0, &_var [91], 0, 0 }, {"^[^/\\\n]+",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, 0 }, {"^\\\\.",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, 0 }, {"^'",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, &_var [96] }, {"^'",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, 0 }, {"^[^'\\\n]+",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, 0 }, {"^\\\\.",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, 0 }, {"^x:?",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, &_var [98] }, {"^[a-zA-Z0-9_]+",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, &_var [107] }, {"^[a-zA-Z0-9_]+",Regexp,0,One, BnfParseRegExp, 0,0,0,0, 0, 0, &_var [108] } }; BNFoTERM _term [] = { {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm }, {"TERM",Term,0, One, BnfParseTerm } }; BNFoCHOICE _choi [] = { {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice }, {"CHOI",Choice,0, One, BnfParseChoice } }; BNFoNODE _comm [] = { {"COMM",Command,0, One, BnfParseCommand, 0,0,0,0, 0, 0, &_var [10] }, {"COMM",Command,0, One, BnfParseCommand, 0,0,0,0, 0, 0, &_var [11] }, {"COMM",Command,0, One, BnfParseCommand, 0,0,0,0, 0, 0, &_var [12] }, {"COMM",Command,0, One, BnfParseCommand, 0,0,0,0, 0, 0, &_var [19] }, {"COMM",Command,0, One, BnfParseCommand, 0,0,0,0, 0, 0, &_var [20] }, {"COMM",Command,0, One, BnfParseCommand, 0,0,0,0, 0, 0, &_var [48] }, {"COMM",Command,0, One, BnfParseCommand, 0,0,0,0, 0, 0, &_var [53] }, {"COMM",Command,0, One, BnfParseCommand, 0,0,0,0, 0, 0, &_var [84] } }; BNFoPRODUCTION _prod [] = { {"scan",Production,0,One, BnfParseProduction, 0,0,0,0, &_var [0], &_var [1], &_var [2], (BNFoNODE*)&_term [0], NULL, 0, 0}, {"arr",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [4], NULL, 0, 0}, {"ln",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [6], NULL, 0, 0}, {"real",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [7], NULL, 0, 0}, {"str",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [8], NULL, 0, 0}, {"template",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, &_var [5], (BNFoNODE*)&_term [9], NULL, 0, 0}, {"prog",Production,0,One, BnfParseProduction, 0,0,0,0, &_var [8], &_var [9], 0, (BNFoNODE*)&_term [10], NULL, 0, 0}, {"body",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [11], NULL, 0, 0}, {"stmnt",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [14], NULL, 0, 0}, {"stassoc",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [24], NULL, 0, 0}, {"expr",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [25], NULL, 0, 0}, {"term1",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [27], NULL, 0, 0}, {"term2",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [31], NULL, 0, 0}, {"term3",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [35], NULL, 0, 0}, {"term4",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_choi [5], NULL, 0, 0}, {"makeop",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [39], NULL, 0, 0}, {"nullopnd",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [40], NULL, 0, 0}, {"logop",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [41], NULL, 0, 0}, {"assop",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [42], NULL, 0, 0}, {"compop",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [43], NULL, 0, 0}, {"op1",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [44], NULL, 0, 0}, {"op2",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [45], NULL, 0, 0}, {"unopleft",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [46], NULL, 0, 0}, {"unopright",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [47], NULL, 0, 0}, {"list",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [48], NULL, 0, 0}, {"assoc",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, &_var [30], (BNFoNODE*)&_term [51], NULL, 0, 0}, {"key",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_choi [8], NULL, 0, 0}, {"value",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_choi [9], NULL, 0, 0}, {"int",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [64], NULL, 0, 0}, {"lambda",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [65], NULL, 0, 0}, {"path",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [67], NULL, 0, 0}, {"ident",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [75], NULL, 0, 0}, {"args",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [76], NULL, 0, 0}, {"unnamedin",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [81], NULL, 0, 0}, {"unnamedout",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [82], NULL, 0, 0}, {"named",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [85], NULL, 0, 0}, {"argvalue",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [86], NULL, 0, 0}, {"name",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [87], NULL, 0, 0}, {"strname",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [88], NULL, 0, 0}, {"reference",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [89], NULL, 0, 0}, {"string",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, &_var [55], (BNFoNODE*)&_term [92], NULL, 0, 0}, {"sqString",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [96], NULL, 0, 0}, {"bqString",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [97], NULL, 0, 0}, {"bqLine",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [99], NULL, 0, 0}, {"dqString",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [107], NULL, 0, 0}, {"var2",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [113], NULL, 0, 0}, {"var",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [114], NULL, 0, 0}, {"file",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [115], NULL, 0, 0}, {"pre",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [116], NULL, 0, 0}, {"init",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [117], NULL, 0, 0}, {"foreach",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [118], NULL, 0, 0}, {"for",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [119], NULL, 0, 0}, {"while",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [126], NULL, 0, 0}, {"if",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [127], NULL, 0, 0}, {"cond",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_choi [23], NULL, 0, 0}, {"production",Production,0,One, BnfParseProduction, 0,0,0,0, 0, &_var [85], 0, (BNFoNODE*)&_term [134], NULL, 0, 0}, {"bnfExpr",Production,0,One, BnfParseProduction, 0,0,0,0, 0, &_var [87], &_var [88], (BNFoNODE*)&_term [135], NULL, 0, 0}, {"term",Production,0,One, BnfParseProduction, 0,0,0,0, 0, &_var [89], &_var [90], (BNFoNODE*)&_term [137], NULL, 0, 0}, {"factor",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_choi [24], NULL, 0, 0}, {"regexp",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, &_var [92], (BNFoNODE*)&_term [149], NULL, 0, 0}, {"reStr",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [150], NULL, 0, 0}, {"literal",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, &_var [95], (BNFoNODE*)&_term [153], NULL, 0, 0}, {"litStr",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [154], NULL, 0, 0}, {"command",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [157], NULL, 0, 0}, {"eoi",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [158], NULL, 0, 0}, {"occur",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_choi [29], NULL, 0, 0}, {"nodeProg",Production,0,One, BnfParseProduction, 0,0,0,0, 0, &_var [103], &_var [104], (BNFoNODE*)&_term [162], NULL, 0, 0}, {"prodName",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [164], NULL, 0, 0}, {"laProdName",Production,0,One, BnfParseProduction, 0,0,0,0, 0, 0, 0, (BNFoNODE*)&_term [165], NULL, 0, 0} }; BNFoPRODNAME _prodN [] = { {"arr",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [1]}, {"ident",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [31]}, {"ln",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [2]}, {"ln",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [2]}, {"var",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [46]}, {"list",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [7], &_prod [24]}, {"stmnt",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [8]}, {"stmnt",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [8]}, {"stmnt",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [8]}, {"if",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [53]}, {"foreach",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [50]}, {"for",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [51]}, {"while",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [52]}, {"init",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [49]}, {"pre",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [48]}, {"file",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [47]}, {"stassoc",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [9]}, {"expr",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [10]}, {"key",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [13], &_prod [26]}, {"ident",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [14], &_prod [31]}, {"term1",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [11]}, {"logop",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [17]}, {"term1",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [11]}, {"makeop",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [15]}, {"term2",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [12]}, {"compop",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [19]}, {"assop",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [15], &_prod [18]}, {"term2",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [16], &_prod [12]}, {"term3",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [13]}, {"op1",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [20]}, {"term3",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [18], &_prod [13]}, {"term4",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [14]}, {"op2",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [21]}, {"term4",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [14]}, {"makeop",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [15]}, {"expr",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [10]}, {"unopleft",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [22]}, {"value",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [27]}, {"unopright",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [23]}, {"assoc",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [25]}, {"value",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [27]}, {"key",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [31], &_prod [26]}, {"value",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [27]}, {"production",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [55]}, {"real",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [32], &_prod [3]}, {"int",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [33], &_prod [28]}, {"name",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [34], &_prod [37]}, {"string",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [40]}, {"ident",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [31]}, {"list",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [24]}, {"lambda",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [29]}, {"reference",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [39]}, {"ln",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [37], &_prod [2]}, {"name",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [39], &_prod [37]}, {"name",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [40], &_prod [37]}, {"ident",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [31]}, {"string",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [42], &_prod [40]}, {"ident",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [43], &_prod [31]}, {"expr",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [10]}, {"args",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [45], &_prod [32]}, {"path",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [30]}, {"named",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [35]}, {"unnamedin",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [33]}, {"named",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [35]}, {"unnamedout",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [34]}, {"argvalue",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [47], &_prod [36]}, {"value",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [27]}, {"expr",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [10]}, {"argvalue",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [50], &_prod [36]}, {"expr",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [10]}, {"name",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [54], &_prod [37]}, {"sqString",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [41]}, {"bqString",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [42]}, {"dqString",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [59], &_prod [44]}, {"bqLine",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [64], &_prod [43]}, {"var",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [67], &_prod [46]}, {"var2",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [68], &_prod [45]}, {"var",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [71], &_prod [46]}, {"var2",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [72], &_prod [45]}, {"path",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, &_var [73], &_var [74], &_prod [30]}, {"string",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [76], &_prod [40]}, {"body",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [77], &_prod [7]}, {"body",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [78], &_prod [7]}, {"ident",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [31]}, {"expr",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [10]}, {"body",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [79], &_prod [7]}, {"expr",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [10]}, {"nullopnd",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [16]}, {"expr",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [10]}, {"nullopnd",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [16]}, {"expr",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [10]}, {"nullopnd",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [16]}, {"body",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [80], &_prod [7]}, {"cond",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [54]}, {"body",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [81], &_prod [7]}, {"cond",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [54]}, {"body",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [7]}, {"cond",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [54]}, {"body",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [7]}, {"body",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [7]}, {"expr",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [10]}, {"expr",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [10]}, {"expr",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [10]}, {"expr",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [10]}, {"nodeProg",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [66]}, {"bnfExpr",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [86], &_prod [56]}, {"term",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [57]}, {"term",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [57]}, {"factor",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [58]}, {"factor",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [58]}, {"command",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [63]}, {"regexp",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [59]}, {"literal",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [61]}, {"eoi",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [64]}, {"prodName",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [67]}, {"laProdName",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [68]}, {"occur",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [65]}, {"nodeProg",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [66]}, {"bnfExpr",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [56]}, {"occur",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [65]}, {"reStr",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [94], &_prod [60]}, {"litStr",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, &_var [97], &_prod [62]}, {"stmnt",ProdName, 0, One, BnfParseProdName, 0,0,0,0, 0, 0, 0, &_prod [8]} }; BNFoREPORT _report[] = { { 1, (BNFoNODE *)&_choi [0] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [0] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [1] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [2] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [0] }, { 0, (BNFoNODE *)&_prodN [3] }, { 1, (BNFoNODE *)&_term [5] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [1] }, { 0, (BNFoNODE *)&_reg [2] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [3] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [4] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [5] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [4] }, { 0, (BNFoNODE *)&_lit [0] }, { 0, (BNFoNODE *)&_prodN [5] }, { 0, NULL }, { 3, (BNFoNODE *)&_prodN [6] }, { 0, (BNFoNODE *)&_comm [0] }, { 0, NULL }, { 0, (BNFoNODE *)&_comm [1] }, { 0, (BNFoNODE *)&_choi [1] }, { 0, (BNFoNODE *)&_comm [2] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [1] }, { 1, (BNFoNODE *)&_prodN [7] }, { 0, (BNFoNODE *)&_lit [2] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [8] }, { 0, NULL }, { 0, (BNFoNODE *)&_choi [2] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [9] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [10] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [11] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [12] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [13] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [14] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [15] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [16] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [17] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [18] }, { 0, (BNFoNODE *)&_prodN [19] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [20] }, { 1, (BNFoNODE *)&_term [26] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [21] }, { 0, (BNFoNODE *)&_prodN [22] }, { 0, (BNFoNODE *)&_prodN [23] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [24] }, { 1, (BNFoNODE *)&_term [28] }, { 0, NULL }, { 0, (BNFoNODE *)&_choi [3] }, { 0, (BNFoNODE *)&_prodN [27] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [25] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [26] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [28] }, { 2, (BNFoNODE *)&_choi [4] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [6] }, { 0, NULL }, { 1, (BNFoNODE *)&_term [34] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [29] }, { 0, (BNFoNODE *)&_prodN [30] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [31] }, { 1, (BNFoNODE *)&_term [36] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [32] }, { 0, (BNFoNODE *)&_prodN [33] }, { 0, (BNFoNODE *)&_prodN [34] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [3] }, { 0, (BNFoNODE *)&_prodN [35] }, { 0, (BNFoNODE *)&_lit [4] }, { 0, NULL }, { 2, (BNFoNODE *)&_prodN [36] }, { 0, (BNFoNODE *)&_prodN [37] }, { 2, (BNFoNODE *)&_prodN [38] }, { 0, NULL }, { 0, (BNFoNODE *)&_comm [3] }, { 0, NULL }, { 0, (BNFoNODE *)&_comm [4] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [7] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [8] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [9] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [10] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [11] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [12] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [13] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [5] }, { 1, (BNFoNODE *)&_choi [6] }, { 0, (BNFoNODE *)&_lit [6] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [39] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [40] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [41] }, { 0, (BNFoNODE *)&_choi [7] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [42] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [7] }, { 0, (BNFoNODE *)&_prodN [43] }, { 0, (BNFoNODE *)&_lit [8] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [14] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [15] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [44] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [45] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [46] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [47] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [48] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [49] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [50] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [51] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [16] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [9] }, { 1, (BNFoNODE *)&_term [66] }, { 0, (BNFoNODE *)&_reg [18] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [17] }, { 0, (BNFoNODE *)&_prodN [52] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [53] }, { 1, (BNFoNODE *)&_choi [10] }, { 2, (BNFoNODE *)&_term [74] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [10] }, { 0, (BNFoNODE *)&_choi [11] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [54] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [11] }, { 0, (BNFoNODE *)&_prodN [55] }, { 0, (BNFoNODE *)&_lit [12] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [56] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [57] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [13] }, { 0, (BNFoNODE *)&_prodN [58] }, { 0, (BNFoNODE *)&_lit [14] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [59] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [15] }, { 0, (BNFoNODE *)&_prodN [60] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [16] }, { 0, (BNFoNODE *)&_choi [12] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [17] }, { 2, (BNFoNODE *)&_choi [13] }, { 1, (BNFoNODE *)&_prodN [63] }, { 0, (BNFoNODE *)&_lit [18] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [61] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [62] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [64] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [65] }, { 0, NULL }, { 0, (BNFoNODE *)&_choi [14] }, { 0, (BNFoNODE *)&_comm [5] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [66] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [19] }, { 0, (BNFoNODE *)&_prodN [67] }, { 0, (BNFoNODE *)&_lit [20] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [19] }, { 0, (BNFoNODE *)&_prodN [68] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [69] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [20] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [21] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [21] }, { 0, (BNFoNODE *)&_choi [15] }, { 0, (BNFoNODE *)&_prodN [70] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [22] }, { 0, NULL }, { 0, (BNFoNODE *)&_comm [6] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [22] }, { 0, (BNFoNODE *)&_choi [16] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [71] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [72] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [23] }, { 0, (BNFoNODE *)&_prodN [73] }, { 0, (BNFoNODE *)&_lit [24] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [23] }, { 0, (BNFoNODE *)&_reg [24] }, { 0, (BNFoNODE *)&_reg [25] }, { 0, NULL }, { 3, (BNFoNODE *)&_term [98] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [25] }, { 0, (BNFoNODE *)&_prodN [74] }, { 0, NULL }, { 1, (BNFoNODE *)&_choi [17] }, { 0, (BNFoNODE *)&_choi [18] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [26] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [27] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [75] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [76] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [28] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [29] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [26] }, { 0, NULL }, { 1, (BNFoNODE *)&_choi [19] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [30] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [31] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [77] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [78] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [27] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [28] }, { 0, (BNFoNODE *)&_prodN [79] }, { 0, (BNFoNODE *)&_lit [29] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [32] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [30] }, { 0, (BNFoNODE *)&_lit [31] }, { 0, (BNFoNODE *)&_prodN [80] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [32] }, { 0, (BNFoNODE *)&_prodN [81] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [33] }, { 0, (BNFoNODE *)&_prodN [82] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [34] }, { 0, (BNFoNODE *)&_lit [35] }, { 0, (BNFoNODE *)&_lit [36] }, { 0, (BNFoNODE *)&_prodN [83] }, { 0, (BNFoNODE *)&_lit [37] }, { 0, (BNFoNODE *)&_lit [38] }, { 0, (BNFoNODE *)&_prodN [84] }, { 0, (BNFoNODE *)&_lit [39] }, { 0, (BNFoNODE *)&_prodN [85] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [40] }, { 0, (BNFoNODE *)&_lit [41] }, { 0, (BNFoNODE *)&_lit [42] }, { 0, (BNFoNODE *)&_choi [20] }, { 0, (BNFoNODE *)&_choi [21] }, { 0, (BNFoNODE *)&_choi [22] }, { 0, (BNFoNODE *)&_lit [43] }, { 0, (BNFoNODE *)&_prodN [92] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [86] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [87] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [88] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [89] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [90] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [91] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [44] }, { 0, (BNFoNODE *)&_lit [45] }, { 0, (BNFoNODE *)&_prodN [93] }, { 0, (BNFoNODE *)&_prodN [94] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [46] }, { 0, (BNFoNODE *)&_lit [47] }, { 0, (BNFoNODE *)&_prodN [95] }, { 0, (BNFoNODE *)&_prodN [96] }, { 1, (BNFoNODE *)&_term [128] }, { 2, (BNFoNODE *)&_term [129] }, { 0, (BNFoNODE *)&_comm [7] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [48] }, { 0, (BNFoNODE *)&_lit [49] }, { 0, (BNFoNODE *)&_prodN [97] }, { 0, (BNFoNODE *)&_prodN [98] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [50] }, { 0, (BNFoNODE *)&_prodN [99] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [51] }, { 0, (BNFoNODE *)&_prodN [100] }, { 0, (BNFoNODE *)&_lit [52] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [53] }, { 0, (BNFoNODE *)&_prodN [101] }, { 0, (BNFoNODE *)&_lit [54] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [55] }, { 0, (BNFoNODE *)&_prodN [102] }, { 0, (BNFoNODE *)&_lit [56] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [103] }, { 0, NULL }, { 2, (BNFoNODE *)&_prodN [104] }, { 0, (BNFoNODE *)&_prodN [105] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [106] }, { 1, (BNFoNODE *)&_term [136] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [57] }, { 0, (BNFoNODE *)&_prodN [107] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [108] }, { 1, (BNFoNODE *)&_term [138] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [109] }, { 0, NULL }, { 0, (BNFoNODE *)&_choi [25] }, { 0, (BNFoNODE *)&_prodN [117] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [33] }, { 0, (BNFoNODE *)&_prodN [110] }, { 0, NULL }, { 0, (BNFoNODE *)&_term [142] }, { 0, NULL }, { 0, (BNFoNODE *)&_choi [26] }, { 2, (BNFoNODE *)&_prodN [116] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [111] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [112] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [113] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [114] }, { 0, NULL }, { 0, (BNFoNODE *)&_prodN [115] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [58] }, { 0, (BNFoNODE *)&_prodN [118] }, { 0, (BNFoNODE *)&_lit [59] }, { 2, (BNFoNODE *)&_prodN [119] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [60] }, { 0, (BNFoNODE *)&_prodN [120] }, { 0, (BNFoNODE *)&_lit [61] }, { 0, NULL }, { 3, (BNFoNODE *)&_choi [27] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [34] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [35] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [36] }, { 0, (BNFoNODE *)&_prodN [121] }, { 0, (BNFoNODE *)&_reg [37] }, { 0, NULL }, { 3, (BNFoNODE *)&_choi [28] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [38] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [39] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [40] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [62] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [63] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [64] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [65] }, { 0, NULL }, { 2, (BNFoNODE *)&_term [163] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [66] }, { 3, (BNFoNODE *)&_prodN [122] }, { 0, (BNFoNODE *)&_lit [67] }, { 0, NULL }, { 0, (BNFoNODE *)&_reg [41] }, { 0, NULL }, { 0, (BNFoNODE *)&_lit [68] }, { 0, (BNFoNODE *)&_reg [42] }, { 0, NULL } }; BNFoNODE *_choiceSet[] = { (BNFoNODE *)&_term [1], (BNFoNODE *)&_term [2], (BNFoNODE *)&_term [3], NULL, (BNFoNODE *)&_term [12], (BNFoNODE *)&_term [13], NULL, (BNFoNODE *)&_term [15], (BNFoNODE *)&_term [16], (BNFoNODE *)&_term [17], (BNFoNODE *)&_term [18], (BNFoNODE *)&_term [19], (BNFoNODE *)&_term [20], (BNFoNODE *)&_term [21], (BNFoNODE *)&_term [22], (BNFoNODE *)&_term [23], NULL, (BNFoNODE *)&_term [29], (BNFoNODE *)&_term [30], NULL, (BNFoNODE *)&_term [32], (BNFoNODE *)&_term [33], NULL, (BNFoNODE *)&_term [37], (BNFoNODE *)&_term [38], NULL, (BNFoNODE *)&_term [49], (BNFoNODE *)&_term [50], NULL, (BNFoNODE *)&_term [52], (BNFoNODE *)&_term [53], NULL, (BNFoNODE *)&_term [54], (BNFoNODE *)&_term [55], NULL, (BNFoNODE *)&_term [56], (BNFoNODE *)&_term [57], (BNFoNODE *)&_term [58], (BNFoNODE *)&_term [59], (BNFoNODE *)&_term [60], (BNFoNODE *)&_term [61], (BNFoNODE *)&_term [62], (BNFoNODE *)&_term [63], NULL, (BNFoNODE *)&_term [68], (BNFoNODE *)&_term [73], NULL, (BNFoNODE *)&_term [69], (BNFoNODE *)&_term [70], (BNFoNODE *)&_term [71], (BNFoNODE *)&_term [72], NULL, (BNFoNODE *)&_term [77], (BNFoNODE *)&_term [80], NULL, (BNFoNODE *)&_term [78], (BNFoNODE *)&_term [79], NULL, (BNFoNODE *)&_term [83], (BNFoNODE *)&_term [84], NULL, (BNFoNODE *)&_term [90], (BNFoNODE *)&_term [91], NULL, (BNFoNODE *)&_term [93], (BNFoNODE *)&_term [94], (BNFoNODE *)&_term [95], NULL, (BNFoNODE *)&_term [100], (BNFoNODE *)&_term [101], (BNFoNODE *)&_term [102], (BNFoNODE *)&_term [103], (BNFoNODE *)&_term [104], NULL, (BNFoNODE *)&_term [105], (BNFoNODE *)&_term [106], NULL, (BNFoNODE *)&_term [108], (BNFoNODE *)&_term [109], (BNFoNODE *)&_term [110], (BNFoNODE *)&_term [111], (BNFoNODE *)&_term [112], NULL, (BNFoNODE *)&_term [120], (BNFoNODE *)&_term [121], NULL, (BNFoNODE *)&_term [122], (BNFoNODE *)&_term [123], NULL, (BNFoNODE *)&_term [124], (BNFoNODE *)&_term [125], NULL, (BNFoNODE *)&_term [130], (BNFoNODE *)&_term [131], (BNFoNODE *)&_term [132], (BNFoNODE *)&_term [133], NULL, (BNFoNODE *)&_term [139], (BNFoNODE *)&_term [148], NULL, (BNFoNODE *)&_term [140], (BNFoNODE *)&_term [141], NULL, (BNFoNODE *)&_term [143], (BNFoNODE *)&_term [144], (BNFoNODE *)&_term [145], (BNFoNODE *)&_term [146], (BNFoNODE *)&_term [147], NULL, (BNFoNODE *)&_term [151], (BNFoNODE *)&_term [152], NULL, (BNFoNODE *)&_term [155], (BNFoNODE *)&_term [156], NULL, (BNFoNODE *)&_term [159], (BNFoNODE *)&_term [160], (BNFoNODE *)&_term [161], NULL }; ICAoSYNTAX *IcaInitSyntax(ICAoSYNTAX *syntax) { static ICAoSYNTAX syntaxStatic; static ICAoJOB job; BNFoNODE *tmp; VARo *prodList=VarNew (); INT4 i,j; if (syntax && syntax->prod) /* already initialized */ return syntax; if (!syntax) syntax = &syntaxStatic; Job = &job; Job->time = BNFxBUILDTIME; j = 0; for(i=0; icurrNode = (BNFoNODE *) &_prod[i]; _BnfExecInit (&_prod[i]); } for(i=0; icurrNode = (BNFoNODE *) &_prodN[i]; _BnfExecInit (&_prodN[i]); } #ifdef LITLNUM for(i=0; icurrNode = (BNFoNODE *) &_lit[i]; _BnfExecInit (&_lit[i]); } #endif #ifdef REGNUM for(i=0; icurrNode = (BNFoNODE *) &_reg[i]; _BnfExecInit (&_reg[i]); } #endif #ifdef COMMNUM for(i=0; icurrNode = (BNFoNODE *) &_comm[i]; _BnfExecInit (&_comm[i]); } #endif #ifdef STRTNUM for(i=0; icurrNode = (BNFoNODE *) &_strt[i]; _BnfExecInit (&_strt[i]); } #endif #ifdef EOINNUM for(i=0; icurrNode = (BNFoNODE *) &_eoin[i]; _BnfExecInit (&_eoin[i]); } #endif VarGet (&job.scope, ""); syntax->prod = prodList; syntax->ign = DEFIGNORE; if (syntax == &syntaxStatic) { syntax->cmnt = DEFCOMMENT; syntax->ignAlt = ""; } if ((syntax->cmntRe = RegComp (syntax->cmnt)) == NULL) _ErrExit2 (e__regerror, syntax->cmntRe); Syntax = syntax; for (i=0; inode, 2); } return syntax; } ob.scope, ""); syntax->prod srs/src/icaop.c char icaop_ID[] = "$Id: icaop.c,v 1.43 1997/03/18 23:28:03 srs Exp $"; /* ** $RCSfile: icaop.c,v $ ** $Revision: 1.43 $ ** $Date: 1997/03/18 23:28:03 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** Copyright by Thure Etzold ** ** Authors: Anatoly Ulyanov ** Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387451 ** Email: ulyanov@embl-heidelberg.de ** ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include /* #include #include */ #include #include "message.h" #include "regexp.h" #include "futil.h" #include "sm.h" #include "lst.h" #include "par.h" #include "strv.h" #include "listv.h" #include "variable.h" #include "toklist.h" #include "cursor.h" #include "icarus.h" #include "icabnf.h" #include "icaarg.h" #include "print.h" #include "icatask.h" #include "odd.h" #define _SRS #include SRSINCLUDE #define IOPxMARK 111 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** external and modulewide variables */ extern ICAoJOB *Job; extern VARoSCOPE *globalScope; extern ICAoSYNTAX *Syntax; static char *currObjId=NULL; VARoSTACK *icaStack[6]={NULL, NULL, NULL, NULL, NULL, NULL}; VARoSTACK *icaStack1[6]={NULL, NULL, NULL, NULL, NULL, NULL}; VARoStack icaStack2[6]; /***************** stack for variable.c **************/ VARoStack *VarStackInit (VARoStack *stack) { if (!stack) stack = calloc (1, sizeof (VARoStack)); stack->n = 0; return stack; } void VarPush2 (VARoStack *stack, VARo *var) { *(_addObj (stack->ptr, stack->n, stack->allocN, VARo*)) = var; } VARo *VarPop2 (VARoStack *stack) { return (!stack->n) ? NULL : stack->ptr[--stack->n]; } /*********** end of stack ****************/ /****** IopSystem ************************************************************* ** ** Take the string as a unix command, execute it and return result ** as a string ** ** INPUT: ** ** RETURNS: output of unix command */ INT4 IopSystem (Int4 runTime, STRv com, STRv script, STRv scriptName, STRv out, STRv error) { FILEo *file; STRv str; char *tmp, s[1000]; Int4 flag, fd; FILE *fp; str = StrNew(); if (runTime) IargGetArgs("com|script|scriptName|out|error", &com, &script, &scriptName, &out, &error); if (script) { tmp = scriptName ? _Str (scriptName) : "tmpscript"; file = FileNew (tmp); FileSetMode (file, "rwxr-xr-x"); FileOpen (FileSetWrite (file)); FileWrite (file, _Str (script), StrLen (script)); FileClose (file); if (!com) com = StrPrintf (NULL, "%s", tmp); } if (out && SmEqs (_Str (out), "stdout")) { if (error) { if (SmEqs (_Str (error), "stdout")) StrPrintf (&com, " 2>&1"); else StrPrintf (&com, " 2>%s", _Str (error)); } system (_Str (com)); } else if((fp = popen (_Str(com), "r")) != NULL) while (fgets(s, BUFSIZ, fp) != NULL) StrAppS (&str, s); IcaReturn("strv", str); return 1; } /****** IcaFunGetFip ********************************************************** ** ** Gets the current file pointer. ** ** INPUT: ** ** RETURNS: */ INT4 IcaFunGetFip () { return (INT4) FileGetFip (Job->file); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Strings Library */ INT4 IcaOpSubStr() { STRv str; Int4 start, len; IargGetArgs("str|s|l", &str, &start, &len); if(len) IcaReturn("strv", StrSub(str, start-1, len)); else IcaReturn("strv", StrRight(str, start-1)); return(TRUE); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** functions for building the icarus interpreted stacks */ #ifdef __ODD INT4 IopObject (VARo *var); INT4 IopReference (VARo *var); #endif #define _Index(x,y) ( ((x)-'a'+1) << 5) +((y)-'a'+1) VARo *IopFile_ (Int4 runTime, VARo *var) { FILEo *file; ICAoJOB *job; VARo *prog; STRv fileName; if (runTime) IargGetArgs ("file", &var); fileName = VarGetStrv (var); file = FileNew (_Str(fileName)); if (!FileOpen (file) ) _ErrExit2 (e__filnotok, _Str(fileName)); /* create new job with current job's syntax */ job = IcaCreateJob (Job->syntax); job->scope = Job->scope; IcaJobSetFile (job, file); IcaGetTokenList (job, "prog"); /* IcaJobDestroy (job);*/ Job->scope = job->scope; job->file = FileDelete (job->file); if (IcaJobIsError (job)) _ErrExit (e__icaErrorsQuit); StrDel (fileName); if (runTime) IargReturn ("var", job->prog); else return job->prog; } void IopEval (Int4 runTime, STRv prog) { if (runTime) IargGetArgs("prog", &prog); IcaEvalInJob (_Str(prog), Job); StrDel (prog); } VARo *IopRef_ (Int4 runTime, VARo *name, Int4 index) { VARo *var, *val, **args; if (runTime) IargGetArgs("name|opt", &name, &index); var = VarNew (); VarSetReadInt (var, (FUNC)IopReference); args = (VARo **) malloc (2*sizeof (void *)); VarSetArgs (var, args); val = VarNew (); VarSetInt (val, index); args[0] = val; val = VarNew (); VarSetStrv (val, VarGetStrv (name)); args[1] = val; if (runTime) IcaReturn ("var", var); else return var; } VARo *IopOpnd_ (Int4 runTime, STRv opnd, STRv type) { IARGvCOM com; FUNC function; VARo *var, *istr, **args, *func, *val; char *t; void *tmp; if (runTime) IargGetArgs("opnd|t", &opnd, &type); var = VarNew (); t = _Str (type); switch (_Index(t[0], t[1])) { case _Index('i','n'): /* int */ VarSetType (var, VARxINT); VarSetStrv (var, StrCpy(opnd)); break; case _Index('r','e'): /* real */ VarSetType (var, VARxREAL); VarSetStrv (var, StrCpy(opnd)); break; case _Index('s','t'): /* string */ VarSetType (var, VARxSTRING); VarSetStrv (var, StrCpy(opnd)); break; case _Index('l','a'): /* lambda */ VarSetType (var, VARxSTRING); /* StrEncode (&opnd);*/ VarSetStrv (var, StrCpy(opnd)); break; case _Index('n','u'): /* null */ VarSetInt (var, 0); break; case _Index('m','a'): /* mark */ VarSetInt (var, 0); VarSetCode (var, IOPxMARK); break; case _Index('i','d'): /* ident */ /* check if the name is a class name */ if (OddIsActive () && (tmp = (void *) OddGetClass (_Str(opnd)))) { OddRegisterObj ((struct SDLoOBJ *) tmp); function = IopObject; VarSetClassName (var, OddGetClassName ((struct SDLoOBJ *) tmp)); VarSetReadType (var, function); VarSetCode (var, IARGxCALL | IARGxODD); } /* or a function name */ else if ((com = IargGetCom (_Str(opnd)))) { if (com->isDirectCall) { VarSetCode (var, IARGxCALL | com->time); switch (com->returnType) { case 1: VarSetReadInt (var, com->function); break; case 2: VarSetReadStr (var, (BFUNC)com->function); break; } args = (VARo **) malloc (1*sizeof (void *)); args[0] = NULL; VarSetArgs (var, args); } else { /* generate new function if call is indirect */ VarSetObject (NULL, var, (void *) com); func = VarNew (); VarSetCode (func, IARGxINDIRECTCALL | IARGxCALL | com->time); VarSetReadType (func, IcaGetFunction ("IopExecCom")); args = (VARo **) malloc (2*sizeof (void *)); args[0] = var; args[1] = NULL; VarSetArgs (func, args); var = func; } } /* else it is a variable */ else { VARo *tmp; var = VarNew (); tmp = VarGet (&Job->scope, _Str(opnd)); VarSetAlias (var, tmp, Job->scope); } break; default: _ErrExit2 (e__unknownoption, type); } VarSetLineN (var, IcaGetCurrLineN ("input")); StrDel (opnd); if (runTime) IcaReturn ("val", var); return var; } Int4 IopGetBinOperator (char *op, VARo *a, VARo *b, Func *func) { IARGoCOM *com; char funcName[80]="IopAss"; if (!(com = IargGetCom (op))) _ErrExit3 (e__objectunknown, "Icarus function", op); if (!(*func = IcaGetFunction (com->functionName))) _ErrExit3 (e__objectunknown, "icarus function", com->functionName); return com->returnType; } VARo *IopBinop_ (Int4 runTime, STRv opName, VARo *a, VARo *b) { Func func; VARo *var, **args; Int4 type; if (runTime) IargGetArgs("op|a|b", &opName, &a, &b); var = VarNew (); VarSetLineN (var, IcaGetCurrLineN ("input")); args = (VARo **) malloc (3*sizeof (void *)); args[0] = a; args[1] = b; args[2] = NULL; VarSetArgs (var, args); switch ((type = IopGetBinOperator (_Str(opName), a, b, &func))) { case VARxINT: VarSetReadInt (var, func); break; case VARxVAR: VarSetReadType (var, func); break; default: _ErrExit2 (e__unknownoption, "type in IopBinop"); } if (runTime) IcaReturn ("var", var); else return var; } VARo *IopInit_ (Int4 runTime, VARo *body) { if (runTime) IargGetArgs("body", &body); VarSetCode (body, VarGetCode (body) | IARGxINIT); if (runTime) IcaReturn ("var", body); else return body; } VARo *IopPre_ (Int4 runTime, VARo *body) { if (runTime) IargGetArgs("body", &body); VarSetCode (body, VarGetCode (body) | IARGxPRE); if (runTime) IcaReturn ("var", body); else return body; } VARo *IopFor_ (Int4 runTime, VARo *i, VARo *c, VARo *u, VARo *b) { FUNC function; VARo *var, **args; var = VarNew (); if (runTime) IargGetArgs("i|c|u|b", &i, &c, &u, &b); if (!(function = IcaGetFunction ("IopFor"))) _ErrExit3 (e__objectunknown, "function", "IopFor"); VarSetReadInt (var, function); args = (VARo **) malloc (4*sizeof (void *)); args[0] = i; args[1] = c; args[2] = u; args[3] = b; VarSetArgs (var, args); VarSetLineN (var, IcaGetCurrLineN ("input")); if (runTime) IcaReturn ("var", var); else return var; } VARo *IopForeach_ (Int4 runTime, VARo *body, VARo *list, VARo *val) { FUNC function; VARo *var, **args; var = VarNew (); if (runTime) IargGetArgs("body|list|var", &body, &list, &val); if (!(function = IcaGetFunction ("IopForeach"))) _ErrExit3 (e__objectunknown, "function", "IopForeach"); VarSetReadInt (var, function); args = (VARo **) malloc (3*sizeof (void *)); args[0] = val; args[1] = list; args[2] = body; VarSetArgs (var, args); VarSetLineN (var, IcaGetCurrLineN ("input")); if (runTime) IcaReturn ("var", var); else return var; } VARo *IopWhile_ (Int4 runTime, VARo *b, VARo *c) { FUNC function; VARo *var, **args; var = VarNew (); if (runTime) IargGetArgs("c|b", &c, &b); if (!(function = IcaGetFunction ("IopWhile"))) _ErrExit3 (e__objectunknown, "function", "IopWhile"); VarSetReadInt (var, function); args = (VARo **) malloc (2*sizeof (void *)); args[0] = c; args[1] = b; VarSetArgs (var, args); VarSetLineN (var, IcaGetCurrLineN ("input")); if (runTime) IcaReturn ("var", var); else return var; } VARo *IopIf_ (Int4 runTime) { static VARoStack *stack=NULL; FUNC function; VARo *var, *tmp, **args; INT4 k, l; var = VarNew (); if (!(function = IcaGetFunction ("IopIf"))) _ErrExit3 (e__objectunknown, "function", "IopIf"); VarSetReadInt (var, function); /* init tmp stack and copy from userstack until NULLNODE is found */ stack = VarStackInit (stack); for (k=0; (tmp = VarPop2 (&icaStack2[0])); k++){ tmp = VarGetVar (tmp, 0); if (VarGetCode (tmp) == IOPxMARK) break; VarPush2 (stack, tmp); } /* allocate a list of pointers to the statements whose number is known now */ args = (VARo **) malloc ((k+1)*sizeof (void *)); VarSetArgs (var, args); /* pop nodes and assign them to the factor list */ for (l=0; k && (tmp = VarPop2 (stack)); k-- , l++){ args[l] = tmp; } args[l] = NULL; VarSetLineN (var, IcaGetCurrLineN ("input")); if (runTime) IcaReturn ("var", var); else return var; } VARo *IopAssoc_ (Int4 runTime, VARo *val, VARo *key) { FUNC function; char *tmp; STRv str; Int4 code; if (runTime) IargGetArgs("key|val", &key, &val); str = VarGetStrv (key); StrDecode (&str); VarSetName (val, _Str(str)); code = VarGetCode (val); if (code & (IARGxODD|IARGxCALL)) { /* name is object-id */ char *className; VarGetClassName (val); if ((className = VarGetClassName (val))) OddIdRegister (OddGetClass (VarGetClassName (val)), _Str(str)); else _ErrExit2 (e__icaUnknownClass, tmp = VarGetName (val) ? tmp : "unknown"); } if (runTime) IcaReturn ("var", val); else return val; } /* builds a list creator */ VARo *IopList_ (Int4 runTime) { static VARoStack *stack=NULL; VARo *(*function)(); VARo *var, *tmp, **args; INT4 k, l; /* init tmp stack and copy from user stack until NULLNODE is found */ stack = VarStackInit (stack); for (k=0; (tmp = VarPop2 (&icaStack2[0])); k++){ tmp = VarGetVar (tmp, 0); if (VarGetCode (tmp) == IOPxMARK) break; VarPush2 (stack, tmp); } /* make the variable that creates the list */ var = VarNew (); if (!(function = (VARo *(*)()) IcaGetFunction ("IopList"))) _ErrExit3 (e__objectunknown, "function", "IopList"); VarSetReadList (var, function); args = (VARo **) malloc ((k+1)*sizeof (void *)); VarSetArgs (var, args); /* pop list elements and assign them to the list */ for (l=0; k && (tmp = VarPop2 (stack)); k--, l++) args[l] = tmp; args[l] = NULL; if (runTime) IcaReturn ("var", var); else return var; } VARo *IopSelect_ (Int4 runTime, VARo *key, VARo *index, VARo *var) { VARo *val, **args; val = VarNew (); if (runTime) IargGetArgs("key|index|var", &key, &index, &var); args = (VARo **) malloc (2*sizeof (void *)); args[0] = var; if (key) { VarSetReadVar (val, IcaGetFunction ("IopSelectAssoc")); args[1] = key; } else if (index) { VarSetReadVar (val, IcaGetFunction ("IopSelect")); args[1] = index; } VarSetArgs (val, args); if (runTime) IcaReturn ("var", val); else return val; } ANYv IopSetWrite_ (Int4 runTime, VARo *var) { ANYv *arg=VarGetArgs (var); AnySetWrite (var); if (arg) /* set recursively write access to nested assoc selects !!!te*/ AnySetWrite (arg[0]); if (runTime) IcaReturn ("var", var); else return var; } VARo *IopMakeArg_ (Int4 runTime, VARo *val, VARo *name) { STRv str; if (runTime) IargGetArgs("val|name", &val, &name); name = VarGetVar (name, 1); str = VarGetStrv (name); VarDefName (val, _Str (str)); StrDel (str); if (runTime) IcaReturn ("opnd", val); else return val; } VARo *IopFunc_ (Int4 runTime) { static VARoStack *stack=NULL; VARo *func, *tmp, **args; INT4 k, l, code, lineN; /* init stack and copy from user stack until mark is found */ stack = VarStackInit (stack); for (k=0; (tmp = VarPop2 (&icaStack2[0])); k++){ tmp = VarGetVar (tmp, 0); if (VarGetCode (tmp) == IOPxMARK) { func = VarPop2 (&icaStack2[0]); break; } VarPush2 (stack, tmp); } if (VarIsAlias (func)) { tmp = VarNew (); lineN = VarGetLineN (func); VarSetStrvS (tmp, VarGetName (VarGetAlias (func, Job->scope))); func = VarNew (); VarSetLineN (func, lineN); args = (VARo **) malloc (2*sizeof (void *)); args[0] = tmp; args[1] = NULL; VarSetArgs (func, args); VarSetCode (func, IARGxINDIRECTCALL | IARGxCALL | IARGxPOST); VarSetReadType (func, IcaGetFunction ("IopExecCom")); } if ((VarGetCode (func)) & IARGxINDIRECTCALL) { args = VarGetArgs (func); /* has already a list with the 'com' object */ args = (VARo **) realloc (args, (k+2)*sizeof (void *)); VarSetArgs (func, args); args++; /* set it past the 'com' object */ } else { args = (VARo **) malloc ((k+1)*sizeof (void *)); VarSetArgs (func, args); } /* pop nodes and assign them to the argument list */ for (l=0; k && (tmp = VarPop2 (stack)); k-- , l++){ args[l] = tmp; } args[l] = NULL; if (runTime) IcaReturn ("var", func); else return func; } INT4 IopProg_ () { static VARoStack *stack=NULL; FUNC function; VARo *prog, *tmp, **args; INT4 k, l; /* init tmp stack and copy from user stack until end mark is found */ stack = VarStackInit (stack); for (k=0; (tmp = VarPop2 (&icaStack2[0])); k++){ tmp = VarGetVar (tmp, 0); if (VarGetCode (tmp) == IOPxMARK) break; VarPush2 (stack, tmp); } /* allocate a list of pointers to the statements whose number is known now */ if (!(function = IcaGetFunction ("IopProg"))) _ErrExit3 (e__objectunknown, "function", "IopProg"); prog = VarNew (); VarSetReadInt (prog, function); args = (VARo **) malloc ((k+2) * sizeof (VARo *)); VarSetArgs (prog, args); /* add file name of program to program variable */ args[0] = VarNew(); if (Job->file) VarSetStrvS (args[0], FileGetName (Job->file, "full")); /* pop nodes and add them to the statement list */ for (l=1; k && (tmp = VarPop2 (stack)); k--, l++) args[l] = tmp; args[l] = NULL; Job->prog = prog; return 1; } VARo *IopStrMake_ (Int4 runTime) { static VARoStack *stack=NULL; static VARoStack *varStack=NULL; STRv str, s; VARo *tmp, *var, *val, **args; char *t; INT4 strN, varN, len, l; /* init tmp stack and copy from user stack until end mark is found */ stack = VarStackInit (stack); varStack = VarStackInit (varStack); for (strN=varN=0; (tmp = VarPop2 (&icaStack2[0]));){ tmp = VarGetVar (tmp, 0); if (VarGetCode (tmp) == IOPxMARK) break; if (VarIsAlias (tmp) || VarGetCode (tmp) & IARGxCALL) { VarPush2 (varStack, tmp); varN++; } else { VarPush2 (stack, tmp); strN++; } } /* concatenate the string: '\' at end of line removes the line feed */ str = StrNew (); for (; strN && (tmp = VarPop2 (stack)); strN--) { s = VarGetStrv (tmp); len = StrLen (s); t = _Str (s); if (len >= 2 && t[len-2] == '\\' && t[len-1] == '\n') t[len-2] = '\0'; StrApp (&str, s); StrDel (s); } StrDecode (&str); var = VarNew (); VarSetStrv (var, str); /* get all variables inside string for interpretation and create new var */ if (varN) { val = var; var = VarNew (); VarSetReadStrv (var, (STRv (*)(char *)) IcaGetFunction ("IopInterpStr_")); args = (VARo **) malloc ((varN+2)*sizeof (void *)); VarSetArgs (var, args); args[0] = val; for (l=1; varN && (tmp = VarPop2 (varStack)); varN-- , l++){ args[l] = tmp; } args[l] = NULL; } if (runTime) IcaReturn ("var", var); else return var; } VARo *IopBody_ (Int4 runTime) { static VARoStack *stack=NULL; FUNC function; VARo *var, *tmp, **args; INT4 k, l; var = VarNew (); if (!(function = IcaGetFunction ("IopBody"))) _ErrExit3 (e__objectunknown, "function", "IopBody"); VarSetReadInt (var, function); /* init tmp stack and copy from userstack until NULLNODE is found */ stack = VarStackInit (stack); for (k=0; (tmp = VarPop2 (&icaStack2[0])); k++){ tmp = VarGetVar (tmp, 0); if (VarGetCode (tmp) == IOPxMARK) break; VarPush2 (stack, tmp); } /* allocate a list of pointers to the statements whose number is known now */ args = (VARo **) malloc ((k+1)*sizeof (void *)); VarSetArgs (var, args); /* pop nodes and assign them to the factor list */ for (l=0; k && (tmp = VarPop2 (stack)); k-- , l++){ args[l] = tmp; } args[l] = NULL; if (runTime) IcaReturn ("var", var); else return var; } /* functions for level 3 icarus commands */ STRv IopInterpStr_ (VARo *var, STRv str, ...) { va_list ap; VARo **arg; STRv tmp; char *s; INT4 k, i, begin; if (var) { arg=VarGetArgs (var); str = VarGetStrv (arg[0]); } else va_start (ap, str); StrBufChange (&str, 0, 0); for (s = _Str(str), i=0, k=1; s[i];) { i += strcspn (&s[i], "\2"); if (s[i] == '\0') break; else { /* replace the mark with variables content */ tmp = VarGetStrv (var ? arg[k++] : va_arg (ap, VARo*)); if (!tmp) _ErrExit (e__icaMissingString); StrSubst (&str, i, 1, tmp); i += StrLen (tmp); StrDel (tmp); s = _Str(str); } } if (!var) va_end (ap); return str; } Int4 IopExecCom (VARo *var) { extern VARo *iargRetVal; VARo **args=VarGetArgs (var); IARGvCOM com; STRv str; Int4 type; type = VarType (args[0]); if (type == VARxSTRING || type == VARxSTRV) { str = VarGetStrv (args[0]); if (!(com = IargGetCom (_Str (str)))) _ErrExit3 (e__objectunknown, "Icarus function", _Str (str)); StrDel (str); } else com = (IARGvCOM) VarGetObject (NULL, args[0]); IargBuildArgs (com, &args[1], 0); iargRetVal = NULL; IargComStack (com, "push"); _IargCall (com); IargComStack (com, "pop"); if (iargRetVal) { switch (VarType (iargRetVal)) { case 0: /* function returns nothing */ break; case VARxINT: VarSetInt (var, (VarGetInt (iargRetVal))); break; case VARxSTRING: VarSetStr (var, (VarGetStr (iargRetVal))); break; case VARxSTRV: str = VarGetStrv (iargRetVal); VarSetStrv (var, str); break; case VARxOBJECT: VarSetObject (NULL, var, (VarGetObject (NULL, iargRetVal))); break; case VARxREAL: break; case VARxLIST: AnySetList (var, iargRetVal); break; case VARxVAR: var = VarSetVar (var, VarGetVar (iargRetVal, 1)); break; default: _ErrExit2 (e__unknownoption, "type in IopExecCom"); } } return 1; } INT4 IopProg (VARo *var) { static ICAoSYNTAX syntax; static INT4 i2cFlag = TRUE; INT4 k; VARo **arg=VarGetArgs (var); STRv str; char *fileNameSave = Job->fileName; globalScope = Job->scope; str = VarGetStrv (arg[0]); Job->fileName = _Str (str); for (k=1; arg[k] != NULL; k++) { Job->lineN = VarGetLineN (arg[k]); VarExec (arg[k]); if( *ParGetStr("ica2cName") && i2cFlag) { i2cFlag = FALSE; syntax.prod = VarGet(&globalScope, "rules"); BnfInitRules (&syntax, FALSE); I2cBnfGenerator(syntax.prod); exit(0); } } StrDel (str); Job->fileName = fileNameSave; /* nested progs with "file" command */ return 1; } INT4 IopTest () { INT4 x, y; char color[44]; IargGetArgs ("x|y|color", &x, &y, color); printf ("x:%d y:%d color:%s\n", x, y, color); return 1; } INT4 IopBody (VARo *var) { INT4 k; VARo **arg=VarGetArgs (var); for (k=0; arg[k] != NULL; k++) { Job->lineN = VarGetLineN (arg[k]); VarExec (arg[k]); } return 1; } INT4 IopAss (VARo *var, VARo *store, VARo *val) { VARo **arg; INT4 type, tmpInt; STRv str; if (var) { arg = VarGetArgs (var); store = arg[0]; val = arg[1]; } if (VarGetCode (store) & IARGxCALL || !VarIsAlias (store)) _ErrExit2 (e__anyIsReadOnly, AnyDebugStr (store)); _VarGetType (val, type); switch (type) { case VARxINT: tmpInt = VarGetInt (val); VarSetInt (store, tmpInt); break; case VARxSTRING: VarSetStr (store, VarGetStr (val)); break; case VARxSTRV: str = VarGetStrv (val); VarSetStrv (store, str); break; case VARxLIST: AnySetList (store, val); break; case VARxOBJECT: VarSetObject (NULL, store, VarGetObject (NULL, val)); break; case VARxUNKNOWN: _ErrExit3 (e__objectunknown, "variable", VarGetName (val)); default: _ErrExit2 (e__unknownoption, "type in IopAss"); } return 1; } INT4 IopMul (VARo *var) { VARo **args=VarGetArgs (var); return VarGetInt (args[0]) * VarGetInt (args[1]); } INT4 IopAdd (VARo *var , VARo *val1, VARo *val2) { VARo **arg; if (var) { arg = VarGetArgs (var); val1 = arg[0]; val2 = arg[1]; } return VarGetInt (val1) + VarGetInt (val2); } INT4 IopDivide (VARo *var) { VARo **args=VarGetArgs (var); return VarGetInt (args[0]) / VarGetInt (args[1]); } INT4 IopSubt (VARo *var) { VARo **args=VarGetArgs (var); return VarGetInt (args[0]) - VarGetInt (args[1]); } INT4 IopAddAss (VARo *var) { VARo **arg=VarGetArgs (var); if (VarType (arg[0]) == VARxLIST) { AnyListApp (arg[0], VarCopy (arg[1], NULL)); return 0; } else { VarSetInt (arg[0], VarGetInt (arg[0]) + VarGetInt (arg[1])); return VarGetInt (arg[0]); } } INT4 IopEq (VARo *var) { VARo **arg=VarGetArgs (var); Int4 typ1, typ2, rv; STRv s1, s2; typ1 = VarGetType (arg[0]); typ2 = VarGetType (arg[1]); if ((typ1 == VARxSTRING || typ1 == VARxSTRV) || (typ2 == VARxSTRING || typ2 == VARxSTRV)) { s1=VarGetStrv (arg[0]); s2=VarGetStrv (arg[1]); rv = SmEqs (_Str(s1), _Str(s2)); StrDel (s1); StrDel (s2); return rv; } else return (VarGetInt (arg[0]) == VarGetInt (arg[1])); } INT4 IopNEq (VARo *var) { VARo **arg=VarGetArgs (var); INT4 typ1, typ2, rv; STRv s1, s2; typ1 = VarGetType (arg[0]); typ2 = VarGetType (arg[1]); if ((typ1 == VARxSTRING || typ1 == VARxSTRV) || (typ2 == VARxSTRING || typ2 == VARxSTRV)) { s1=VarGetStrv (arg[0]); s2=VarGetStrv (arg[1]); rv = SmEqs (_Str(s1), _Str(s2)); StrDel (s1); StrDel (s2); return !rv; } else return !(VarGetInt (arg[0]) == VarGetInt (arg[1])); } INT4 IopLogAnd (VARo *var) { VARo **arg=VarGetArgs (var); INT4 typ1, typ2; if (!VarGetInt (arg[0])) return 0; if (!VarGetInt (arg[1])) return 0; return 1; } INT4 IopLogOr (VARo *var) { VARo **arg=VarGetArgs (var); INT4 typ1, typ2; if (VarGetInt (arg[0])) return 1; if (VarGetInt (arg[1])) return 1; return 0; } INT4 IopLT (VARo *var) { VARo **args=VarGetArgs (var); return (VarGetInt (args[0]) < VarGetInt (args[1])); } INT4 IopGT (VARo *var) { VARo **args=VarGetArgs (var); return (VarGetInt (args[0]) > VarGetInt (args[1])); } INT4 IopFor (VARo *var) { VARo **args=VarGetArgs (var); VarExec (args[0]); while (VarGetInt (args[1])) { VarExec (args[3]); VarExec (args[2]); } return 1; } enum IOPeInList {IOPxFIRST, IOPxMIDDLE, IOPxLAST}; enum IOPeInList inListPos; INT4 IopForeach (ANYv any) { STRv str; ANYv list, var, tmp, *arg=VarGetArgs (any); char *name; Int4 type, i; var = arg[0]; list = AnyListCpy (arg[1]); for (i=0; (tmp = AnyNextInList (list, &i));){ if (i==1) inListPos = IOPxFIRST; else if (i==AnyListLen (list)) inListPos = IOPxLAST; else inListPos = IOPxMIDDLE; switch (VarGetType (tmp)) { case VARxSTRING: VarSetStr (var, VarGetStr (tmp)); break; case VARxSTRV: str = VarGetStrv (tmp); VarSetStrv (var, str); break; case VARxINT: VarSetInt (var, VarGetInt (tmp)); break; case VARxOBJECT: VarSetObject (NULL, var, VarGetObject (NULL, tmp)); break; case VARxVAR: VarSetVar (var, VarGetVar (tmp, 0)); break; case VARxLIST: AnySetList (var, tmp); break; case VARxUNKNOWN: break; default: _ErrExit2 (e__unknownoption, "type in IopForeach"); break; } VarExec (arg[2]); if (tmp == list) break; } VarDestroy2 (list); return 1; } STRv IopIsFirst (Int4 runTime, ANYv elem, ANYv list) { IcaReturn ("strv", inListPos == IOPxFIRST); } STRv IopIsLast (Int4 runTime, ANYv elem, ANYv list) { IcaReturn ("strv", inListPos == IOPxLAST); } INT4 IopWhile (VARo *var) { VARo **args=VarGetArgs (var); while (VarGetInt (args[1])) { VarGetInt (args[0]); } return 1; } INT4 IopExit () { INT4 val; IargGetArgs ("val", &val); exit (val); } /* builds a list */ VARo *IopList (VARo *var) { INT4 k; ANYv *arg=VarGetArgs (var), any, varList; varList = VarNew (); for (k=0; arg[k] != NULL; k++) { any = arg[k]; VarGetType (any); if (any->type == VARxLIST) any = AnyListCpy (any); AnyListApp (varList, any); } if (!k) AnySetList (varList, AnyNewList ()); return varList; } INT4 IopIf (VARo *var) { VARo **arg; for (arg=VarGetArgs (var); *arg; arg++) if (VarGetInt (*arg++)) { VarGetInt (*arg); break; } return 1; } VARo *IopSelect (VARo *var) { VARo **arg=VarGetArgs (var), *val; return (val = AnyGetListIndex (arg[0], VarGetInt (arg[1])-1)); } VARo *IopSelectAssoc (VARo *var) { static ANYv empty; STRv str; ANYv *arg=VarGetArgs (var), val, tmp; if (!empty) empty = VarNew (); str = VarGetStrv (arg[1]); if (AnyIsWrite (var)) /* read/write */ tmp = AnyGetListAssoc (arg[0], _Str(str)); else { if (!(tmp = AnyFindListAssoc (arg[0], _Str(str)))) { VarReset (empty); tmp = empty; } } StrDel (str); return tmp; } /* only for ODD compiler */ #ifdef __ODD extern ODDoCDEFINE cDefine[100]; extern INT4 cDefineN; INT4 IopCDefine () { char name[80]; INT4 k, n; IargGetArgs("n|name", &n, name); for (k=0; k < cDefineN; k++) if (SmEqs (name, cDefine[k].name)) return; strcpy (cDefine[cDefineN].name, name); cDefine[cDefineN].n = n; cDefineN++; } INT4 IopReference (VARo *var) { VARo **arg=VarGetArgs (var); STRv str=VarGetStrv (arg[1]); Int4 id=OddIdRetrieve (_Str(str), VarGetInt (arg[0])); StrDel (str); return id; } INT4 IopObject (VARo *var) { struct SDLoOBJ *class; ANYv tmp, attr, list, *arg=VarGetArgs (var); char *className; void *obj; INT4 k, c; OddInitDepot (); Job->lineN = VarGetLineN (var); className = VarGetClassName (var); if (!(class = (struct SDLoOBJ *)OddGetClass (className))) _ErrExit3 (e__objectunknown, "class", className); OddRegisterObj (class); while (arg && (attr = *arg++)) { list = AnyListCpy (attr); if (OddIsPartOfList (class, VarGetRealName (attr))) { for (k=0,c=0; (tmp = AnyNextInList (list, &c)); k++) VarGetType (tmp); OddSetObjListSize (class, VarGetRealName (list), k); } else OddObjAttribute (class, VarGetRealName (attr), list); VarDestroy2 (list); } VarSetObject (NULL, var, (obj = OddFinishObj (class))); if (SmEqs (className, "com")) IargSetCom ((struct IARGoCOM *)obj, IargGetComName ((struct IARGoCOM *)obj)); return 1; } #endif typedef struct { INT4 count; } BNFoLEVEL; INT4 BnfPrintProgs (BNFoNODE *node, SMoBUFF *buff) { VARo **stmnt; INT4 n[3], k; for (k=0, n[0]=n[1]=n[2]=0; k<3; k++) { if (node->exec[k]) { stmnt = VarGetArgs (node->exec[k]); for (n[k]=0; stmnt && *stmnt; stmnt++, n[k]++) ; } } /* substract from 'pre' and 'post' the debug statement */ if (n[1]) n[1]--; if (n[2]) n[2]--; if (n[0]+n[1]+n[2]) { BuffPrintF (buff, " {"); if (n[0]) BuffPrintF (buff, " *%d", n[0]); if (n[1]) BuffPrintF (buff, " -%d", n[1]); if (n[2]) BuffPrintF (buff, " +%d", n[2]); BuffPrintF (buff, " }"); } return (n[0]+n[1]+n[2]); } void BnfPrintNode (BNFoNODE *node, INT4 level) { static SMoBUFF *buff=NULL; static STRv str=NULL; char c; buff = BuffInit (buff, 40); if (!str) str = StrNew (); switch (node->counter) { case 0: c = ' '; break; case ZeroOrOne: c = '?'; break; case ZeroOrMore: c = '*'; break; case OneOrMore: c = '+'; break; } if (node->name) { StrSetS (&str, node->name); StrEncode (&str); } switch(node->type) { case ProdName: BuffPrintF (buff, "ProdName: %s%c", _Str(str), c); BnfPrintProgs (node, buff); break; case Production: BuffPrintF (buff, "Production: %s%c", node->name ? node->name : "?", c); BnfPrintProgs (node, buff); break; case Literal: BuffPrintF (buff, "Literal: '%s'%c", _Str(str), c); BnfPrintProgs (node, buff); break; case Regexp: BuffPrintF (buff, "RegExp: /%s/%c", _Str(str), c); BnfPrintProgs (node, buff); break; case Term: BuffPrintF (buff, "Term%c", c); break; case Choice: BuffPrintF (buff, "Choice%c", c); break; case Command: BuffPrintF (buff, "Command%c", c); BnfPrintProgs (node, buff); break; case LineStart: BuffPrintF (buff, "LineStart%c", c); break; default: BuffPrintF (buff, "unknown%c", c); break; } printf ("%s\n", BuffFormat (buff, 80, level*4, level*4, NULL)); } INT4 IopPrintProduction (VARo *var) { BNFoPRODUCTION *prod; IargGetArgs("prod", &prod); BnfTreeTraverse ((BNFoNODE *) prod, BnfPrintNode, 1); } STRv IopPrintFormat (Int4 runTime, STRv s, STRv label, Int4 width, Int4 firstIndent, Int4 indent) { STRv tmp; char *p, *pSave; Int4 k, lineLen; if (runTime) IargGetArgs ("s|label|width|indent|firstIndent", &s, &label, &width, &indent, &firstIndent); tmp=StrNew (); if (label) indent = StrLen (label); /* text or ident to the left of first line */ if (label) StrApp (&tmp, label); else if (firstIndent) StrFill (&tmp, firstIndent, ' '); lineLen = StrLen (tmp); for (k=lineLen + StrLen (s), p=_Str (s); k >= width; ) { pSave = p; p += width - lineLen; while (*p != ' ' && p > pSave) /* find the next ' ' backwards */ p--; if (p == pSave) /* no space was found break at line end */ p += width - lineLen; *(p++) = '\0'; StrAppS (&tmp, pSave); StrAppS (&tmp, "\n"); /* text or ident to the left of following lines */ if (label) StrApp (&tmp, label); else StrFill (&tmp, firstIndent, ' '); lineLen = indent; k = k - strlen (pSave) + lineLen; } StrAppS (&tmp, p); StrDel (s); StrDel (label); } INT4 IopPrint (INT4 runTime, VARo *val, FILEo *file, Int4 mode, VARo *var) { STRv str; if (runTime) IargGetArgs("s|f|mode|v", &val, &file, &mode, &var); if (!val) { _ErrMsg (e__icaMissingString); return 0; } str = VarPrintf (val); if (var) VarAppStrv (var, str); else if (file) fwrite (_Str (str), StrLen (str), 1, file->file); else printf ("%s", _Str (str)); StrDel (str); return 1; } STRv IopAltStr (Int4 runTime, Int4 cond, STRv t, STRv f) { STRv s; if (runTime) IargGetArgs("cond|t|f", &cond, &t, &f); if (!t) t = StrNew (); if (!f) f = StrNew (); if (cond) { StrDel (f); s = t; } else { StrDel (t); s = f; } if (runTime) IcaReturn ("strv", s); else return s; } STRv IopPrintForeach (Int4 runTime, ANYv var, ANYv in, ANYv s, ANYv sep) { ANYv tmp; STRv str=StrNew(); Int4 i; if (runTime) IargGetArgs("var|in|s|sep", &var, &in, &s, &sep); for (i=0; (tmp = AnyNextInList (in, &i));){ VarCopy (tmp, var); StrApp (&str, VarPrintf (s)); if (i != AnyListLen (in)) StrApp (&str, VarPrintf (sep)); } if (runTime) IcaReturn ("strv", str); else return str; } INT4 IopDebugPrint (INT4 runTime, VARo *val) { STRv str; if (runTime) IargGetArgs("s", &val); str = VarPrintf (val); printf ("|%s|\n", _Str (StrEncode (&str))); StrDel (str); return 1; } INT4 IopOut (INT4 runTime, STRv name) { char *tableName; if (Job->time == BNFxBUILDTIME) { if (runTime) IargGetArgs("name", &name); tableName = name ? _Str(name) : Job->currNode->name; Job->tokList = TokGetList (tableName, &Job->tokList); Job->currNode->wrtTokList = Job->outTokList = Job->tokList; TokSetStyle(Job->currNode->wrtTokList, COPYSTYLE); if (name) StrDel (name); } else /*Job->tokList =*/ Job->outTokList = Job->currNode->wrtTokList; return 1; } INT4 IopNot () { Job->currNode->action |= BNFxNOT; return 1; } INT4 IopProbe () { Job->currNode->action |= BNFxPROBE; return 1; } INT4 IopNoskip () { Job->currNode->action |= BNFxNOSKIP; return 1; } INT4 IopProd () { BNFoPRODUCTION *prod; char name[80]; IargGetArgs("name", name); if (!(prod = BnfGetProduction (Job->syntax, name, 0))) _ErrMsg3 (e__objectunknown, "production", name); BnfParseProduction (prod); } INT4 IopIn (Int4 runTime, STRv in, STRv codeName, Int4 code, STRv prodName, STRv inFileName, STRv sharesFile, STRv task, STRv countCodeName, VARo *countVar, Int4 selectN, VARo *inCode) { static INT4 c = 0, tokCount; BNFoPRODUCTION *prod, *prodCurr=(BNFoPRODUCTION *) Job->currNode; TOKoLIST *tokList; TOKoTOKEN *tok; INT4 countCode=-1, codeCurr, k; if (runTime) IargGetArgs("in|ic|n|p|file|share|t|count|var|select|c", &in, &codeName, &code, &prodName, &inFileName, &sharesFile, &task, &countCodeName, &countVar, &selectN, &inCode); /* INIT and PRE time */ if (in) { if (countCodeName) countCode = TokStrToCode (_Str(countCodeName)); tokList = TokGetList (_Str(in), &Job->tokList); Job->tokList = Job->currNode->rdTokList = tokList; } /* convert list of code names to numeric codes and attach to current node */ if (Job->time == BNFxBUILDTIME && inCode) { ANYv tmp, list; Int4 i; STRv s; list = AnyListCpy (inCode); for (i=0; (tmp=AnyNextInList (list, &i));) { s = VarGetStrv (tmp); *_addObj (prodCurr->inCode, prodCurr->inCodeN, prodCurr->inCodeAllocN, Int4) = TokStrToCode (_Str (s)); StrDel (s); } VarDestroy2 (list); } if (Job->time == BNFxBUILDTIME) { if (inFileName) ; else if (task) { if (prodName) prod = BnfGetProduction (NULL, _Str(prodName), 0); else prod = IcaGetSupplyNode (Job->currNode->rdTokList->name); prod->taskLinks = TaskRequestLink (&Job->syntax->taskList, _Str(task), (BNFoPRODUCTION *) Job->currNode, prod->taskLinks); } } /* PRE time only */ else { if (inFileName) { FILEo *file; if (!(file = (*Job->inputStreamer) (_Str (inFileName), Job->inputStreamerData))) IcaSetInputEnd (Job); IcaSetInputFile (Job, file, sharesFile ? sharesFile : inFileName); } else if (TokIsListActive (tokList)) { if (countCodeName) { /* client asked for a counter */ if (TokIsListStart (tokList)) tokCount = 0; while ((tok = TokNext (tokList, &c))) { if ((code = TokGetCode (tok)) == countCode) tokCount++; for (k=0; k < prodCurr->inCodeN; k++) if (prodCurr->inCode[k] == code) break; if ((k < prodCurr->inCodeN || !prodCurr->inCodeN) && (!selectN || selectN == tokCount)) { if (countVar) VarSetInt (countVar, tokCount); break; } } Job->inToken = tok; CursorInstall (Job->cursor, tok, tokList); } else { Job->inToken = NULL; while ((tok = TokNext (tokList, &c))) { for (k=0, code=TokGetCode (tok); k < prodCurr->inCodeN; k++) if (prodCurr->inCode[k] == code) break; if (k < prodCurr->inCodeN || !prodCurr->inCodeN) break; } Job->inToken = tok; CursorInstall (Job->cursor, Job->inToken, tokList); } } } StrDel (in); StrDel (codeName); StrDel (prodName); StrDel (inFileName); StrDel (sharesFile); StrDel (task); StrDel (countCodeName); } void IopSetDebug (Int4 runTime, Int4 isOn) { if (runTime) IargGetArgs ("state", &isOn); Job->isDebug = isOn; } void IopDebug (Int4 time) { static STRv str=NULL; BNFoNODE *node; char input[100]; if (!str) str = StrNew (); if (time == PROGxPREPARSE) printf (" * before *\n"); else if (time == PROGxPOSTPARSE) printf (" * after *\n"); if (Job->isDebug) { node = Job->currNode; BnfPrintNode (node, 1); strncpy (input, Job->cursor->current, 50); input[50] = '\0'; StrSetS (&str, input); StrEncode (&str); printf (" Input: |%s|\n", _Str(str)); } } INT4 IopWrt (VARo *var) { TOKoLIST *tokList; char *match; INT4 code=-1, k, length; VARo **arg=VarGetArgs (var); STRv str=NULL, c; if (arg) for (k=0; arg[k] != NULL; k++) switch (VarGetRealName (arg[k])[0]) { case 's': str = VarPrintf (arg[k]); break; case 'c': case ':': c = VarGetStrv (arg[k]); code = TokStrToCode (_Str(c)); StrDel (c); break; case 'n': code = VarGetInt (arg[k]); break; default: _ErrExit2 (e__unknownoption, "IopWrt"); } tokList = Job->outTokList; if (str) TokAdd (tokList, _Str(str), StrLen (str), code); else { CursorGetMatch (Job->cursor, &match, &length); TokAdd (tokList, match, length, code); } if (str) StrDel (str); return 1; } void IopUniq (VARo *var) { TOKoLIST *tokList; char *match, *s=NULL; INT4 code=0, k, length; VARo **arg=VarGetArgs (var); STRv str=NULL, c; if (arg) for (k=0; arg[k] != NULL; k++) switch (VarGetRealName (arg[k])[0]) { case 's': str = VarPrintf (arg[k]); break; case 'c': case ':': c = VarGetStrv (arg[k]); code = TokStrToCode (_Str(c)); StrDel (c); break; case 'n': code = VarGetInt (arg[k]); break; default: _ErrExit2 (e__unknownoption, "IopWrt"); } tokList = Job->outTokList; if (str) { TokAddUniq (tokList, _Str(str), StrLen (str), code); /* if (TokIsUniq (tokList, s, (length=strlen(s)), code)) TokAdd (tokList, s, length, code);*/ } else { CursorGetMatch (Job->cursor, &match, &length); TokAddUniq (tokList, match, length, code); /* if (TokIsUniq (tokList, match, length, code)) TokAdd (tokList, match, length, code);*/ } if (str) StrDel (str); } INT4 IopApp (VARo *var) { VARo **arg=VarGetArgs (var); char *match, *s=NULL; INT4 length, k; STRv str=NULL; if (arg) for (k=0; arg[k] != NULL; k++) switch (VarGetRealName (arg[k])[0]) { case 's': str = VarPrintf (arg[k]); s = _Str (str); break; } if (s) TokAppend (Job->outTokList, s, strlen (s)); else { CursorGetMatch (Job->cursor, &match, &length); TokAppend (Job->outTokList, match, length); } if (str) StrDel (str); } INT4 IopRep (Int4 runTime, VARo *list) { VARo *value; STRv str; if (runTime) IargGetArgs("s", &list); str = VarPrintf (list); CursorReplaceMatch (Job->cursor, _Str (str), StrLen (str)); StrDel (str); } STRv IopStrTrim (Int4 runTime, STRv str, STRv skip) { if (runTime) IargGetArgs("s|skip", &str, &skip); StrTrim (&str, skip ? _Str (skip) : NULL); StrDel (skip); StrDel (str); /* StrTrim makes a new copy */ if (runTime) IcaReturn ("strv", str); return str; } void IopStrApp(Int4 runTime, VARo* v, STRv s) { if (runTime) IargGetArgs("v|s",&v,&s); if (v) VarAppStrv (v, s); } INT4 IopGetc (VARo *var) { VARo **arg=VarGetArgs (var); CursorSetLength (Job->cursor, VarGetInt (arg[0])); return 1; } void IopRestrictLength (VARo *var) { static Int4 cursorLenSave, tmpLenSave; VARo **arg=VarGetArgs (var); Int4 len; len = arg[0] ? VarGetInt (arg[0]) : 0; if (len && Job->currNode) { if (Job->time == BNFxPREPARSE) { cursorLenSave = CursorGetLength (Job->cursor); tmpLenSave = CursorSetTmpLength (Job->cursor, len); } else if (Job->time == BNFxPOSTPARSE) { CursorSetMatch (Job->cursor, CursorGetLength (Job->cursor)); CursorIncrement (Job->cursor); CursorResetLength (Job->cursor, cursorLenSave - tmpLenSave); } } } void IopMove (VARo *var) { VARo **arg=VarGetArgs (var); Int4 len= arg[0] ? VarGetInt(arg[0]) : 0; if (len > CursorGetLength (Job->cursor)) Job->parseError = 1; else { CursorSetLength (Job->cursor, VarGetInt (arg[0])); CursorMove (Job->cursor); Job->doAdvance = 1; /* make sure next symbol advances input */ } } INT4 IopRequest () { TOKoLIST *tokList, *tokListCurr; char name[80]; IargGetArgs("name", name); tokListCurr = Job->outTokList; tokList = IcaGetTokenList (Job, name); Job->outTokList = tokListCurr; return 1; } INT4 IopJobTokens () { FILEo *outFile; ICAoJOB *job; TOKoLIST *tokList; TOKoTOKEN *tok; char name[80], codeName[80], taskName[80], *s; INT4 c, code, doPrint, withCode; IargGetArgs("job|name|n|code|print|task|withCode|outFile", &job, name, &code, codeName, &doPrint, taskName, &withCode, &outFile); if (*codeName) code = TokStrToCode (codeName); else code = -1; if (*taskName) IcaSetTask (job, taskName, 1); if ((tokList = IcaGetTokenList (job, name))) { if (doPrint) { if (withCode) printf ("\n----- list: %s ------\n", TokListGetName (tokList)); for (c=0; (tok = TokNextWithCode (tokList, code, &c));) { if (withCode) { char* code=TokCodeToStr (TokGetCode (tok)); s=TokGetStringCopy (tokList, tok); printf ("code: %s string: |%s|\n",code,s); } else { s = TokGetStringCopy (tokList, tok); fwrite (s, strlen (s), 1, outFile ? FileGetFile (outFile) : stdout); } } } } IcaReturn ("int", 1); } Int4 IopJobHasInput () { ICAoJOB *job; IargGetArgs ("job", &job); if (IcaIsJobEnd (job)) IcaReturn ("int", 0); else IcaReturn ("int", 1); } void IopFail (Int4 runTime) { Job->parseError = 1; Job->doAdvance = 1; } INT4 IopSetSkip (Int4 runTime, Int4 state, STRv ws) { char *tmp; if (runTime) IargGetArgs("state|s", &state, &ws); if (ws) { Job->syntax->ign = malloc (StrLen(ws) + 1); strcpy (Job->syntax->ign, _Str(ws)); StrDel (ws); } if ((!state && *Job->syntax->ign) || (state && !*Job->syntax->ign)) { tmp = Job->syntax->ign; Job->syntax->ign = Job->syntax->ignAlt; Job->syntax->ignAlt = tmp; } } Int4 IopFip (INT4 runTime, Int4 flag) { Int4 fip; if (runTime) IargGetArgs ("switch", &flag); if (flag) FileSetGetFip (Job->file, (flag == 1) ? 1 : 0); else if (Job->file) { fip = (Int4) FileGetFip (Job->file); if (runTime) IcaReturn ("int", fip); else return fip; } else return 0; } FILEo *IopFile (Int4 runTime) { if (runTime) IcaReturn ("file", Job->file); else return Job->file; } STRv IopSubMatch (INT4 runTime, INT4 n) { STRv str; if (runTime) IargGetArgs("n", &n); str = StrNCpyS (Job->regExp->startp[n], (Int4)(Job->regExp->endp[n] - Job->regExp->startp[n])); if (runTime) IcaReturn ("strv", str); else return str; } /* should be called directly */ STRv IopCurrToken (INT4 runTime) { STRv str; char *p; Int4 len; CursorGetMatch (Job->cursor, &p, &len); str = StrNCpyS (p, len); if (runTime) IcaReturn ("strv", str); else return str; } STRv IopInTokenCode (INT4 runTime) { static STRv str=NULL; if (!str) str = StrNew (); if (Job->inToken) StrSetS (&str, TokCodeToStr (TokGetCode (Job->inToken))); else StrClear (&str); if (runTime) IcaReturn ("strv", StrCpy (str)); else return StrCpy(str); } STRv IopInToken (INT4 runTime, Int4 n) { STRv str=StrNew (); if (runTime) IargGetArgs ("n", &n); if (n && ncursor->len) StrAppN (&str, Job->cursor->current, n); else StrAppN (&str, Job->cursor->current, Job->cursor->len); if (runTime) IcaReturn ("strv", str); else return str; } char *IopKey () { static STRv str=NULL; VARo *val; char *tmp; if (!str) str = StrNew (); IargGetArgs ("val", &val); if ((tmp = VarGetName (val))) StrSetS (&str, tmp); else StrClear (&str); IcaReturn ("strv", StrCpy (str)); } void IopPush_ (INT4 runTime, VARo *var, INT4 stackN) { VARoStack *stack; if (runTime) IargGetArgs ("value|stack", &var, &stackN); VarPush2 (&icaStack2[stackN], VarDuplicate(var)); } VARo *IopPop_ (INT4 runTime, INT4 stackN) { VARo *var; if (runTime) IargGetArgs ("stack", &stackN); if (!(var = VarPop2 (&icaStack2[stackN]))) _ErrExit2 (e__icastackempty, stackN); if (runTime) IcaReturn ("var", var); else return var; } INT4 IopPush (INT4 runTime, VARo *var, INT4 stackN) { VARoSTACK *stack; VARo *tmp; if (runTime) IargGetArgs ("value|stack", &var, &stackN); stack = icaStack[stackN]; if (!stack) { stack = VarStackNew (10); icaStack[stackN] = stack; } tmp = VarPushNew (stack); switch (VarGetType (var)) { case VARxSTRING: VarSetStr (tmp, VarGetStr (var)); break; case VARxINT: VarSetInt (tmp, VarGetInt (var)); break; case VARxOBJECT: VarSetObject (NULL, tmp, VarGetObject (NULL, var)); break; case VARxSTRV: VarSetStrv (tmp, VarGetStrv (var)); break; default: _ErrExit2 (e__unknownoption, "type in IopPush"); } } VARo *IopPop (INT4 runTime, INT4 stackN) { VARo *var; if (runTime) IargGetArgs ("stack", &stackN); if (!icaStack[stackN] || !(var = VarPop (icaStack[stackN]))) _ErrExit2 (e__icastackempty, stackN); if (runTime) IcaReturn ("var", var); else return var; } INT4 IopSetFunctions () { FUNC function; char name[132]; IargGetArgs ("name", name); if (!(function = IcaGetFunction (name))) _ErrExit3 (e__objectunknown, "function", name); (*function)(); return 1; } /* gcg programs */ INT4 GCGWordsearch () { static SMoBUFF *buff=NULL; FUNC function; char inFile1Name[132], inFile2Name[132]; buff = BuffInit (buff, 100); IargGetArgs ("inFile1|inFile2", inFile1Name, inFile2Name); BuffPrintF (buff, "wordsearch "); BuffPrintF (buff, "-infile1=%s ", inFile1Name); BuffPrintF (buff, "-infile2=%s ", inFile2Name); BuffPrintF (buff, "-def "); printf ("%s\n", BuffGetPtr (buff)); system (BuffGetPtr (buff)); return 1; } INT4 IopParDel (Int4 runTime, STRv name) { if (runTime) IargGetArgs ("name", &name); if (name) { ParDeleteMatch (_Str (name)); StrDel (name); } } INT4 IopParStr (Int4 runTime, STRv name, STRv set) { if (runTime) IargGetArgs ("name|set", &name, &set); if (set) { ParDefStr (_Str(name), _Str(set)); StrDel (set); } else IcaReturn ("strv", StrCpyS (ParGetStr (_Str(name)))); StrDel (name); } INT4 IopParInt (Int4 runTime, STRv name, Int4 set) { if (runTime) IargGetArgs ("name|set", &name, &set); if (set != 2) ParDefNum (_Str(name), set); else IcaReturn ("int", ParGetNum (_Str(name))); StrDel (name); } INT4 IopEnv (Int4 runTime, STRv name, STRv set) { STRv com, s; char *tmp; if (runTime) IargGetArgs ("name|set", &name, &set); if (set) { com=StrNew (); StrPrintf (&com, "%s=%s", _Str(name), _Str(set)); putenv (_Str (com)); StrDel (com); StrDel (set); } s = StrNew (); if ((tmp = getenv (_Str(name)))) StrAppS (&s , tmp); IcaReturn ("strv", s); StrDel (name); } INT4 IopHtmlSpace () { static SMoBUFF *buff=NULL; INT4 bigN, sn=0, n, ln=0, s, l; buff=BuffInit (buff, 20); /* question: represent a number n of 1/4 or 1/3 characters by a combination of 3/4 and 4/4 or 2/3 and 3/3 resp. solution: s is the smaller of 3,4 or 2,3 -> 3 or 2 l is the larger of the pair -> 3 or 4 sn, ln refers to the numbers in the combination ln = n % s; sn = n - (ln*l) / s */ /* s=3; l=4;*/ IargGetArgs ("thirds|s|l", &n, &s, &l); if (n == s) sn = 1; else if (n == l && n < 2*s) /* an approximation here */ ln = 1; else if (n >= 2*s) if (n) { ln = n%s; sn = (n - ln*l) / s; } if (ln) BuffFill (buff, ln, ' '); if (sn) { BuffCopyString (buff, ""); BuffFill (buff, sn, ' '); BuffCopyString (buff, ""); } IcaReturn ("string", BuffGetPtr (buff)); } INT4 IopStrlen () { char s[500]; IargGetArgs ("s", s); IcaReturn ("int", strlen(s)); } INT4 IopStrLen (Int4 runTime, STRv s) { Int4 len; if (runTime) IargGetArgs ("s", &s); len = StrLen (s); if (runTime) IcaReturn ("int", len); StrDel (s); return len; } STRv IopStrPad (Int4 runTime, STRv s, Int4 len, STRv c) { STRv t; char padS[1000]; Int4 padLen, k; if (runTime) IargGetArgs ("s|len|c", &s, &len, &c); t = StrCpy (s); if (StrLen (t) < len) { padLen = len - StrLen (t); for (k=0; k < padLen; k++) padS[k] = *(_Str (c)); padS[k] = '\0'; StrAppS (&t, padS); } StrDel (c); StrDel (s); IcaReturn ("strv", t); } STRv IopStrTrans (Int4 runTime, STRv s, STRv from, STRv to) { STRv t; if (runTime) IargGetArgs ("s|from|to", &s, &from, &to); t = StrCpy (s); StrTranslate (&t, _Str(from), _Str(to)); StrDel (from); StrDel (to); StrDel (s); IcaReturn ("strv", t); } STRv IopStrUpper (Int4 runTime, STRv s) { STRv t; if (runTime) IargGetArgs ("s", &s); t = StrCpy (s); StrDel (s); StrUpper (&t); IcaReturn ("strv", t); } STRv IopStrLower (Int4 runTime, STRv s) { STRv t; if (runTime) IargGetArgs ("s", &s); t = StrCpy (s); StrDel (s); StrLower (&t); IcaReturn ("strv", t); } STRv IopStrReplace (Int4 runTime, STRv s, STRv from, STRv to) { STRv t; if (runTime) IargGetArgs ("s|from|to", &s, &from, &to); t = StrCpy (s); StrDel (s); StrReplace (&t, _Str(from), _Str (to)); StrDel (from); StrDel (to); IcaReturn ("strv", t); } INT4 IopFileOpen (Int4 runTime, STRv name, Int4 mode) { FILEo *file; IargGetArgs ("name|mode", &name, &mode); file = FileNew (name ? _Str(name) : NULL); if (mode==2) /* write access */ FileSetWrite (file); if (!FileOpen (file) ) _ErrExit2 (e__filnotok, _Str(name)); StrDel (name); IcaReturn ("file", file); } void IopFileClose () { FILEo *file; IargGetArgs ("file", &file); if (file) { FileDelete (file); } } STRv IopFileName (Int4 runTime, Int4 option) { STRv s; FILEo *file; if (runTime) IargGetArgs ("type", &option); if ((file = IcaJobGetFile (Job))) { switch (option) { case 1: s = StrCpyS (FileGetName (file, "path")); break; case 2: s = StrCpyS (FileGetName (file, "dir")); break; case 3: s = StrCpyS (FileGetName (file, "name")); break; case 4: s = StrCpyS (FileGetName (file, "file")); break; case 5: s = StrCpyS (FileGetName (file, "ext")); break; } } else s = StrNew (); IcaReturn ("strv", s); } /* used by IopJobNew as optional input streamer */ FILEo *IopInputStreamer (char *name, void *data) { FILEo *file; if (Job->file) return FileIsEof (Job->file) ? NULL : Job->file; else { file = FileNew (_Str ((STRv) data)); if (!FileOpen (file) ) _ErrExit2 (e__filnotok, _Str ((STRv) data)); return file; } } ICAoJOB *IopJobNew (Int4 runTime, VARo *prod, STRv skip, STRv comment, FILEo *file, STRv str, Int4 doShow, Int4 doTree, STRv fileName) { ICAoSYNTAX *syntax; ICAoJOB *job; if (runTime) IargGetArgs ("prod|skip|comment|file|str|show|tree|fileName", &prod, &skip, &comment, &file, &str, &doShow, &doTree, &fileName); /* new syntax object */ if ((syntax = (ICAoSYNTAX *) calloc (sizeof(ICAoSYNTAX), 1)) == NULL) _ErrExit2 (e__allocfail, "syntax object");; syntax->ign = skip ? _Str (skip) : ""; syntax->ignAlt = ""; syntax->cmnt = comment ? _Str (comment) : ""; syntax->prod = prod; /* new job object */ if ((job = (ICAoJOB *) calloc (sizeof(ICAoJOB), 1)) == NULL) _ErrExit2 (e__allocfail, "job object"); job->fileName = Job->fileName; /* for error messages */ IcaContext ("push", &job); job->syntax = syntax; job->time = BNFxBUILDTIME; BnfInitRules (syntax, doTree); job->time = 0; IcaContext ("pop", NULL); IcaCursorSet (&job->inCursor, CursorNew (), NULL); /* which input to parse? */ if (fileName) { IcaSetInputStreamer (job, IopInputStreamer); IcaSetInputStreamerData (job, (void*) fileName); IcaJobNext (job); /* TokGetList (INTOKLIST, &job->tokList); */ } else if (file) IcaJobSetFile (job, file); else if (str) IcaJobSetString (job, _Str (str)); if (runTime) IcaReturn ("job", job); else return job; } INT4 IopJobNext (Int4 runTime, ICAoJOB *job, FILEo *file) { if (runTime) IargGetArgs ("job|file", &job, &file); if (file) IcaJobSetFile (job, file); IcaJobNext (job); } INT4 IopJobEnd () { ICAoJOB *job; IargGetArgs ("job", &job); IcaEndJob (job); } void IopBreak (Int4 runTime, Int4 cond, Int4 time) { if (runTime) IargGetArgs ("cond|time", &cond, &time); Job->currNode->dbgBreak = IARGxPRE | IARGxPOST; if (Job->time != BNFxBUILDTIME && cond) Job->currNode->dbgBreak = IARGxPRE | IARGxPOST; else Job->currNode->dbgBreak = 0; } void IopContinue () { DbgSetContinue (); } void IopNext () { DbgSetNext (); } Int4 IopTestMode () { IcaReturn ("int", ParGetNum ("fromSrs") ? 0 : 1); } Int4 IopListLen(Int4 runTime, ANYv list) { Int4 len; if (runTime) IargGetArgs("list",&list); len=AnyListLen(list); if (runTime) IcaReturn("int",len); return len; } void EntryIopSetFieldFormat (); INT4 QuerySetFunctions (); INT4 SeqIopNew (); INT4 SeqIopLen (); INT4 SeqIopApp (); INT4 SeqIopPrint (); INT4 SeqIopMake (); INT4 SeqIopTrunc (); void SdbFunctions (); void SeqIopGet2Bit (); /****** IcaOpLibrary ****************************************************** */ INT4 IcaOpLibrary() { /* for icarus interpreter */ IcaSetFunction("IcaOpSubStr", (FUNC)IcaOpSubStr); /* for icarus interpreter but level 4 */ IcaSetFunction("IopList_", (Func)IopList_); IcaSetFunction("IopProg_", (Func)IopProg_); IcaSetFunction("IopBinop_", (Func)IopBinop_); IcaSetFunction("IopStrMake_", (Func)IopStrMake_); IcaSetFunction("IopPush_", (Func)IopPush_); IcaSetFunction("IopPop_", (Func)IopPop_); IcaSetFunction("IopOpnd_", (Func)IopOpnd_); IcaSetFunction("IopAssoc_", (Func)IopAssoc_); IcaSetFunction("IopBody_", (Func)IopBody_); IcaSetFunction("IopSelect_", (Func)IopSelect_); IcaSetFunction("IopFunc_", (Func)IopFunc_); IcaSetFunction("IopSetWrite_", (Func)IopSetWrite_); IcaSetFunction("IopMakeArg_", (Func)IopMakeArg_); IcaSetFunction("IopRef_", (Func)IopRef_); IcaSetFunction("IopPre_", (Func)IopPre_); IcaSetFunction("IopInit_", (Func)IopInit_); IcaSetFunction("IopFor_", (Func)IopFor_); IcaSetFunction("IopForeach_", (Func)IopForeach_); IcaSetFunction("IopWhile_", (Func)IopWhile_); IcaSetFunction("IopIf_", (Func)IopIf_); IcaSetFunction("IopFile_", (Func)IopFile_); /* new level 3 icarus commands */ IcaSetFunction("IopSystem", (FUNC)IopSystem); IcaSetFunction("IopInterpStr_", (FUNC)IopInterpStr_); IcaSetFunction("IopTest", (FUNC)IopTest); IcaSetFunction("IopExecCom", (FUNC)IopExecCom); IcaSetFunction("IopProg", (FUNC)IopProg); IcaSetFunction("IopBody", (FUNC)IopBody); IcaSetFunction("IopFor", (FUNC)IopFor); IcaSetFunction("IopForeach", (FUNC)IopForeach); IcaSetFunction("IopIf", (FUNC)IopIf); IcaSetFunction("IopWhile", (FUNC)IopWhile); IcaSetFunction("IopList", (FUNC)IopList); IcaSetFunction("IopExit", (FUNC)IopExit); IcaSetFunction("IopMul", (FUNC)IopMul); IcaSetFunction("IopAdd", (FUNC)IopAdd); IcaSetFunction("IopDivide", (FUNC)IopDivide); IcaSetFunction("IopSubt", (FUNC)IopSubt); IcaSetFunction("IopAss", (FUNC)IopAss); IcaSetFunction("IopAddAss", (FUNC)IopAddAss); IcaSetFunction("IopEq", (FUNC)IopEq); IcaSetFunction("IopNEq", (FUNC)IopNEq); IcaSetFunction("IopLogAnd", (FUNC)IopLogAnd); IcaSetFunction("IopLogOr", (FUNC)IopLogOr); IcaSetFunction("IopLT", (FUNC)IopLT); IcaSetFunction("IopGT", (FUNC)IopGT); IcaSetFunction("IopSetSkip", (FUNC)IopSetSkip); IcaSetFunction("IopSelect", (FUNC)IopSelect); IcaSetFunction("IopSelectAssoc", (FUNC)IopSelectAssoc); IcaSetFunction("IopPrintProduction", (FUNC)IopPrintProduction); IcaSetFunction("IopPrintFormat", (FUNC)IopPrintFormat); IcaSetFunction("IopPrint", (FUNC)IopPrint); IcaSetFunction("IopDebugPrint", (FUNC)IopDebugPrint); IcaSetFunction("IopAltStr", (FUNC)IopAltStr); IcaSetFunction("IopPrintForeach", (FUNC)IopPrintForeach); IcaSetFunction("IopOut", (FUNC)IopOut); IcaSetFunction("IopIn", (FUNC)IopIn); IcaSetFunction("IopGetc", (FUNC)IopGetc); IcaSetFunction("IopRestrictLength", (FUNC)IopRestrictLength); IcaSetFunction("IopMove", (FUNC)IopMove); IcaSetFunction("IopWrt", (FUNC)IopWrt); IcaSetFunction("IopUniq", (FUNC)IopUniq); IcaSetFunction("IopApp", (FUNC)IopApp); IcaSetFunction("IopRep", (FUNC)IopRep); IcaSetFunction("IopNot", (FUNC)IopNot); IcaSetFunction("IopProbe", (FUNC)IopProbe); IcaSetFunction("IopProd", (FUNC)IopProd); IcaSetFunction("IopNoskip", (FUNC)IopNoskip); IcaSetFunction("IopRequest", (FUNC)IopRequest); IcaSetFunction("IopJobTokens", (FUNC)IopJobTokens); IcaSetFunction("IopJobHasInput", (FUNC)IopJobHasInput); IcaSetFunction("IopFileOpen", (FUNC)IopFileOpen); IcaSetFunction("IopFileClose", (FUNC)IopFileClose); IcaSetFunction("IopFileName", (FUNC)IopFileName); IcaSetFunction("IopCurrToken", (FUNC)IopCurrToken); IcaSetFunction("IopInTokenCode", (FUNC)IopInTokenCode); IcaSetFunction("IopInToken", (FUNC)IopInToken); IcaSetFunction("IopFail", (FUNC)IopFail); IcaSetFunction("IopFip", (FUNC)IopFip); IcaSetFunction("IopFile", (FUNC)IopFile); IcaSetFunction("IopKey", (FUNC)IopKey); IcaSetFunction("IopIsFirst", (FUNC)IopIsFirst); IcaSetFunction("IopIsLast", (FUNC)IopIsLast); IcaSetFunction("IopListLen", (FUNC)IopListLen); IcaSetFunction("IopPush", (FUNC)IopPush); IcaSetFunction("IopPop", (FUNC)IopPop); IcaSetFunction("IopSubMatch", (FUNC)IopSubMatch); IcaSetFunction("IopSetFunctions", (FUNC)IopSetFunctions); IcaSetFunction("IopCDefine", (FUNC)IopCDefine); IcaSetFunction("IopHtmlSpace", (FUNC)IopHtmlSpace); IcaSetFunction("IopStrlen", (FUNC)IopStrlen); IcaSetFunction("IopStrLen", (FUNC)IopStrLen); IcaSetFunction("IopStrPad", (FUNC)IopStrPad); IcaSetFunction("IopStrTrans", (FUNC)IopStrTrans); IcaSetFunction("IopStrLower", (FUNC)IopStrLower); IcaSetFunction("IopStrUpper", (FUNC)IopStrUpper); IcaSetFunction("IopStrReplace", (FUNC)IopStrReplace); IcaSetFunction("IopStrTrim", (FUNC)IopStrTrim); IcaSetFunction("IopStrApp", (FUNC)IopStrApp); IcaSetFunction("IopJobNew", (FUNC)IopJobNew); IcaSetFunction("IopJobNext", (FUNC)IopJobNext); IcaSetFunction("IopJobEnd", (FUNC)IopJobEnd); IcaSetFunction("IopParStr", (FUNC)IopParStr); IcaSetFunction("IopParInt", (FUNC)IopParInt); IcaSetFunction("IopParDel", (FUNC)IopParDel); IcaSetFunction("IopEnv", (FUNC)IopEnv); IcaSetFunction("IopEval", (FUNC)IopEval); IcaSetFunction("IopSetDebug", (FUNC)IopSetDebug); IcaSetFunction("IopBreak", (FUNC)IopBreak); IcaSetFunction("IopContinue", (FUNC)IopContinue); IcaSetFunction("IopNext", (FUNC)IopNext); IcaSetFunction("IopTestMode", (FUNC)IopTestMode); IcaSetFunction("QuerySetFunctions", (FUNC)QuerySetFunctions); IcaSetFunction("GCGWordsearch", (FUNC)GCGWordsearch); IcaSetFunction("SeqIopGet2Bit", (FUNC)SeqIopGet2Bit); IcaSetFunction("SeqIopNew", (FUNC)SeqIopNew); IcaSetFunction("SeqIopLen", (FUNC)SeqIopLen); IcaSetFunction("SeqIopApp", (FUNC)SeqIopApp); IcaSetFunction("SeqIopPrint", (FUNC)SeqIopPrint); IcaSetFunction("SeqIopMake", (FUNC)SeqIopMake); IcaSetFunction("SeqIopTrunc", (FUNC)SeqIopTrunc); IcaSetFunction("SdbFunctions", (FUNC)SdbFunctions); IcaSetFunction("EntryIopSetFieldFormat", (FUNC)EntryIopSetFieldFormat); return(TRUE); } IopGet2Bit); IcaSetFunction("SeqIopNew", (FUNC)SeqIopNew); IcaSetFunction("SeqIopLen", (FUNC)SeqIopLen); IcaSetFunction("SeqIopApp", (FUNC)SeqIopApp); IcaSetFunction("SeqIopPrint", (FUNC)SeqIopPrint); IcaSetFunction("SeqIopMake", (FUNC)SeqIopMake); IcaSetFunction("SeqIopTrunc", (FUNC)SeqIopTrunc); srs/src/icarus.c char icarus_ID[] = "$Id: icarus.c,v 1.29 1997/03/12 16:17:37 srs Exp $"; /* ** ** $RCSfile: icarus.c,v $ ** $Revision: 1.29 $ ** $Date: 1997/03/12 16:17:37 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** Copyright by Thure Etzold ** ** Author: Anatoly Ulyanov ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387451 ** Email: ulyanov@embl-heidelberg.de ** ** ** ** ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include "message.h" #include "regexp.h" #include "futil.h" #include "lst.h" #include "sm.h" #include "library.h" #include "strv.h" #include "variable.h" #include "toklist.h" #include "cursor.h" #include "icatask.h" #include "icarus.h" #include "icabnf.h" #define _SRS #include SRSINCLUDE INT4 NameListId = 0; ICAoJOB *Job; VARoSCOPE *globalScope; ICAoSYNTAX *newSyntax; INT4 IcaFunGetFip(); static void IcaJobActivate (ICAoJOB *job); void LocalSetFunctions (); static void NameDump(FILE *f, void *o) { ICAoNAMELIST *t = (ICAoNAMELIST *)o; printf("Namelist: %s\n", t->name); } static void NameKill(void *o){} /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** defines a list of input cursors which are needed for multiple ** stream input */ typedef struct ICAoCursor { CURSORo *cursorCurr; CURSORo *cursor[5]; STRv name[5]; Int4 cursorN; } ICAoCursor; static CURSORo *IcaCursorGet (ICAoCursor *c, STRv name) { Int4 k; if (!c) return NULL; for (k=0; k < c->cursorN; k++) if (!name || !c->name[k] || StrEqual (name, c->name[k])) return c->cursor[k]; return NULL; } static Int4 IcaCursorIsInput (ICAoCursor *c, CURSORo *cursor) { Int4 k; if (!c) return 0; for (k=0; k < c->cursorN; k++) if (c->cursor[k] == cursor) return 1; return 0; } CURSORo *IcaCursorSet (ICAoCursor **c, CURSORo *cursor, STRv name) { Int4 k; if (!*c) if ((*c = (ICAoCursor *) calloc (sizeof(ICAoCursor), 1)) == NULL) _ErrExit2 (e__allocfail, "icarus cursor list"); for (k=0; k < (*c)->cursorN; k++) if (!name || !(*c)->name || StrEqual (name, (*c)->name[k])) { (*c)->cursorN--; break; } (*c)->cursorN++; (*c)->cursor[k] = cursor; (*c)->name[k] = name ? StrCpy (name) : NULL; (*c)->cursorCurr = cursor; return cursor; } static CURSORo *IcaCursorGetCurr (ICAoCursor *c) { return c->cursorCurr; } static void IcaCursorDelete (ICAoCursor **c) { Int4 k; if (!*c) return; for (k=0; k < (*c)->cursorN; k++) { CursorDelete (&(*c)->cursor[k]); if ((*c)->name[k]) StrDel ((*c)->name[k]); } free (*c); *c=NULL; return; } void IcaSetLogicStream (ICAoJOB *job, char *name) { STRv s=StrTemp (name); if (!IcaCursorGet (job->inCursor, s)) IcaCursorSet (&job->inCursor, CursorNew (), s); } /**API* IcaCreateJob ********************************************************* ** ** This function creates and initializes a new job object which is ** needed for iterating through, eg, a flat file databank. A job object ** is generally needed when the parser should step through a file and ** halt at some position, eg, the entry end. **

    ** To associate the 'job' to the input (file or string) use IcaNewJob. ** ** INPUT: the syntax object [W] ** IMPLICIT: ** Job (ICAoJOB *) ** ** RETURNS: address of new job object */ ICAoJOB *IcaCreateJob(ICAoSYNTAX *syntax) { ICAoJOB *job; if ((job = (ICAoJOB *) calloc (sizeof(ICAoJOB), 1)) == NULL) _ErrExit2 (e__allocfail, "job object"); if (!NameListId) LstManageClass(&NameListId, sizeof(ICAoNAMELIST), NULL, NameKill,NameDump); job->syntax = syntax; job->parseError = 0; job->syntax->taskList = NULL; /* define icarus commands */ LocalSetFunctions (); BnfSetOpFunctions (); IcaOpLibrary(); /* initialize syntax */ if (!syntax->prod) { job->time = BNFxBUILDTIME; BnfBuild (syntax); job->scope = (VARoSCOPE *) VarCopyScope (syntax->scope); IcaContext ("push", &job); BnfInitRules (syntax, 0); /* run "init" programs */ IcaContext ("pop", NULL); job->time = 0; } else job->scope = (VARoSCOPE *) VarCopyScope (syntax->scope); return job; } /**API* IcaJobDestroy ********************************************************* ** ** Deletes a job object. ** ** INPUT: address of the pointer to the job object [W] ** */ void IcaJobDestroy (ICAoJOB **job) { ICAoJOB *tmp; if (job && *job) { tmp = *job; if (tmp->inCursor) IcaCursorDelete (&tmp->inCursor); if (tmp->tokList) TokDeleteAllLists (tmp->tokList); if (tmp->scope) VarScopeDestroy (&tmp->scope); free (tmp); *job = NULL; } } /**API* IcaDoJob ************************************************************* ** ** Activates the parser with the specified start production. Function ** requires a job object created with JobCreateJob which is already ** associated with the input (file, string) using IcaJobSetFile or ** IcaJobSetString. ** ** INPUT: the job object [W] ** the name of the start production (start symbol) [R] ** IMPLICIT: ** Job (ICAoJOB *) ** ** RETURNS: TRUE if parsing was successful ** FALSE otherwise */ INT4 IcaDoJob (ICAoJOB *job, char *startName) { BNFoPRODUCTION *start; Int4 rv; if (!(start = BnfGetProduction (job->syntax, startName, 0))) _ErrRet3 (e__objectunknown, "start production", startName); IcaContext ("push", &job); rv = BnfParseProduction (start); IcaContext ("pop", NULL); return rv; } void IcaExecProg (ICAoJOB *job) { if (job->prog) { IcaContext ("push", &job); VarExec (job->prog); IcaContext ("pop", NULL); } } void IcaContext (char *option, ICAoJOB **job) { static INT4 count=-1; static struct { ICAoJOB *job; CURSORo *cursor; VARoSCOPE *globalScope; } context[100]; switch (option[1]) { case 'u': /* push */ if (count >= 100 - 1) _ErrExit3 (f__limitexceeded, "Parsing contexts", 100); count++; context[count].job = Job; context[count].globalScope = globalScope; Job = *job; if (Job->scope) globalScope = Job->scope; break; case 'o': /* pop */ if (count) { Job = context[count].job; globalScope = context[count].globalScope; count--; if (job) *job = Job; } break; default: _ErrExit2 (e__unknownoption, option); } } static void IcaJobActivate (ICAoJOB *job) { job->parseError = 0; job->doAdvance = 1; job->isActive = 1; job->cursor = IcaCursorGetCurr (job->inCursor); } /**API* IcaNewJob ************************************************************ ** ** Takes a job object created by IcaCreateJob and associates it ** with the input to be parsed. The input can ** be either a file or a string. The parsing itself can be initiated ** by IcaDoJob (forced parsing) or by IcaGetTokenList (lazy parsing). ** Both functions may parse through only part of the input. To continue ** call first IcaEndJob and then IcaNewJob again. **

    ** The parsing can process can be influenzed for both lazy and forced ** parsing by activating a 'task' with IcaSetTask. ** ** INPUT: o job object [W] ** o file object (file must be opened for read access) ** [R] or NULL ** o string to be parsed [R] or NULL ** IMPLICIT: ** Job (ICAoJOB *) ** ** RETURNS: TRUE - new job prepared ** FALSE - if the input (file) is exhausted */ INT4 IcaNewJob(ICAoJOB *job, FILEo *file, char *string) { CURSORo *cursor; job->file = file; TokGetList(INTOKLIST, &job->tokList); if (!TokIsListActive (job->tokList) || file || string) { if (TokIsListActive (job->tokList)) TokResetList (job->tokList); if (string && strlen(string) ) { TokSetStyle (job->tokList, "copy"); TokAdd (job->tokList, string, strlen (string), ICAxUNDEFCODE); } else if (file) { if (FileIsEof (file)) return(FALSE); TokSetFile(job->tokList, file); } else return(FALSE); cursor = IcaCursorSet (&job->inCursor, CursorNew (), NULL); CursorInstall (cursor, TokGetFirst (job->tokList), job->tokList); } IcaJobActivate (job); return(TRUE); } /**API* IcaJobNext ************************************************************ ** ** Takes a job object created by IcaCreateJob. ** ** INPUT: job object ** IMPLICIT: ** Job (ICAoJOB *) ** ** RETURNS: TRUE - new job prepared ** FALSE - if the input (file) is exhausted */ void IcaJobNext(ICAoJOB *job) { CURSORo *cursor; TOKoLIST *tokList; Int4 k; if (IcaIsActive (job)) IcaEndJob (job); job->tokList = tokList = TokGetList (INTOKLIST, &job->tokList); if (!TokIsListActive(tokList)) { for (k=0; k < job->inCursor->cursorN; k++) { cursor = job->inCursor->cursor[k]; CursorInstall (cursor, TokGetFirst (tokList), tokList); } } IcaJobActivate (job); } /**API* IcaJobSetString ******************************************************* ** ** Sets a new input string with which to continue next job. ** ** INPUT: job object [W] ** string [R] */ void IcaJobSetString (ICAoJOB *job, char *str) { CURSORo *cursor; TOKoLIST *tokList; tokList = TokGetList (INTOKLIST, &job->tokList); if (TokIsListActive (tokList)) TokResetList (tokList); TokSetStyle (tokList, "copy"); TokAdd (tokList, str, strlen (str), ICAxUNDEFCODE); cursor = IcaCursorSet (&job->inCursor, CursorNew (), NULL); CursorInstall (cursor, TokGetFirst (tokList), tokList); IcaJobActivate (job); } /**API* IcaJobSetFile ******************************************************** ** ** Sets a new input file with which to continue next job. ** ** INPUT: job object [W] ** string [R] */ void IcaJobSetFile (ICAoJOB *job, FILEo *file) { CURSORo *cursor; TOKoLIST *tokList; tokList = TokGetList (INTOKLIST, &job->tokList); if (TokIsListActive (tokList)) TokResetList (tokList); job->file = file; TokSetFile (tokList, file); cursor = IcaCursorSet (&job->inCursor, CursorNew (), NULL); CursorInstall (cursor, TokGetFirst (tokList), tokList); IcaJobActivate (job); } /**api* IcaIsActive *********************************************************** ** ** Returns TRUE if the job object is active ie initiated by IcaNewJob, ** IcaNextJob. The job can be terminated by IcaEndJob. ** See also IcaNextJob. ** ** INPUT: job object [W] ** ** RETURNS: 1: active ** 0: not active */ Int4 IcaIsActive (ICAoJOB *job) { return job->isActive; } /**api* IcaIsActive *********************************************************** ** ** Returns TRUE if the input for the next job is exhausted. Applicable *** for both input from a file or from a string. ** ** INPUT: job object [R] ** ** RETURNS: 1: no more input ** 0: input still left */ Int4 IcaIsJobEnd (ICAoJOB *job) { if (!job->file && job->inputStreamer) return 0; else return job->file ? FileIsEof (job->file) : CursorIsEnd (IcaCursorGetCurr (job->inCursor)); } Int4 IcaIsInputEnd (ICAoJOB *job) { return job->isInputEnd; } Int4 IcaSetInputEnd (ICAoJOB *job) { job->isInputEnd = 1; } /**API* IcaEndJob ************************************************************* ** ** Resets a job object and prepares it for the next call to IcaNewJob. ** It does NOT delete the job object. ** Use of this function should be replaced by the combination of ** IcaJobNext and IcaJobSetString. ** ** INPUT: job object [W] ** IMPLICIT: ** Job (ICAoJOB *) ** */ void IcaEndJob(ICAoJOB *job) { TOKoLIST *tokList = job->tokList; if (job->isActive) { if (tokList) { LstFirst((void **) &tokList); do { if (!SmEqs (tokList->name, INTOKLIST)) TokResetList(tokList); }while(LstNext((void **) &tokList)); } TaskDisableAll(Job->syntax->taskList); job->isActive = 0; job->isInputEnd = 0; } } /**API* IcaGetInputString ***************************************************** ** ** Returns the input string of the specified job. This is used when ** the parsing job modifies the string which must be reallocated to ** (most probably) a new address if the string grows in size. ** Must be called before IcaEndJob. ** ** INPUT: job object [W] ** ** RETURNS: the input string ** */ char *IcaGetInputString (ICAoJOB *job) { /* pointer is not enough since token is not 0 terminated - would be nice to return a STRv */ return TokGetStringCopy (job->tokList, TokGetFirst (job->tokList)); } void IcaPrintMessage (MSGo *msg) { char *fileName, fileLoc[200]=""; INT4 lnN; switch(msg->msg_code) { case e__duplicatekey: case e__icaUnknownClass: case e__parsererror3: /* report position in current input file */ case e__parsererror2: /* report position in current input file */ if ((fileName = IcaGetCurrFileName ("input"))) { lnN = IcaGetCurrLineN ("input"); sprintf (fileLoc, "%s:%d: ", fileName, lnN); } break; default: /* report position in program */ if (!MsgIs (msg, "info")) { if ((fileName = IcaGetCurrFileName ("prog"))) { lnN = IcaGetCurrLineN ("prog"); sprintf (fileLoc, "%s:%d: ", fileName, lnN); } } break; } if (msg->msg_t == MSGxINFO) fprintf (stderr, "%s\n", msg->secmsg); else { IcaJobSetErrorFlag (Job, 1); if (*fileLoc) fprintf (stderr, fileLoc); if (msg->secmsg && *msg->secmsg) fprintf (stderr, "error: %s, %s\n", msg->primsg, msg->secmsg); else fprintf (stderr, "error: %s\n", msg->primsg); } } /**api* IcaJobSharesScope ***************************************************** ** ** Lets a job share its variable scope with another job. ** The sharing works only if the other job does not have a scope ** already. ** ** INPUT: job with the scope to be shared [W] ** job with which to share the scope [W] ** ** RETURNS: 1: if the two jobs can share ** 0: if the second job has a scope already */ Int4 IcaJobSharesScope (ICAoJOB *job1, ICAoJOB *job2) { return 0; if (job2->scope) return 0; else /* job2->scope = job1->scope;*/ return 1; } /**API* IcaGetTokenList ******************************************************* ** ** Retrieves a token list from the current job. If the token table ** does not yet exist it will result in the initiation of the parsing ** process. This behaviour is called "lazy parsing". The function ** requires an active 'job' which is provided by IcaNewJob. ** ** INPUT: the job object [W] ** name of the desired output token list [W] ** ** RETURNS: address of the token list ** NULL: parsing failed to produce the token list */ TOKoLIST *IcaGetTokenList (ICAoJOB *job, char *name) { TOKoLIST *tokList, *tokListRead; BNFoPRODUCTION *production; INT4 rv; IcaJobSharesScope (Job, job); IcaContext("push", &job); tokList = TokGetList(name, &job->tokList); /* if tokList is empty, activate producer production */ if( !TokIsListActive(tokList) ) { production = IcaGetSupplyNode(name); /* "parent" tokList found, it is possible to read it and to parse */ if(production->rdTokList) { tokListRead = IcaGetTokenList (job, production->rdTokList->name); if(TokIsListActive (tokListRead)) { job->cursor = CursorNew(); rv = BnfParseProdLoop (production); } } else { /* chose job input token list */ tokListRead = TokFindList(INTOKLIST, &job->tokList); job->cursor = IcaCursorGetCurr (job->inCursor); rv = BnfParseProduction(production); } if (!IcaCursorIsInput (job->inCursor, job->cursor)) { CursorDelete (&job->cursor); job->cursor = NULL; } } IcaContext("pop", NULL); tokList->isActive=1; /* te!!!*/ return(tokList); } /**API* IcaSetInputStreamer *************************************************** ** ** Sets a function to be called by the $In command. ** ** INPUT: o job object [W} ** o function that returns a file object and takes the ** symbolic stream name (see LibGetFileType), and ** the streamer data (see IcaSetInputStreamerData). */ void IcaSetInputStreamer (ICAoJOB *job, FILEo *(*func)(char*, void*)) { job->inputStreamer = func; } /**API* IcaSetInputStreamerData *********************************************** ** ** Sets optionally ** the data for the input streamer defined by IcaSetInputStreamer. ** ** INPUT: job object [W} ** pointer to the data object [R] */ void IcaSetInputStreamerData (ICAoJOB *job, void* data) { job->inputStreamerData = data; } /**API* IcaSetInputFile ******************************************************* ** ** Sets an input file for a job activated with IcaJobNext. ** ** INPUT: job object [W} ** file object [R] or NULL (end of file input) ** logical name of the file [R] or NULL */ void IcaSetInputFile (ICAoJOB *job, FILEo *file, STRv name) { TokSetFile (job->tokList, file); job->cursor = IcaCursorGet (job->inCursor, name); if (file && !file->lnN) /* if file just opened */ CursorSetFile (job->cursor, file); job->file = file; } /**API* IcaSetTask ************************************************************ ** ** Enable or disable a 'task' for the current 'job' set by ** IcaNewJob. This function must be called BEFORE initiating the ** parsing process. ** ** INPUT: the job object [W] ** task name [R] ** flag: TRUE activates, FALSE deactivates ** IMPLICIT: ** ** RETURNS: */ void IcaSetTask (ICAoJOB *job, char *taskName, INT4 flag) { if (flag) TaskEnable (job->syntax->taskList, taskName); else TaskDisable (job->syntax->taskList, taskName); } static struct ICAoNAMELIST *funcList=NULL; /* list of function pointers */ /**API* IcaSetFunction ******************************************************* ** ** Put the function pointer in the special named list ** ** INPUT: name of a function ** pointer to the function ** IMPLICIT: ** list reference Job->funcList ** ** RETURNS: */ void IcaSetFunction(char *functionName, FUNC function) { if( !LstHashSearch((void **) &funcList, functionName) ) { LstNew((void **) &funcList, NameListId); strcpy(funcList->name, functionName); funcList->pointer = (void *)function; } } /**API* IcaGetFunction ******************************************************* ** ** Get the pointer to function by it name in the list of ** function pointers. ** ** INPUT: name of a function ** IMPLICIT: ** list reference Job->funcList ** ** RETURNS: ** pointer to the function */ FUNC IcaGetFunction(char *functionName) { if (LstFirstNamed ((void **) &funcList, functionName)) return (FUNC)funcList->pointer; else return NULL; } /**API* IcaFunctionName ****************************************************** ** ** Find function name by it pointer in the function list. ** ** INPUT: function pointer ** IMPLICIT: ** list reference Job->funcList ** ** RETURNS: ** function name */ char *IcaFunctionName (Func function) { if( LstFirst((void **) &funcList) ) do { if(function == (Func) funcList->pointer) return(funcList->name); }while( LstNext((void **) &funcList) ); return(NULL); } /**API* IcaGetSupplyNode ***************************************************** ** ** Find a node that can supply input token list for given toklist ** ** INPUT: token list name ** IMPLICIT: ** list of production names: Job->prodList ** ** RETURNS: ** node pointer ** exit otherwise */ BNFoPRODUCTION *IcaGetSupplyNode(char *tokListName) { VARo *var; TOKoLIST *tokList; BNFoPRODUCTION *prod; Int4 i; if (Job->syntax->prod) { for (i=0; (var = AnyNextInList (Job->syntax->prod, &i)); ) { prod = VarGetObject (NULL, var); if( (tokList = prod->wrtTokList) != NULL) if( !strcmp(tokListName, tokList->name) ) return(prod); } } _ErrExit3 (e__objectunknown, "Output token list", tokListName); } /**API* IcaErrPrint ********************************************************** ** ** Pretty-print function to print parsing error ** ** INPUT: production name ** fail pattern ** beginning of input token ** point where pattern fail ** IMPLICIT: ** ** RETURNS: */ void IcaErrPrint(char *nodeName, char *pattern, char *begin, char *point) { static char line[MAXPRINTSIZE+1], dots[MAXPRINTSIZE+1]; static STRv pat=NULL; char *ptr; INT4 len, isEOL; if (pattern) { if (!pat) pat=StrNew (); StrSetS (&pat, pattern); StrEncode (&pat); } memset(line, 0, MAXPRINTSIZE); memset(dots, 0, MAXPRINTSIZE); isEOL = FALSE; ptr = point; len = 0; if(*ptr == '\n') { ptr--; len++; isEOL = TRUE; } while(ptr > begin && len < MAXPRINTSIZE/2 && *ptr != '\n') { len++; ptr--; } if(*ptr == '\n' && len) { ptr++; len--; } if(len) { strncpy(line, ptr, len); memset(dots, '.', len+1); if(isEOL) line[len] = ' '; } strcat(dots, "^"); ptr = point; len = 1; while(ptrfile ? FileGetName (Job->file, "file") : NULL; break; case 'p': if (Job->fileName) name = Job->fileName; else if (Job->syntax) name = Job->syntax->fileName; break; default: _ErrExit2 (e__unknownoption, option); } return name; } /**api* function ************************************************************** ** ** Returns the name of the file that is currently being parsed. ** ** INPUT: option "input" or "prog" [R] ** IMPLICIT: ** Job (ICAoJOB *job) [R] ** ** RETURNS: a file name */ INT4 IcaGetCurrLineN (char *option) { switch (option[0]) { case 'i': /* input */ return Job->file ? FileGetLineN (Job->file) : 0; case 'p': return Job->lineN; default: _ErrExit2 (e__unknownoption, option); } } /**api* function ************************************************************** ** ** Evaluates an string with a list of icarus statements. ** ** INPUT: the address of job object [W] or NULL. ** string with one or more Icarus statements [R] ** ** RETURNS: 1 */ INT4 IcaEval (ICAoJOB **jobPtr, char *prog) { static ICAoJOB *jobStatic=NULL; ICAoJOB **job; ICAoSYNTAX *syntax; job = jobPtr ? jobPtr : &jobStatic; if (!*job) { syntax = (ICAoSYNTAX*)LibObjByName ("syntax", "icarus"); *job = IcaCreateJob (syntax); } else IcaJobNext (*job); IcaJobSetString (*job, prog); IcaGetTokenList (*job, "prog"); IcaExecProg (*job); } /**api* function ************************************************************** ** ** Like IcaEval but takes the specified job with all its variables as ** environment. ** ** INPUT: string with one or more Icarus statements [R] ** job object to be used as environment [W] ** ** RETURNS: 1 */ INT4 IcaEvalInJob (char *prog, ICAoJOB *job) { static ICAoJOB *iJob=NULL, tmpJob; ICAoSYNTAX *syntax; if (!iJob) { syntax = (ICAoSYNTAX*)LibObjByName ("syntax", "icarus"); iJob = IcaCreateJob (syntax); iJob->scope = job->scope; } else IcaJobNext (iJob); IcaJobSetString (iJob, prog); IcaGetTokenList (iJob, "prog"); memcpy (&tmpJob, job, sizeof (ICAoJOB)); tmpJob.prog = iJob->prog; IcaExecProg (&tmpJob); } FILEo *IcaJobGetFile (ICAoJOB *job) { return job->file; } IcaJobSetErrorFlag (ICAoJOB *job, int flag) { job->isError=flag; } IcaJobIsError (ICAoJOB *job) { return job->isError; } syntax = (ICAoSYNTAX*)LibObjByName ("syntax", "icarus"); iJob = IcaCreateJob (syntax); iJob->scope = job->scope; } else IcaJobNext (iJob); IcaJobSetString (iJob, prog); IcaGetTokenList (iJob, "prog"); memcpy (&tmpJob, job, sizeof (ICAoJOB)); tmpJob.prog = iJob->prog; IcaExecProg (&tmpJob); } FILEo *IcaJosrs/src/icarus.h ** ** $RCSfile: icarus.h,v $ ** $Revision: 1.14 $ ** $Date: 1997/03/19 11:17:27 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** Copyright by Thure Etzold ** ** Author: Anatoly Ulyanov ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387451 ** Email: ulyanov@embl-heidelberg.de ** */ #define ICAxMAXNAMESIZE 32 #define MAXKEYWORDS 8 #define MAXARGSNUM 32 #define MAXNAMESIZE 32 #define MAXPRINTSIZE 72 #define MAXBRANCHES 128 #define MAXLINESIZE 512 #define NODE "NODE" #define COPYSTYLE "copy" #define ECHOSTYLE "echo" #define ENDOFINPUT "\001\003\005\007\009\013" #define TMPIN "@TmpStackIn" #define TMPOUT "@TmpStackOut" #define INTOKLIST "@DefStackIn" #define OUTTOKLIST "@DefStackOut" #define VARTOKLISTIN "tli" #define VARTOKLISTOUT "tlo" #define VARCODEIN "ci" #define VARCODEOUT "co" #define VARCURRTOKEN "ct" #define ICAxUNDEFCODE -1 #define ICAxNEWPARSEERROR 1 #define ICAxPARSEERROR 2 /* rename or delete */ #define PROGxBUILDTIME 1 #define PROGxPREPARSE 2 #define PROGxPOSTPARSE 4 typedef struct ICAoJOB { char *string; /* !obsolete! */ struct FILEo *file; /* file to parse */ struct TOKoLIST *tokList; /* list of tokLists */ struct ICAoSYNTAX *syntax; /* ICARUS syntax */ struct TOKoLIST *outTokList; /* current output tokList */ struct TOKoTOKEN *inToken; /* current input token */ struct regexp *regExp; /* current regExp */ struct BNFoNODE *currNode; /* current node */ struct VARoSCOPE *scope; /* the scope containing variables */ struct CURSORo *cursor; /* currently active cursor */ struct ICAoCursor *inCursor; /* state of 1 or more input streams*/ char *failPattern; /* pattern that fail to parse */ INT4 parseError; /* error code */ INT4 isNew; /* flag */ INT4 isOptional; /* flag */ INT4 time; /* time of Icarus statement execution */ INT4 isTrace; /* flag */ INT4 isTraceTree; /* flag */ INT4 isDebug; INT4 isActive; INT4 isInputEnd; Int4 isError; INT4 doAdvance; INT4 lineN; /* curr line no of curr program */ char *fileName; /* name of current program file */ struct VARo *prog; /* Icarus program compiled by "job" */ struct FILEo *(*inputStreamer)(char*,void*); void *inputStreamerData; } ICAoJOB; typedef struct ICAoSYNTAX { char *name; /* Name of the syntax. */ char *fileName; /* Name of the file with ICA rules */ char *rules; /* Pointer to rules */ struct SMoBUFF *buff; /* Buffer with ICA productions */ struct ICAoSYNTAX *commandSyntax; /* The syntax of for the commands. */ struct ICAoNAMELIST *prodList; struct ICAoCOMMAND *userCommand; struct TASKo *taskList; /* pool of task links */ char *ign; /* Chars to be ignored */ char *cmnt; /* reg exp for comments */ INT4 initflag; struct VARo *prod; /* list of productions as var objects*/ struct VARoSCOPE *scope; struct regexp *cmntRe; char *ignAlt; /* alternative set of skip chars */ } ICAoSYNTAX; #define _ICAoSYNTAX typedef struct ICAoNAMELIST { char *list; int listId; char name[ICAxMAXNAMESIZE]; void *pointer; INT4 isInit; } ICAoNAMELIST; /* module prototypes ***************************************/ typedef struct FILEo *dummytointroducestructtagFILEo; typedef struct ICAoJOB *ICAvJOB; struct BNFoPRODUCTION *IcaGetSupplyNode(char *tokListName); FUNC IcaGetFunction(char *); char *IcaFunctionName(FUNC); char *IcaGetCodeName(INT4); void IcaErrPrint(char *nodeName, char *pattern, char *begin, char *point); void IcaSetFunction(char *, FUNC); char *IcaGetCurrFileName (); INT4 IcaInterprete (char *prog); void IcaPrintMessage (MSGo *msg); /* working with parsing jobs */ void IcaContext (char *option, ICAoJOB **job); ICAvJOB IcaCreateJob (struct ICAoSYNTAX *); void IcaEndJob (ICAvJOB); Int4 IcaNewJob (ICAvJOB, struct FILEo *, char *); void IcaJobNext(ICAoJOB *job); void IcaJobSetString (ICAoJOB *job, char *str); void IcaJobDestroy (ICAoJOB **job); struct FILEo* IcaJobGetFile (ICAoJOB *job); void IcaSetTask (ICAvJOB, char *taskName, INT4 flag); void IcaSetInputStreamer (ICAvJOB, struct FILEo *(*func)(char*, void*)); void IcaSetInputStreamerData (ICAvJOB, void* data); void IcaSetInputFile (ICAvJOB, struct FILEo *file, struct STRo *name); struct TOKoLIST* IcaGetTokenList (ICAvJOB, char *); char* IcaGetInputString (ICAvJOB); Int4 IcaIsActive (ICAvJOB); INT4 IcaEvalInJob (char *prog, ICAvJOB job); INT4 IcaEval (ICAvJOB *job, char *prog); vJOB, char *taskName, INT4 flag); void IcaSetInputStreamer (ICAvJOB, struct FILEo *(*func)(char*, void*)); void IcaSetInputStreamerData (ICAvJOB, void* data); void IcaSetInputFile (ICAvJOB, struct FILEo *file, struct STRo *name); struct TOKoLIST* IcaGetTokenList (ICAvJOB, char *); char* IcaGetInputString (ICAvJOB); Int4 IcaIsActive (ICAvJOB); INT4 IcaEvalInJob (char *prog, ICAvJOB josrs/src/icarusi.c #include #include #include #include "srs.h" ICAoSYNTAX *IcaInitSyntax (ICAoSYNTAX *); static INT4 PrintMessage (MSGo *msg); void ReadBuiltin (ICAoSYNTAX *syntax) { FILEo *file; ICAoJOB *job; SDLo *odd; Int4 opt; /* never write C-conversion */ opt = ParGetBool("ica2C"); ParDefBool("ica2C", 0); ParDefBool ("doSection", 1); /* pointers instead of numbers */ job = IcaCreateJob (syntax); /* process class information */ odd = OddInit (oddObjs, 1); file = FileNew ("SRSSDL:builtin.ic"); if (!FileOpen (file)) _ErrExit2 (e__filnotok, "SRSSDL:builtin.ic"); IcaJobSetFile (job, file); IcaGetTokenList (job, "prog"); IcaExecProg (job); /* process objects */ odd = OddInit (odd, 2); file = FileNew ("SRSSDL:builtin.i"); if (!FileOpen (file)) _ErrExit2 (e__filnotok, "SRSSDL:builtin.i"); IcaJobSetFile (job, file, NULL); IcaGetTokenList (job, "prog"); FileClose (job->file); job->file = NULL; IcaExecProg (job); ParDefBool ("ica2C", opt); } main(int argc, char **argv) { SDLo *odd; ARGoLIST *arglist; FILEo *file; ICAoJOB *job; ICAoSYNTAX *syntax; char line[MAXLINESIZE], *tokStr, *name; INT4 printAll, tokCode, c, rv; SrsEnv (); LibOpen ("srs5"); MsgSetFnct ((FUNC)IcaPrintMessage); arglist = LibObjByName ("arglist", "try"); argc = ArgGet (arglist, argc, argv); if (!ParGetBool ("useIni")) syntax = IcaInitSyntax ((ICAoSYNTAX*)LibObjByName ("syntax", "icarus")); else syntax = (ICAoSYNTAX*)LibObjByName ("syntax", "icarus"); odd = OddInit (def, 1); if (ParGetBool ("doCommandInfo")) { IargPrintInfo (); exit (0); } if (argc != 2) { ArgUsage (arglist); _ErrorExit (); } job = IcaCreateJob (syntax); file = FileNew(argv[1]); if (!FileOpen (file)) _ErrExit2 (e__filnotok, argv[1]); IcaJobSetFile (job, file); IcaGetTokenList (job, "prog"); FileClose (job->file); job->file = NULL; if (IcaJobIsError (job)) _ErrExit (e__icaErrorsQuit); if (job->prog) { if (ParGetBool ("readBuiltin")) ReadBuiltin (syntax); IcaExecProg (job); } if (ParGetBool ("doClassInfo")) { odd = OddInit (odd, 2); OddWriteClassInfo (odd); } } } job = IcaCreateJob (syntax); file = FileNew(argv[1]); if (!FileOpen (file)) _ErrExit2 (e__filnotok, argv[1]); IcaJobSetFile (job, file); IcaGetTokenList (job, "psrs/src/icatask.c char icatask_srs_ID[] = "$Id: icatask.c,v 1.1 1996/05/06 15:16:43 srs Exp $"; /* ** $RCSfile: icatask.c,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:16:43 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** Copyright by Thure Etzold ** ** Authors: Thure Etzold ** Anatoly Ulyanov ** ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Description ** =========== ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include "message.h" #include "lst.h" #include "icatask.h" #define _SRS #include SRSINCLUDE /****** TaskLinkNew *********************************************************** ** ** Returns a new link object in the list of links. ** ** INPUT: link object list [W] ** IMPLICIT: ** ** RETURNS: new link object */ static TASKoLINK *TaskLinkNew (TASKoLINKS *links) { if (!links->linkAllocN) { if ((links->link = (void *) malloc (sizeof (TASKoLINK))) == NULL) _ErrExit2 (e__allocfail, "task link list"); links->linkN = 0; links->linkAllocN = 1; } else if (links->linkN >= links->linkAllocN) { links->linkAllocN *= 2; if ((links->link = (void *) realloc (links->link, links->linkAllocN * sizeof (TASKoLINK))) == NULL) _ErrExit2 (e__allocfail, "task link list"); } return &links->link[links->linkN++]; } /****** TaskIsRegister ******************************************************** ** ** Checks if the task is not already registered. ** ** INPUT: the name of the task [R] ** the syntax with which to register [W] ** IMPLICIT: ** ** RETURNS: TRUE if task registered ** FALSE otherwise ** */ INT4 TaskIsRegister (TASKo *task, char *name) { return(LstHashSearch((void **) &task, name)); } /****** TaskRegister ********************************************************** ** ** Registers a new task for the specified syntax and disables it. ** Checks first if the task is not already registered. ** ** INPUT: the name of the task [R] ** the syntax with which to register [W] ** IMPLICIT: ** ** RETURNS: the address of the flag whether the task is enabled or not ** */ static INT4 *TaskRegister (TASKo **task, char *name) { static int classId=0; if(!classId) LstManageClass (&classId, sizeof (TASKo), NULL, NULL, NULL); if (!LstHashSearch ((void **) task, name)) { LstNewNamed ((void **) task, classId, name); (*task)->isEnabled = 0; } return &((*task)->isEnabled); } /****** TaskEnable ************************************************************ ** ** Disables or deactivates a task for specified syntax. ** ** INPUT: task name [R] ** task object (list) [W] ** IMPLICIT: ** ** RETURNS: ** */ void TaskEnable (TASKo *task, char *name) { if (LstHashSearch ((void **) &task, name)) task->isEnabled = 1; } /****** TaskDisable *********************************************************** ** ** Disable or inactivates a task for specified syntax. ** ** INPUT: task name [R] ** task object (list) [W] ** IMPLICIT: ** ** RETURNS: ** */ void TaskDisable (TASKo *task, char *name) { if (LstHashSearch ((void **) &task, name)) task->isEnabled = 0; } /****** TaskDisablAll *********************************************************** ** Disable or inactivates all tasks. ** ** INPUT: task name [R] ** task object (list) [W] ** IMPLICIT: ** ** RETURNS: ** */ void TaskDisableAll(TASKo *task) { if( LstFirst((void **) &task) ) do { task->isEnabled = 0; } while( LstNext((void **) &task) ); } /**api* TaskAllocLinks ******************************************************** ** ** This function must be called during parser build time whenever ** a new link object requered for a node ** ** INPUT: ** RETURNS: */ static TASKoLINKS *TaskAllocLinks() { TASKoLINKS *links; if( (links = (TASKoLINKS *)malloc(sizeof(TASKoLINKS))) == NULL) _ErrExit2 (e__allocfail, "task links "); memset(links, NULL, sizeof(TASKoLINKS)); return(links); } /**api* TaskRequestLink ******************************************************* ** ** This function must be called during parser build time whenever ** a node (production) getting input from another production ** is associated with a task. ** This function will also register the task. ** ** INPUT: o task object (list) [W] ** o name of the task [R] ** o name of the input token list [R] ** o the token code if only tokens with that code should ** trigger the task [R] ** RETURNS: */ TASKoLINKS *TaskRequestLink (TASKo **task, char *taskName, struct BNFoPRODUCTION *currNode, TASKoLINKS *taskLinks) { TASKoLINK *link; if( !taskLinks ) taskLinks = TaskAllocLinks(); link = TaskLinkNew(taskLinks); link->node = currNode; link->isEnabledPtr = TaskRegister (task, taskName); return(taskLinks); } /**api* TaskNextActiveNode **************************************************** ** ** Returns the next (if any) active node associated with a currently ** active task and matching token code. ** ** INPUT: link object list [W] ** token code [R] ** pointer to iteration context - set to 0 to begin iter. [W] ** IMPLICIT: ** ** RETURNS: new link object */ struct BNFoPRODUCTION *TaskNextActiveNode (TASKoLINKS *linkList, INT4 *context) { TASKoLINK *link; while (1) { if (*context >= linkList->linkN) { *context = 0; return NULL; } link = &linkList->link[(*context)++]; if (*link->isEnabledPtr) break; } return link->node; } ** token code [R] ** pointer to iteration context - set to 0 to begin iter. [W] ** IMPLICIT: ** ** RETURNS: new link object */ struct BNFoPRODUCTION *TaskNextActiveNode (TASKoLINKS *linkList, INTsrs/src/icatask.h ** ** $RCSfile: icatask.h,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:16:44 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** Copyright by Thure Etzold ** */ typedef struct TASKo { char *list; /* for usage of module "list" only! */ INT4 class_id; /* for "list" module */ char name[30]; INT4 isEnabled; } TASKo; typedef struct TASKoLINK { struct BNFoPRODUCTION *node; INT4 *isEnabledPtr; } TASKoLINK; typedef struct TASKoLINKS { TASKoLINK *link; INT4 linkAllocN; INT4 linkN; } TASKoLINKS; /* module prototypes ***************************************/ void TaskEnable (TASKo *task, char *name); void TaskDisable (TASKo *task, char *name); void TaskDisableAll (TASKo *task); INT4 TaskIsRegister (TASKo *task, char *name); struct BNFoPRODUCTION *TaskNextActiveNode (TASKoLINKS *, INT4 *); TASKoLINKS *TaskRequestLink (TASKo **, char *, struct BNFoPRODUCTION *, TASKoLINKS *); { TASKoLINK *link; INT4 linkAllocN; INT4 linkN; } TASKoLINKS; /* module prototypes ***************************************/ void TaskEnable (TASKo *task, char *name); void TaskDisable (TASKo *task, char *name); void TaskDisableAll (TASKo *task); INT4 TaskIsRegister (TASKo *task, char *name); struct BNFoPRODUCTION *TaskNextActiveNode (TASKoLINKS *, INT4 *); TASKoLINKS *TaskRequestLink (TASKo **, char *srs/src/id.c char id_ID[] = "$Id: id.c,v 1.4 1997/03/03 18:20:38 srs Exp $"; /* ** ** $RCSfile: id.c,v $ ** $Revision: 1.4 $ ** $Date: 1997/03/03 18:20:38 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port: Lukas Rosenthaler and Reinhard Doelz ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** Requires: file, sm, message ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** functions for manupulating IDs ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include "message.h" #include "sm.h" #include "futil.h" #include "binpack.h" #include "id.h" #include "library.h" /**api* IdSplit *************************************************************** ** ** Splits an ID into its components and ** populates all fields of the id object. ID object can be obtained ** by IdBuild. ** ** INPUT: id object [W] ** IMPLICIT: ** ** RETURNS: */ void IdSplit (IDoENTRY *id) { IDPTR tmp; tmp = id->id + id->idType->fddbeg; _BinUnpack3Byte (tmp, id->fip); id->siz = id->idType->siz; id->lib_x = (unsigned char) id->id[id->idType->lbxbeg]; /* library index */ tmp = id->id + id->idType->lxbeg; if (id->idType->lxlen > 0) _BinUnpack2Byte (tmp, id->subentry_n); /* subentry number */ else id->subentry_n = 0; } /**api* IdMakeFromBuff ******************************************************** ** ** Takes a buffer to an ID buffer and creates a temporary ID object which ** will be overwritten in the next call to IdMakeFromBuff. ** Populates all fields of the id object. ** ** INPUT: id buffer [R] ** id type object [R] ** IMPLICIT: ** ** RETURNS: temporary ID object */ IDoENTRY *IdMakeFromBuff (IDPTR tmp, IDoTYPE *idType) { static IDoENTRY id; memset (&id, 0, sizeof (IDoENTRY)); id.idType = idType; memcpy (id.id, tmp, idType->siz); IdSplit (&id); return &id; } /**api* IdBuild ** ************************************************************ ** ** builds an ID from fadd and library-index; function assumes fixed l ** lengths for all parts of the ID ...which is because of the byte anding ** and shifting - macros should be done for packing and unpacking ** numbers with a flexible byte length (as argument...switch..) **

    ** Function assigns the id an ID-type object if still missing. ** ** INPUT: address of ID [W] ** library ID [R] ** file pointer to record in ID index [R] ** list index [R] or 0 ** ** IMPLICIT: ** ** RETURNS: 1 */ INT4 IdBuild (IDoENTRY *id, INT4 libId, UINT4 fip, INT4 list_x) { IDoTYPE *idType=id->idType; IDPTR tmp; /* get the ID-type if missing */ if (!idType) { idType = LibGetIdType (NULL, libId, list_x ? 6 : 4); id->idType = idType; } id->lib_x = libId; id->fip = fip; tmp = id->id + idType->fddbeg; /* fip */ _BinPack3Byte (tmp, fip); id->siz = id->idType->siz; id->id[idType->lbxbeg] = libId; /* library ID */ if (idType->lxlen == 2) { /* subentry ID */ tmp = id->id + idType->lxbeg; _BinPack2Byte (tmp, list_x); } return 1; } /**API* IdCopy *************************************************************** ** ** Copies an ID. ** ** INPUT: address of output ID [W] ** address of input ID [R] ** IMPLICIT: ** ** RETURNS: */ void IdCopy (IDoENTRY *a, IDoENTRY *b) { memcpy (a->id, b->id, b->siz); a->siz = b->siz; a->lib_x = b->lib_x; a->idType = b->idType; a->fip = b->fip; a->subentry_n = b->subentry_n; } /**API* IdToStr *************************************************************** ** ** Converts an ID into a string with a hexadecimal number. ** An ID of four byte is converted to a string 8 byte long. ** ** INPUT: address of ID-object [R] ** address of output hex number string [W] ** IMPLICIT: ** ** RETURNS: */ INT4 IdToStr (IDoENTRY *id, char *numstr) { char *tmp; INT4 k; /* ** go through each byte of ID (from first to last) convert it into ** two digit hex num - one digit numbers gets a '0' in front and copy ** it into a growing number string; */ for (k=0; k < id->idType->siz; k++) { tmp = &numstr[k*2]; sprintf (tmp, "%2x", id->id[k]); if (*tmp == ' ') *tmp = '0'; /** prefix a "0" if it is a one digit hexnum */ } return 1; } /**API* IdFromStr ************************************************************ ** ** Converts a string with a hexadecimal number into an ID object. ** ** INPUT: address of ID object [W] ** string with hex number [W] ** IMPLICIT: ** ** RETURNS: 1 if success ** e__novalentryidlen + */ INT4 IdFromStr (IDoENTRY *id, char *numstr) { INT4 len, k, num; char *tmp; len = strlen (numstr); id->siz = len / 2; /* ** find an appropriate id type description...this is only preliminary ** to give IdSplit the ID description with correct offsets...should ** be replaced later by correct ID type */ if (!(id->idType = LibGetIdType (NULL, 0, id->siz))) _ErrRet3 (e__novalentryidlen, id->siz, numstr); /* ** exactly reverse SrsIDToStr ...go through number string from the ** end to the beginning in steps of two characters; */ for (k= id->siz - 1; k >= 0; k--) { tmp = &numstr[k*2]; sscanf (tmp, "%x", &num); id->id[k] = num; *tmp = '\0'; } IdSplit (id); /* ** now we can access the library-ID and assign the correct ** idType */ id->idType = LibGetIdType (NULL, id->lib_x, id->siz); return 1; } /**api* IdIsSub ************************************************************ ** ** returns TRUE if the ID is pointing to a subentry; ** ** INPUT: address of number string [W] ** IMPLICIT: ** ** RETURNS: ID-object */ INT4 IdIsSub (IDoENTRY *id) { if (id->idType && id->idType->siz < 6) return 0; if (id->siz < 6) return 0; return 1; } /**api* IdGetSubN ************************************************************* ** ** Returns the subentry number; ** ** INPUT: ID object [R] ** IMPLICIT: ** ** RETURNS: subentry number */ INT4 IdGetSubN (IDoENTRY *id) { return id->subentry_n; } /**api* IdSize *************************************************************** ** ** Returns the size of the ID in bytes ** INPUT: address of ID-type object [R] ** ** RETURNS: size of ID in bytes */ Int4 IdSize (IDoTYPE *idType) { return idType->siz; } /**api* IdGetName ************************************************************* ** ** Returns the name of the ID type in bytes ** INPUT: address of ID-type object [R] ** ** RETURNS: id name */ char *IdGetName (IDoTYPE *idType) { return idType->nam; } /**api* IdPatch *************************************************************** ** ** ** INPUT: address of ID-object [R] ** IMPLICIT: ** ** RETURNS: hexnumber string */ INT4 IdPatch (IDoENTRY *id, char *patchList) { return 1; } /**api* IdBuildSub ************************************************************ ** ** combines an entry-ID and a subentry number to a subentry-ID ** ** INPUT: address of output subentry-ID object [W] ** input entry-ID object [R] ** subentry number [R] ** IMPLICIT: ** ** RETURNS: 0: if subEntryN is not valid ** 1: success */ INT4 IdBuildSub (IDoENTRY *idSub, IDoENTRY *id, INT4 subEntryN) { static IDoTYPE *idType=NULL; IDPTR tmp; if (!idType) idType = (IDoTYPE*) LibObjByName ("idType", "SubEntry-ID"); if (subEntryN < 0 || subEntryN > 65536) return 0; memcpy ((idSub->id + idType->fddbeg), id->id, id->siz); tmp = idSub->id + idType->lxbeg; _BinPack2Byte (tmp, subEntryN); idSub->idType = idType; idSub->siz = idType->siz; return 1; } if subEntryN is not valid ** 1: success */ INT4 IdBuildSub (IDoENTRY *idSub, IDoENTRY *id, INT4 subEntryN) { static IDoTYPE *idType=NULL; IDPTR tmp; if (!idType) idsrs/src/id.h ** ** $RCSfile: id.h,v $ ** $Revision: 1.3 $ ** $Date: 1996/11/20 16:36:16 $ ** $Author: etzold $ ** ** $Locker: $ ** $State: Exp $ ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port: Lukas Rosenthaler and Reinhard Doelz ** */ #define IDxXID 12 /* same as SRSxXID, max size of ID */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** definition of an ID type - this object class is also defined in ODD */ #ifndef _IDoTYPE #define _IDoTYPE typedef struct IDoTYPE { char *nam; INT4 siz; INT4 fddbeg; INT4 fddlen; INT4 lbxbeg; INT4 lbxlen; INT4 lxbeg; INT4 lxlen; INT4 (*cpy) (); } IDoTYPE; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Descriptor of an entry- or subentry-ID. This ID can be obtained ** from a "set" and used to open the corresponding "entry". */ typedef struct IDoENTRY { INT4 siz; /* length of the ID */ INT4 lib_x; /* (API) part of entry-ID that identifies the library where the entry resides */ UINT4 fip; /* part of entry-ID: pointer to node in ID-inx */ INT4 subentry_n; /* (API) part of subentry-ID: number of subentry within entry*/ unsigned char id[IDxXID]; /* entry-ID itself */ struct IDoTYPE *idType; /* descriptor of entry-ID type */ } IDoENTRY; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ... */ #define _IdPatch(id, idPatch, idType) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** function prototypes */ INT4 IdBuild (IDoENTRY *id, INT4 libId, UINT4 fip, INT4 list_x); INT4 IdToStr (IDoENTRY *id, char *numstr); INT4 IdFromStr (IDoENTRY *id, char *numstr); INT4 IdIsSub (IDoENTRY *id); INT4 IdBuildSub (IDoENTRY *idSub, IDoENTRY *id, INT4 subEntryN); INT4 IdPatch (IDoENTRY *id, char *patchList); void IdSplit (IDoENTRY *id); IDoENTRY *IdMakeFromBuff (IDPTR tmp, IDoTYPE *idType); void IdCopy (IDoENTRY *a, IDoENTRY *b); Int4 IdSize (struct IDoTYPE *idType); char *IdGetName (struct IDoTYPE *idType); otypes */ INT4 IdBuild (IDoENTRY *id, INT4 libId, UINT4 fip, INT4 list_x); INT4 IdToStr (IDoENTRY *id, char *numstr); INT4 IdFromStr (IDoENTRY *id, char *numstr); INT4 IdIsSubsrs/src/ids.c char ids_ID[] = "$Id: ids.c,v 1.5 1997/03/18 17:20:21 srs Exp $"; /* ** ** $RCSfile: ids.c,v $ ** $Revision: 1.5 $ ** $Date: 1997/03/18 17:20:21 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.x Copyright by Thure Etzold ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** Requires: ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include "message.h" #include "sm.h" #include "binpack.h" #include "futil.h" #include "tm.h" #include "id.h" #include "ids.h" #include "set.h" #include "library.h" #include "map.h" #define IDSxCURRENT_VERSION 1000000 #define IDSxMAXINFOBUFF 300 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of static functions */ static void IdsInfoWrite (IDSoFILE *idsFile); static INT4 IdsInfoRead (IDSoFILE *idsFile); /**api* IdsOpen *************************************************************** ** ** opens an IDS file (ID or entry pointer list); ** ** INPUT: o address of file name [R] ** o string specifying access type: ** "read", "write", "compress", "merge" [R] ** o size of cache (in blocks of 512 bytes) ** used for writing the IDS, or NULL [R] ** o name of id-type [R] or NULL ** o address of error code [W] or NULL ** e__iscompressed ** e__indexisbusy ** e__notcompressed ** e__filopenerr ** ** IMPLICIT: ** ** RETURNS: new btree object ** NULL if there is a problem */ IDSoFILE *IdsOpen (char *name, char *option, INT4 cacheSize, char *idTypeName, INT4 *errCode) { IDSoFILE *idsFile; char fileName[FILxXNAM+1]; INT4 rv; /* main object */ if ((idsFile = (IDSoFILE *) calloc (1, sizeof (IDSoFILE))) == NULL) _ErrExit2 (e__allocfail, "idsFile-object"); sprintf (fileName, "%s.ids", name); strcpy (idsFile->fileName, _FilTempLN (fileName)); if (idTypeName) { if (!(idsFile->idType = (IDoTYPE *) LibObjByName ("idtype", idTypeName))) _ErrExit3 (e__objectunknown, "idType", idTypeName); strcpy (idsFile->idTypeName, idTypeName); } switch (tolower (option[0])) { case 'r': /* read */ if (!(idsFile->file = fopen (idsFile->fileName, "rb"))) { _ErrSet (errCode, e__filopenerr); return NULL; } rv = IdsInfoRead (idsFile); _ErrIf (rv) return NULL; if (!(idsFile->idType = (IDoTYPE *) LibObjByName ("idtype", idsFile->idTypeName))) _ErrExit3 (e__objectunknown, "idType", idTypeName); if (idsFile->isBusy) _ErrSet (errCode, e__indexisbusy); else if (!idsFile->isCompressed) { _ErrSet (errCode, e__notcompressed); return idsFile; } else return idsFile; fclose (idsFile->file); free (idsFile); return NULL; case 'c': /* compress */ /* virtual memory object */ if ((idsFile->vm = (MAPo *) calloc (1, sizeof (MAPo))) == NULL) _ErrExit2 (e__allocfail, "virtual memory object"); rv = MapMem ((MAPo *) idsFile->vm, idsFile->fileName, NULL, 0); _ErrIf (rv) { free (idsFile); return NULL; } IdsInfoRead (idsFile); rv = IdsInfoRead (idsFile); _ErrIf (rv) { free (idsFile); return NULL; } idsFile->idType = (IDoTYPE *) LibObjByName ("idtype", idsFile->idTypeName); if (idsFile->isBusy) { _ErrSet (errCode, e__indexisbusy); return NULL; } else if (idsFile->isCompressed) { _ErrSet (errCode, e__iscompressed); return NULL; } #ifndef VMS /* ** delete the IDS previously opened for read access - only one ** version of the file can exist at a time (the output file) the ** input file has been just read into memory */ remove (idsFile->fileName); #endif /* cache */ if ((idsFile->cache = (MAPoCCH *) calloc (1, sizeof (MAPoCCH))) == NULL) _ErrExit2 (e__allocfail, "ids-cache-object"); idsFile->cache->nbloc = cacheSize; MapInitCache (idsFile->cache, idsFile->fileName, &idsFile->fileSize, 1); idsFile->isBusy = 1; idsFile->isCompressed = 1; idsFile->idsInsertedN = 0; IdsInfoWrite (idsFile); break; case 'm': /* merge */ idsFile->isCompressed = 1; case 'w': /* write */ if (!idsFile->idType) _ErrExit2 (e__parnotdefined, "Id-type"); /* cache */ if ((idsFile->cache = (MAPoCCH *) calloc (1, sizeof (MAPoCCH))) == NULL) _ErrExit2 (e__allocfail, "ids-cache-object"); idsFile->cache->nbloc = cacheSize; rv = MapInitCache (idsFile->cache, idsFile->fileName, &idsFile->fileSize, 1); _ErrIf (rv) { free (idsFile); return NULL; } idsFile->isBusy = 1; IdsInfoWrite (idsFile); idsFile->idsInsertedN = 0; break; default: _ErrExit2 (e__unknownoption, option); } return idsFile; } /**api* IdsClose ************************************************************** ** ** closes an ids file; ** ** INPUT: address of IDS-file object [W] ** IMPLICIT: ** ** RETURNS: */ void IdsClose (IDSoFILE *idsFile) { idsFile->isBusy = 0; if (idsFile->cache) { _ErrMsg4 (i__wroteidfile, idsFile->fileName, (idsFile->fileSize+999)/1000, idsFile->idsInsertedN); MapCloseCache (idsFile->cache); idsFile->cache = NULL; idsFile->file = fopen (idsFile->fileName, "r+"); idsFile->timeCreated = TimeGet (); IdsInfoWrite (idsFile); } if (idsFile->set) SetDelete (idsFile->set->nam); if (idsFile->file) fclose (idsFile->file); if (idsFile->vm) { MapFree (idsFile->vm); free (idsFile->vm); } if (idsFile->infoBuff) free (idsFile->infoBuff); free (idsFile); } /****** IdsInfoWrite ********************************************************** ** ** writes information about the file to the begin of file; ** writes an integer with the size of the info buffer in the front; ** ** INPUT: address of IDS-file object [R] ** IMPLICIT: ** ** RETURNS: */ static void IdsInfoWrite (IDSoFILE *idsFile) { INT4 infoBuffSize=0; char *buff, *buffOff; if ((idsFile->infoBuff = (char *) malloc (IDSxMAXINFOBUFF)) == NULL) _ErrExit2 (e__allocfail, "info-buffer"); buff = idsFile->infoBuff; _BinPackNum (buff, infoBuffSize); /* size of following buffer */ buffOff = buff; /* real start of info buffer */ _BinPackNum (buff, IDSxCURRENT_VERSION); /* version number */ _BinPackNum (buff, idsFile->fileSize); _BinPackNum (buff, idsFile->isBusy); _BinPackNum (buff, idsFile->isCompressed); _BinPackNum (buff, idsFile->idsInsertedN); _BinPackNum (buff, idsFile->timeCreated); _BinPackFixStr (buff, idsFile->idTypeName, 20); infoBuffSize = buff - buffOff; buff = idsFile->infoBuff; _BinPackNum (buff, infoBuffSize); /* size of following buffer */ if (idsFile->cache) MapCWrite (idsFile->cache, idsFile->infoBuff, infoBuffSize + 4); else if (idsFile->file) { fseek (idsFile->file, 0, 0); fwrite (idsFile->infoBuff, infoBuffSize + 4, 1, idsFile->file); } } /****** IdsInfoRead *********************************************************** ** ** compresses a linked list of IDs into a block ** ** INPUT: o address of IDS-file object [R] ** o address of ID object [R] ** o file address of previous ID in list ** or 0 if first in list [R] ** IMPLICIT: ** ** RETURNS: address of inserted ID */ static INT4 IdsInfoRead (IDSoFILE *idsFile) { INT4 infoBuffSize; char *buff; if (idsFile->vm) { /* file is already in memory */ buff = idsFile->vm->data; _BinUnpackNum (buff, infoBuffSize); } else { _BinFileUnpackNum (idsFile->file, infoBuffSize); if ((idsFile->infoBuff = (char *) malloc (infoBuffSize)) == NULL) _ErrExit2 (e__allocfail, "info-buffer"); fread (idsFile->infoBuff, infoBuffSize, 1, idsFile->file); buff = idsFile->infoBuff; } _BinUnpackNum (buff, idsFile->versionN); /* check version number */ if (idsFile->versionN != IDSxCURRENT_VERSION) _ErrRet4 (e__indexwrongversion, idsFile->fileName, idsFile->versionN, IDSxCURRENT_VERSION); _BinUnpackNum (buff, idsFile->fileSize); _BinUnpackNum (buff, idsFile->isBusy); _BinUnpackNum (buff, idsFile->isCompressed); _BinUnpackNum (buff, idsFile->idsInsertedN); _BinUnpackNum (buff, idsFile->timeCreated); _BinUnpackFixStr (buff, idsFile->idTypeName, 20); return 1; } /**api* IdsInsert ************************************************************* ** ** inserts an ID into the IDS-file ** ** INPUT: o address of IDS-file object [R] ** o address of ID object [R] ** o file address of previous ID in list ** or 0 if first in list [R] ** IMPLICIT: ** ** RETURNS: address of inserted ID */ FIP IdsInsert (IDSoFILE *idsFile, IDoENTRY *id, FIP idPrevFip) { static char nullFipBuff[4] = {0,0,0,0}; MAPoCCH *idsCache = idsFile->cache; char idFipBuff[4]; char *idPrev, *idFipBuffPtr = idFipBuff; FIP idFip; /* ** get file address of write offset, write then the address to the next ** ID (initially 0) and then the ID which is already in packed format */ MapCNew (idsCache, &idFip); MapCWrite (idsCache, nullFipBuff, 4); MapCWrite (idsCache, (char *) id->id, id->siz); /* ** if this is not the first ID in the list then the "pointer-to-next" of ** previous ID in list must be updated -> the previous ID is either still ** in cache or has been already written to the file */ if (idPrevFip) { if (!MapInCache (idsCache, idPrevFip, (void **) &idPrev)) { _BinPackFip (idFipBuffPtr, idFip); MapCUpdate (idsCache, idPrevFip, idFipBuff); MapDuplicateOverlap (idsCache, idPrevFip, idFipBuff, 4); } else _BinPackFip (idPrev, idFip); } idsFile->idsInsertedN++; return idFip; } #define IDSxTMPSETSIZE 200000 /**api* IdsCompress *********************************************************** ** ** compresses a linked list of IDs into a block ** ** INPUT: address of IDS-file object [R] ** file pointer to first ID in the list [W] ** IMPLICIT: ** ** RETURNS: number of IDs found in linked list */ INT4 IdsCompress (IDSoFILE *idsFile, FIP *idsFirstFip) { SETo *set = idsFile->set; MAPoCCH *idsCache=idsFile->cache; IDoTYPE *idType=idsFile->idType; FIP idNextFip, idFipSave; INT4 idN=0, k; char *tmpPtr, *idPtrSave; if (!set) { idsFile->set = SetNew (NULL, "temp"); set = idsFile->set; SetAlloc (set, IDSxTMPSETSIZE, idType); } else set->n = 0; /* ** get pointer to the begin of the ID list, save it... for the calculation ** of the next ID's address and unpack the address of the next ID in list */ tmpPtr = idsFile->vm->data + *idsFirstFip; /* ptr to begin of IID */ idFipSave = *idsFirstFip; idPtrSave = tmpPtr; _BinUnpackFip (tmpPtr, idNextFip); /* get fip to next ID ... pointer now at begin of ID */ do { if (!idN++) MapCNew (idsCache, idsFirstFip); /* address of first ID */ else { tmpPtr = idPtrSave + (idNextFip - idFipSave); /* address of next ID */ _BinUnpackFip (tmpPtr, idNextFip); } if (set->n >= set->allocN) SetRealloc (set, set->n + IDSxTMPSETSIZE, idType); /*_ErrExit3 (f__limitexceeded, "IDSxTMPSETSIZE", IDSxTMPSETSIZE);*/ memcpy (set->id_p + set->n++ * idType->siz, tmpPtr, idType->siz); } while (idNextFip); for (k=0; k < set->n; k++) { MapCWrite (idsCache, (char *) (set->id_p + k*idType->siz), idType->siz); idsFile->idsInsertedN++; } return idN; } /**api* IdsPut **************************************************************** ** ** Writes a block of entry-IDs into the IDS file and returns the ** file address of the first ID written. ** ** INPUT: address of IDS-file object [W] ** buffer with IDs [R] ** number of IDs to write [R] ** ** RETURNS: file address of first ID in IDS file */ FIP IdsPut (IDSoFILE *ids, char *buff, Int4 n) { FIP fip; Int4 k, size=IdSize(ids->idType); MapCNew (ids->cache, &fip); for (k=0; k < n; k++) MapCWrite (ids->cache, buff+(k*size), size); ids->idsInsertedN += n; return fip; } /**api* IdsGet **************************************************************** ** ** compresses a linked list of IDs into a block ** ** INPUT: address of IDS-file object [R] ** file pointer to first ID in the list [W] ** IMPLICIT: ** ** RETURNS: number of IDs */ INT4 IdsGet (IDSoFILE *idsFile, IDPTR idBuff, FIP idsFip, INT4 idN) { fseek (idsFile->file, idsFip, 0); fread (idBuff, idsFile->idType->siz, idN, idsFile->file); return idN; /* or correct number, if less ? */ } void IdsEntryIncrement (IDSoFILE *idsFile, IDPTR buff, Int4 idN, Int4 add) { fprintf (stderr, "IdsEntryIncrement is not implemented\n"); } /**api* IdsGetRange *********************************************************** ** ** compresses a linked list of IDs into a block ** ** INPUT: address of IDS-file object [R] ** id-buffer or NULL (no read!) [R] ** file pointer to first group of ID's [R] ** number of ID's in first group of ID's [R] ** file pointer to last group of ID's [R] ** number of ID's in last group of ID's [R] ** IMPLICIT: ** ** RETURNS: number of IDs found in linked list */ INT4 IdsGetRange (IDSoFILE *idsFile, IDPTR idBuff, FIP idsFip1, FIP idsFip2, INT4 idN1, INT4 idN2) { INT4 idBlockSize; FIP tmpFip; if (idsFip1 > idsFip2) /* obsolete */ tmpFip = idsFip1, idsFip1 = idsFip2, idsFip2 = tmpFip, idN2 = idN1; idBlockSize = idsFip2 - idsFip1 + idN2 * idsFile->idType->siz; if (idBuff) { /* read id's */ fseek (idsFile->file, idsFip1, 0); fread (idBuff, idBlockSize, 1, idsFile->file); } return idBlockSize / idsFile->idType->siz; } /**api* IdsGetFileSize ******************************************************** ** ** gets the file size in bytes; ** ** INPUT: address of IDS-file object [R] ** IMPLICIT: ** ** RETURNS: file size in bytes */ INT4 IdsGetFileSize (IDSoFILE *idsFile) { return idsFile->fileSize; } /**api* IdsGetTimeCreated ***************************************************** ** ** gets creation time; ** ** INPUT: address of IDS-file object [R] ** IMPLICIT: ** ** RETURNS: creation time */ INT4 IdsGetTimeCreated (IDSoFILE *idsFile) { return idsFile->timeCreated; } /**api* IdsGetIdN ************************************************************* ** ** gets the number of IDs; ** ** INPUT: address of IDS-file object [R] ** IMPLICIT: ** ** RETURNS: number of IDs */ INT4 IdsGetIdN (IDSoFILE *idsFile) { return idsFile->idsInsertedN; } /**api* IdsIsCompressed ******************************************************* ** ** returns TRUE if the ids file is compressed ** ** INPUT: address of ids file object [R] ** IMPLICIT: ** ** RETURNS: 1 or 0 */ INT4 IdsIsCompressed (IDSoFILE *idsFile) { return idsFile->isCompressed; } /**api* IdsGetIdType ********************************************************* ** ** Returns the object describing the IDs stored in the file. ** ** INPUT: Ids file object [R] ** IMPLICIT: ** ** RETURNS: ID type object */ IDoTYPE *IdsGetIdType (IDSoFILE *idsFile) { return idsFile->idType; } pressed ** ** INPUT: address of ids file object [R] ** srs/src/ids.h ** ** $RCSfile: ids.h,v $ ** $Revision: 1.3 $ ** $Date: 1996/09/09 20:17:17 $ ** $Author: etzold $ ** ** $Locker: $ ** $State: Exp $ ** */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ids-file object */ typedef struct IDSoFILE { FILE *file; /* file handle to IDS file */ char *infoBuff; char idTypeName[20]; struct IDoTYPE *idType; struct MAPo *vm; struct MAPoCCH *cache; char fileName[FILxXNAM+1]; /* file name of index file */ INT4 idsInsertedN; INT4 isBusy; INT4 isCompressed; FIP fileSize; /* write offset which defines also the size of the file -> pointer after last byte */ UINT4 timeCreated; INT4 versionN; struct SETo *set; /* needed for compression */ } IDSoFILE; #ifndef _IDoENTRY typedef struct IDoENTRY *IDSdummytointroducestructtagIDoENTRY; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of exported functions */ IDSoFILE *IdsOpen (char *name, char *option, INT4 cacheSize, char *idTypeName, INT4 *errCode); void IdsClose (IDSoFILE *idsFile); FIP IdsInsert (IDSoFILE *idsFile, struct IDoENTRY *id, FIP previous); INT4 IdsCompress (IDSoFILE *idsFile, FIP *idsFirstFip); FIP IdsPut (IDSoFILE *ids, char *buff, Int4 n); INT4 IdsGet (IDSoFILE *idsFile, IDPTR idBuff, FIP idsFip, INT4 idN); INT4 IdsGetRange (IDSoFILE *idsFile, IDPTR idBuff, FIP idsFip1, FIP idsFip2, INT4 idN1, INT4 idN2); void IdsEntryIncrement (IDSoFILE *idsFile, IDPTR buff, Int4 idN, Int4 add); /* info about ids-file */ INT4 IdsGetFileSize (IDSoFILE *idsFile); INT4 IdsGetTimeCreated (IDSoFILE *idsFile); INT4 IdsGetIdN (IDSoFILE *idsFile); INT4 IdsIsCompressed (IDSoFILE *idsFile); struct IDoTYPE *IdsGetIdType (IDSoFILE *idsFile); f, Int4 n); INT4 IdsGet (IDSoFILE *idsFile, IDPTR srs/src/idx.c char idx_ID[] = "$Id: idx.c,v 1.7 1997/03/18 17:20:22 srs Exp $"; /* ** ** $RCSfile: idx.c,v $ ** $Revision: 1.7 $ ** $Date: 1997/03/18 17:20:22 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.x Copyright by Thure Etzold ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** Requires: file, sm, message ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** Creates a list of fixed length records for each entry in the databank ** the record format is originally: ** ** fip1 (fip) | fip2 (fip)| fileX (num) | entryName (fixed length ascii) | ** ** The propoese extension is to optionally add to this: ** o more file pointers ** o numbers of subentries in the entry (there can be more than one ** subentry type in the databank) ** o parts of the file name (for databanks with one file per entry) ** ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include "message.h" #include "sm.h" #include "tm.h" #include "futil.h" #include "binpack.h" #define IDXxMAXRELNAMELEN 50 #define IDXxWRITEBUFFSIZ 500 #define IDXxREADBUFFSIZ 1 #define IDXxCURRENT_VERSION 1002 #define _IDXo typedef struct IDXo { FILE *file; /* file handle to ID file */ char fileName[FILxXNAM+1]; /* file name of ID file */ SMoBUFF *infoBuff; /* buffer for info block */ SMoBUFF *flatFileNames; /* buffer for info block */ FIP firstRecordFip; /* fip of first record in file */ INT4 isWriteOpen; /* file open for write access */ INT4 isUpdateOpen; /* file open for update access */ INT4 isBusy; INT4 recordSize; /* total (fixed) record size */ INT4 recordN; /* number of ID-records in the file */ INT4 fileSize; /* file size in Bytes */ UINT4 timeCreated; INT4 versionN; char *buff; /* temporary buffer for reading/writing */ char *buffPtr; /* current offset in buffer */ INT4 buffSize; /* allocated size (n * recordSize); */ INT4 flatFileNameN; /* number of those file names */ char relName[IDXxMAXRELNAMELEN+1]; /* release name (eg, "23.0") */ } IDXo; #include "idx.h" /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of static functions */ static INT4 IdxInfoRead (IDXo *idx); static void IdxInfoWrite (IDXo *idx); static void IdxWriteBlock (IDXo *idx); /**api* IdxOpen *************************************************************** ** ** opens an ID-index file; ** ** INPUT: o address of file name (without extension) [R] ** o string specifying access type: ** "read", "write", "update" [R] ** o maximum string length (reserved space) for the ID-names [R] ** or 0 ** o address of error code [W] ** IMPLICIT: ** ** RETURNS: new ID-index object ** NULL if there is a problem */ IDXo *IdxOpen (char *name, char *option, int recordSize, INT4 *errCode) { IDXo *idx; if ((idx = (IDXo *) calloc (1, sizeof (IDXo))) == NULL) _ErrExit2 (e__allocfail, "id-index-object"); sprintf (idx->fileName, "%s.idx", name); idx->infoBuff = BuffNew (50); idx->flatFileNames = BuffNew (20); _ErrSet (errCode, 0); switch (tolower (option[0])) { case 'r': /* read */ if (!(idx->file = fopen (_FilTempLN (idx->fileName), "rb"))) { _ErrSet (errCode, e__filopenerr); return NULL; } if (idx->isBusy) { _ErrSet (errCode, e__indexisbusy); return NULL; } IdxInfoRead (idx); idx->isWriteOpen = 0; idx->isUpdateOpen = 0; idx->buffSize = idx->recordSize * IDXxREADBUFFSIZ; if (!(idx->buff = (char *) malloc (idx->buffSize))) _ErrExit2 (e__allocfail, "id-index-object"); break; case 'u': if (!(idx->file = fopen (_FilTempLN (idx->fileName), "r+b"))) _ErrSet (errCode, e__filopenerr); if (idx->isBusy) { _ErrSet (errCode, e__indexisbusy); break; } IdxInfoRead (idx); idx->buffSize = idx->recordSize * IDXxREADBUFFSIZ; if (!(idx->buff = (char *) malloc (idx->buffSize))) _ErrExit2 (e__allocfail, "id-index-object"); idx->isBusy = 1; idx->isWriteOpen = 0; idx->isUpdateOpen = 1; break; case 'w': /* write */ if (!(idx->file = fopen (_FilTempLN (idx->fileName), "wb"))) { _ErrSet (errCode, e__filopenerr); return NULL; } idx->recordSize = recordSize; idx->buffSize = idx->recordSize * IDXxWRITEBUFFSIZ; if (!(idx->buff = (char *) malloc (idx->buffSize))) _ErrExit2 (e__allocfail, "id-index-object"); idx->buffPtr = idx->buff; idx->recordN = 0; idx->isBusy = 1; idx->isWriteOpen = 1; idx->isUpdateOpen = 0; idx->flatFileNameN = 0; idx->relName[0] = '\0'; IdxInfoWrite (idx); break; default: _ErrExit2 (e__unknownoption, option); } return idx; } /**api* IdxClose ************************************************************** ** ** closes an ID-index opened for read or write access; ** ** INPUT: patch file object [W] ** IMPLICIT: ** ** RETURNS: */ void IdxClose (IDXo *idx) { if (idx->isWriteOpen || idx->isUpdateOpen) { if (idx->isWriteOpen) IdxWriteBlock (idx); /* flush buffer */ idx->isBusy = 0; if (!idx->isUpdateOpen) idx->timeCreated = TimeGet (); IdxInfoWrite (idx); if (idx->isWriteOpen) _ErrMsg4 (i__wroteidfile, idx->fileName, (idx->fileSize+999)/1000, idx->recordN); } fclose (idx->file); if (idx->buff) free (idx->buff); free (idx); } /****** IdxInfoWrite ********************************************************** ** ** writes information about the file to the begin of file; ** writes an integer with the size of the info buffer in the front; ** ** INPUT: address of IDS-file object [R] ** IMPLICIT: ** ** RETURNS: */ static void IdxInfoWrite (IDXo *idx) { SMoBUFF *buff; INT4 size; buff = idx->infoBuff; BuffReset (buff); BuffPack (buff, "i7a50i", 0, IDXxCURRENT_VERSION, idx->fileSize, idx->isBusy, idx->recordN, idx->timeCreated, idx->recordSize, idx->relName, idx->flatFileNameN); BuffResetRead (idx->flatFileNames); BuffCat (buff, idx->flatFileNames); size = BuffLength (buff); idx->firstRecordFip = size; BuffReset (buff); BuffPack (buff, "i", size); fseek (idx->file, 0, 0); fwrite (BuffGetPtr (idx->infoBuff), size, 1, idx->file); } /****** IdsInfoRead *********************************************************** ** ** compresses a linked list of IDs into a block ** ** INPUT: o address of IDS-file object [R] ** o address of ID object [R] ** o file address of previous ID in list ** or 0 if first in list [R] ** IMPLICIT: ** ** RETURNS: address of inserted ID */ static INT4 IdxInfoRead (IDXo *idx) { INT4 size, k; SMoBUFF *buff=idx->infoBuff; fseek (idx->file, 0, 0); BuffReset (buff); BuffReadFile (buff, idx->file, 20); if (feof (idx->file)) return e__filnotok; BuffUnpack (buff, "i2", &size, &idx->versionN); if (idx->versionN != IDXxCURRENT_VERSION && idx->versionN != 1001) _ErrRet4 (e__indexwrongversion, idx->fileName, idx->versionN, IDXxCURRENT_VERSION); BuffReadFile (buff, idx->file, size - 20); BuffUnpack (buff, "i5a50i", &idx->fileSize, &idx->isBusy, &idx->recordN, &idx->timeCreated, &idx->recordSize, idx->relName, &idx->flatFileNameN); BuffCat (idx->flatFileNames, buff); idx->firstRecordFip = BuffLength (buff); /* compatibility with old version */ if (idx->versionN == 1001) idx->firstRecordFip += 4; fseek (idx->file, idx->firstRecordFip, 0); return 1; } /**api* IdxWriteBlock ********************************************************* ** ** writes a block with ID-records to file ** ** INPUT: address of IDX-file object [R] ** IMPLICIT: ** ** RETURNS: */ static void IdxWriteBlock (IDXo *idx) { int size; size = (unsigned long) idx->buffPtr - (unsigned long) idx->buff; fwrite (idx->buff, size, 1, idx->file); idx->buffPtr = idx->buff; idx->fileSize += size; } /**API* IdxPutBuff ************************************************************ ** ** Puts the contents of a "buff" object into the index file as a ** record. ** ** INPUT: address of IDX-file object [R] ** address of "buff" object [R] ** IMPLICIT: ** ** RETURNS: file pointer to inserted record */ FIP IdxPutBuff (IDXo *idx, SMoBUFF *buff) { static INT4 isInit=0; INT4 size = BuffLength (buff); if (!isInit) { idx->recordSize = size; idx->buffSize = idx->recordSize * IDXxWRITEBUFFSIZ; if (!(idx->buff = (char *) malloc (idx->buffSize))) _ErrExit2 (e__allocfail, "id-index-object"); idx->buffPtr = idx->buff; isInit = 1; } else if (idx->recordSize != size) { _ErrExit4 (e__novalvar3, "IDX record size", size, idx->recordSize); } if ((unsigned long) idx->buffPtr - (unsigned long)idx->buff >= idx->buffSize) IdxWriteBlock (idx); memcpy (idx->buffPtr, BuffGetPtr (buff), size); idx->buffPtr += size; return ++(idx->recordN); } /**API* IdxGetBuff ************************************************************ ** ** Retrieves a record from the index. ** ** INPUT: address of IDX-file object [R] ** IMPLICIT: ** ** RETURNS: file pointer to inserted record */ void IdxGetBuff (IDXo *idx, FIP fip, SMoBUFF *buff) { fip = idx->firstRecordFip + (fip-1) * idx->recordSize; fseek (idx->file, fip, 0); BuffReadFile (buff, idx->file, idx->recordSize); } /**API* IdxNextBuff *********************************************************** ** ** Retrieves a record from the index. ** ** INPUT: address of IDX-file object [R] ** address of iteration variable [W] ** ** RETURNS: buff object with next record ** NULL: if at end of file */ SMoBUFF *IdxNextBuff (IDXo *idx, Int4 *c) { static SMoBUFF *buff=NULL; FIP fip; if (!buff) buff = BuffNew (idx->recordSize); else BuffReset (buff); if (*c >= IdxGetRecordN (idx)) { *c = 0; return NULL; } fip = idx->firstRecordFip + *c * idx->recordSize; fseek (idx->file, fip, 0); BuffReadFile (buff, idx->file, idx->recordSize); (*c)++; return buff; } /**api* function ************************************************************** ** ** Returns the address of a new record in the IDX file. The record can ** be filled from externally and will not be written to the file until ** the next call to IdxRecordNew. ** ** INPUT: address of IDX-file object [R] ** ** RETURNS: pointer to new record */ char *IdxRecordNew (IDXo *idx) { char *buff; ASSERT ((idx!=NULL), "idx not opened"); if ((unsigned long) idx->buffPtr - (unsigned long)idx->buff >= idx->buffSize) IdxWriteBlock (idx); buff = idx->buffPtr; idx->buffPtr += idx->recordSize; idx->recordN++; return buff; } /**api* function *********************************************************** ** ** Returns a record with specified fip (file pointer) from the opened ** IDX file for read access. ** ** INPUT: address of IDX-file object [R] ** file pointer [R] ** ** RETURNS: record buffer */ char *IdxRecordGet (IDXo *idx, FIP fip) { fip = idx->firstRecordFip + (fip-1) * idx->recordSize; fseek (idx->file, fip, 0); fread (idx->buff, 1, idx->recordSize, idx->file); idx->buffPtr = idx->buff; return idx->buff; } /**API* IdxGetRecordN ********************************************************* ** ** Returns number of records in the IDX-file. ** ** INPUT: address of IDX object [R] ** IMPLICIT: ** ** RETURNS: number of records */ INT4 IdxGetRecordN (IDXo *idx) { return idx->recordN; } /**API* IdxGetTimeCreated ***************************************************** ** ** Returns creation time of IDX file. ** ** INPUT: address of IDX object [R] ** IMPLICIT: ** ** RETURNS: number of records */ UINT4 IdxGetTimeCreated (IDXo *idx) { return idx->timeCreated; } /**api* IdxTouch ************************************************************** ** ** sets the internal index time to current time; ** ** INPUT: address of Idx object [W] ** IMPLICIT: ** ** RETURNS: */ void IdxTouch (char *fileName) { IDXo *idx; INT4 errCode; if (!(idx = IdxOpen (fileName, "update", 0, &errCode))) _ErrExit2 (errCode, fileName); idx->timeCreated = TimeGet (); IdxClose (idx); } /**api* IdxSetReleaseName ***************************************************** ** ** sets a release name (typically a number, eg, "23.0"; ** ** INPUT: address of idx object [R] ** IMPLICIT: ** ** RETURNS: */ void IdxSetReleaseName (IDXo *idx, char *relName) { if (strlen (relName) > IDXxMAXRELNAMELEN) _ErrExit3 (e__strtoolong, relName, IDXxMAXRELNAMELEN); strcpy (idx->relName, relName); } /**API* IdxGetReleaseName ***************************************************** ** ** Return release name (release number) of IDX file. ** ** INPUT: address of IDX object [R] ** IMPLICIT: ** ** RETURNS: release name */ char *IdxGetReleaseName (IDXo *idx) { return idx->relName; } /**api* IdxGetFlatFileNameN *************************************************** ** ** gets release name; ** ** INPUT: address of Btree object [R] ** IMPLICIT: ** ** RETURNS: release name */ INT4 IdxGetFlatFileNameN (IDXo *idx) { return idx->flatFileNameN; } /**api* IdxGetFlatFileName **************************************************** ** ** get the next file name. ** ** INPUT: address of Btree object [R] ** IMPLICIT: ** ** RETURNS: file name ** or NULL if no more names */ char *IdxGetFlatFileName (IDXo *idx, INT4 *c) { char *s=NULL; INT4 k; if (idx->flatFileNameN) { if (*c == 0) { BuffResetRead (idx->flatFileNames); *c = 1; } if (!BuffUnpack (idx->flatFileNames, "z", &s)) { *c = 0; s = NULL; } } return s; } /**api* IdxSetFlatFileName **************************************************** ** ** gets release name; ** ** INPUT: address of Btree object [R] ** IMPLICIT: ** ** RETURNS: index that new file name receives in the list (first=0) */ INT4 IdxSetFlatFileName (IDXo *idx, char *flatFileName) { BuffPack (idx->flatFileNames, "a", flatFileName); return ++idx->flatFileNameN; } /**api* IdxWriteFlatFileNames ************************************************* ** ** Commits accumulated file names to index file; ** ** INPUT: address of Btree object [R] ** IMPLICIT: ** ** RETURNS: index that new file name receives in the list (first=0) */ INT4 IdxWriteFlatFileNames (IDXo *idx) { IdxInfoWrite (idx); return idx->flatFileNameN; } eName (IDXo *idx, char *flatFileName) { BuffPack (idx->flatFileNames, "a", flatFileName); return ++idsrs/src/idx.h ** ** $RCSfile: idx.h,v $ ** $Revision: 1.3 $ ** $Date: 1997/03/03 18:20:39 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** */ typedef struct IDXo *IDXv; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of exported functions */ struct IDXo *IdxOpen (char *name, char *option, int maxStrLen, INT4 *errCode); void IdxClose (struct IDXo *idx); void IdxTouch (char *fileName); FIP IdxPutBuff (struct IDXo *idx, struct SMoBUFF *buff); void IdxGetBuff (struct IDXo *idx, FIP fip, struct SMoBUFF *buff); struct SMoBUFF *IdxNextBuff (struct IDXo *idx, Int4 *c); FIP IdxPut (struct IDXo *idx, char *name, FIP textFip, FIP dataFip, int fileX); void IdxGet (struct IDXo *idx, FIP fip, char *name, FIP *textFip, FIP *dataFip, int *fileX); char *IdxRecordNew (struct IDXo *idx); char *IdxRecordGet (struct IDXo *idx, FIP fip); /* get and set of some individual attributes */ char *IdxGetReleaseName (struct IDXo *idx); void IdxSetReleaseName (struct IDXo *idx, char *relName); UINT4 IdxGetTimeCreated (struct IDXo *idx); INT4 IdxGetRecordN (struct IDXo *idx); INT4 IdxSetFlatFileName (struct IDXo *idx, char *fileName); char *IdxGetFlatFileName (struct IDXo *idx, INT4 *context); INT4 IdxWriteFlatFileNames (struct IDXo *idx); INT4 IdxGetFlatFileNameN (struct IDXo *idx); DXo *idx); char *IdxRecordGet (struct IDXo *idx, FIP fip); /* get and set of some individual attributes srs/src/index.c char index_srs_ID[] = "$Id: index.c,v 1.7 1996/11/20 16:36:17 etzold Exp $"; /* ** ** $RCSfile: index.c,v $ ** $Revision: 1.7 $ ** $Date: 1996/11/20 16:36:17 $ ** $Author: etzold $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.x Copyright by Thure Etzold ** Unix port: Lukas Rosenthaler and Reinhard Doelz ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** D-69012 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** Requires: file, sm, message, parser, map ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** module for building index-files ** ** index of type KEY or TREE consists of two files: ** seqlibname_indexname.inx and *.ids ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include "message.h" #include "sm.h" #include "futil.h" #include "binpack.h" #include "btree.h" #include "id.h" #include "ids.h" #include "hash.h" #include "index.h" /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** declaration of global or module wide variables */ static INXo *indexCurr; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of static functions */ static INT4 InxHashSearch (void *value, void *record, HSHo *table); static void InxIdListUpdate (BTRoVALUE *idList, void *record); static void InxBtreeInsert (HSHo *table); static void InxDelete (INXo *inx); /************************************************************ ** definitions and functions for use of hash table */ typedef struct { BTRoVALUE idList; INT4 value; } HASHNUMOBJ; typedef struct { BTRoVALUE idList; double value; } HASHREALOBJ; typedef struct { BTRoVALUE idList; char value[1]; } HASHSTROBJ; typedef struct { BTRoVALUE idList; } HASHANYOBJ; INT4 myhash_func (HSHo *table, void *obj) { register unsigned long h=0, g, i; register char *p; INT4 len; switch (indexCurr->valueType) { case BTRxSTR: case BTRxIDENTRY: p = ((HASHSTROBJ*) obj)->value; len = strlen(p); break; case BTRxNUM: p = (char*) &((HASHNUMOBJ*) obj)->value; len = sizeof(((HASHNUMOBJ*) obj)->value); break; case BTRxREAL: p = (char*) &((HASHREALOBJ*) obj)->value; len = sizeof(((HASHREALOBJ*) obj)->value); break; } for (i=0; i> 24)) ^ g; } return (INT4) h % table->max_hash_elem; } INT4 mycompare_func(void *obj1, void *obj2) { switch (indexCurr->valueType) { case BTRxSTR: case BTRxIDENTRY: return strcmp( ((HASHSTROBJ*)obj1)->value, ((HASHSTROBJ*)obj2)->value ); case BTRxNUM: return ((HASHNUMOBJ*)obj1)->value - ((HASHNUMOBJ*)obj2)->value; case BTRxREAL: if ( ((HASHREALOBJ*)obj1)->value < ((HASHREALOBJ*)obj2)->value ) return -1; if ( ((HASHREALOBJ*)obj1)->value > ((HASHREALOBJ*)obj2)->value ) return 1; return 0; } return -9999; /* no legal valueType */ } INT4 myprint_func(void *obj) { if (!obj) { printf("no object\n"); return 0; } else switch (indexCurr->valueType) { case BTRxSTR: case BTRxIDENTRY: printf("%s\n", ((HASHSTROBJ*) obj)->value); break; case BTRxNUM: printf("%20d\n", ((HASHNUMOBJ*) obj)->value); break; case BTRxREAL: printf("%20.2f\n", ((HASHREALOBJ*) obj)->value); break; } return 1; } INT4 mydelete_func(void *obj) { if (obj) free (obj); return 1; } /****** InxHashSearch ************************************************** ** ** searches an element in hash table and inserts the element, ** if not found. The hash table must be initialized before ** in InxOpen. ** ** INPUT: address of keyword [R] ** address of pointer to hash table [R] ** IMPLICIT: ** ** OUTPUT: ** returns: 1 if keyword was found ** 0 if new element was added */ static INT4 InxHashSearch (void *value, void *record, HSHo *table) { HASHANYOBJ *insertObj, *foundObj=NULL; BTRoVALUE *idList; INT4 errCode, size; FIP fip; /* ** construct object to search for depending on index value type. ** search for the object in the existing hash table */ switch (indexCurr->valueType) { case BTRxSTR: case BTRxIDENTRY: size = sizeof (HASHSTROBJ) + strlen((char*)value); insertObj = (HASHANYOBJ*) malloc (size); strcpy (((HASHSTROBJ*) insertObj)->value, (char*)value); break; case BTRxNUM: insertObj = (HASHANYOBJ*) malloc (sizeof(HASHNUMOBJ)); ((HASHNUMOBJ*) insertObj)->value = atol((char*)value); break; case BTRxREAL: insertObj = (HASHANYOBJ*) malloc (sizeof(HASHREALOBJ)); ((HASHREALOBJ*) insertObj)->value = atof((char*)value); break; } if ((foundObj = HshSearchObject(table, (void*)insertObj))) { free((void*)insertObj); InxIdListUpdate(&((HASHANYOBJ*)foundObj)->idList, record); } else { if (!indexCurr->idsFile) indexCurr->idsFile = IdsOpen (indexCurr->fileName, "write", indexCurr->idsCacheSize, ((IDoENTRY *) record)->idType->nam, &errCode); HshInsertObject(table, (void*)insertObj); idList = &insertObj->idList; fip = IdsInsert (indexCurr->idsFile, (IDoENTRY *) record, 0); idList->firstIdFip = idList->lastIdFip = fip; idList->idN = 1; } /* ERROR HANDLING ????????????? */ return foundObj ? 1 : 0; } /**api* InxInsertStr ********************************************************** ** ** searches a key in an index and inserts a new node if not found; ** ** INPUT: address of index object (INXo) [W] ** address of value string [R] ** address of ID object [R] ** IMPLICIT: ** indexCurr (INXo *) current index object [W] ** ** RETURNS: 1 if value was found in tree ** 0 if it was newly inserted */ INT4 InxInsertStr (INXo *inx, char *value, IDoENTRY *id) { INT4 rv, errCode; /* ** ...check index */ if (!inx->isWriteOpen) _ErrExit2 (e__notwriteopen, inx->fileName); if (!inx->type) _ErrExit2 (e__parnotdefined, "index type"); indexCurr = inx; /** make index object wide */ if (!indexCurr->idsFile) indexCurr->idsFile = IdsOpen (indexCurr->fileName, "write", indexCurr->idsCacheSize, id->idType->nam, &errCode); if ((rv = InxHashSearch (value, id, inx->table))) inx->valueFoundN++; else inx->valueInsertedN++; return rv; } /****** InxIdListUpdate ****************************************************** ** ** updates idList ** ** INPUT: pointer to BTRoVALUE ** address of new id-record ** IMPLICIT: ** indexCurr (INXo *) [W] ** ** RETURNS: */ static void InxIdListUpdate(BTRoVALUE *idList, void *record) { FIP fip; if (indexCurr->valueType == BTRxIDENTRY) return; fip = IdsInsert(indexCurr->idsFile, (IDoENTRY*) record, idList->lastIdFip); idList->lastIdFip = fip; idList->idN++; } /****** InxBtreeInsert ****************************************************** ** ** ** INPUT: pointer to hash table [R] ** IMPLICIT: ** indexCurr (INXo *) [R] ** ** RETURNS: */ static void InxBtreeInsert (HSHo *table) { HASHANYOBJ *obj; BTRoREC record; char valStr[80]; INT4 i; for (i=0; i < table->cur_hash_elem; i++) { obj = (HASHANYOBJ*) table->hash_list[i]; switch (indexCurr->valueType) { case BTRxNUM: sprintf (valStr, "%d", ((HASHNUMOBJ*) obj)->value); record.str = valStr; break; case BTRxREAL: sprintf (valStr, "%f", ((HASHREALOBJ*) obj)->value); record.str = valStr; break; case BTRxIDENTRY: case BTRxSTR: record.str = ((HASHSTROBJ*) obj)->value; break; } record.type = BTRxVALUE; memcpy (&record.r.value, &obj->idList, sizeof (BTRoVALUE)); BtrInsertRecord (&record); } } /**api* InxSetType ************************************************************ ** ** searches a key in an index and inserts a new node if not found; ** ** INPUT: address of index object (INXo) ** index type: "id", "string", "number", "real" [R] ** IMPLICIT: ** ** RETURN: */ void InxSetType (INXo *inx, char *option) { if (inx->type) _ErrExit2 (e__parisdefined, "index type"); switch (tolower (option[0])) { case 'i': case 's': inx->type = BTRxVALUE; inx->valueType = BTRxSTR; break; case 'n': inx->type = BTRxVALUE; inx->valueType = BTRxNUM; break; case 'r': inx->type = BTRxVALUE; inx->valueType = BTRxREAL; break; default: _ErrExit2 (e__unknownoption, option); } } /**api* InxSetCache *********************************************************** ** ** sets the cache with specified size for the ID-list ** ** INPUT: address of index object (INXo) ** cache size in ? [R] ** IMPLICIT: ** ** RETURN: */ void InxSetCache (INXo *inx, INT4 cacheSize) { inx->idsCacheSize = cacheSize; } /**api* InxClose ************************************************************** ** ** close index and ids-file (if not INXxID); ** ** INPUT: address of index description (INXo) [W] ** IMPLICIT: ** indexCurr (INXo *inx) [W] ** ** RETURNS: 1 if success */ INT4 InxClose (INXo *inx) { BTRo *btree; INT4 errCode; if (!inx || /*!inx->valueInsertedN ||*/ !inx->table) return 0; btree = BtrOpen (inx->fileName, "write", &errCode); _ErrExit2 (errCode, FileGetName (btree->file, "path")); switch (inx->valueType) { case BTRxIDENTRY: case BTRxSTR: BtrSetType (btree, "str"); break; case BTRxNUM: BtrSetType (btree, "num"); break; case BTRxREAL: BtrSetType (btree, "real"); break; } indexCurr = inx; HshSort(inx->table); BtrBuildStartPhase1 (btree, inx->valueInsertedN); InxBtreeInsert (inx->table); BtrBuildStartPhase2 (); InxBtreeInsert (inx->table); BtrClose (btree); if (!inx->idsFile) inx->idsFile = IdsOpen (inx->fileName, "write", inx->idsCacheSize, "Entry-ID", &errCode); IdsClose (inx->idsFile); InxDelete (inx); return 1; } static void InxDelete (INXo *inx) { HshDeleteAll (&inx->table); free (inx); } /**api* InxOpen *************************************************************** ** ** opens an index and return an index object ** ** INPUT: name of index file name [R] ** option: "new" [R] ** IMPLICIT: ** ** RETURNS: 1 */ INXo *InxOpen (char *nam, char *option) { INXo *inx; switch (tolower (option[0])) { /* ** write new index */ case 'n': if ((inx = (INXo *) calloc (1, sizeof (INXo))) == NULL) _ErrExit2 (e__allocfail, "index-object"); inx->valueType = 0; inx->type = 0; inx->isWriteOpen = 1; strcpy (inx->fileName, nam); inx->table = HshNewTable(5013, 70, myhash_func, mycompare_func, myprint_func, mydelete_func); break; default: _ErrExit2 (e__unknownoption, option); } return inx; } (tolower (option[0])) { /* ** write new index */ case 'n': if ((inx = (INXo *) calloc (1, sizeof (INXo))) == NULL) _ErrExit2 (e__allocfail, "index-object"); inx->valueType = 0; inx->type = 0; inx->isWriteOpen = 1; strcpy (inx->fileName, nam); inx->table = HshNewTable(5013, 70, srs/src/index.h ** ** $RCSfile: index.h,v $ ** $Revision: 1.2 $ ** $Date: 1996/11/25 19:42:46 $ ** $Author: etzold $ ** ** $Locker: $ ** $State: Exp $ ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port: Lukas Rosenthaler and Reinhard Doelz ** Implementing HashTable instead of AVL Tree: Gerald Schaefer ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #define INXxXKEY 80 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** describes an index of all types */ typedef struct INXo { struct HSHo *table; /* hash table */ char fileName[133]; /* name of index output file */ char patchName[133]; INT4 type; /* index type */ INT4 valueType; /* value type */ INT4 valueInsertedN; /* no of inserted values */ INT4 valueFoundN; /* no of times value was found in index */ INT4 isWriteOpen; /* flag if index is open for "write" */ struct IDSoFILE *idsFile; struct IDPoFILE *idpFile; FIP idFip; /* INT4 avlOff; obsolete */ /* INT4 nodeCnt; obsolete */ INT4 idsCacheSize; } INXo; typedef struct IDoENTRY *dummytagIDoENTRYindex; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of exported functions */ /* manipulating indices */ INXo *InxOpen (char *nam, char *option); INT4 InxClose (INXo *inx); void InxSetType (INXo *inx, char *option); void InxSetCache (INXo *inx, INT4 cacheSize); void InxSetPatch (INXo *inx, char *patchName); /* inserting */ INT4 InxInsertStr (INXo *inx, char *value, struct IDoENTRY *id); FIP InxInsertId (INXo *inx, char *str, struct BTRoID *idRec); /* searching */ struct BTRoID *InxSearchId (INXo *inx, char *str, FIP *idFip); ** prototypes of exported functions */ /* manipulating indices */ INXo *InxOpen (char *nam, char *option); INT4 InxClose (INXo *inx); void InxSetType (INXo *inx, char *option); void InxSetCache (INXo *inx, INT4 cacheSize); void InxSetPatch (INXo *inx, char *patchName); /* inserting */ INT4 InxInsertStr (INXo *inx, char *value, struct IDoENTRY *id); FIP InxInsertId (INXo *inx, char *str, struct BTRoID *idRec); /* searchinsrs/src/library.c char library_ID[] = "$Id: library.c,v 1.23 1997/03/12 19:07:35 srs Exp $"; /* ** ** $RCSfile: library.c,v $ ** $Revision: 1.23 $ ** $Date: 1997/03/12 19:07:35 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port by Lukas Rosenthaler and Reinhard ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** Requires: message, file, sm ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** functions open flat files and indices for read access only - compare ** time stamps and retrieve entry information from ID-indices ** ** Global Parameters: ** "printf" ** "parSetFields" - fields are turned on/off by parameters ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include "message.h" #include "futil.h" #include "sm.h" #include "strv.h" #include "lst.h" #include "tm.h" #include "btree.h" #include "sdlget.h" #include "ids.h" #include "idx.h" #include "par.h" #include "dict.h" #include "field.h" #include "appl.h" #include "library.h" #define _SRS #define _SLB #include SRSINCLUDE #ifndef TRUE # define TRUE 1 # define FALSE 0 #endif #ifdef sun extern INT4 printf (); #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** constants and enums */ #define LIBxMAXINXOPEN 10 /* max no of indices opened */ #define LIBxMAXFILESOPEN 20 /* max no of indices opened */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** description of a library flat file opened for read access */ typedef struct { FILEo *file; /* file object...opened with FilURead */ struct SLBo *lib; /* address of library object */ INT4 fileX; /* index to file within library */ struct SRSoFILTYP *fileType; /* address of file type object */ } LIBoFLATFILE; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** static functions */ static LibActivate (SLBo *lib); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** external, global and module wide variables */ #ifdef O_WIN struct WINo *winBase; #endif extern struct SDLo *oddObjs; /* defined in oddclass.h */ SRSoDB *srsdb; INT4 SdlGetObjects (long int **obj_n, void ***obj_p, char *sec_nm); static INT4 LibGetTokenCode (char *tokName); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** for the 'group' dictionarya */ static void* GroupToKey (void* e) { return (*(SRSoGROUP **)e)->com; } static CLASSoDICT groupDictClass = { (ValComparer)strequal, (ValHasher)strhash, (KeyAccessor)GroupToKey, NULL, 0 }; static DICTv groupDict=NULL; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** default function for printing lines */ static INT4 LibPrint (char *s) { Int4 len; len = strlen (s); if (len) { if (s[len-1] != '\n') puts (s); else fwrite (s, len, 1, stdout); } return 1; } static INT4 LibPrintField (char *s, SLBoFIELD *field, void *data) { Int4 len; len = strlen (s); if (len) { if (s[len-1] != '\n') puts (s); else fwrite (s, len, 1, stdout); } return 1; } static INT4 LibPrintf (char *formatStr, ...) { va_list ap; va_start (ap, formatStr); vprintf (formatStr, ap); va_end (ap); if (formatStr[strlen (formatStr) -1] != '\n') putc ('\n', stdout); return 1; } /**api* LibIndexOpen ********************************************************** ** ** opens the btree and the ids file (if not ID field) but first checks ** if these are in a list of up to MAXINXOPEN open files; ** ** INPUT: library object [R] ** field object [R] or NULL to open auxilliary index ** flag if opening for info only [R] ** IMPLICIT: ** ** RETURNS: lib index object ** or NULL */ LIBoINDEX *LibIndexOpen ( SLBo *lib, SLBoFIELD *field, INT4 isForInfo) { static LIBoINDEX libInx[LIBxMAXINXOPEN], *libInxPtr; static INT4 libInxCnt = 0; BTRo *btree=NULL; IDSoFILE *idsFile = NULL; struct IDXo *idx = NULL; char indexName[132]; INT4 errCode, k, isIdIndex; if (LibIs (lib, "subentries")) lib = LibGetParentLib (lib); /* ** check if requested index is among those that are already open...index ** is defined by library and field objects */ for (k=0; k < LIBxMAXINXOPEN && k < libInxCnt; k++) if (lib == libInx[k].lib && field == libInx[k].field) return &libInx[k]; /* ** open both btree and ids file (if ID field also the IDX file */ /* open auxilliary index if field not specified */ if (!field) { LibGetIndexName (lib, NULL, indexName, "read"); if (!(idx = IdxOpen (indexName, "read", 0, &errCode))) { if (!isForInfo) _ErrMsg2 (errCode, indexName); return NULL; } } else { LibGetIndexName (lib, field, indexName, "read"); btree = BtrOpen (indexName, "read", &errCode); if (_ErrIs (errCode)) { if (!isForInfo) _ErrMsg2 (errCode, FileGetName (btree->file, "path")); return NULL; } isIdIndex = 0; if (!(idsFile = IdsOpen (indexName, "read", 0, NULL, &errCode))) { if (!isForInfo) _ErrMsg2 (errCode, indexName); return NULL; } if (_ErrIs (errCode) && !isForInfo) { /* index is not compressed */ _ErrMsg2 (errCode, indexName); return NULL; } if (FieldIs (field, "id")) { isIdIndex = 1; if (!(idx = IdxOpen (indexName, "read", lib->maxNameLen, &errCode))) { if (!isForInfo) _ErrMsg2 (errCode, indexName); return NULL; } if (LibHasNoFiles (lib)) LibSetLibFlatFiles (lib, idx); } } /* ** get new lib index object ...if all are in use then close btree and ** ids file (if opened) */ libInxPtr = &libInx[libInxCnt % LIBxMAXINXOPEN]; if (libInxCnt++ >= LIBxMAXINXOPEN) { if (libInxPtr->btree) BtrClose (libInxPtr->btree); if (libInxPtr->idsFile) { IdsClose (libInxPtr->idsFile); libInxPtr->idsFile = NULL; } if (libInxPtr->idx) { IdxClose (libInxPtr->idx); libInxPtr->idx = NULL; } } libInxPtr->isIdIndex = isIdIndex; libInxPtr->idsFile = idsFile; libInxPtr->idx = idx; libInxPtr->btree = btree; libInxPtr->lib = lib; libInxPtr->field = field; return libInxPtr; } /**API* LibName *************************************************************** ** ** Returns the library name. ** ** INPUT: library object [R] ** IMPLICIT: ** ** RETURNS: library name if found ** NULL if the library name is unknown */ char *LibName (SLBo *lib) { return lib->nam; } /**API* LibName *************************************************************** ** ** Returns the name of the subentry type. ** ** INPUT: subentry type object [R] ** IMPLICIT: ** ** RETURNS: subentry type name */ char *LibGetSubEntryName (LIBoSUBENTRY *se) { return se->name; } /**API* LibGetLinkFromName **************************************************** ** ** Returns the "from" name of a link. This name is usually a databank ** name but can also be a symbolic one, such as "parent" or "tax_parent". ** ** INPUT: link object [R] ** ** RETURNS: the name or empty string if there is none */ char *LibGetLinkFromName (LINKo *link) { return (link->nam1 ? link->nam1 : ""); } /**API* LibGetLinkToName ***************************************************** ** ** Returns the "to" name of a link. See also LibGetLinkFromName. ** ** INPUT: link object [R] ** ** RETURNS: the name or empty string if there is none */ char *LibGetLinkToName (LINKo *link) { return (link->nam2 ? link->nam2 : ""); } /**API* LibGetName ************************************************************ ** ** Returns the library name in various formats. ** ** INPUT: address of library object [R] ** option: "full", "short", "logical" [R] ** IMPLICIT: ** ** RETURNS: library name if found ** NULL if the library name is unknown */ char *LibGetName (SLBo *lib, char *option) { switch (tolower (option[0])) { case 'f': /* full */ return lib->nam; case 's': /* short */ return NULL; case 'l': /* logical */ return NULL; default: _ErrExit2 (e__unknownoption, option); return NULL; } } /**API* LibGetPartSize ******************************************************** ** ** Returns the part size in number of entries used for ** partioning the indexes. Use LibIs with option "partitioned" to find ** out if library indices should be partitioned. ** ** INPUT: library object [R] ** ** RETURNS: the part size */ Int4 LibGetPartSize (SLBo *lib) { return lib->partSize; } /**API* LibGetIcarusFileName ************************************************** ** ** Returns the name of the icarus file which has the specified ** information for a library. The function uses information in ** the section if specified otherwise it makes an 'educated guess' so ** the file with the returned name is not guaranteed to exist. ** ** INPUT: address of library object [R] ** option: "info", "syntax", "structure" [R] ** IMPLICIT: ** ** RETURNS: the full file name (path) */ char *LibGetIcarusFileName (SLBo *lib, char *option) { static STRv name=NULL; char tmp[100]; if (!name) name = StrNew (); else StrClear (&name); strcpy (tmp, LibName (lib)); SmEdit (tmp, SMxLOWCASE); StrSetS (&name, "SRSDB:"); StrAppS (&name, tmp); switch (tolower (option[1])) { case 'n': /* info */ StrAppS (&name, ".it"); break; case 'y': /* syntax */ StrAppS (&name, ".is"); break; case 't': /* structure */ StrAppS (&name, ".i"); break; default: _ErrExit2 (e__unknownoption, option); return NULL; } return _Str(name); } /**API* LibGetGroupName ******************************************************* ** ** Returns the library group name in various formats. ** ** INPUT: address of library object [R] ** option: "full", "short" [R] ** IMPLICIT: ** ** RETURNS: library name if found ** NULL if the library name is unknown */ char *LibGetGroupName (SRSoGROUP *group, char *option) { switch (tolower (option[0])) { case 'f': /* full */ return group->com; case 's': /* short */ return group->short_nm; default: _ErrExit2 (e__unknownoption, option); return NULL; } } /**API* LibGetFieldName ******************************************************* ** ** obsolete: see FieldGetName
    ** Returns the name of a data-field. Returns "unknown" if the field ** name could not be found. See also LibGetFieldTypeName. ** ** INPUT: address of field object [R] ** IMPLICIT: ** ** RETURNS: field name */ char *LibGetFieldName (SLBoFIELD *field) { static char unknown[30] = "unknown field"; if (field && field->type && field != (SLBoFIELD *) 1L) { if (field->type->ityp == SRSxHEADER) return (field->name); else return field->type->nam; } else return unknown; } /**API* LibGetFieldTypeName *************************************************** ** ** Returns the name of a data-field type. ** ** INPUT: address of field type object [R] ** IMPLICIT: ** ** RETURNS: field name */ char *LibGetFieldTypeName (SRSoFLD *type) { return type->nam; } /**API* LibGetFieldShortName ************************************************** ** ** obsolete: see FieldGetShortName
    ** Returns the short name of a data-field. ** ** INPUT: address of field object [R] ** IMPLICIT: ** ** RETURNS: short field name */ char *LibGetFieldShortName (SLBoFIELD *field) { if (field->type->ityp == SRSxHEADER) return (field->name); else return field->type->shortn; } /**api* function ************************************************************** ** ** Returns the max name length of the entry used for the ID index. ** ** INPUT: address of library object [R] ** ** RETURNS: max name length */ Int4 LibGetMaxNameLength (SLBo *lib) { return lib->maxNameLen; } /**api* function ************************************************************** ** ** Returns the type describing which part of the file name is to be ** stored in the ID record of an entry. Only one of possibly several ** file types of a library can specify a name to be saved. ** ** INPUT: address of library object [R] ** ** RETURNS: max name length */ Int4 LibGetSaveNameType (SLBo *lib) { SRSoFILTYP *ft; Int4 c; for (c=0; (ft=LibNextFileType (lib, &c));) if ((ft->saveNameLength)) return ft->saveName; return 0; } /**api* function ************************************************************** ** ** Returns the max length of part of the file name that is to be ** stored in the ID record of an entry. Only one of possibly several ** file types of a library can specify a name to be saved. ** ** INPUT: address of library object [R] ** ** RETURNS: max name length */ Int4 LibGetSaveNameLength (SLBo *lib) { SRSoFILTYP *ft; Int4 c, len; for (c=0; (ft=LibNextFileType (lib, &c));) if ((len=ft->saveNameLength)) return len; return 0; } /**API* LibGetFieldIType ****************************************************** ** ** obsolete: see FieldGetIndexType
    ** Returns the index type of a field as string. ** ** INPUT: address of field object [R] ** IMPLICIT: ** ** RETURNS: field name ** NULL */ char *LibGetFieldIType (SLBoFIELD *field) { static char *fieldIType[10]={"", "id", "index", "link", "show", "tree", "num", "real", "group"}; return fieldIType[field->index]; } /**api* LibOpenFlatFile ******************************************************* ** ** Opens a flat file. ** More than one file may be open at a time - ** so if limit is exceeded some files ** have to be closed again; ** selects global "library" ** If a file could not be opened it will be marked bad - so no attempt ** will be done to open it again. ** ** INPUT: address of library object [W] ** file index [R] ** file type object [R] ** pointer to address of file object [W] ** IMPLICIT: ** ** RETURNS: 1 if file was opened ** 2 if already open ** file could not be opened: e__filnotok + ** file is known to be 'unopenable': e__badfile */ FILEo *LibOpenFlatFile (SLBo *lib, INT4 fileX, SRSoFILTYP *ft, INT4 *errCode) { static LIBoFLATFILE openFiles[LIBxMAXFILESOPEN]; static INT4 count = 0; FILEo *file; LIBoFLATFILE *openFile; char fileName[FILxXNAM+1], *dirName; INT4 k, c; if (LibIs (lib, "subentries")) lib = LibGetParentLib (lib); /* ** check first if the file is already opened ...find out by comparing ** the library and the file index; */ for (k=0; k < LIBxMAXFILESOPEN; k++) { if (lib == openFiles[k].lib && fileX == openFiles[k].fileX && ft == openFiles[k].fileType) return openFiles[k].file; } /* ** return error if there were previous unsuccessful attempts to open */ if (lib->fil[fileX].isBad) { if (errCode) *errCode = e__badfile; return NULL; } /* ** get the next 'openfile' object in the ring */ openFile = &(openFiles[count++ % LIBxMAXFILESOPEN]); if (!openFile->file) openFile->file = FileNew(NULL); file = openFile->file; /* iterate over directory names - first can be empty! */ for (c=0, k=0; (dirName = LibGetNextFlatFileDirName (lib, &c)) || !k; k++) { if (!dirName) dirName =""; FileSetName (file, "dir", dirName); FileSetName (file, "name", lib->fil[fileX].nam); FileSetName (file, "ext", ft->typ_nm); FileSetMaxLine (file, ft->ln_z); if (!FileOpen (file)) { lib->fil[fileX].isBad = 1; /* don't try again to open it */ _ErrMsg2 (e__filnotok, FileGetName (file, "path")); return NULL; } else break; } openFile->lib = lib; openFile->fileX = fileX; openFile->fileType = ft; return file; } /**api* LibGetFileType ******************************************************** ** ** Returns the file type object with the specified name or the first ** in the list if no name was specified. See also LibNextFileType. ** If the file type name is not specified then the first file type ** is returned. ** ** INPUT: the library object [R] ** symbolic name of the file stream (or NULL) [R] ** pointer to the index of the file type object (or NULL) [W] ** ** RETURNS: the file type object ** NULL: not found */ SRSoFILTYP *LibGetFileType (SLBo *lib, char *name, Int4 *index) { SRSoFILTYP *ft; Int4 c=0, k; if (LibIs (lib, "subentries")) lib = LibGetParentLib (lib); for (c=0, k=0; (ft=LibNextFileType (lib, &c)); k++) { if (!name) return ft; if (SmEqs (LibGetFileTypeName (ft), name)) { if (index) *index = k; return ft; } } return NULL; } /**api* LibNextFileType ****************************************************** ** ** Can be used to iterate over all file types specified for a databank. ** Eg, GCG formatted EMBL has two file types: one for the file with ** the annotation and one for the sequence file. See also LibGetFileType. ** ** INPUT: the library object [R] ** pointer to iterator which must be set to 0 to start [W] ** ** RETURNS: the file type object ** NULL: end of iteration */ SRSoFILTYP *LibNextFileType (SLBo *lib, Int4 *c) { if (LibIs (lib, "subentries")) lib = LibGetParentLib (lib); if (*c >= 2 || *c < 0 || !lib->form->fil_t[*c]) { *c = 0; return NULL; } return lib->form->fil_t[(*c)++]; } /**api* LibGetFileTypeName **************************************************** ** ** Returns the name of the file type object. ** ** INPUT: the file type object [R] ** ** RETURNS: the file type name */ char *LibGetFileTypeName (SRSoFILTYP *ft) { return ft->name; } /**api* LibGetFileTypeFipName ************************************************* ** ** Returns the name variable which stores the file pointer obtained ** by parsing the entry. ** ** INPUT: the file type object [R] ** ** RETURNS: a variable name */ char *LibGetFileTypeFipName (SRSoFILTYP *ft) { return ft->fipVar; } /**api* LibGetFileTypeTokenTableName ****************************************** ** ** Returns the name of the token table with the field tokens parsed ** from the file with specified file type. ** ** INPUT: the file type object [R] ** ** RETURNS: a token table name */ char *LibGetFileTypeTokenTableName (SRSoFILTYP *ft) { return ft->fieldTokens; } SRSoFILTYP *LibGetFileTypeSharesFile (SLBo *lib, SRSoFILTYP *ft, Int4 *index) { SRSoFILTYP *tmp; Int4 c=0, k; if (LibIs (lib, "subentries")) lib = LibGetParentLib (lib); if (ft->shareWith) { for (c=0, k=0; (tmp=LibNextFileType (lib, &c)); k++) { if (tmp == ft->shareWith) { *index = k; return tmp; } } } return NULL; } /**api* LibOpenNextFlatFile *************************************************** ** ** Opens the next flat file. ** ** INPUT: the library object [R] ** address of file object (set to NULL the first time) [W] ** the file type object [R] ** ** RETURNS: 1: next entry is in current file ** 2: new flat file was opened ** 0: end of the input stream (no more flat files) ** -1: failure during open */ Int4 LibOpenNextFlatFile (SLBo *lib, FILEo **file, SRSoFILTYP *ft, Int4 *fileX) { Int4 rv; if (!*file || FileIsEof (*file)) { if (++(*fileX) >= lib->nfil) return 0; if ((*file = LibOpenFlatFile (lib, *fileX, ft, &rv))) return 2; else { _ErrExit (e__eof); return -1; } } return 1; } /**api* LibOpenNextEntryFile ************************************************** ** ** Opens the next file that matches a search expression specified ** by the library object. To begin start with file set to NULL. ** The file object holds the iteration context itself. ** ** INPUT: the library object [R] ** address of file object (set to NULL the first time) [W] ** the file type object [R] ** ** RETURNS: number of files in the iteration */ Int4 LibOpenNextEntryFile (SLBo *lib, FILEo **file, SRSoFILTYP *ft) { char *tmp; Int4 c; if (!*file) { *file = FileNew (NULL); FileSetMaxLine (*file, ft->ln_z); if (*ft->pipe) FileSetPipe (*file, ft->pipe); c=0; tmp = LibGetNextFlatFileDirName (lib, &c); FileSetName (*file, "dir", tmp ? tmp : ""); FileSetName (*file, "name", *ft->searchName ? ft->searchName : "*"); if (!*ft->searchName) FileSetName (*file, "ext", ft->typ_nm); } /* construct file name */ return FileNext (*file); } /**api* LibOpenEntryFile ****************************************************** ** ** Opens the file that matches a search expression specified ** by the library object. To begin start with file set to NULL. ** The file object holds the iteration context itself. ** ** INPUT: the library object [R] ** address of file object (set to NULL the first time) [W] ** the file type object [R] ** ** RETURNS: number of files in the iteration */ Int4 LibOpenEntryFile (SLBo *lib, FILEo **file, SRSoFILTYP *ft, char *name) { Int4 c; char tmp[100]="", *t; /*SmEdit (name, SMxLOWCASE);*/ if (!*file) { *file = FileNew (NULL); FileSetMaxLine (*file, ft->ln_z); if (*ft->pipe) FileSetPipe (*file, ft->pipe); c=0; t = LibGetNextFlatFileDirName (lib, &c); FileSetName (*file, "dir", t ? t : ""); FileSetName (*file, "name", name); FileSetName (*file, "ext", ft->typ_nm); /* complete or partial file name has been saved */ if ((LibGetSaveNameLength (lib))) { switch (LibGetSaveNameType (lib)) { case LIBxFILE: FileSetName (*file, "file", name); break; case LIBxNAME: FileSetName (*file, "name", name); break; case LIBxPATH: FileSetName (*file, "path", name); break; } } return FileNext (*file); } return 1; } /**api* function ************************************************************** ** ** Writes an entry record into a buffer which can then be appended to ** the IDX file. ** ** INPUT: address entry-object [R] ** address of write buffer (must be allocated) [W] */ Int4 LibGetIdRecordSize (SLBo *lib) { Int4 size; size = LibGetMaxNameLength (lib) + 1; size += 8; /* size for two file pointers is default */ size += 4; /* index into the $file list */ size += LibGetSaveNameLength (lib) + 1; return size; } /**api* LibGetEntryAuxInfo **************************************************** ** ** Retrieves a record with auxilliary information. ** ** INPUT: file pointer in to node in ID-index [R] ** library object [R] ** initialized buffer object [W] ** IMPLICIT: ** ** RETURNS: 1 */ INT4 LibGetEntryAuxInfo (UINT4 fip, SLBo *lib, SMoBUFF *buff) { LIBoINDEX *libInx; if (!(libInx = LibIndexOpen (lib, NULL, 0))) _ErrRet (e__error); IdxGetBuff (libInx->idx, fip, buff); return 1; } /**api* LibSetField *********************************************************** ** ** selects a field-type for processing; field type can be specified ** directly or through a library - field type is only switched on if a ** library (if specified) points to it; ** ** INPUT: o name of library [R] ** o name of field type [R] or NULL ** o option: "init" - all fields are turned off
    ** "set" - field is turned on [R]
    ** "unset" - specified field is turned off
    ** "xinit" - same as "init" but ID-field is ** turned on...init for indexing
    ** "readlink" - turns on ID field + link fields
    ** "allindex" - all index fields are turned on
    ** "compress" - all compressable index fields are ** turned on
    ** "entry" - all fields of entry are turned on ** IMPLICIT: ** ** RETURNS: 1 if field was set (ie, was not set before); ** 0 if not */ INT4 LibSetField (char *libName, char *fieldName, char *option) { SLBo *lib; SLBoFORM *form; SLBoFIELD *field; SRSoFLD *fieldTypeCurr, *fieldType=NULL; INT4 k, setF = 0; /* ** get objects for library [and fieldtype] */ if (!(lib = (SLBo *) LibObjByName ("library", libName))) _ErrExit3 (e__objectunknown, "library", libName); if (fieldName) { if ((field = LibHasFieldNamed (lib, fieldName))) fieldType = field->type; else _ErrExit3 (e__objectunknown, "data-field", fieldName); } /* ** loop over all data-fields of selected library ** and set or unset the "do" flag */ form = lib->form; for (k=0; k < form->nf; k++) { field = &(form->f[k]); fieldTypeCurr = field->type; switch (tolower (option[0])) { case 'u': /* unset */ if (fieldType != fieldTypeCurr) /* otherwise fall through case */ break; case 'i': /* init */ field->do_f = 0; break; case 's': /* set */ if (fieldType == fieldTypeCurr && !field->do_f) { field->do_f = 1; setF = 1; } break; case 'r': /* readlink */ field->do_f = (field->index==SRSxID || field->index == SRSxLINK) ? 1 : 0; break; case 'x': /* xinit */ field->do_f = (field->index == SRSxID) ? 1 : 0; break; case 'a': /* allindex */ case 'c': /*compress */ if (FieldIs (field, "index")) { field->do_f = 1; setF = 1; } break; case 'e': /* entry */ field->do_f = 1; setF = 1; break; default: _ErrExit2 (e__unknownoption, option); } } return setF; } /****** LibSetActiveFields **************************************************** ** ** sets fields to be listed within entry list by what is specified in ** the global parameter list; ** ** INPUT: address of library descr. [R] ** IMPLICIT: ** ** RETURNS: 1 */ void LibSetActiveFields (SLBo *lib) { SLBoFORM *form; SLBoFIELD *df; INT4 k; if (!(ParGetBool ("parSetFields"))) return; form = lib->form; form->access_f = FALSE; for (k=0; k < form->nf; k++) { df = &form->f[k]; df->do_f = ParGetBool (df->type->nam) ? TRUE : FALSE; if (df->do_f) form->access_f = TRUE; } } /****** LibFieldIsActive ****************************************************** ** ** checks if certain field is to be processed; ** ** INPUT: library object [R] ** field index [R] ** pointer to flag if field is first in entry [W] ** IMPLICIT: ** ** RETURNS: FALSE if not ** TRUE if yes */ INT4 LibFieldIsActive (SLBo *lib, INT4 fieldInx, INT4 *isFirst) { SLBoFIELD *field; field = &(lib->form->f)[fieldInx]; if (FieldIs (field, "id")) { /* or the ID field is first field */ *isFirst = TRUE; return 1; } *isFirst = FALSE; if (field->do_f) return 1; return 0; } /**api* LibHasField *********************************************************** ** ** Checks if library has field with specified type and returns it. ** See also LibHasFieldNamed to get a field by name and LibGetFieldType. ** ** INPUT: library object [R] ** field type object [R] ** IMPLICIT: ** ** RETURNS: the field object ** NULL: not found */ SLBoFIELD *LibHasField (SLBo *lib, SRSoFLD *fieldType) { SLBoFIELD *field; Int4 k; for (k=0; k < lib->form->nf; k++) { field = &lib->form->f[k]; if (field->type == fieldType) return field; } return NULL; } /**api* LibHasFieldNamed ****************************************************** ** ** Checks if library has field with specified name returns it. ** Function assumes that the library has only ONE field with that ** name. ** See also LibHasField, LibGetFieldType, LibGetIdField, LibSetField, ** LibNextFieldInGroup, LibNextField, LibNextGroupField, ** LibGetFieldWithCode. ** ** INPUT: library object [R] ** long or short field name [R] ** IMPLICIT: ** ** RETURNS: the field object ** NULL: not found */ SLBoFIELD *LibHasFieldNamed (SLBo *lib, char *name) { SLBoFIELD *field; SRSoFLD *fieldType; Int4 c; for (c=0; (fieldType = LibNextFieldType (name, &c));) { if ((field = LibHasField (lib, fieldType))) return field; } return NULL; } /**api* LibGetFieldType ******************************************************* ** ** checks if data-field for specified library or library group exists ** and return pointer to ** the data-field type object; field name can be the short name or the ** full name. See also LibFieldType. ** ** INPUT: library name [R] ** field name [R] ** ** RETURNS: field type object ** NULL: not found */ SRSoFLD *LibGetFieldType (char *lib_nm, char *field_nm) { SRSoFLD *df_t; SRSoGROUP *libgroup; SLBo *lib; INT4 k; if (!LibGetLibGroup (lib_nm, &libgroup, &lib)) return NULL; /* ** name of a library was specified */ if (lib != NULL) for (k=0; k < lib->form->nf; k++) { df_t = lib->form->f[k].type; if (SmEqs (field_nm, df_t->shortn) || SmEqs (field_nm, df_t->nam)) return df_t; } /* ** else fields of the library group must be checked */ else exit (0); return NULL; } /**api* LibFieldType ********************************************************** ** ** obsolete: see FielGetType
    ** Returns for a field object the object describing its type. See also ** LibGetFieldType. ** ** INPUT: field object [R] ** ** RETURNS: field type object */ SRSoFLD *LibFieldType (SLBoFIELD *field) { return field->type; } /**api* LibGetIdField ********************************************************* ** ** returns the ID field object of specified library; ** ** INPUT: library object [R] ** IMPLICIT: ** ** RETURNS: data-field object ** NULL */ SLBoFIELD *LibGetIdField (SLBo *lib) { INT4 context; SLBoFIELD *field; if (LibIs (lib, "subentries")) lib = LibGetParentLib (lib); for (context=0; (field = LibNextField (lib, &context)); ) if (FieldIs (field, "id")) return field; return NULL; } /****** LibAlias ************************************************************** ** ** checks if an alias name (library name or logical name for either the ** library itself or for a single of its flatfiles) corresponds to a ** libary; ** ** INPUT: alias name [R] ** IMPLICIT: ** ** RETURNS: pointer to the library ** NULL if not found */ SLBo *LibAlias (char *lib_nm) { SRSoGROUP *group; SLBo *lib; INT4 l, c1, c2; for (c1=0; (group = LibNextLibGroup (&c1)); ) for (c2=0; (lib = LibNextLib (group, &c2)); ) { if (!lib->isActive) continue; /* library is not active */ if (SmEqs (lib->nam, lib_nm)) return lib; for (l=0; l < lib->nfil; l++) if (SmEqs (lib->fil[l].lnam, lib_nm)) return lib; for (l=0; *(lib->lnam[l]) != '\0'; l++) /* search all lib names */ if (SmEqs (lib->lnam[l], lib_nm)) return lib; } return NULL; } /**api* LibNextFieldInGroup *************************************************** ** ** Iterates for specified library over all fields that belong to ** specified field group. ** ** INPUT: library object [R] ** group field object [R] ** address of iterator [W} must be set to 0 to start ** ** RETURNS: address of field object ** NULL: the list has been exhausted */ SLBoFIELD *LibNextFieldInGroup (SLBo *lib, SLBoFIELD *fieldGroup, Int4 *c) { SLBoFIELD *field; while ((field = LibNextField (lib, c))) if (fieldGroup->type == field->type->group) return field; *c = 0; return NULL; } /**api* LibGetLibGroup ******************************************************** ** ** takes either library group name and library name and returns address ** of library and libgroup (library name) or only libgroup; ** comparison is case insensitive; sets "library" to NULL if name of ** library group.

    ** function is also useful for testing if library or group names are ** valid! ** ** INPUT: address of name [R] ** address of pointer to libgroup descr. [W] or NULL ** address of pointer to library descr. [W] or NULL ** IMPLICIT: ** srsdb (SRSoDB *) [R] ** ** RETURNS: 1 if name found ** 0 if not */ INT4 LibGetLibGroup (char *nam, SRSoGROUP **libgroup, SLBo **library) { SRSoGROUP *group; SLBo *lib; INT4 c1, c2; /* ** if name is from a library group set "library" to NULL and return */ for (c1=0; (group = LibNextLibGroup (&c1)); ) if (SmEqs (nam, group->short_nm) || SmEqs (nam, group->com)) { if (libgroup) *libgroup = group; if (library) *library = NULL; return 1; } for (c1=0; (group = LibNextLibGroup (&c1)); ) for (c2=0; (lib = LibNextLib (group, &c2)); ) { if (!lib->isActive) continue; /* library is not active */ if (SmEqs (nam, lib->nam)) { if (!library) return 1; *library = lib; break; } } if (!library || *library == NULL) return 0; /* name not known */ /* ** find library's group */ for (c1=0; (group = LibNextLibGroup (&c1)); ) { *libgroup = group; for (c2=0; (lib = LibNextLib (group, &c2)); ) { if (lib == *library) return 1; } } return 1; } /**api* LibRegisterObj ******************************************************** ** ** Registers an object so that it can be retrieved again by "LibObjByName" ** ** INPUT: o name of class: "library", "fieldtype", "group" ** "parser", "idtype", "arglist", "expression", ** "environment", "syntax" [R] ** o pointer to object [R] or NULL to initialize dictionary ** IMPLICIT: ** ** RETURNS: pointer to object ** NULL if not found */ void LibRegisterObj (char *className, void *obj) { INT4 c; SRSoGROUP *group; switch (tolower (className[2])) { case 'o': /* group */ if (!groupDict) { groupDict = DictCreate (&groupDictClass); for (c=0; (group = LibNextLibGroup (&c)); ) DictSet (&groupDict, group->com, SRSoGROUP*) = group; } if (obj) DictSet (&groupDict, ((SRSoGROUP*) obj)->com, SRSoGROUP*) = (SRSoGROUP*) obj; break; default: _ErrExit2 (e__unknownnam, className); } } /**api* LibObjByName ********************************************************** ** ** returns pointer to object with specified name from specified ** object class; case insensitive! ** ** INPUT: o name of class: "library", "fieldtype", "group" ** "parser", "idtype", "arglist" ** "environment", "syntax", "application" [R] ** o name of object [R] ** IMPLICIT: ** srsdb (SRSoDB *) [R] ** ** RETURNS: pointer to object ** NULL if not found */ void *LibObjByName (char *class_nm, char *objName) { Iter i; INT4 k; switch (tolower (class_nm[2])) { case 'o': /* group */ if (!groupDict) LibRegisterObj ("group", NULL); i = DictWith (groupDict, objName); return i ? DictIn (i, SRSoGROUP*) : NULL; break; case 'b': /* library */ for (k=0; k < srsdb->nslb; k++) { if (!srsdb->slb[k].isActive) continue; /* library is not active */ if (SmEqs (objName, srsdb->slb[k].nam)) return (void *) &srsdb->slb[k]; } break; case 'e': /* fieldtype */ for (k=0; k < srsdb->nfld; k++) /* long name */ if (SmEqs (objName, srsdb->fld[k].nam)) return (void *) &srsdb->fld[k]; for (k=0; k < srsdb->nfld; k++) /* short name */ if (SmEqs (objName, srsdb->fld[k].shortn)) return (void *) &srsdb->fld[k]; break; case 't': /* idtype */ for (k=0; k < srsdb->niddsc; k++) if (SmEqs (objName, srsdb->iddsc[k].nam)) return (void *) &srsdb->iddsc[k]; break; case 'g': /* arglist */ for (k=0; k < srsdb->commandN; k++) if (!strcmp (objName, srsdb->command[k].name)) return (void *) &srsdb->command[k]; break; case 'v': /* environment */ for (k=0; k < srsdb->environmentN; k++) if (SmEqs (objName, srsdb->environment[k].name)) return (void *) &srsdb->environment[k]; case 'n': /* syntax */ for (k=0; k < srsdb->syntaxN; k++) if (SmEqs (objName, srsdb->syntax[k].name)) return (void *) &srsdb->syntax[k]; case 'p': /* application */ for (k=0; k < srsdb->applicationN; k++) if (SmEqs (objName, ApplGetName (&srsdb->application[k]))) return (void *) &srsdb->application[k]; default: _ErrExit2 (e__unknownnam, class_nm); } return NULL; } /**api* LibNextFieldType ****************************************************** ** ** Returns the next field type with the specified long or short name. ** ** INPUT: o name of class: "library", "link" "fetch" [R] ** o object-ID [R] ** IMPLICIT: ** srsdb (SRSoDB *) [R] ** ** RETURNS: pointer to object ** NULL if not found */ SRSoFLD *LibNextFieldType (char *name, Int4 *c) { for (; *c < srsdb->nfld; (*c)++) if (SmEqs (name, srsdb->fld[*c].nam) || SmEqs (name, srsdb->fld[*c].shortn)) return &srsdb->fld[(*c)++]; /* not found */ *c = 0; return NULL; } /**api* LibObjById ********************************************************** ** ** returns pointer of object with specified object-ID from specified ** object class; case insensitive! ** ** INPUT: o name of class: "library", "link" "fetch" [R] ** o object-ID [R] ** IMPLICIT: ** srsdb (SRSoDB *) [R] ** ** RETURNS: pointer to object ** NULL if not found */ void *LibObjById (char *class_nm, INT4 objId) { switch (tolower (class_nm[2])) { case 'b': /* library */ if (objId < 256 && objId > 0) return (void *) srsdb->libTable[objId]; break; case 'n': /* link */ if (objId < srsdb->nlnk) return (void *) &(srsdb->lnk)[objId]; break; default: _ErrExit2 (e__unknownnam, class_nm); } return NULL; } static INT4 LibGetTokenCode (char *tokName) { /* separate 'tokentable|code' into two fields */ for (; *tokName && *tokName != '|'; tokName++) ; if (*tokName == '|') { *tokName = '\0'; return TokStrToCode (tokName+1); } return -1; } /**api* LibActiveLinks ******************************************************** ** ** marks links between active libraries; sets link names to library names; ** ** INPUT: ** IMPLICIT: ** srsdb (SRSoDB *) [R] ** ** RETURNS: 1 */ INT4 LibActiveLinks () { SRSoGROUP *group; SLBo *lib; LINKo *link; IDoTYPE *idType = (IDoTYPE*) LibObjByName ("idtype", "Entry-ID"); INT4 c1, c2, k; for (k=0; k < srsdb->nslb; srsdb->slb[k++].upd_f=FALSE) ; for (c1=0; (group = LibNextLibGroup (&c1)); ) for (c2=0; (lib = LibNextLib (group, &c2)); ) lib->upd_f = 1; for (k=0; k < srsdb->nlnk; k++) { /* can't use the function LibNextLink! */ link = &srsdb->lnk[k]; if (LinkIsMapsToParent (link)) link->isActive = TRUE; else if (!link->lib2) link->isActive = FALSE; else if (!link->lib1) /* parent links */ link->isActive = TRUE; else { if (!link->lib1->upd_f || !link->lib2->upd_f) link->isActive = FALSE; else { if (!link->id1_d) link->id1_d = idType; if (!link->id2_d) link->id2_d = idType; if (!*link->nam1) link->nam1 = link->lib1->nam; if (!*link->nam2) link->nam2 = link->lib2->nam; link->isActive = TRUE; link->tokCode = LibGetTokenCode (link->token); } } } return 1; } /**api* LibIsIdField ********************************************************** ** ** returns TRUE if the specified field is an ID field; ** ** INPUT: library name [R] ** data-field type name [R] ** IMPLICIT: ** ** RETURNS: 1 ** 0 */ INT4 LibIsIdField (char *libName, char *fieldName) { SLBo *lib; SLBoFIELD *field; INT4 c; if (!(lib = (SLBo *) LibObjByName ("library", libName))) _ErrExit3 (e__objectunknown, "data bank", fieldName); for (c=0; field = LibNextField (lib, &c);) if(SmEqs(field->type->nam,fieldName)||SmEqs(field->type->shortn,fieldName)) return (field->index == SRSxID) ? 1 : 0; return 0; } /**api* LibIsFieldType ******************************************************** ** ** returns TRUE if the specified field is of specified type; ** ** INPUT: field object [R] ** type: "index", "ID", "link", "show", "num", "real" ** "group", "active" [R] ** IMPLICIT: ** ** RETURNS: 1 ** 0 */ INT4 LibIsFieldType (SRSoFLD *fType, char *option) { switch (tolower (option[1])) { case 'n': /* index */ return (fType->ityp == SRSxID || fType->ityp == SRSxKEY || fType->ityp == SRSxNUM || fType->ityp == SRSxREAL) ? 1 : 0; case 'd': /* ID */ return (fType->ityp == SRSxID) ? 1 : 0; case 'i': /* link */ return (fType->ityp == SRSxLINK) ? 1 : 0; case 'h': /* show */ return (fType->ityp != SRSxGROUP) ? 1 : 0; case 'o': /* doquery */ return (fType->ityp == SRSxID || fType->ityp == SRSxKEY || fType->ityp == SRSxNUM || fType->ityp == SRSxREAL || fType->ityp == SRSxGROUP) ? 1 : 0; case 'u': /* num */ return (fType->ityp == SRSxNUM) ? 1 : 0; case 'e': /* real */ return (fType->ityp == SRSxREAL) ? 1 : 0; case 'r': /* group */ return (fType->ityp == SRSxGROUP) ? 1 : 0; case 'c': /* active */ return (ParGetBool (fType->nam)); default: _ErrExit2 (e__unknownoption, option); } return 0; } /**API* LibGetSubEntryField *************************************************** ** ** Exchanges a field object for the parent entry for the one the ** corresponds with it in the subentry objects. If none found it is ** simply returned. ** ** INPUT: o library object [R] ** o subentry object [R] ** o field object to be exchanged for subentry field [R] ** ** RETURNS: subentry field object */ SLBoFIELD *LibGetSubEntryField (SLBo *lib, LIBoSUBENTRY *subEntry, SLBoFIELD *entryField) { SLBoFIELD *field, *tmp; Int4 k; field = entryField; for (k=0; (tmp = LibNextSubEntryField (subEntry, &k));) if (tmp->type == entryField->type || tmp->replace == entryField->type) field = tmp; return field; } /**API* LibFieldHeaderHasWith ************************************************* ** ** Returns the number of field with the specified characteristic that ** is associated with the specified header field. Associated here means ** simply the fields following the header field in the $libformat ** definition until the next header field. ** ** INPUT: o address of library object [R] ** o header field object [R] ** o one of options suitable for FieldIs [R] or NULL ** ** RETURNS: number of fields in the group defined by the header field */ INT4 LibFieldHeaderHasWith (SLBo *lib, SLBoFIELD *header, char *option) { SLBoFIELD *field; Int4 c, k; for (c=0, k=0; (field = LibNextField (lib, &c));) { if (field == header) k++; else if (k) { if (FieldIs (field, "header")) break; else if (!option || FieldIs (field, option)) k++; } } return k ? k-1 : 0; } /**API* LibIsSubField ********************************************************* ** ** Returns TRUE if the specified characteristic is true for the specified ** data-field of a subentry. ** ** INPUT: o field object [R] ** o subentry object [R] ** o option: "inSubEntry", "first", "fromParent" [R] ** ** RETURNS: TRUE or FALSE */ INT4 LibIsSubField (SLBoFIELD *field, LIBoSUBENTRY *subEntry, char *option) { Int4 i; if (!field) return 0; switch (tolower (option[1])) { case 'n': /* insubEntry */ for (i=0; i < subEntry->fieldsN; i++) if (subEntry->fields[i].type == field->type) return 1; return 0; case 'i': /* first */ return (subEntry->first == field->type) ? 1 : 0; case 'r': /* fromParent */ return field->indexId == subEntry->idType ? 0 : 1; default: _ErrExit2 (e__unknownoption, option); } return 0; } /**api* LibGetFieldWithCode ************************************************** ** ** Returns for the field object with specified "fields" token code. ** ** INPUT: library object [R] ** (numeric) token code [R] ** ** RETURNS: the field object ** NULL: if not found */ SLBoFIELD *LibGetFieldWithCode (SLBo *lib, Int4 code) { SLBoFIELD *field; Int4 i; for (i=0; (field=LibNextField (lib, &i));) { if (field->fieldTokCode == 0) field->fieldTokCode = TokStrToCode (field->code); if (field->fieldTokCode == code) return field; } return NULL; } /**api* LibGetIndexTokenType ************************************************** ** ** Returns for specified data-field the name of the token table containing ** the words to be indexed and their token code if specified. ** ** INPUT: address of field object [R] ** address of code [W] ** IMPLICIT: ** ** RETURNS: the name of the token table */ char *LibGetIndexTokenType (SLBoFIELD *field, INT4 *code) { return field->indexToken[0]; } /**api* LibIsGenericId ******************************************************** ** ** returns TRUE if the ID name for each entry is to be generated during ** indexing, ie, no suitable data-field with unique identifiers exist; ** ** INPUT: address of library object [R] ** IMPLICIT: ** ** RETURNS: 1 ** 0 */ INT4 LibIsGenericId (SLBo *lib) { #ifdef xxx return lib->form->f[0].gnrc_f; /* field with index 0 is ID-field */ #endif return 1; } /**api* LibIsFilePerEntry ***************************************************** ** ** returns TRUE if the library is organized as a directory of files, each ** containing a single entry; ** ** INPUT: address of library object [R] ** ** RETURNS: 1 ** 0 */ INT4 LibIsFilePerEntry (SLBo *lib) { if (LibIs (lib, "subentries")) lib = LibGetParentLib (lib); return lib->form->fil_t[0]->sngl_f; } int (*funct)(char *, int); /**API* LibOpen *************************************************************** ** ** Opens specified depot file with all the run-time-data defined in the ** ODD files. ** ** INPUT: name of depot file [R] ** IMPLICIT: ** ** RETURNS: ** */ void LibOpen () { LIBoID *libId; SLBo *seLib; SRSoGROUP *group; char **object_p; long *object_n; INT4 idNum, k, c, i; SdlGetObjects (&object_n, (void ***) &object_p, "srs5"); srsdb = (SRSoDB *) object_p[O_SRSDB]; /* initialize the icarus syntax */ IcaInitSyntax (LibObjByName ("syntax", "icarus")); ParSetTable ("global", NULL, "PRIVATE"); ParInit (srsdb->parTable); ViewInitDefined (srsdb->view, srsdb->viewN); if ((srsdb->libTable = (SLBo **) calloc (256, sizeof (SLBo *))) == NULL) _ErrExit2 (e__allocfail, "library-ID list"); /* ** go through defined library-Ids, check and create a table of ** library objects where the Id serves as index */ for (k=0; k < srsdb->libIdN; k++) { libId = &srsdb->libId[k]; if (!libId->library) /* pointer is still a forward */ continue; idNum = libId->n; if (idNum <= 0 || idNum > 255) /* check range */ _ErrExit3 (e__novallibid, idNum, libId->library->nam); if (srsdb->libTable[idNum]) /* is ID already in use? */ _ErrExit4 (e__dupllibid, idNum, libId->library->nam, srsdb->libTable[idNum]->nam); srsdb->libTable[idNum] = libId->library; if (libId->library->idNum) /* has library an ID already? */ _ErrExit4 (e__libidexst, idNum, libId->library->nam, libId->library->idNum); libId->library->idNum = idNum; /* assign library plus potential sub libraries to a group */ if ((group = libId->library->group)) { group->library[group->libraryN++] = libId->library; for (c=0; (seLib = LibNextSubEntryLib (libId->library, &c));) { seLib->parent = libId->library; for (i=0; ilibraryN; i++) /* check if already in */ if (group->library[i] == seLib) break; if (i==group->libraryN) group->library[group->libraryN++] = seLib; } } } /* ** set an initial default environment ...can be changed later */ #ifdef VMS LibSetEnvironment ("vms"); #else LibSetEnvironment ("unix"); #endif OddInit (oddObjs, 1); /* for odd compiler */ } /**api* function ************************************************************** ** ** Initializes the templates for hypertext links. If a link is to ** the local SRSWWW server then the "-id" option is added to the ** command line which means that the function should be called after ** the global parameter "userIdOpt" is defined. ** */ void LibInitHyperLinks () { STRv hl=NULL; char *userId=ParGetStr ("userIdOpt"), *tmp, *p; Int4 k; hl = StrNew (); for (k=0; k < srsdb->hrefN; k++) { tmp = srsdb->href[k].link; if (*userId && (p=strstr (tmp, "=wgetz?"))) { p += 7; /* point after "=wgetz?" */ StrNSetS (&hl, tmp, p-tmp); StrAppS (&hl, userId); StrAppS (&hl, p); ParDefStr (srsdb->href[k].name, _Str(hl)); } else ParDefStr (srsdb->href[k].name, tmp); ParSetVolatile (srsdb->href[k].name); } StrDel (hl); } /**API* LibSetEnvironment ***************************************************** ** ** Sets library environment with specified name. ** ** INPUT: name of environment object [R] ** IMPLICIT: ** ** RETURNS: ** */ INT4 LibSetEnvironment (char *envName) { SLBo *lib, *seLib; LIBoENV *env; LIBoLIBENV *libenv; INT4 k, l, c; ParDefStr ("env", envName); if (!(env = (LIBoENV *) LibObjByName ("environment", envName))) _ErrExit3 (e__objectunknown, "environment", envName); for (k=0; k < srsdb->nslb; k++) /* turn all libs OFF */ srsdb->slb[k].isActive = 0; /* iterate over databanks in "site" and init libraries */ for (k=0; k < env->libenvN; k++) { libenv = &env->libenv[k]; for (l=0; *(libenv->lib->dirName[l] = libenv->dirName[l]) && l < 3; l++) ; lib = libenv->lib; lib->indexDirName = libenv->indexDirName; lib->isActive = 1; LibActivate (lib); /* activate also subentry libraries */ for (c=0; (seLib = LibNextSubEntryLib (lib, &c));) LibActivate (seLib); } /* ** initialize links...links between existing libs are activated */ LibActiveLinks (); ParDefFunction ("printf", (Func) LibPrintf); ParDefFunction ("print", (Func) LibPrint); ParDefFunction ("printField", (Func) LibPrintField); return 1; } static LibActivate (SLBo *lib) { IDoTYPE *idType = (IDoTYPE *) LibObjByName ("idtype", "Entry-ID"); SLBoFIELD *field; Int4 i, c; lib->isActive = 1; if (!lib->isInit && !lib->form->isInit) { lib->isInit = 1; lib->form->isInit = 1; for (c=0; (field = LibNextField (lib, &c));) { for (i=0; i<5; i++) if (*field->indexToken[i]) field->indexTokCode[i] = LibGetTokenCode (field->indexToken[i]); if (*field->tableToken) field->tableTokCode = LibGetTokenCode (field->tableToken); if (*field->token) field->fieldTokCode = LibGetTokenCode (field->token); if (!field->indexId) field->indexId = idType; } } } /**API* LibNextLink *********************************************************** ** ** Returns next link object if available. The context must be initially ** set to 0. The function returns only 'active' links, ie, links between ** existing databanks. See also LinkNext. ** ** INPUT: address of context [W] ** IMPLICIT: ** ** RETURNS: address of link object ** NULL if the list is exhausted (next call will start at begin) */ LINKo *LibNextLink (INT4 *context) { LINKo *link; if (*context >= srsdb->nlnk) { *context = 0; return NULL; } while (*context < srsdb->nlnk) { link = &srsdb->lnk[(*context)++]; if (link->isActive) return link; } *context = 0; return NULL; } /**API* LibNextLibGroup ******************************************************* ** ** Returns next library group object if available. The context must be ** initially set to 0. ** ** INPUT: address of context [W] ** IMPLICIT: ** ** RETURNS: address of library group object ** NULL if the list is exhausted (next call will start at begin) */ SRSoGROUP *LibNextLibGroup (INT4 *context) { if (*context >= srsdb->ngroup) { *context = 0; return NULL; } return &srsdb->group[(*context)++]; } /**API* LibNextLib ************************************************************ ** ** Returns next library object of specified library group if available. ** The context must be initially set to 0. ** ** INPUT: o address of library group object [W] ** o address of context [W] ** IMPLICIT: ** ** RETURNS: address of library object ** NULL if the list is exhausted (next call will start at begin) */ SLBo *LibNextLib (SRSoGROUP *group, INT4 *context) { SLBo *lib; while ((lib = group->library[(*context)++]) && !lib->isActive) ; if (!lib) *context = 0; return lib; } /**API* LibNextSubEntryLib ****************************************************** ** ** Returns next subentry object for specified library if available. ** The context must be initially set to 0. ** ** INPUT: o address of library object [R] ** o address of context [W] ** IMPLICIT: ** ** RETURNS: subentry object ** NULL if the list is exhausted (next call will start at begin) */ SLBo *LibNextSubEntryLib (SLBo *lib, Int4 *context) { SLBo *seLib; if (!(seLib = lib->subEntries[(*context)++])) { *context = 0; return NULL; } else return seLib; } /**API* LibNextField ********************************************************** ** ** Returns next field object of specified library if available; ** The context must be initially set to 0. ** ** INPUT: o address of library object [R] ** o address of context [W] ** IMPLICIT: ** ** RETURNS: address of field object ** NULL if the list is exhausted (next call will start at begin) */ SLBoFIELD *LibNextField (SLBo *lib, INT4 *context) { static SLBo *libCurr; if (*context == 0) libCurr = lib; if (*context >= libCurr->form->nf) { *context = 0; return NULL; } return &libCurr->form->f[(*context)++]; } /**api* LibNextDataType ******************************************************* ** ** Returns next data type object. ** ** INPUT: o address of library object [R] ** o address of context [W] ** IMPLICIT: ** ** RETURNS: data type object ** NULL: the list is exhausted (next call will start at begin) */ LIBoDataType *LibNextDataType (SLBo *lib, INT4 *c) { if (*c >= 5/*te!!!*/ || !lib->form->contains[*c]) { *c=0; return NULL; } else return lib->form->contains[(*c)++]; } /**API* LibNextSubEntryField ************************************************** ** ** Returns next field object of specified library's subentry type if ** available; ** The context must be initially set to 0. ** ** INPUT: o address of subentry object [R] ** o address of context [W] ** IMPLICIT: ** ** RETURNS: address of field object ** NULL if the list is exhausted (next call will start at begin) */ SLBoFIELD *LibNextSubEntryField (LIBoSUBENTRY *subEntry, INT4 *context) { if (*context >= subEntry->fieldsN) { *context = 0; return NULL; } return &subEntry->fields[(*context)++]; } /**API* LibNextFieldFormat **************************************************** ** ** Returns next field object of specified library if available; ** The context must be initially set to 0. ** ** INPUT: o address of library object [R] ** o address of context [W] ** IMPLICIT: ** ** RETURNS: address of field object ** NULL if the list is exhausted (next call will start at begin) */ LIBoFieldFormat *LibNextFieldFormat (SRSoFLD *fieldType, INT4 *context) { static SLBo *libCurr; if (fieldType->formatN <= *context) { *context = 0; return NULL; } else return &fieldType->format[(*context)++]; } /**api* LibFieldFormat ******************************************************** ** ** obsolete! see FieldGetFormat ** ** Returns the field format object if there is the field has a format with ** the specified name. if an empty name is specified then the first ** format in the list is returned (default format). ** ** INPUT: address of field object [R] ** format name (or NULL or empty string) [R] ** ** RETURNS: data-field format object */ LIBoFieldFormat *LibFieldFormat (SLBoFIELD *field, char *name) { LIBoFieldFormat *format; Int4 c; for (c=0; (format = LibNextFieldFormat (field->type, &c));) if (!name || !*name || SmEqs (format->name, name)) return format; return NULL; } void LibSelectFieldFormat (SRSoFLD *fieldType, char *name) { LIBoFieldFormat *format; Int4 c; if (name && *name) for (c=0; (format=LibNextFieldFormat (fieldType, &c));) { if (SmEqs (format->name, name)) format->isSelected = 1; else format->isSelected =0; } } char *LibGetFieldFormatEval (SLBoFIELD *field) { SRSoFLD *fieldType = field->type; Int4 k; if (!fieldType->formatN) return NULL; for (k=0; kformatN; k++) if (fieldType->format[k].isSelected) return fieldType->format[k].eval; return field->type->format[0].eval; /* first in list is default */ } /**api* LibGroupNew *********************************************************** ** ** Creates a new (empty) databank group with specified name (if any). ** ** INPUT: name of the group [R] or NULL ** ** RETURNS: the group object */ SRSoGROUP *LibGroupNew (char *name) { SRSoGROUP *group; if (!(group = (SRSoGROUP *) calloc (sizeof (SRSoGROUP), 1))) _ErrExit2 (e__allocfail, "db group"); if (name) { group->com = malloc (strlen (name) + 1); strcpy (group->com, name); LibRegisterObj ("group", group); } return group; } /**api* LibGroupAddDb ********************************************************* ** ** Adds one more data bank to the group. ** ** INPUT: group object [W] ** databank object [R] ** */ void LibGroupAddDb (SRSoGROUP *group, SLBo *lib) { group->library[group->libraryN++] = lib; } #define LIBxMaxFieldsInGroup 800 /**api* LibNextGroupField ***************************************************** ** ** Iterates over all field objects in an entire databank group. ** See also LibGroupNew and LibGroupAddDb for creating and extending ** library groups. ** ** INPUT: o group object [W] ** o flag if to show all fields or only those that all ** databanks in the group have in common [R] ** o iterator [W] ** */ SLBoFIELD *LibNextGroupField (SRSoGROUP *group, INT4 isOnlyCommon, INT4 *c) { SLBo *lib; SLBoFIELD *field; INT4 c1, c2, k; /* init first */ if (!group->fieldN) { group->fieldCount = (char *) calloc (LIBxMaxFieldsInGroup, sizeof(char)); for (c1=0; (lib = LibNextLib (group, &c1));) for (c2=0; (field = LibNextField (lib, &c2));) { for (k=0; k < group->fieldN; k++) if (group->field[k]->type == field->type && !FieldIs (field, "header")) { group->fieldCount[k]++; break; } if (k == group->fieldN) { if (k == LIBxMaxFieldsInGroup) _ErrExit3 (f__limitexceeded, "fields in group", LIBxMaxFieldsInGroup); else { group->fieldCount[group->fieldN] = 1; group->field[group->fieldN++] = field; } } } } /* return next field */ if (!*c) *c = 0; else if (*c == group->fieldN) { *c = 0; return NULL; } if (isOnlyCommon) { for (; *c < group->fieldN; (*c)++) if (group->fieldCount[*c] == group->libraryN) return (group->field[(*c)++]); } else return group->field[(*c)++]; return NULL; } /**api* LibToId *************************************************************** ** ** finds a library-ID for a library object; ** ** INPUT: address of library object [R] ** IMPLICIT: ** ** RETURNS: library ID or -1 if not found */ INT4 LibToId (SLBo *lib) { return lib->isActive ? lib->idNum : -1; } /**api* LibLinkToId *********************************************************** ** ** finds a link-ID for a link object; ** ** INPUT: address of link object [R] ** IMPLICIT: ** ** RETURNS: link ID or -1 if not found */ INT4 LibLinkToId (LINKo *link) { INT4 k; for (k=0; k < srsdb->nlnk; k++) if (link == &srsdb->lnk[k]) return k; return -1; } /**API* LibGetNextFlatFileDirName ********************************************* ** ** Returns the next flat file directory name in the list. To get the ** first the context must be set to 0. ** ** INPUT: address of library object [R] ** context (must be set to 0 for first in list) [W] ** IMPLICIT: ** ** RETURNS: o pointer to directory name ** o NULL if the list is exhausted (next call will start ** at begin) */ char *LibGetNextFlatFileDirName (SLBo *lib, INT4 *context) { char *dirName, parName[80]; if (!lib->dirName[*context] || !*lib->dirName[*context] || *context > 3) { *context = 0; return NULL; } if (LibIs (lib, "user")) { sprintf (parName, "%sDirName", lib->nam); if (!(dirName = ParGetStr (parName)) || !*dirName) dirName = lib->dirName[(*context)++]; } else dirName = lib->dirName[(*context)++]; return dirName; } /**API* LibGetNextFlatFileName ********************************************** ** ** Returns the next flat file directory name in the list. To get the ** first the context must be set to 0. ** ** INPUT: address of library object [R] ** context (must be set to 0 for first in list) [W] ** IMPLICIT: ** ** RETURNS: o pointer to directory name ** o NULL if the list is exhausted (next call will start ** at begin) */ char *LibGetNextFlatFileName (SLBo *lib, UINT4 *context) { static char *dirName; static char fileName[300]; static INT4 c; SRSoFILTYP *fileType=lib->form->fil_t[0]; if (LibIs (lib, "subentries")) lib = LibGetParentLib (lib); if (!*context) { c = 0; dirName = LibGetNextFlatFileDirName (lib, &c); } do { if (*fileType->searchName) sprintf (fileName, "%s%s", dirName, fileType->searchName); else sprintf (fileName, "%s*.%s", dirName, fileType->typ_nm); if (FilSearch (fileName, fileName, context)) return fileName; *context = 0; } while ((dirName = LibGetNextFlatFileDirName (lib, &c))); /* no more file names */ return NULL; } /**api* LibGetIndexName ******************************************************* ** ** finds a library-ID for a library object; composes a name that contains ** the directory + lib name and short field name...the extensions ** have to be added by the index modules; ** ** If the field object is omitted (NULL instead) then the name for ** the auxilliary index is returned. ** ** INPUT: address of library object [R] ** field object [R] or NULL ** address of output string [W] or NULL (uses static string) ** mode: "read" or "write" [R] ** IMPLICIT: ** global parameter "indexDirName" [R] ** ** RETURNS: pointer to index name ** NULL: not successful */ char *LibGetIndexName (SLBo *lib, SLBoFIELD *field, char *indexName, char *mode) { static char statIndexName[200]; char *indexDirName=NULL, tmp1[80], tmp2[80], *libName, *name; if (LibIs (lib, "subentries")) lib = LibGetParentLib (lib); libName = *lib->shortName ? lib->shortName : LibName (lib); if (LibIs (lib, "user")) { sprintf (tmp1, "%sDirName", libName); if (!(indexDirName = ParGetStr (tmp1)) || !*indexDirName) indexDirName = lib->indexDirName; } else { switch (tolower (mode[0])) { case 'r': if (!(indexDirName = ParGetStr ("indexDirName")) || !*indexDirName) indexDirName = lib->indexDirName; break; case 'w': /* ** check if either output dir or (with lesser priority) index dir ** are defined (command line) */ if (!(indexDirName = ParGetStr ("outDirName")) || !*indexDirName) if (!(indexDirName = ParGetStr ("indexDirName")) || !*indexDirName) indexDirName = lib->indexDirName; break; default: _ErrExit2 (e__unknownoption, mode); } } name = indexName ? indexName : statIndexName; if (field) sprintf (name, "%s%s_%s", indexDirName, SmEdit (strcpy (tmp1, libName), SMxLOWCASE), SmEdit (strcpy (tmp2, field->type->shortn), SMxLOWCASE)); else sprintf (name, "%s%s", indexDirName, SmEdit (strcpy (tmp1, libName), SMxLOWCASE)); return name; } /**API* function ************************************************************** ** ** Returns subentry library identified by specified subentry number. ** See also LibGetParentLib. ** ** INPUT: parent library object [R] ** subentry number [R] ** ** RETURNS: subentry library object */ SLBo *LibGetSubEntryLib (SLBo *lib, Int4 subEntryN) { return lib->subEntries[0]; } /**API* function ************************************************************** ** ** Returns parent library of subentry library. See also LibGetSubEntryLib. ** ** INPUT: subentry library object [R] ** ** RETURNS: parent library object */ SLBo *LibGetParentLib (SLBo *lib) { return lib->parent; } /**API* LibGetLink ************************************************************ ** ** Returns link between the libraries specified. ** ** INPUT: first library's name [R] ** second library's name [R] ** IMPLICIT: ** ** RETURNS: o address of link object ** o NULL if the library names could not be resolved or if ** there is no link specified between the two. */ LINKo *LibGetLink (char *lib1Name, char *lib2Name) { LINKo *link; SLBo *lib1,*lib2; INT4 context; if (!(lib1 = (SLBo *) LibObjByName ("library", lib1Name))) { _ErrMsg3 (e__objectunknown, "library", lib1Name); return NULL; } if (!(lib2 = (SLBo *) LibObjByName ("library", lib2Name))) { _ErrMsg3 (e__objectunknown, "library", lib2Name); return NULL; } for (context=0; (link = LibNextLink (&context)); ) if ( (link->lib1 == lib1 && link->lib2 == lib2) || (link->lib1 == lib2 && link->lib2 == lib1)) return link; return NULL; } /**api* LibGetLinkName ******************************************************* ** ** composes the file name for a link file ** ** INPUT: address of link object [R] ** flag if file with link in reverse dir [R] ** address of output string [W] ** mode: "read" or "write" [R] ** IMPLICIT: ** global parameter "indexDirName" [R] ** ** RETURNS: 1 if ok */ void LibGetLinkName (LINKo *link, INT4 isReverse, char *fileName, char *mode) { char *indexDirName=NULL, tmp1[80], tmp2[80]; if (LibIs (link->lib1, "user") || LibIs (link->lib2, "user")) { sprintf (tmp1, "%sDirName", link->lib1->nam); if (!(indexDirName = ParGetStr (tmp1)) || !*indexDirName) indexDirName = link->lib1->indexDirName; } else { switch (tolower (mode[0])) { case 'r': if (!(indexDirName = ParGetStr ("indexDirName")) || !*indexDirName) indexDirName = link->lib1->indexDirName; break; case 'w': /* ** check if either output dir or (with lesser priority) index dir ** are defined (command line) */ if (!(indexDirName = ParGetStr ("outDirName")) || !*indexDirName) if (!(indexDirName = ParGetStr ("indexDirName")) || !*indexDirName) indexDirName = link->lib1->indexDirName; break; default: _ErrExit2 (e__unknownoption, mode); } } if (!isReverse) sprintf (fileName, "%s%s_%s.link", indexDirName, SmEdit (strcpy (tmp1, link->nam1), SMxLOWCASE), SmEdit (strcpy (tmp2, link->nam2), SMxLOWCASE)); else sprintf (fileName, "%s%s_%s.link", indexDirName, SmEdit (strcpy (tmp1, link->nam2), SMxLOWCASE), SmEdit (strcpy (tmp2, link->nam1), SMxLOWCASE)); } /**API* LibPrintLibs ********************************************************** ** ** Lists all active libraries + some information ** ** INPUT: ** IMPLICIT: ** srsdb (SRSoDB *) [R] ** ** RETURNS: */ void LibPrintLibs () { SRSoGROUP *group; SLBo *lib; LIBoINDEX *libInx; INT4 context1, context2, (*print)(char *,...); if (!(print = (INT4 (*)(char *, ...)) ParGetFunction ("printf"))) print = (INT4 (*)(char *, ...)) printf; print (" Library Group Entries Index Date\n"); print ("-------------------------------------------------------------------\n"); for (context1=0; (group = LibNextLibGroup (&context1)); ) for (context2=0; (lib = LibNextLib (group, &context2)); ) { if (LibIs (lib, "subentries")) continue; if ((libInx = LibIndexOpen (lib, LibGetIdField (lib), 1))) { print ("%24s %-18s %7d %12s\n", lib->nam, group->com, BtrGetRecordN (libInx->btree), TimeToString (BtrGetTimeCreated (libInx->btree), "short")); } } } /****** LibPrintInfo ********************************************************** ** ** displays info about library ** ** INPUT: address of library name [R] ** IMPLICIT: ** ** RETURNS: 1 */ void LibPrintInfo (char *libName) { static char ln[132], *fieldType[10]={"", "id", "index", "link", "show", "tree", "num", "real", "group"}, *linkType[3]={"", " read-link", "index-link"}; SRSoGROUP *group; SLBo *lib; LINKo *link; SRSoFILTYP *fileType; SLBoFIELD *field; LIBoINDEX *libInx; char *dirName, relName[100], *tmp; INT4 c, k, l, isIdField, (*print)(char *, ...); if (!(lib = (SLBo *) LibObjByName ("library", libName))) _ErrExit3 (e__objectunknown, "library", libName); if (!(print = (INT4 (*)(char *, ...))ParGetFunction ("printf"))) print = (INT4 (*)(char *, ...)) printf; LibGetLibGroup (libName, &group, &lib); field = LibGetIdField (lib); /* ** find the release name if available */ relName[0] = '\0'; if ((libInx = LibIndexOpen (lib, field, 1))) if ((tmp = IdxGetReleaseName (libInx->idx)) && *tmp) sprintf (relName, ", release: %s, ", tmp); print ("\nLibrary: \"%s\"%s from group: \"%s\"\n\n", lib->nam, relName, group->com); /* ** list all indices */ print ("Data Fields (B=busy, C=compressed):\n\n"); print ("Name Short Type Inx Ids No No Creation B C\n"); print (" Name (kb) (kb) Words IDs Date \n"); print ("-------------------------------------------------------------------------------\n"); for (c=0, *ln='\0'; (field = LibNextField (lib, &c)); ) { sprintf (ln, "%-20s", LibGetFieldName (field)); sprintf (ln, "%s %-5s", ln, field->type->shortn); sprintf (ln, "%s %-5s", ln, fieldType[field->index]); if (FieldIs (field, "index") && (libInx = LibIndexOpen (lib, field, 1))) { isIdField = FieldIs (field, "id"); sprintf (ln, "%s %6d", ln, BtrGetFileSize (libInx->btree) / 1000); sprintf (ln, "%s %6d", ln, !isIdField ? IdsGetFileSize (libInx->idsFile) /1000 : 0); sprintf (ln, "%s %7d", ln, BtrGetRecordN (libInx->btree)); sprintf (ln, "%s %8d", ln, !isIdField ? IdsGetIdN (libInx->idsFile) : 0); sprintf (ln, "%s %9s", ln, TimeToString (BtrGetTimeCreated (libInx->btree), "short")); sprintf (ln, "%s %d", ln, BtrIsBusy (libInx->btree)); sprintf (ln, "%s %d", ln, IdsIsCompressed (libInx->idsFile)); } print ("%s\n", ln); } /* ** print link info */ print ("\n\nLinks:\n\n"); for (c=0; (link = LibNextLink (&c)); ) if (lib == link->lib1) print ("%s \"%s\" to \"%s\"\n", linkType[link->typ], lib->nam, link->lib2->nam); print (" \n"); for (c=0; (link = LibNextLink (&c)); ) if (lib == link->lib2) print ("%s \"%s\" to \"%s\"\n", linkType[link->typ], link->lib1->nam, lib->nam); print (" \n"); /* ** list names of flatfiles */ print ("Directory: "); for (c=0; (dirName = LibGetNextFlatFileDirName (lib, &c));) print (" \"%s\" ", dirName); print ("\n\n"); print ("Filename(s):\n"); if (LibIsFilePerEntry (lib)) print (" \"*\"\n"); else for (k=0; k < lib->nfil; k++) { *ln = '\0'; for (l=0; (fileType = lib->form->fil_t[l]); l++) sprintf (ln, "%s %15s.%s", ln, lib->fil[k].nam, fileType->typ_nm); print ("%s\n", ln); } print (" \n"); } /**api* LibParSetLibs ******************************************************** ** ** sets a list of libraries by taking a string with lib names separated ** by space; the "libList" "reset" will turn all libraries OFF; ** ** INPUT: string with a list of field names [R] ** ** IMPLICIT: ** ** RETURNS: 1 ** 0 if something is wrong */ INT4 LibParSetLibs (char *libList) { SRSoGROUP *group; SLBo *lib; char *tok, *tokList, tmp[132]; int context1, context2; strcpy (tmp, libList); tokList = tmp; if (SmEqs (libList, "reset")) { for (context1=0; (group = LibNextLibGroup (&context1));) for (context2=0; (lib = LibNextLib (group, &context2));) ParDefNum (lib->nam, 0); return 1; } while ((tok = strtok (tokList, " "))) { tokList = NULL; if ((lib = LibAlias (tok))) ParDefNum (lib->nam, 1); else { _ErrMsg3 (e__objectunknown, "library", tok); return 0; } } return 1; } /**api* LibParSetLinkLibs ***************************************************** ** ** sets a list of libraries by taking a string with lib names separated ** by space; the "libList" "reset" will turn all libraries OFF; ** ** INPUT: string with a list of field names [R] ** ** IMPLICIT: ** ** RETURNS: 1 ** 0 if something is wrong */ INT4 LibParSetLinkLibs (char *libList) { SRSoGROUP *group; SLBo *lib; char *tok, *tokList, tmp[132], parName[80]; int context1, context2; if (SmEqs (libList, "reset")) { for (context1=0; (group = LibNextLibGroup (&context1));) for (context2=0; (lib = LibNextLib (group, &context2));) { sprintf (parName, "%sLink", lib->nam); ParDefNum (parName, 0); } return 1; } strcpy (tmp, libList); tokList = tmp; while ((tok = strtok (tokList, " "))) { tokList = NULL; if ((lib = LibAlias (tok))) { sprintf (parName, "%sLink", lib->nam); ParDefNum (parName, 1); ParDefNum ("linkToLibs", 1); } else { _ErrMsg3 (e__objectunknown, "library", tok); return 0; } } return 1; } /**api* LibParSetFields ******************************************************* ** ** sets a list of fields by taking a string with fields separated by ** space; the "fieldList" "reset" will turn all fields OFF ** ** INPUT: string with a list of field names [R] ** ** IMPLICIT: ** srsdb (SRSoDB *) [R] ** ** RETURNS: 1 ** 0 if something is wrong */ INT4 LibParSetFields (char *fieldList) { SRSoFLD *fieldType; char *tok, *tokList, tmp[132]; int k, c, isFound; if (SmEqs (fieldList, "reset")) { for (k=0; k < srsdb->nfld; k++) { ParDefNum (srsdb->fld[k].nam, 0); ParSetVolatile (srsdb->fld[k].nam); } return 1; } strcpy (tmp, fieldList); tokList = tmp; ParDefNum ("parSetFields", 1); while ((tok = strtok (tokList, " "))) { tokList = NULL; for (isFound=0, c=0; (fieldType=LibNextFieldType (tok, &c));) { ParDefNum (fieldType->nam, 1); isFound=1; } if (!isFound) { _ErrMsg3 (e__objectunknown, "data-field", tok); return 0; } } return 1; } /**api* LibIs ***************************************************************** ** ** returns some boolean information about the library; ** ** INPUT: o library object [R] ** o option: "marked", "user", "selected", "linkTarget", ** "subEntries", "partitioned" [R] ** IMPLICIT: ** ** RETURNS: 1 ** 0 */ INT4 LibIs (SLBo *lib, char *option) { char parName[80]; switch (_Index(tolower (option[0]), tolower (option[1]))) { case _Index('s','e'): /* selected */ return (ParGetBool (lib->nam)); case _Index('m','a'): /* marked */ return lib->upd_f; case _Index('u','s'): /* user */ return lib->isFromUser; case _Index('l','i'): /* linkTarget */ sprintf (parName, "%sLink", lib->nam); return (ParGetBool (parName)); case _Index('p','a'): /* partitioned */ return lib->partFiles || lib->partSize ? 1 : 0; case _Index('s','u'): /* subentries */ return lib->parent ? 1 : 0; default: _ErrExit2 (e__unknownoption, option); } return 0; } /**api* LibMarkLinkedLibs ***************************************************** ** ** marks all libraries that are either directly or indirectly linked - all ** others are unmarked; the mark can be questioned by the function ** "LibIs"; marking includes library specified as argument; ** ** INPUT: library name [R] ** IMPLICIT: ** ** RETURNS: 1 if library is linked to at least one other ** 0 otherwise */ INT4 LibMarkLinkedLibs (char *libName) { SRSoGROUP *group; SLBo *lib; LINKo *link; INT4 isLinked=0, context1, context2, k, l; /* unmark all libraries */ for (context1=0; (group = LibNextLibGroup (&context1)); ) for (context2=0; (lib = LibNextLib (group, &context2)); ) lib->upd_f = 0; /* test if library is linked at all */ for (k=0, context1=0; (link = LibNextLink (&context1)); k++) if (link->typ != 3 && (SmEqs (libName, link->lib1->nam) || SmEqs (libName, link->lib2->nam))) { link->lib1->upd_f = link->lib2->upd_f = 1; isLinked = 1; } /* propagate all links by marking all libs that have a marked partner in a link - repeat number of link times */ for (l=0; l < k; l++) for (context1=0; (link = LibNextLink (&context1));) if (link->typ != 3 && (link->lib1->upd_f || link->lib2->upd_f)) link->lib1->upd_f = link->lib2->upd_f = 1; return isLinked; } /**api* LibIsAnyFieldActive *************************************************** ** ** tests is any field of library has been activated; ** ** INPUT: library name [R] ** IMPLICIT: ** ** RETURNS: 1 if at least one field is active ** 0 otherwise */ INT4 LibIsAnyFieldActive (char *libName) { SLBo *lib; SLBoFIELD *field; INT4 context; if (!(lib = (SLBo *) LibObjByName ("library", libName))) _ErrExit3 (e__objectunknown, "library", libName); for (context=0; (field = LibNextField (lib, &context)); ) if (FieldIs (field, "active")) return 1; return 0; } /**api* LibIsFieldInGroup ***************************************************** ** ** returns 1 if field type belongs logically to the field type group; ** ** INPUT: field type object [R] ** field type (group) object [R] ** IMPLICIT: ** ** RETURNS: 1 ** 0 */ INT4 LibIsFieldInGroup (struct SRSoFLD *fieldType, struct SRSoFLD *fieldTypeGroup) { return fieldType->group == fieldTypeGroup ? 1 : 0; } /**API* LibIsDataType ********************************************************* ** ** Returns 1 if databank contains protein sequences. ** ** INPUT: library object [R] ** one of: "protein", "dna" ** IMPLICIT: ** ** RETURNS: 1 ** 0 */ INT4 LibIsDataType (struct SLBo *lib, char *option) { switch (tolower (option[0])) { case 'p': /* protein */ return lib->dataType == 1 ? 1 : 0; case 'd': /* dna */ return lib->dataType == 2 ? 1 : 0; default: _ErrExit2 (e__unknownoption, option); } } /**API* LibSetStatus ********************************************************** ** ** Activates/Deactivates the specified library. ** ** INPUT: library name [R] ** 1=activate, 0=deactivate [R] ** IMPLICIT: ** ** RETURNS: ** library object ** NULL if library name not valid */ SLBo *LibSetStatus (char *libName, int doActivate) { SLBo *lib; INT4 k, isActive; /* iterate over all libraries - not just the active ones */ for (k=0; k < srsdb->nslb; k++) { lib = &srsdb->slb[k]; if (SmEqs (libName, lib->nam)) { isActive = lib->isActive; lib->isActive = doActivate; if (isActive != doActivate) LibActiveLinks (); return lib; } } return NULL; } /**API* LibSetIndexDir ***************************************************** ** ** Sets a new index directory for the specified library. ** ** INPUT: library object [W] ** directory name [R] ** IMPLICIT: ** ** RETURNS: */ void LibSetIndexDir (SLBo *lib, char *dirName) { char *tmp; if (!(tmp = (char *) malloc (strlen (dirName)+1))) _ErrExit2 (e__allocfail, "directory name"); strcpy (tmp, dirName); if (!OddIsInDepot (lib->indexDirName)) free (lib->indexDirName); lib->indexDirName = tmp; } /**API* LibSetFlatFileName ***************************************************** ** ** Sets a new flat file name without the extension (!) that is specified ** by the file type object. ** ** INPUT: library object [W] ** file name [R] ** ** RETURNS: */ void LibSetFlatFileName (SLBo *lib, char *fileName) { SLBoFIL *file; char *tmp; if (!(file = (SLBoFIL *) malloc (sizeof (SLBoFIL)))) _ErrExit2 (e__allocfail, "file object"); /* file name */ if (!(tmp = (char *) malloc (strlen (fileName)+1))) _ErrExit2 (e__allocfail, "file name"); strcpy (tmp, fileName); file->nam = tmp; /* (empty) logical file name */ if (!(tmp = (char *) malloc (4))) _ErrExit2 (e__allocfail, "logical file name"); *tmp = '\0'; file->lnam = tmp; lib->fil = file; lib->nfil = 1; } /**API* LibSetFlatFileDir ***************************************************** ** ** Sets a new flat file directory for specified library. ** ** INPUT: library object [W] ** directory name [R] ** ** RETURNS: */ void LibSetFlatFileDir (SLBo *lib, char *dirName) { char *tmp; if (!(tmp = (char *) malloc (strlen (dirName)+1))) _ErrExit2 (e__allocfail, "directory name"); strcpy (tmp, dirName); lib->dirName[0] = tmp; } /**API* LibGetIdType ********************************************************* ** ** Returns an IDtype object. ** If either library name or library ID are specified the ID type ** specific for that library is returned otherwise a default ID type that ** corresponds with the specified ID size. ** ** INPUT: library name [R] or NULL ** library-ID [R] or 0 ** length of ID [R] ** ** RETURNS: ** address of ID-type object */ IDoTYPE *LibGetIdType (char *libName, INT4 libId, INT4 idSize) { SLBo *lib=NULL; if (idSize == 4) { if (libName) { if (!(lib = (SLBo *) LibObjByName ("library", libName))) _ErrMsg3 (e__objectunknown, "library", libName); } else if (libId) { if (!(lib = (SLBo *) LibObjById ("library", libId))) _ErrMsg2 (e__libidnotknown, libId); } else { return (IDoTYPE *) LibObjByName ("idtype", "entry-id"); } if (lib) return (LibGetIdField (lib))->indexId; } else if (idSize == 6) { /* there is no other at the moment */ return (IDoTYPE *) LibObjByName ("idtype", "seq-ft-id"); } else { _ErrMsg4 (e__novalvar, "IDlength", idSize, "4 or 6"); } return NULL; } /**api* LibGetIdTypeName ****************************************************** ** ** Returns the name of the ID type object. ** ** INPUT: ID-type object [R] ** ** RETURNS: the name of the ID-type */ char *LibGetIdTypeName (IDoTYPE *idType) { return idType->nam; } /**API* LibHasNoFiles **************************************************** ** ** Returns TRUE if no flat file name records are associated with ** library object, ie, no source flat files were specified in ** the ODD specificiation. ** Returns TRUE only if entries of library are not in separate files - ** here flat file names are never directly specified. ** ** INPUT: library object [W] ** ** RETURNS: ** 1 ** 0 */ INT4 LibHasNoFiles (SLBo *lib) { if (lib->nfil || LibIsFilePerEntry (lib)) return 0; else return 1; } /**API* LibSetLibFlatFiles **************************************************** ** ** Searches directory for files that match the search string or the ** name '*.externsion' and puts these names into the array of flat file ** source names. These names are also stored in the IDX file. ** ** INPUT: library object [W] ** IDX file object [R] ** ** RETURNS: ** number of files found ** 0 files */ INT4 LibSetLibFlatFiles (SLBo *lib, struct IDXo *idx) { static char emptyLNam[1]=""; SLBoFIL *libFile; char *fileName, name[80]; INT4 c1=0, k; UINT4 c2; if (!IdxGetFlatFileNameN (idx)) { for (c2=0; (fileName = LibGetNextFlatFileName (lib, &c2));) { FilParse(fileName, name, FILxNAME); IdxSetFlatFileName (idx, name); } IdxWriteFlatFileNames (idx); /* flush file names into IDX file */ } k = IdxGetFlatFileNameN (idx); if (!(libFile = (SLBoFIL *) calloc (k, sizeof (SLBoFIL)))) _ErrExit2 (e__allocfail, "library file objects"); for (c1=0, k=0; (fileName = IdxGetFlatFileName (idx, &c1)); k++) { libFile[k].nam = fileName; libFile[k].lnam = emptyLNam; } lib->fil = libFile; lib->nfil = k; return k; } /**API* LibPrintStartupInfo *************************************************** ** ** Prints selected information about the library groups, databanks, fields ** and links that are needed by interfaces talking to some remote ** server.Prints to stdout. ** ** INPUT: ** ** RETURNS: */ void LibPrintStartupInfo () { static classId = 0; static struct LibCoords { char *intern; INT4 type_id; char name[100]; INT4 x, y; } *coords=NULL; FILo file; SRSoGROUP *group; SLBo *lib; LINKo *link; SLBoFIELD *field; LIBoINDEX *libInx; INT4 c1, c2, c3, x, y; char *tmp; /* ** init list for storing the libraries coordinates in the network ** picture ** Try to read the file (if exists) and save the coordinates */ if (!classId) LstManageClass (&classId, sizeof (struct LibCoords), NULL, NULL, NULL); if (!_ErrIs (FilUOpen (&file, "SRSWWW:srsnet.dat", 100, 0))) { while (!FilEof (&file)) { LstNew ((void **) &coords, classId); if (sscanf (file.ln, "coord: %s %d %d", coords->name, &coords->x, &coords->y) == 3) FilURead (&file); } } for (c1=0; (group = LibNextLibGroup (&c1)); ) { printf ("group: %s, searchall: %d\n", group->com, !group->single_f); } for (c1=0; (group = LibNextLibGroup (&c1)); ) for (c2=0; (lib = LibNextLib (group, &c2)); ) if ((libInx = LibIndexOpen (lib, LibGetIdField (lib), 1))) { if (LstHashSearch ((void **) &coords, lib->nam)) x = coords->x, y = coords->y; else x = y = 0; /* print library */ printf ("lib: %s, rel: %s, entries: %d, date: %s, group: %s, x: %d, y: %d\n", lib->nam, (tmp = IdxGetReleaseName (libInx->idx)) ? tmp : "", BtrGetRecordN (libInx->btree), TimeToString (BtrGetTimeCreated (libInx->btree), "date"), group->com, x, y); /* print fields */ for (c3=0; (field = LibNextField (lib, &c3)); ) if (!FieldIs (field, "system")) printf ("field: %s, type: %s\n", LibGetFieldName (field), LibGetFieldIType (field)); } /* print links */ for (c1=0; (link = LibNextLink (&c1)); ) if (link->lib1 && link->lib2) printf ("link: %s %s\n", link->lib1->nam, link->lib2->nam); } /**api* LibGetMaxNameSize ***************************************************** ** ** Returns the maximum size for a library name or field name. ** The max field length can include the max format name length ** ("formattedField"). The function can return the max length ** within the specified library, group, or if neither are specified ** in all groups. ** ** INPUT: group object (or NULL) [R] ** library object (or NULL) [R] ** option: "library", "field", "formattedField" ** IMPLICIT: ** ** RETURNS: the maximum string length */ Int4 LibGetMaxNameSize (SRSoGROUP *group, SLBo *lib, char *option) { LIBoFieldFormat *format; SLBoFIELD *field; INT4 c1, c2, c3, c4, len, fLen=0, isSingleGroup=0, isSingleLib=0, maxLen=0, maxFLen=0; if (group) isSingleGroup = 1; if (lib) { isSingleGroup = 1; isSingleLib = 1; } if (option[2] == 'b') { /* library */ for (c1=0; isSingleGroup || (group = LibNextLibGroup (&c1)); ) { for (c2=0; isSingleLib || (lib = LibNextLib (group, &c2)); ) { if (LibIs (lib, "subentries")) /* don't count subentry libs */ continue; if ((len = strlen (LibName (lib))) > maxLen) maxLen = len; } if (isSingleGroup) break; } } else { /* field or formattedField */ for (c1=0; isSingleGroup || (group = LibNextLibGroup (&c1)); ) { for (c2=0; isSingleLib || (lib = LibNextLib (group, &c2)); ) { for (c3=0; (field = LibNextField(lib, &c3));) { if (!FieldIs (field, "header")) { len = strlen (LibGetFieldName (field)); if (option[2] == 'r') /* formattedField */ { for (c4=0; (format=LibNextFieldFormat (field->type, &c4));) if ((fLen = strlen (format->name)) > maxFLen) maxFLen = fLen; len += fLen; } if (len > maxLen) maxLen = len; } } if (isSingleLib) break; } if (isSingleGroup) break; } } return maxLen; } /**api* LibParViewSetLibsRoot ************************************************* ** ** sets a list of libraries by taking a string with lib names separated ** by space; the "viewLibListRoot" "reset" will turn all libraries OFF; ** ** INPUT: string with a list of field names [R] ** ** IMPLICIT: ** ** RETURNS: 1 ** 0 if something is wrong */ INT4 LibParSetLibsViewRoot (char *libList) { SRSoGROUP *group; SLBo *lib; char *tok, *tokList, tmp[132]; int context1, context2; char parName[80]; char libName[80]; int viewNumber; strcpy (tmp, libList); tokList = tmp; if (SmEqs (libList, "reset")) { for (context1=0; (group = LibNextLibGroup (&context1));) for (context2=0; (lib = LibNextLib (group, &context2));) { sprintf(parName,"v%d_R_%s",ParGetNum("viewNumber"),libName); ParDefNum (parName, 0); } return 1; } while ((tok = strtok (tokList, " "))) { tokList = NULL; if(SmEqs(tok,"~~~~~~~~~~~~~~")) continue; sscanf(tok,"v%d_R_%s",&viewNumber,libName); if ((lib = LibAlias (libName))) { sprintf(parName,"v%d_R_%s",viewNumber,libName); ParDefNum (parName, 1); } else { _ErrMsg3 (e__objectunknown, "library", tok); return 0; } } return 1; } /**api* LibParViewSetLibsLeaf ************************************************* ** ** sets a list of libraries by taking a string with lib names separated ** by space; the "viewLibListLeaf" "reset" will turn all libraries OFF; ** ** INPUT: string with a list of field names [R] ** ** IMPLICIT: ** ** RETURNS: 1 ** 0 if something is wrong */ INT4 LibParSetLibsViewLeaf (char *libList) { SRSoGROUP *group; SLBo *lib; char *tok, *tokList, tmp[132]; int context1, context2; char parName[80]; char libName[80]; int viewNumber; strcpy (tmp, libList); tokList = tmp; if (SmEqs (libList, "reset")) { for (context1=0; (group = LibNextLibGroup (&context1));) for (context2=0; (lib = LibNextLib (group, &context2));) { sprintf(parName,"v%d_L_%s",ParGetNum("viewNumber"),libName); ParDefNum (parName, 0); } return 1; } while ((tok = strtok (tokList, " "))) { tokList = NULL; if(SmEqs(tok,"~~~~~~~~~~~~~~")) continue; sscanf(tok,"v%d_L_%s",&viewNumber,libName); if ((lib = LibAlias (libName))) { sprintf(parName,"v%d_L_%s",viewNumber,libName); ParDefNum (parName, 1); } else { _ErrMsg3 (e__objectunknown, "library", tok); return 0; } } return 1; } ));) { sprintf(parName,"v%d_L_%s",ParGetNum("viewNumber"),libName); ParDefNum (parName, 0); } return 1; } while ((tok = strtok (tokList, " "))) { tokList = NULL; if(SmEqs(tok,"~~~~~~~~~~~~~~")) continue; sscanf(tok,"v%d_L_%s",&viewNumber,libName); if ((lib = LibAlias (libName))) { sprintf(parName,"v%d_L_%s",viewNumber,libName); ParDefNum (parName, 1); } else { _ErrMsg3 (e__objectunknown, "library", tok); srs/src/library.h ** ** $RCSfile: library.h,v $ ** $Revision: 1.16 $ ** $Date: 1997/03/12 16:17:41 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port: Lukas Rosenthaler and Reinhard Doelz ** */ #define LIBxNULL 255 /* formerly SLBxNULL */ /* definition of data field types */ enum srs_dft {SRSxID=1, SRSxKEY, SRSxLINK, SRSxSHOW, SRSxHEADER, SRSxNUM, SRSxREAL, SRSxGROUP}; enum LIBeFORMAT {LIBxLISTING=1, LIBxLEFT, LIBxRIGHT, LIBxCENTER, LIBxPREFORMAT, LIBxTOPICLIST, LIBxNUMBERLIST, LIBxBULLETLIST, LIBxTABLE, LIBxTABLE2, LIBxTEXT}; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** contains neccessary info for accessing indexes to search a key and for ** retrieval of IDs */ typedef struct LIBoINDEX { struct SLBo *lib; /* library descriptor */ struct SLBoFIELD *field; /* data-field descriptor */ struct BTRo *btree; /* b-tree object */ struct IDSoFILE *idsFile; /* file with ID-lists */ struct IDXo *idx; /* id-index */ INT4 isIdIndex; } LIBoINDEX; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** list of functions exported by module "seqlib" */ #ifndef _SRSoGROUP typedef struct SRSoGROUP *dummytointroducestructtagSRSoGROUP; #endif #ifndef _SRSoFLD typedef struct SRSoFLD *dummytointroducestructtagSRSoFLD; #endif #ifndef _LINKo typedef struct LINKo *dummytointroducestructtagLINKo; #endif #ifndef _LIBoSUBENTRY typedef struct LIBoSUBENTRY *dummytointroducestructtagLIBoSUBENTRY; #endif /* get info */ char *LibName (struct SLBo *lib); char *LibGetName (struct SLBo *lib, char *option); char *LibGetSubEntryName (struct LIBoSUBENTRY *se); char *LibGetGroupName (struct SRSoGROUP *group, char *option); char *LibGetIcarusFileName (struct SLBo *lib, char *option); void LibPrintInfo (char *libName); void LibPrintStartupInfo (); void LibPrintLibs (); INT4 LibGetEntryAuxInfo (UINT4 fip, struct SLBo *lib, struct SMoBUFF *buff); INT4 LibGetLibGroup (char *nam, struct SRSoGROUP **libgroup, struct SLBo **library); Int4 libGetMaxNameSize (struct SRSoGROUP *group, struct SLBo *lib, char *option); struct LIBoFieldFormat *LibFieldFormat (struct SLBoFIELD *field, char *name); struct SLBo *LibAlias (char *lib_nm); void *LibObjByName (char *class_nm, char *obj_nm); void *LibObjById (char *class_nm, INT4 ObjId); struct SRSoFLD *LibGetFieldType (char *lib_nm, char *field_nm); struct SRSoFLD *LibFieldType (struct SLBoFIELD *field); INT4 LibToId (struct SLBo *lib); INT4 LibLinkToId (struct LINKo *link); INT4 LibMarkLinkedLibs (char *libName); struct LINKo *LibGetLink (char *lib1Name, char *lib2Name); struct IDoTYPE *LibGetIdType (char *libName, INT4 libId, INT4 idSize); struct SLBoFIELD *LibGetFieldWithCode (struct SLBo *lib, Int4 code); struct SLBoFIELD *LibGetSubEntryField (struct SLBo *lib, struct LIBoSUBENTRY *subEntry, struct SLBoFIELD *entryField); struct SLBo *LibGetSubEntryLib (struct SLBo *lib, Int4 subEntryN); struct SLBo *LibGetParentLib (struct SLBo *lib); /* functions returning booleans */ INT4 LibIs (struct SLBo *lib, char *option); INT4 LibFieldIsActive (struct SLBo *lib, INT4 fd_x, INT4 *first_f); INT4 LibIsIdField (char *libName, char *fieldName); INT4 LibIsFilePerEntry (struct SLBo *lib); INT4 LibIsGenericId (struct SLBo *lib); INT4 LibIsFieldType (struct SRSoFLD *fieldType, char *option); struct SLBoFIELD *LibHasFieldNamed (struct SLBo *lib, char *name); struct SLBoFIELD *LibHasField (struct SLBo *lib, struct SRSoFLD *fieldType); INT4 LibIsAnyFieldActive (char *libName); INT4 LibIsFieldInGroup (struct SRSoFLD *fieldType, struct SRSoFLD *fieldTypeGroup); INT4 LibIsDataType (struct SLBo *lib, char *option); INT4 LibHasNoFiles (struct SLBo *lib); /* working on databank groups */ struct SLBoFIELD *LibNextGroupField (struct SRSoGROUP *group, INT4 isOnlyCommon, INT4 *c); void LibGroupAddDb (struct SRSoGROUP *group, struct SLBo *lib); struct SRSoGROUP *LibGroupNew (char *name); /* for iteration */ struct SRSoFLD *LibNextFieldType (char *name, Int4 *c); struct SLBoFIELD *LibNextFieldInGroup (struct SLBo *lib, struct SLBoFIELD *fieldGroup, Int4 *c); struct SRSoGROUP *LibNextLibGroup (INT4 *context); struct SLBo *LibNextLib (struct SRSoGROUP *group, INT4 *context); struct SLBoFIELD *LibNextField (struct SLBo *lib, INT4 *context); struct SLBo *LibNextSubEntryLib (struct SLBo *lib, Int4 *context); struct SLBoFIELD *LibNextSubEntryField (struct LIBoSUBENTRY *subEntry, INT4 *context); struct LINKo *LibNextLink (INT4 *context); struct LIBoFieldFormat *LibNextFieldFormat (struct SRSoFLD *field, INT4 *context); struct LIBoDataType *LibNextDataType (struct SLBo*, INT4*); struct LIBoApplication *LibNextAppl (struct LIBoDataType*, INT4*); /* working with file types */ struct SRSoFILTYP *LibGetFileType (struct SLBo *lib, char *name, Int4 *index); struct SRSoFILTYP *LibNextFileType (struct SLBo *lib, Int4 *c); char *LibGetFileTypeName (struct SRSoFILTYP *ft); char *LibGetFileTypeFipName (struct SRSoFILTYP *ft); char *LibGetFileTypeTokenTableName (struct SRSoFILTYP *ft); struct SRSoFILTYP *LibGetFileTypeSharesFile (struct SLBo *lib, struct SRSoFILTYP *ft, Int4 *index); /* others */ char *LibGetFieldFormatEval (struct SLBoFIELD *field); INT4 LibSetField (char *lib_nm, char *field_nm, char *optiona); void LibSetActiveFields (struct SLBo *lib); char *LibGetIndexName (struct SLBo *lib, struct SLBoFIELD *field, char *indexName, char *mode); void LibGetLinkName (struct LINKo *link, INT4 isReverse, char *fileName, char *mode); struct SLBoFIELD *LibGetIdField (struct SLBo *lib); INT4 LibActiveLinks (); void LibSetIndexDir (struct SLBo *lib, char *dirName); struct SLBo *LibSetStatus (char *libName, int doActivate); void LibSetFlatFileDir (struct SLBo *lib, char *dirName); void LibSetFlatFileName (struct SLBo *lib, char *fileName); INT4 LibSetLibFlatFiles (struct SLBo *lib, struct IDXo *idx); char *LibGetNextFlatFileDirName (struct SLBo *lib, INT4 *context); char *LibGetFieldName (struct SLBoFIELD *field); char *LibGetFieldTypeName (struct SRSoFLD *type); char *LibGetFieldShortName (struct SLBoFIELD *field); char *LibGetFieldIType (struct SLBoFIELD *field); char *LibGetIdTypeName (struct IDoTYPE *idType); INT4 LibSetEnvironment (char *envName); char *LibGetLinkToName (struct LINKo *link); char *LibGetLinkFromName (struct LINKo *link); /* for checking parameters */ INT4 LibParSetLib (char *libName); /* open files */ void LibOpen (); LIBoINDEX *LibIndexOpen (struct SLBo*, struct SLBoFIELD*, INT4); struct FILEo *LibOpenFlatFile (struct SLBo*, INT4, struct SRSoFILTYP*, INT4*); Int4 LibOpenNextEntryFile (struct SLBo*, struct FILEo**, struct SRSoFILTYP *); Int4 LibOpenEntryFile(struct SLBo*, struct FILEo**, struct SRSoFILTYP*, char*); Int4 LibOpenNextFlatFile (struct SLBo*, struct FILEo**, struct SRSoFILTYP*, Int4*); /* for checking parameters */ INT4 LibParSetLib (char *libName); /* open files */ void LibOpen (); LIBoINDEX *LibIndexOpen (struct SLBo*, struct SLBoFIELD*, INT4); struct FILEo *LibOpenFlatFile (struct SLBo*, INT4, struct SRSoFILTYP*, INT4*); Int4 LibOpenNextEntryFile (struct SLBo*, struct FILEo**, struct SRSoFILTYP *); Int4 LibOpenEntryFile(struct SLBo*, struct FILEo**, struct SRSoFILTYP*, char*); Int4 LibOpenNextFlasrs/src/link.c char link_srs_ID[] = "$Id: link.c,v 1.16 1997/03/03 18:20:42 srs Exp $"; /* ** ** $RCSfile: link.c,v $ ** $Revision: 1.16 $ ** $Date: 1997/03/03 18:20:42 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port: Lukas Rosenthaler and Reinhard Doelz ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** Requires: query, sm, setop, srs, message ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** module has functions for linkage of sets of different ** types and/or origin (library). ** ** Global Parameters: ** "isPrintNoPath" - if "1" print error message if a path between to ** libs was not found ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include "message.h" #include "futil.h" #include "sm.h" #include "id.h" #include "lst.h" #include "set.h" #include "par.h" #include "link.h" #include "map.h" #include "btree.h" #include "ids.h" #include "library.h" #include "binpack.h" #include "query.h" #define _CONSTANTS #define _SRS #define _SLB #include SRSINCLUDE #define LINKxMAXIDN 600000 #define LINKxMAXCOST 1000000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** points to other link-node and to the link descrition; */ typedef struct LINKoEDGE { char *list; /* for usage of module "list" only! */ INT4 class_id; /* for "list" module */ struct LINKoNODE *fromNode; struct LINKoNODE *toNode; struct LINKo *link; INT4 cost; INT4 isReverse; /* TRUE if link specified in node is reverse to link in link-descripton */ } LINKoEDGE; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** describes a node in linkage map; */ typedef struct LINKoNODE { char *list; /* for usage of module "list" only! */ INT4 class_id; /* for "list" module */ char name[100]; struct LINKoEDGE *fromEdge; struct LINKoEDGE *edge; INT4 minCost; } LINKoNODE; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** extern, global or modulewide variables */ static char linkbuff[LNKxBUFFSIZ]; static LINKoNODE *node=NULL; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of static functions */ static void LinkConnectNodes (LINKo *link, INT4 isReverse); static void LinkExplore (LINKoEDGE *fromEdge, LINKoNODE *startNode, INT4 minCost); static INT4 LinkAnalNames (char *a_nm, char *b_nm, char **liba_nm, char **libb_nm, INT4 *a_n, INT4 *b_n); static INT4 LinkGoPath (char *fromName, char *toName, INT4 fromLibN, INT4 toLibN, LINKoNODE *node, SETo *outSet); static INT4 LinkCheckIdTyp (LINKo *Link, IDoTYPE *id1_d, IDoTYPE *id2_d); static INT4 LinkMapSingle (LINKo *lnk, char *a_nm, INT4 a_n, SETo *c, INT4 rev_f); static INT4 LinkGetLSet (LINKo *lnk, unsigned char **id_p, INT4 *n, INT4 rev_f); static INT4 LinkGetSet (SETo *s, unsigned char **id_p, INT4 *n, INT4 lib_x); static void LinkAddLink (LINKo *link, IDoENTRY *fromId, IDoENTRY *toId); /**api* LinkInit ************************************************************** ** ** selects links to active libraries; ** Copies library-names to link-descriptors where neccessary, initializes ** linkage map; ** ** INPUT: address of array of link-descriptors [R] ** number of link-descriptors [R] ** IMPLICIT: ** ** RETURNS: 1 */ INT4 LinkInit () { static INT4 isInit=0; LINKo *link; INT4 c; if (isInit) return 0; LibActiveLinks (); for (c=0; (link = LibNextLink (&c)); ) { if (!link->isActive || !link->lib1 || !link->lib2) continue; LinkConnectNodes (link, 1); LinkConnectNodes (link, 0); } isInit=1; return 1; } static void LinkNewNode (LINKoNODE *node) { node->edge = NULL; } Int4 LinkIsMapsToParent (LINKo *link) { return link->typ == LINKxToParent ? 1 : 0; } /****** LinkConnectNode ******************************************************* ** ** Connects to nodes. Creates both nodes if they don't exist and ** creates an edge object for first node. ** The connection is unidirectional and must be repeated in reverse order ** to achieve bidirectionality of the link. ** ** INPUT: o link object [R] ** o TRUE if direction is reverse to direction ** specified in ODD [R] ** IMPLICIT: ** node (LINKoNODE *) [W] ** ** RETURNS: */ static void LinkConnectNodes (LINKo *link, INT4 isReverse) { static INT4 nodeClassId=0, edgeClassId=0; LINKoEDGE *edge; char fromName[100], toName[100]; if (!nodeClassId) { LstManageClass (&nodeClassId, sizeof (LINKoNODE), (void *) LinkNewNode, NULL, NULL); LstManageClass (&edgeClassId, sizeof (LINKoEDGE), NULL, NULL, NULL); node = NULL; } if (isReverse) { strcpy (fromName, LibGetLinkToName (link)); strcpy (toName, LibGetLinkFromName (link)); } else { strcpy (fromName, LibGetLinkFromName (link)); strcpy (toName, LibGetLinkToName (link)); } if (!LstHashSearch ((void **) &node, SmEdit (fromName, SMxLOWCASE))) LstNewNamed ((void **) &node, nodeClassId, fromName); LstNew ((void **) &node->edge, edgeClassId); edge = node->edge; edge->fromNode = node; edge->cost = link->val; /* ** has to be reverse the other way round since ** the path is searched always in reverse direction ** ...to 'go' the path one has then to backtrack */ edge->isReverse = !isReverse; edge->link = link; if (!LstHashSearch ((void **) &node, SmEdit (toName, SMxLOWCASE))) LstNewNamed ((void **) &node, nodeClassId, toName); edge->toNode = node; } /**API* LinkSearchPath ******************************************************** ** ** Searches shortest path from one (library) node to another. ** Searches way from target to start - optimal way to target is recorded ** and placed in list of "LINKoSTEP" which can be "walked" in reverse ** direction. ** ** INPUT: first node's name [R] ** second node's name [R] ** IMPLICIT: ** node (LINKoNODE *) ** ** RETURNS: address of first node in path ** NULL if no path found */ LINKoNODE *LinkSearchPath (char *from, char *to) { SLBo *lib; char fromName[100], toName[100]; LinkInit (); strcpy (fromName, from); strcpy (toName, to); /* init all nodes */ LstFirst ((void **) &node); do node->minCost = LINKxMAXCOST; while (LstNext ((void **) &node)); if (!LstHashSearch ((void **) &node, SmEdit (fromName, SMxLOWCASE))) return NULL; LinkExplore (NULL, node, 0); if (LstHashSearch ((void **) &node, SmEdit (toName, SMxLOWCASE))) return (node->minCost == LINKxMAXCOST || node->minCost == 0) ? NULL : node; else return NULL; } /****** LinkExplore *********************************************************** ** ** ** INPUT: node (current) location at function call [R] or NULL ** node where exploration should be commenced [W] ** minCost so far [R] ** IMPLICIT: ** node (LINKoNODE *) ** ** RETURNS: address of first node in path ** NULL if no path found */ static void LinkExplore (LINKoEDGE *fromEdge, LINKoNODE *startNode, INT4 minCost) { LINKoEDGE *edge=startNode->edge; INT4 newMinCost; startNode->minCost = minCost; startNode->fromEdge = fromEdge; LstFirst ((void **) &edge); do { newMinCost = minCost + edge->cost; if (edge->toNode->minCost > newMinCost) LinkExplore (edge, edge->toNode, newMinCost); } while (LstNext ((void **) &edge)); } /**API* LinkBackTrack ******************************************************** ** ** ** INPUT: node from which to backtrack [R] ** pointer to address of link object [W] or NULL ** pointer to flag whether link is reverse or not [W] or NULL ** IMPLICIT: ** ** RETURNS: NULL if already at end of path ** node one step back in path */ LINKoNODE *LinkBackTrack (LINKoNODE *toNode, LINKo **link, INT4 *isReverse) { LINKoEDGE *edge=toNode->fromEdge; if (!edge) return NULL; if (link) *link = edge->link; if (isReverse) *isReverse = edge->isReverse; return edge->fromNode; } /**API* LinkGetPathLength ***************************************************** ** ** Returns the number of steps in a path ** ** INPUT: address of target node [R] ** IMPLICIT: ** ** RETURNS: nr. of steps in path */ INT4 LinkGetPathLength (LINKoNODE *toNode) { INT4 k; for (k=0; (toNode = LinkBackTrack (toNode, NULL, NULL)); k++) ; return k; } /**API* LinkGetNextInPath ***************************************************** ** ** Walks back one step and returns node object. ** ** INPUT: address of target node [R] ** address of flag for link direction [W] or NULL ** ** RETURNS: node object one step back in the path ** NULL if at end of path */ LINKoNODE *LinkGetNextInPath (LINKoNODE *toNode, INT4 *isReverse) { return LinkBackTrack (toNode, NULL, isReverse); } /****** LinkMap *************************************************************** ** ** top level function of this module; ** processes all possible linkages, set "b" will be mapped unto set "a" ** resulting in set c that is a subset of set "a"; ** set with second identifier will be mapped (i.e. has type of) onto ** set with first identifier; ** ** INPUT: address of first identifier [R] ** address of second identifier [R] ** address of resultant set [R] ** IMPLICIT: ** ** RETURNS: 1 ** e__unknownnam + ** e__ambigouslink + ** e__unknownnam + ** e__filopenerr + */ INT4 LinkMap (char *toName, char *fromName, SETo *c) { LINKoNODE *node; char *toLibName, *fromLibName; INT4 fromLibN, toLibN, rv; LinkInit (); if ((rv = LinkToParent (toName, fromName, c)) != 0) { _ErrIf (rv) { SetDelete (c->nam); return rv; } else return 1; } for (fromLibN=toLibN=0; (rv = LinkAnalNames (toName, fromName, &toLibName, &fromLibName, &toLibN, &fromLibN)) != 0;) { _ErrRet (rv); /* search path in reverse direction ...then backtrack */ if (!(node = LinkSearchPath (toLibName, fromLibName))) { if (ParGetNum ("isPrintNoPath")) _ErrMsg3 (e__nopath, fromLibName, toLibName); continue; } rv = LinkGoPath (fromName, toName, fromLibN, toLibN, node, c); _ErrRet (rv); } return 1; } /**api* LinkToParent ********************************************************** ** ** processes two kinds of linkages which involve both a conversion ** from CHILD-type to PARENT-type IDs; ** 1) conversion of set of CHILD-type IDs directly to PARENT-type ID's ** here second identifier must be name of conversion-link descriptor; ** 2) mapping of set of CHILD-type IDs to set of PARENT-type ids; ** ** INPUT: name of first set or "parent" [R] ** name of second set [R] ** address of resul set [W] ** IMPLICIT: ** ** RETURNS: 1: success ** 0: no path known to connect sets ** e__unknownnam: one of the two names is known ** e__novallink: link is known but not valid */ INT4 LinkToParent (char *a_nm, char *b_nm, SETo *c) { SETo *a, *b; LINKo *lnka=NULL, *lnkb, *lnk; INT4 a_t, b_t; if ((a_t = LinkIdentify (a_nm, &a, &lnka)) == 0) _ErrRet2 (e__unknownnam, a_nm); if ((b_t = LinkIdentify (b_nm, &b, &lnkb)) == 0) _ErrRet2 (e__unknownnam, b_nm); LinkIdentify ("PARENT", NULL, &lnk); if (a_t == LNKxSET && b_t == LNKxSET) { if (LinkCheckIdTyp (lnk, a->idType, b->idType)) { c->id_p = SetMapIds (a->id_p, b->id_p, a->n, b->n, &c->n, a->idType->siz, b->idType->siz, a->idType->fddbeg, b->idType->fddbeg, a->idType->fddlen + a->idType->lbxlen); SetMakeOwn (c, a->idType); return 1; } } else if (b_t == LNKxSET && (lnka && lnka->typ == LNKxMAPRNT)) { if (lnka->id2_d == b->idType) { c->id_p = SetMapToParent (b->id_p, b->n, &c->n, b->idType->siz, b->idType->fddbeg, b->idType->fddlen + b->idType->lbxlen); SetMakeOwn (c, lnk->id1_d); return 1; } else if (b->idType) _ErrRet3 (e__novallink, a_nm, b_nm); } return 0; } /****** LinkCheckIdTyp ******************************************************** ** ** checks if both ID-types are listed in link-descriptor; ** ** INPUT: address of link-descr. [R] ** address of first id-descr. [R] ** address of second id-descr. [R] ** IMPLICIT: ** ** RETURNS: 1 if ok ** 0 if not */ static INT4 LinkCheckIdTyp (LINKo *lnk, IDoTYPE *id1_d, IDoTYPE *id2_d) { if (id1_d == lnk->id1_d) { if (id2_d == lnk->id2_d) return 1; } else if (id1_d == lnk->id2_d) { if (id2_d == lnk->id1_d) return 1; } return 0; } /****** LinkAnalNames ********************************************************* ** ** input names may be set or library names; function gets for a ** set-name the associated library name with specified number (there may ** be many libraries associated with a set!). ** numbers must be 0 initially and will be incremented by one if there is ** a library name left. ** ** INPUT: address of first identifier [R] ** address of second identifier [R] ** output address of first library name [W] ** output address of second library name [W] ** output address of library number of first set [W] ** output address of library number of second set [W] ** IMPLICIT: ** ** ** RETURNS: 0 if no library name left ** 1 if success ** e__unknownnam + ** e__ambigouslink + */ static INT4 LinkAnalNames (char *a_nm, char *b_nm, char **liba_nm, char **libb_nm, INT4 *a_n, INT4 *b_n) { LINKo *lnka, *lnkb; SETo *a, *b; INT4 a_t, b_t, libb_f = FALSE, liba_f = FALSE; if ((a_t = LinkIdentify (a_nm, &a, &lnka)) == 0) _ErrRet2 (e__unknownnam, a_nm); if ((b_t = LinkIdentify (b_nm, &b, &lnkb)) == 0) _ErrRet2 (e__unknownnam, b_nm); if (a_t == LNKxSET) { if (a->n == 0) return 0; if (!a->anal_f) SetLibStat (a); } if (b_t == LNKxSET) { if (b->n == 0) return 0; if (!b->anal_f) SetLibStat (b); } if (a_t == LNKxSET && b_t == LNKxSET) { if (a->lib_n > 1 && b->lib_n > 1) _ErrRet3 (e__ambigouslink, a_nm, b_nm); } if (a_t == LNKxSET && *a_n < a->lib_n) { *liba_nm = a->lib_nm[(*a_n)++]; liba_f = TRUE; } else if (*a_n < 1) { *liba_nm = a_nm; liba_f = TRUE; } if (b_t == LNKxSET && *b_n < b->lib_n) { *libb_nm = b->lib_nm[(*b_n)++]; libb_f = TRUE; } else if (*b_n < 1) { *libb_nm = b_nm; libb_f = TRUE; } if (a_t == LNKxLINK && b_t == LNKxLINK) { (*b_n)++; (*a_n)++; } return liba_f && libb_f ? 1 : 0; } /****** LinkGoPath ************************************************************ ** ** processes each step of a path in sequential order; and adds set of ** found entries to resultant set; ** ** INPUT: address of first identifier [R] ** address of second identifier [R] ** number of library in first set [R] ** number of library in second set [R] ** address of path's first step [R] ** address of resultant set [W] ** IMPLICIT: ** ** RETURNS: 1 ** e__unknownnam + ** e__filopenerr + */ static INT4 LinkGoPath (char *fromName, char *toName, INT4 fromLibN, INT4 toLibN, LINKoNODE *node, SETo *outSet) { SETo *tmp, *toSet; LINKo *link; INT4 rv, nStep, isReverse; char tmp1Name[SETxXNAM+1], tmp2Name[SETxXNAM+1]; char *nextFromName; tmp1Name[0] = tmp2Name[0] = '\0'; for (nStep=0; (node = LinkBackTrack (node, &link, &isReverse)); nStep++){ if (!nStep) /* first step */ nextFromName = fromName; else { strcpy (tmp2Name, tmp1Name); nextFromName = tmp2Name; } /* ** perform next link and put result into newly created temporary set ** delete input temporary sets */ tmp = SetNew (tmp1Name, "temp"); /* output set */ rv = LinkMapSingle (link, nextFromName, nStep ? 1 : fromLibN, tmp, isReverse); _ErrRet (rv); SetMakeOwn (tmp, isReverse ? link->id1_d : link->id2_d); if (*tmp2Name) SetDelete (tmp2Name); } if (LinkIdentify (toName, &toSet, NULL) == LNKxSET) SetOp (tmp, toSet, NULL, SETxAND); SetOp (outSet, tmp, NULL, SETxOR); SetDelete (tmp1Name); return 1; } /**api* LinkIdentify ********************************************************** ** ** takes and identifier and finds out if its either a set name or a ** library name or nothing ** ** INPUT: address of name string [R] ** address of pointer to link-dscr. [W] or NULL ** address of pointer to set-dscr [W] or NULL ** IMPLICIT: ** ** RETURNS: 0 if unknown identifier ** LNKxLINK if a link ** LNKxSET if a set */ INT4 LinkIdentify (char *name, SETo **setPtr, LINKo **linkPtr) { SETo* set; LINKo* link; INT4 c; LinkInit (); if (SmEqs ("parent", name)) for (c=0; (link = LibNextLink (&c)); ) if (SmEqs (name, link->nam1) || SmEqs(name, link->nam2)) { if (linkPtr) *linkPtr = link; return LNKxLINK; } if ((set = (SETo *) SetGet (name)) != NULL) { if (setPtr != NULL) *setPtr = set; if (SetIsDB (set)) return LNKxLINK; else return LNKxSET; } else return 0; } /****** LinkDoLink ************************************************************ ** ** performs a single step in an linkage path; set's identifier ** must be either a setname or a library name; map is performed to the ** other library specified in the link-dsc. ** ** INPUT: address of linkage descriptor [R] ** set identifier [R] ** number of subset [R] ** address of resultant set's descr. [W] ** reverse flag [R] ** IMPLICIT: ** ** RETURNS: 1 ** e__unknownnam + ** e__filopenerr + */ static INT4 LinkMapSingle (LINKo *lnk, char *a_nm, INT4 a_n, SETo *c, INT4 rev_f) { LINKo *lnka; SETo *a; unsigned char *aid_p, *bid_p; INT4 a_t, a_z, b_z, rv; if ((a_t = LinkIdentify (a_nm, &a, &lnka)) == 0) _ErrRet2 (e__unknownnam, a_nm); rv = LinkGetLSet (lnk, &bid_p, &b_z, a_t == LNKxSET ? rev_f : !rev_f); _ErrRet (rv); if (a_t == LNKxSET) { LinkGetSet (a, &aid_p, &a_z, a_n); c->id_p = SetLink (aid_p, a_z, bid_p, b_z, &c->n, rev_f); } else c->id_p = SetCutLink (bid_p, b_z, &c->n, rev_f); SetRemoveDouble (c->id_p, c->n, 4, &c->n); if (ParGetNum ("doQueryReport")) Message (5, i__mappedset, 0, rev_f ? lnk->nam1 : lnk->nam2, c->n); return 1; } /****** LinkGetSet ************************************************************ ** ** returns pointer to ids and number of ids - the returned set is a subset ** of the input set containing ids of only one library - specified by ** number; ** if s->anal_f = FALSE it is assumed that the set contains ID's of ** only one primary library; ** ** INPUT: address of set-descr. [R] ** address of pointer to id's [W] ** address of set size [W] ** library index within set [R] ** IMPLICIT: ** ** RETURNS: 1 */ static INT4 LinkGetSet (SETo *s, unsigned char **id_p, INT4 *n, INT4 lib_x) { INT4 k, fst_x; if (!s->anal_f) { *id_p = s->id_p; *n = s->n; } else { for (k=0, fst_x=0; k < lib_x-1; fst_x += (INT4) s->lib_z[k++]) /*$$$$*/ ; *n = s->lib_z[k]; *id_p = s->id_p + s->idType->siz * fst_x; } return 1; } /****** LinkGetLSet *********************************************************** ** ** gets a set of link Id's: set is either already in memory or has ** to be read; set must be sorted depending on linkage (reverse or not) ** after first of second id. ** ** INPUT: address of link descr. [W] ** address of pointer to ID-block [W] ** address of set size [R] ** flag if link is in reverse direction [R] ** IMPLICIT: ** linkbuff (char []) [W] ** ** RETURNS: 1 ** e__filopenerr + */ static INT4 LinkGetLSet (LINKo *link, unsigned char **id_p, INT4 *n, INT4 rev_f) { static MAPo map; static char nam_s[FILxXNAM+1]; INT4 rv; char nam[FILxXNAM+1], *tmp; if (link->use) link = link->use; LibGetLinkName (link, rev_f, nam, "read"); if (strcmp (nam, nam_s) != 0) { if (nam_s[0] != '\0') MapFree (&map); #ifdef VMS rv = MapMem (&map, nam, linkbuff, LNKxBUFFSIZ); #else rv = MapMem (&map, nam, linkbuff, LNKxBUFFSIZ - 512); #endif _ErrRet (rv); strcpy (nam_s, nam); } /* ** first INT4 in mapsection contains the number of IDs - copy that ** number ...the set of link IDs start right after that number */ tmp = map.data; _BinUnpackNum (tmp, link->linkIdN); if (rev_f) _BinUnpackNum (tmp, link->lib2EntryN); else _BinUnpackNum (tmp, link->lib1EntryN); if (LNKxBUFFSIZ/8 < link->linkIdN) _ErrExit3 (f__limitexceeded, "links in buffer", LNKxBUFFSIZ/8); *n = link->linkIdN; *id_p = (unsigned char *) tmp; return 1; } /****** LinkReadLSet ********************************************************** ** ** reads a set of link ID's from file; ** ** INPUT: set name [R] ** address of set pointer [W] ** address of link-desc. [R] ** reverse flag [R] ** IMPLICIT: ** ** RETURNS: 1 ** e__filnotok + */ INT4 LinkReadLSet (char *nam, SETo **set_p, LINKo *lnk, INT4 rev_f) { SETo *set; FILE *fil; char fil_nm[FILxXNAM+1]; int errCode; sprintf (fil_nm, "%s%s.lnk", lnk->lib1->indexDirName, nam); fil = (FILE *) FilOpenR (fil_nm, &errCode); _ErrRet2 (errCode, fil_nm); set = SetNew (nam, "temp"); fread ((void *) &set->n, sizeof (INT4), 1, fil); fread (set->id_p, 8, set->n, fil); fclose (fil); SetMakeOwn (set, (IDoTYPE *) LibObjByName ("idtype", "link-id")); *set_p = set; return 1; } /**api* LinkOpen ************************************************************** ** ** ** INPUT: link object obtained by, eg, LibGetLink [W] ** option: "read", "writeread" or "writeindex" [R] ** IMPLICIT: ** ** RETURNS: the link object ** NULL: if the index does not exist ("read") */ LINKo *LinkOpen (LINKo *link, char *opt) { FILEo *file; SLBoFIELD *field; char fileName[FILxXNAM+1]; INT4 buffSize, errCode; /* ** read access */ if (SmEqs ("read", opt)) { LibGetLinkName (link, 0, fileName, "read"); file = FileNew (fileName); link->toFile = file; if (!(file = FileOpen (file))) return NULL; _BinFileUnpackNum (FileGetFile (file), link->linkIdN); _BinFileUnpackNum (FileGetFile (file), link->lib1EntryN); link->toFile = file; LibGetLinkName (link, 1, fileName, "read"); file = FileNew (fileName); link->fromFile = file; if (!(file = FileOpen (file))) return NULL; _BinFileUnpackNum (FileGetFile (file), link->linkIdN); _BinFileUnpackNum (FileGetFile (file), link->lib2EntryN); return link; } /* ** write access */ else { buffSize = LINKxMAXIDN * (link->id1_d->siz + link->id2_d->siz); if ((link->id_p = (unsigned char *) malloc (buffSize)) == NULL) { _ErrMsg2 (e__allocfail, "link ID buffer"); return NULL; } link->idWrtOff = (char *) link->id_p; link->goodRefN = link->badRefN = link->linkIdN = 0; /* ** open associated indices */ if (SmEqs ("writeindex", opt)) { /* if this is an index link */ if ((field = LibHasField (link->lib1, link->fromField))) { LibGetIndexName (link->lib1, field, fileName, "read"); link->btree1 = BtrOpen (fileName, "read", &errCode); _ErrMsg2 (errCode, FileGetName (link->btree1->file, "path")); link->ids1 = IdsOpen (fileName, "read", 0, NULL, &errCode); _ErrMsg2 (errCode, fileName); } else _ErrExit3 (e__dbhasnotfield, LibName(link->lib1),link->fromField->nam); } if ((field = LibHasField (link->lib2, link->toField))) { LibGetIndexName (link->lib2, field, fileName, "read"); link->btree2 = BtrOpen (fileName, "read", &errCode); _ErrMsg2 (errCode, FileGetName (link->btree2->file, "path")); link->ids2 = IdsOpen (fileName, "read", 0, NULL, &errCode); _ErrMsg2 (errCode, fileName); link->isOpen = 1; } else _ErrExit3 (e__dbhasnotfield, LibName (link->lib2), link->toField ? link->toField->nam : "unspecified"); return link; } } /**api* LinkGetCreTime ***************************************************** ** ** Returns the creation time of the link indices. Link must be ** already opened for read access with LinkOpen. ** ** INPUT: link object (must be opened for read access) [R] ** ** RETURNS: creation time */ Int4 LinkGetCreTime (LINKo *link) { return FileGetTime (link->toFile, "create"); } /**api* LinkGetLinkN ********************************************************** ** ** returns the number of links found in link index ** ** INPUT: link object (must be opened for read access) [R] ** IMPLICIT: ** ** RETURNS: number of links */ INT4 LinkGetLinkN (LINKo *link) { return link->linkIdN; } /**api* LinkGetEntryN ********************************************************* ** ** returns the number of entries of library used as sorting criterion ** found in the link (always the first library name in the link name); ** ** INPUT: link object (must be opened for read access) [R] ** IMPLICIT: ** ** RETURNS: number of entries */ INT4 LinkGetEntryN (LINKo *link, INT4 isReverse) { return isReverse ? link->lib2EntryN : link->lib1EntryN; } /**api* LinkSets ************************************************************** ** ** ** INPUT: link object [W] ** first set [R] ** second set [R] ** IMPLICIT: ** ** RETURNS: 1 */ void LinkSets (LINKo *link, SETo *fromSet, SETo *toSet) { IDoENTRY fromId, toId; INT4 i, j; for (i=0; SetNextId (fromSet, &fromId, &i);) for (j=0; SetNextId (toSet, &toId, &j);) LinkAddLink (link, &fromId, &toId); } /**api* LinkClose ************************************************************* ** ** writes two files with link ID's - first with with link-IDs sorted ** afters first entry-ID, second with link-IDs sorted after second ** entry ID; ** ** INPUT: link object [R] ** IMPLICIT: ** ** RETURNS: 1 */ void LinkClose (LINKo *link) { FILE *file; char fileName[FILxXNAM+1]; int errCode; /* ** close indices */ if (link->btree1) BtrClose (link->btree1); if (link->btree2) BtrClose (link->btree2); if (link->ids1) IdsClose (link->ids1); if (link->ids2) IdsClose (link->ids2); /* ** sort after first entry and write to file */ LibGetLinkName (link, 0, fileName, "write"); file = FilOpenW (fileName, &errCode); _ErrExit2 (errCode, fileName); SetHeapSort (link->id_p, link->linkIdN, 8, 0, 4); SetRemoveDouble (link->id_p, link->linkIdN, 8, &link->linkIdN); link->lib1EntryN = SetCountKey (link->id_p, link->linkIdN, 8, 0, 4); /* ** convert number of IDs to platform independent format */ _BinFilePackNum (file, link->linkIdN); _BinFilePackNum (file, link->lib1EntryN); fwrite (link->id_p, 8, link->linkIdN, file); fclose (file); /* ** sort after second entry and write out */ LibGetLinkName (link, 1, fileName, "write"); file = FilOpenW (fileName, &errCode); _ErrExit2 (errCode, fileName); SetHeapSort (link->id_p, link->linkIdN, 8, 4, 4); link->lib2EntryN = SetCountKey (link->id_p, link->linkIdN, 8, 4, 4); _BinFilePackNum (file, link->linkIdN); _BinFilePackNum (file, link->lib2EntryN); fwrite (link->id_p, 8, link->linkIdN, file); fclose (file); _ErrMsg6 (i__builtlink, link->lib1->nam, link->lib2->nam, link->goodRefN, link->badRefN, link->linkIdN); link->isOpen = 0; } /**api* LinkNext ************************************************************ ** ** Returns the next link where the specified library participates and ** which has the specified characteristic. ** See also LibNextLink. ** ** INPUT: the library object [R] ** address of iterator which must be set to 0 to start [R] ** option: "read" [R] ** ** RETURNS: the link object ** NULL: list is exhausted */ LINKo *LinkNext (SLBo *lib, char *option, Int4 *i) { LINKo *link; switch (option[0]) { case 'r': /* read */ while (link = LibNextLink (i)) { if (link->lib1 == lib && *link->token) return link; } break; default: _ErrExit2 (e__unknownoption, option); } *i = 0; return NULL; } /**api* LinkIs *************************************************************** ** ** Returns whether or not the specified characteristic is true for ** the link. ** ** INPUT: the link object [R] ** option: "read", "index", "user", "libs", "using" [R] ** ** RETURNS: TRUE or FALSE */ Int4 LinkIs (LINKo *link, char *option) { switch (tolower (option[2])) { case 'a': /* read */ return *link->token ? 1 : 0; case 'd': /* index */ return *link->token ? 0 : 1; case 'e': /* user */ return (LibIs (link->lib1, "user") || LibIs (link->lib2, "user")) ? 1: 0; case 'b': /* libs */ return link->lib1 && link->lib2 ? 1 : 0; case 'i': /* using */ return link->use ? 1 : 0; default: _ErrExit2 (e__unknownoption, option); return NULL; } } /**api* LinkNextToken ********************************************************* ** ** Iterates over the tokens used for building 'read' links. ** The token is characterized by token table name and token code. ** Returns the name of the token table. The token code is written ** into specified address. ** ** INPUT: the link object [R] ** address of token code [W] ** address of iterator. Must be set to 0 to start [W] ** ** RETURNS: name of token table ** NULL: list is exhausted */ char *LinkNextToken (LINKo *link, Int4 *code, Int4 *i) { if (!*i) { (*i)++; *code = link->tokCode; return link->token; } else { *i = 0; return NULL; } } /**api* LinkIdWithString ************************************************************ ** ** Links an entry-ID with a all entries that 'have' the string in ** the index specified by the link. ** ** INPUT: link object [W] ** ID object [R] ** string [R] ** ** RETURNS: TRUE if entries to be linked where identified by string */ Int4 LinkIdWithString (LINKo *link, IDoENTRY *fromId, char *s) { static SETo set; IDoENTRY toId; BTRoREC *record; FIP idFip; Int4 i; SmEdit (s, SMxLOWCASE); if ((record = BtrSearch (link->btree2, s, &idFip, 0))) { LinkCollectSet (&set, record, link->ids2); for (i=0; SetNextId (&set, &toId, &i);) LinkAddLink (link, fromId, &toId); link->goodRefN++; return 1; } else { link->badRefN++; return 0; } } /**api* LinkAddLink ************************************************************ ** ** Adds a new link to the link-ID buffer. ** ** INPUT: link object [W] ** from-ID object [R] ** to-ID object [R] */ static void LinkAddLink (LINKo *link, IDoENTRY *fromId, IDoENTRY *toId) { if (link->linkIdN + 1 > LINKxMAXIDN) _ErrExit3 (e__settoosmall, link->linkIdN + 1, LINKxMAXIDN); memcpy (link->idWrtOff, fromId->id, fromId->siz); link->idWrtOff += fromId->siz; memcpy (link->idWrtOff, toId->id, toId->siz); link->idWrtOff += toId->siz; link->linkIdN++; } /**api* LinkCollectSet ********************************************************* ** ** Collects all the Ids linked to btree records into specified set. ** ** INPUT: set object [W] ** record from btree object [R] ** Ids file object [R] */ void LinkCollectSet (SETo *set, BTRoREC *record, IDSoFILE *idsFile) { IDoTYPE *idType; IDPTR tmp; idType = IdsGetIdType (idsFile); tmp = SetGetIdBuff (set, record->r.value.idN * IdSize (idType)); IdsGet (idsFile, tmp, record->r.value.firstIdFip, record->r.value.idN); SetSetEntryN (set, record->r.value.idN); SetSetIdType (set, idType); } to btree records into specified set. ** ** INPUT: set object [W] ** record from btree object [R] ** Ids file object [R] */ void LinkCollectSet (SETo *set, BTRoREC *record, IDSoFILE *idsFile) { IDoTYPE *idType; IDPTR tmp; idType = IdsGetIdType (idsFile); tmp = SetGetIdBuff (set, record->r.value.idN * IdSize (idType)); IdsGet (idsFile, tmp, record->r.value.firstIdFip, record->r.value.idN); SetSetEntryN (set, record->r.value.idN); SetSesrs/src/link.h ** ** $RCSfile: link.h,v $ ** $Revision: 1.6 $ ** $Date: 1997/03/17 23:24:50 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** Copyright by Thure Etzold ** Unix port: Lukas Rosenthaler and Reinhard Doelz ** */ #define LNKxSET 1 #define LNKxLINK 2 #define LNKxBUFFSIZ 8*600000 #define LNKxREAD 1 #define LNKxINDEX 2 #define LNKxMAPRNT 3 #define LINKxToParent 3 typedef struct LINKo *LINKv; typedef struct LINKoNODE *LINKvNode; #ifndef _SLBo typedef struct SLBo *dummytointroducestructtagSLBolink; #endif typedef struct BTRoREC *dummytointroducestructtagBTRoREClink; typedef struct IDSoFILE *dummytointroducestructtagIDSoFILElink; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of exported functions */ INT4 LinkInit (); INT4 LinkMap (char *a_nm, char *b_nm, SETo *c); INT4 LinkIdentify (char *nam, SETo **s_p, LINKv *linkPtr); LINKv LinkOpen (LINKv link, char *opt); void LinkSets (LINKv link, struct SETo *set1, struct SETo *set2); void LinkIds (LINKv link, struct IDoENTRY *id1, IDoENTRY *id2); void LinkClose (LINKv link); Int4 LinkGetCreTimeLinkN (LINKv link); INT4 LinkGetLinkN (LINKv link); INT4 LinkGetEntryN (LINKv link, INT4 isReverse); INT4 LinkToParent (char *a_nm, char *b_nm, SETo *c); Int4 LinkIsMapsToParent (LINKv link); LINKv LinkNext (struct SLBo *lib, char *option, Int4 *i); char *LinkNextToken (LINKv link, Int4 *code, Int4 *i); void LinkCollectSet (struct SETo *set, struct BTRoREC *record, struct IDSoFILE *idsFile); /* for playing with paths */ struct LINKoNODE *LinkSearchPath (char *fromName, char *toName); INT4 LinkGetPathLength (struct LINKoNODE *toNode); struct LINKoNODE *LinkBackTrack (struct LINKoNODE *fromNode, LINKv *link, INT4 *isReverse); struct LINKoNODE *LinkGetNextInPath (struct LINKoNODE *toNode, INT4 *isReverse); nt4 *i); char *LinkNextToken (LINKv link, Int4 *code,srs/src/listv.c #include #include "def.h" #include "message.h" #include "listv.h" /******************************************************************** ** SIMPLE LIST: ** only for elements that can be created, destroyed, copied and moved ** without the need of calling management functions. ********************************************************************/ int listPos; int listAddPos; LISTo* ListAllocImpl(int sz) { LISTo* l=(LISTo*)malloc(sizeof(LISTo)+sz); ASSERT(l,"CouldNotAllocList"); l->h.usage=1; l->h.end=sz; return l; } void* ListNewImpl(int sz) { LISTo* l=(LISTo*)malloc(sizeof(LISTo)+sz); ASSERT(l,"CouldNotAllocList"); l->h.usage=1; l->h.end=sz; l->h.len=0; return l+1; } void ListChangeImpl(void** list, int beg, int end) { LISTo* l=(LISTo*)cast(*list, LISTo*)-1; int len=l->h.len; int dlen=end-beg; if (l->h.endh.usage>1) { LISTo* old=l+1; l=ListAllocImpl(len+dlen); l->h.len=len+dlen;l++; memcpy(offset(l, end, void*), offset(old,beg,void*), len-beg); if (dlen>0) memcpy(l, old, beg); else memcpy(l, old, end); ListDel(old); } else { l->h.len+=dlen; l++; _MemMove(offset(l,end, void*), offset(l,beg,void*), len-beg); } *list=l; } void ListDel(void* list) { LISTo* l=cast(list, LISTo*)-1; if (!--l->h.usage) free(l); } void ListDebug(void* list, int sz) { LISTo* l=(LISTo*)list-1; printf("LISTo:%p len:%d",list,l->h.len/sz); if (l->h.end!=l->h.len) printf(" grow:%d",(l->h.end-l->h.len)/sz); if (l->h.usage>1) printf(" shared:%d",l->h.usage-1); printf("\n"); } void ListIntDebug(int* list) { int i; ListDebug(list,sizeof(int)); printf("{ "); for (i=0; i<_ListLen(list); i++) { printf("%d ",list[i]); } printf("}\n"); } void ListPtrDebug(void** list) { int i; ListDebug(list,sizeof(void*)); printf("{ "); for (i=0; i<_ListLen(list); i++) { printf("%p ",list[i]); } printf("}\n"); } /************************************************************************** ** ALLOCATION POOL **************************************************************************/ /*#define POOL_DEBUG*/ #define POOL_MAX_ELEM_SIZE 256 #define POOL_CHUNK_SIZE 4096 #define ALIGN_SIZE_LOG 3 /* const WORD SMALL_OBJ_MASK=(POOL_MAX_ELEM_SIZE-1); const WORD TOO_BIG_MASK=~(POOL_CHUNK_SIZE-1); const WORD NOT_FITTING_OBJ_MASK=~((POOL_CHUNK_SIZE-1)&~SMALL_OBJ_MASK); */ void** pools[POOL_MAX_ELEM_SIZE>>ALIGN_SIZE_LOG]; long poolAllocated[POOL_MAX_ELEM_SIZE>>ALIGN_SIZE_LOG]; long poolAvailable[POOL_MAX_ELEM_SIZE>>ALIGN_SIZE_LOG]; void* palloc(int size) { if (size<=POOL_MAX_ELEM_SIZE) { void** pool; size=(size-1)>>ALIGN_SIZE_LOG; pool=pools[size]; if (pool) { /* return the first free element, and remove from list */ pools[size]=(void**)*pool; } else { /* create a new pool */ void **curr,**prev; int elemSize=(size+1)<pool) { *curr=prev; prev=curr; curr=offset(curr,-elemSize, void**); } pools[size]=prev; /* first free elem */ #ifdef POOL_DEBUG poolAvailable[size]+=poolNum; #endif } #ifdef POOL_DEBUG poolAllocated[size]++; poolAvailable[size]--; #endif return pool; } else return malloc(size); } void pfree(void* obj, int size) { ASSERT(obj, "FreeingNull"); if (size<=POOL_MAX_ELEM_SIZE) { void** elem=(void**)obj; /* add elem to free list */ size=(size-1)>>ALIGN_SIZE_LOG; *elem=pools[size]; pools[size]=elem; #ifdef POOL_DEBUG poolAllocated[size]--; poolAvailable[size]++; #endif } else free(obj); } void PoolDebug(int size) { #ifdef POOL_DEBUG int sz=(size-1)>>ALIGN_SIZE_LOG; printf("POOL size:%d allocated:%ld available:%ld\n", size, poolAllocated[sz], poolAvailable[sz]); #endif } void PoolDebugAll() { #ifdef POOL_DEBUG int sz; for (sz=0; sz>ALIGN_SIZE_LOG; sz++) { if (pools[sz]) PoolDebug((sz+1)<>ALIGN_SIZE_LOG; printf("POOL size:%d allocated:%ld available:%ld\n", size, poolAllsrs/src/listv.h #define _SLIST_H /******************************************************************** ** SIMPLE LIST: ** only for elements that can be created, destroyed, copied and moved ** without the need of calling management functions. ********************************************************************/ /* internals */ typedef union LISTo { struct { int usage; int len; int end; } h; void* tail_aligned; } LISTo; void* ListNewImpl (int sz); void ListChangeImpl(void** list, int beg, int end); extern int listAddPos; extern int listPos; #define _ListAddImpl(plist,pos) listAddPos=(pos)*sizeof(**(plist)),ListChangeImpl((void**)(plist),listAddPos,\ listAddPos+sizeof(**(plist))),*(plist)+(pos) /* end internals */ /******************************************************************* ** API: the List type *******************************************************************/ #define _List(type) type* /* creation/deletion */ void ListDel(void* list); /**api* macro ************************************************************ ** ** Creates a new empty LISTv with space allocated for 'num' elements ** ** INPUT: the type name of the list element ** the number of elements to be allocated ** RETURNS: the emtpy LISTv */ #define _ListNew(type,num) ((type*)ListNewImpl(num*sizeof(type))) /**api* macro ************************************************************ ** ** Sets the given LISTv to a new empty LISTv with space allocated ** for 'num' elements. The LISTv must NOT contain a valid list ** value, must be unassigned (can contain a random pointer) ** ** INPUT: [W] the LISTv to be assigned ** the number of elements to be allocated */ #define _ListNewIn(plist,num) (ListDel(*(plist)),*(void**)(plist)=ListNewImpl(num*sizeof(**(plist)))) /**api* macro ************************************************************ ** ** Just an alias to the ListDel function ** ** INPUT: the LISTv */ #define _ListDel(list) ListDel(list) /* debugging */ void ListDebug (void* list, int sz); void ListIntDebug (int* list); void ListPtrDebug (void** list); /* virtual copy management */ /**api* macro ************************************************************ ** ** If the list buffer is shared between multiple copies, creates ** a private copy ready to be modified. Returns the modified copy ** ** INPUT: [W] the pointer to the LISTv ** RETURNS: the LISTv ready to be modified */ #define _ListChange(plist) (ListChangeImpl((void**)(plist),0,0),*plist) /**api* macro ************************************************************ ** ** Returns a (virtual) copy of the list ** ** INPUT: the LISTv to be copied ** RETURNS: the copied LISTv */ #define _ListCpy(list) (!(list)||((LISTo*)(list)-1)->h.usage++,(list)) /**api* macro ************************************************************ ** ** Assignes to a LISTv a (virtual) copy of a list value ** ** INPUT: [W] the pointer to the LISTv to be assigned ** the new LISTv value */ #define _ListSet(plist,list) (ListDel(*(plist)),*(plist)=_ListCpy(list)) /* element operations */ /**api* macro ************************************************************ ** ** Inserts a new element at the beginning of a LISTv ** ** INPUT: [W] the pointer to the LISTv to be modified ** RETURNS: the new element */ #define _ListIns(plist) *(ListChangeImpl((void**)(plist),0,sizeof(**(plist))),*(plist)) /**api* macro ************************************************************ ** ** Adds a new element at the given poisition 'pos' in the LISTv. ** ** INPUT: [W] the pointer to the LISTv to be modified ** pos=the insertion position ** RETURNS: the new element */ #define _ListAdd(plist,pos) *(_ListAddImpl(plist,pos)) /**api* macro ************************************************************ ** ** Appends a new element at the end of a LISTv ** ** INPUT: [W] the pointer to the LISTv to be modified ** RETURNS: the new element */ #define _ListApp(plist) *(listPos=_ListLen(*(plist)),_ListAddImpl(plist,listPos)) /**api* macro ************************************************************ ** ** Deletes an element at the given position 'pos' of a LISTv ** ** INPUT: [W] the pointer to the LISTv to be modified ** pos=the deletion position */ #define _ListCut(plist,pos) (listPos=(pos)*sizeof(**(plist)),ListChangeImpl((void**)(plist),listPos+sizeof(**(plist)),listPos)) /* multiple elem operations */ /**api* macro ************************************************************ ** ** Deletes a given number 'num' of elements at the given ** position 'pos' of a LISTv ** ** INPUT: [W] the pointer to the LISTv to be modified ** pos=the deletion position ** num=the number of elements */ #define _ListCutMany(plist,pos,num) (listPos=(pos)*sizeof(**(plist)),ListChangeImpl((void**)(plist),listPos+sizeof(**(plist))*(num),listPos)) /**api* macro ************************************************************ ** ** Inserts a given number 'num' of new elements at the ** beginning of a LISTv ** ** INPUT: [W] the pointer to the LISTv to be modified ** num=the number of elements ** RETURNS: a pointer to the first of the new elements */ #define _ListInsMany(plist,num) (ListChangeImpl((void**)plist,0,sizeof(**plist)*(num)),(*plist)[pos]) /**api* macro ************************************************************ ** ** Adds a given number 'num' of new elements at the given ** position 'pos' of a LISTv ** ** INPUT: [W] the pointer to the LISTv to be modified ** pos=the insertion position ** num=the number of elements ** RETURNS: a pointer to the first of the new elements */ #define _ListAddMany(plist,pos,num) (listAddPos=(pos)*sizeof(**(plist)),\ ListChangeImpl((void**)(plist),listAddPos,listAddPos+sizeof(**(plist))*(num)),*(plist)+(pos)) /**api* macro ************************************************************ ** ** Appends a given number 'num' of new elements at the ** end of a LISTv ** ** INPUT: [W] the pointer to the LISTv to be modified ** num=the number of elements ** RETURNS: a pointer to the first of the new elements */ #define _ListAppMany(plist,num) (listPos=_ListLen(*(plist)),_ListAddMany(plist,listPos,num)) /**api* macro ************************************************************ ** ** Adds a number 'num' of elements from a C array 'arr' at the given ** position 'pos' of a LISTv ** ** INPUT: [W] the pointer to the LISTv to be modified ** pos=the insertion position ** arr=the array of elements ** num=the number of elements */ #define _ListAddArr(plist,pos,arr,num) memcpy(_ListAddMany(plist,pos,num),arr,sizeof(*plist)*(num)) /**api* macro ************************************************************ ** ** Inserts a number 'num' of elements from a C array 'arr' at ** the beginning of a LISTv ** ** INPUT: [W] the pointer to the LISTv to be modified ** arr=the array of elements ** num=the number of elements */ #define _ListInsArr(plist,arr,num) memcpy(_ListInsMany(plist,num),arr,sizeof(*plist)*(num)) /**api* macro ************************************************************ ** ** Appends a number 'num' of elements from a C array 'arr' at ** the end of a LISTv ** ** INPUT: [W] the pointer to the LISTv to be modified ** arr=the array of elements ** num=the number of elements */ #define _ListAppArr(plist,arr,num) memcpy(_ListAppMany(plist,num),arr,sizeof(*plist)*(num)) /**api* macro ************************************************************ ** ** Adds the elements of a LISTv at the position 'pos' of a LISTv ** ** INPUT: [W] the pointer to the LISTv to be modified ** pos=the insertion position ** the LISTv to be added */ #define _ListAddList(plist,pos,list) _ListAddArr(plist,pos,list,_ListLen(list)) /**api* macro ************************************************************ ** ** Inserts the elements of a LISTv at the beginning of a LISTv ** ** INPUT: [W] the pointer to the LISTv to be modified ** the LISTv to be inserted */ #define _ListInsList(plist,list) _ListInsArr(plist,list,_ListLen(list)) /**api* macro ************************************************************ ** ** Appends the elements of a LISTv at the end of a LISTv ** ** INPUT: [W] the pointer to the LISTv to be modified ** the LISTv to be appended */ #define _ListAppList(plist,list) _ListAppArr(plist,list,_ListLen(list)) /* access */ /**api* macro ************************************************************ ** ** INPUT: the LISTv ** RETURNS: the lenght of the LISTv */ #define _ListLen(list) (((LISTo*)(list)-1)->h.len/sizeof(*(list))) /**api* macro ************************************************************ ** ** INPUT: the LISTv ** RETURNS: the number of other LISTvs sharing this buffer */ #define _ListShared(list) (((LISTo*)(list)-1)->h.usage-1) /**api* macro ************************************************************ ** ** INPUT: the LISTv ** access position ** RETURNS: the element in the position. ** fails with OutOfBounds if element cannot be retrieved */ #define _ListAt(list,pos) *(ASSERT((pos)<_ListLen(list), "OutOfBounds"),(list)+(pos)) /**api* macro ************************************************************ ** ** INPUT: the LISTv ** RETURNS: the first element of the LISTv */ #define _ListFirst(list) _ListAt(list,0) /**api* macro ************************************************************ ** ** INPUT: the LISTv ** RETURNS: the last element of the LISTv */ #define _ListLast(list) *(listPos=_ListLen(list),ASSERT(listPos>0, "OutOfBounds"),(list)+(listPos-1)) /* STACK operations */ /**api* macro ************************************************************ ** ** Alias for ListApp ** See also: _ListPop, _ListTop ** ** INPUT: [W] the pointer to the LISTv to be modified ** RETURNS: the new element */ #define _ListPush(plist) _ListApp(plist) /**api* macro ************************************************************ ** ** Removes the last element of the LISTv ** See also: _ListPush, _ListTop ** ** INPUT: [W] the pointer to the LISTv to be modified */ #define _ListPop(plist) (listPos=_ListLen(*(plist))-1,_ListCut(plist, listPos)) /**api* macro ************************************************************ ** ** Returns the last element of the LISTv. Alias to _ListLast ** See also: _ListPush, _ListTop ** ** INPUT: [W] the pointer to the LISTv to be modified */ #define _ListTop(list) _ListLast(list) /************************************************************************** ** ALLOCATION POOL **************************************************************************/ void* palloc(int size); void pfree(void* obj, int size); #define _palloc(type) ((type*)palloc(sizeof(type))) #define _pfree(ptr) (pfree(ptr, sizeof(*(ptr)))) void PoolDebug(int size); void PoolDebugAll(); #endif UT: [W] the pointer to the LISTv to be modified */ #define _ListTop(list) _ListLast(list) /************************************************************************** ** ALLOCATION POOL **************************************************************************/ void* palloc(int size); void pfree(void* obj, int size); #define _palloc(type) ((type*)palloc(sizeof(type))) #define _pfree(ptr) srs/src/local.c #include #include #include #include #define DECLARE_ONLY #include "srs.h" INT4 IopCalc () { INT4 l, r, result; char op[10]; IargGetArgs ("op|r|l", op, &r, &l); switch (*op) { case '+': result = l + r; break; case '-': result = l - r; break; case '/': result = l / r; break; case '*': result = l * r; break; } IcaReturn ("int", result); } void LocalSetFunctions () { IcaSetFunction("IopCalc", (FUNC)IopCalc); } include #include #include #include #define DECLARE_ONLY #include "srs.h" INT4 IopCalc () { INT4 l, r, result; char op[10]; IargGetArgs ("op|r|l", op, &r, &l); switch (*op) { case '+': result = l + r; break; case '-': result = l - r; break; case '/': result = l / r; break; case '*': result = l * r; break; } IcaReturn ("int", result); } void LocalSetFunctions () { IcaSetFunction("IopCalcsrs/src/logicals.c char logicals_ID[] = "$Id: logicals.c,v 1.2 1996/11/25 20:14:55 etzold Exp $"; /* ** ** $RCSfile: logicals.c,v $ ** $Revision: 1.2 $ ** $Date: 1996/11/25 20:14:55 $ ** $Author: etzold $ ** ** $Locker: $ ** $State: Exp $ ** ** Author of this module: Lukas Rosenthaler and Reinhard Doelz ** Heavy Modifications by Thure Etzold and John Smith ** Copyright granted to Thure Etzold for distribution withing the SRS package ** ****************************************************************************** ** * *********************************************************** * * * * * BIOFTP.UNIBAS.CH SOFTWARE DISTRIBUTION * * * * * *---------------------------------------------------------* * * Copyright notice * * * * * * This program package has been written starting from '92 * * * at the Biocomputing Laboratory, University of Basel, by * * * Lukas Rosenthaler. Though it has been a major effort to * * * make it work, no responsibility can be taken for errors * * * occuring while running the programs or resulting from * * * processing the program's output. The writing of these * * * was supported by Basel University. * * * * * * This program is public domain and can by used, copied * * * and modified without restriction as long as this * * * copyright notice is included. * * * * * * This program version can be obtained from the bioftp * * * anonymous ftp server, together with the README file. * * * Software may be used without charge following the rules * * * stated therein. Users should acknowledge the program * * * properly if results to be published are obtained. * * *********************************************************** * * * +----------------------------+--------------------------------------+ * | Dr. Lukas Rosenthaler | RF * rosenth@urz.unibas.ch | * | Biocomputing | DECNET 20579::48130::rosenth | * |Biozentrum der Universitaet | | * | Klingelbergstrasse 70 | FAX +41 61 261- 6760 or 267- 2078 | * | CH-4056 Basel | TEL +41 61 267- 2076 or 2247 | * +----------- bioftp.unibas.ch is the SWISS EMBnet node -------------+ * ----------------------------------------- * ****************************************************************************** */ /****************************************************************************** * * Description, Purpose * ^^^^^^^^^^^^^^^^^^^^ * * This modules implements a consistent handling of VMS logicals and * Unix environment variables (furtheron the term "logicals" is applied * both to VMS logical names and Unix environment variables). * The logicals may be nested, as long as the first component of a pathname * is a logical. A logical itself may reference another logical up to a * nesting depth of 32. * * Examples: * VMS: * $ define GCGDIR D$DISK:[SOFTWARE.GCG.] * $ define DATADIR GCGDIR:[PROTDATA.] * $ define WORKDB DATADIR:[WORK]WORKING_DATABASE.DAT * * WORKDB will translate to: * "D$DISK:[SOFTWARE.GCG][.PROTDATA.][WORK]WORKING_DATABASE.DAT" * * Unix: (assuming /bin/csh) * % setenv GCGDIR /usr/software/gcg * % setenv DATADIR GCGDIR/protdata * % setenv WORKDB DATADIR/work/working_database.dat * * WORKDB will translate to: * "/usr/software/gcg/protdata/work/working_database.dat" * ****************************************************************************** * * include files: * */ #include #include #ifdef VMS # include unixio # include stdio # include stdlib #else # include # include #endif #if defined dos # define SLASH '\\' # else # define SLASH '/' #endif #define PATH_BUF_LEN 132 /* maximal length of pathname */ /***api* LogNameTranslate ***************************************************** ** ** Translation of (possibly recursive) definition of VMS logical names of ** Unix environment variables. The routine uses the "getenv()" call which, ** in Unix, just returns the value of an environment variable. On VMS, ** "getenv()" first tries to use it's argument as a logical name that is to ** be translated, then searches the symbol name space. ** ** translate_logical() can resolve recursive definition of logiacls/environ- ** ment variables as long as the logical is always the first component of ** the path. The nesting depth may *NOT* be greater than 32 in order to ** prevent infinite loops which may occur (logical ONE points to TWO, which ** itself is a logical pointing to ONE...) ** ** If there is no translation, the routine returns the original path. ** The routine does *NOT* allocate memory for the translated path, so the ** caller has to provide the buffer and indicate it's length! ** * Parameters : * char *name : path to translate * char *trans_name : translated path * int len : length of string supplied as trans_name * ** RETURNS: success or failure */ int LogNameTranslate (char *name, char *trans_name, int len) { char strbuf1[PATH_BUF_LEN], strbuf2[PATH_BUF_LEN], log[PATH_BUF_LEN]; char *strptr; int depth, i, l; int no_more_trans; no_more_trans = 0; depth = 0; (void) strncpy (strbuf1, name, PATH_BUF_LEN); do { /* * search first delimiter in string. */ # ifdef VMS strptr = strchr (strbuf1, ':'); # else if ((strptr = strchr (strbuf1, ':')) == NULL) { strptr = strchr (strbuf1, SLASH); } else { strptr[0] = SLASH; } # endif if (strptr != NULL) { /* we do have a delimiter, we try to translate only up to the delimiter */ l = strptr - strbuf1; for (i = 0; i < l; i++) log[i] = strbuf1[i]; log[i] = '\0'; } else { /* no delimiter, we try to translate the whole string */ l = 0; (void) strcpy (log, strbuf1); } # ifdef VMS for (i = 0; i _LT_ strlen (log); i++) log[i] = (char) toupper ((int) log[i]); # endif if ((strptr = getenv (log)) != NULL) { /* * ok, we found translation */ (void) strcpy (strbuf2, strptr); if (l > 0) { #ifdef VMS /* * delimiter ":" included */ (void) strcat (strbuf2, &(strbuf1[l + 1])); #else /* * delimiter "/" or "\" for dos, *NOT* included */ (void) strcat (strbuf2, &(strbuf1[l])); #endif } (void) strcpy (strbuf1, strbuf2); } else { /* sorry, no translation */ no_more_trans = 1; } depth++; } while ((! no_more_trans) && (depth < 32)); /* * check, if logicals are too deeply nested, as e.g. * * VMS: define TEST MIST: * define MIST TEST: * unix: setenv TEST MIST * setenv MIST TEST * * These declarations will produce infinte loops * in resolving the "logicals". * Therefore we allow only a depth of 32 ! */ if (depth == 32) { /* infinite loop ? */ return (999); } /* * result string supplied was too short */ if (strlen (strbuf1) > len) { return (999); } else { #if defined dos { char * ds; if((ds=strstr(strbuf1,"\\\\"))==NULL); /* no double bslashes found */ else{ /* conv \\ to :\ */ *ds=':'; } } #endif (void) strcpy (trans_name, strbuf1); } return (0); } ons will produce infinte loops * in resolving the "logicals". * Therefore we allow only a depth of 32 ! */ if (depth == 32) { /* infinite loop ? */ return (999); } /* * result string supplied was too short */ srs/src/logicals.h ** ** $RCSfile: logicals.h,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:16:54 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** Author of this module: Lukas Rosenthaler and Reinhard Doelz ** Copyright granted to Thure Etzold for distribution withing the SRS package ** ** ** ******************************************************************** ** * * ** * BIOFTP.UNIBAS.CH SOFTWARE DISTRIBUTION * ** * * ** * Copyright Notice * ** * ================ * ** * * ** * This include file contains the declarations for "logcials.c" * ** * Biocomputing Laboratory, University of Basel, by Lukas Rosen- * ** * thaler. For a detailed copyright notice see the README file or * ** * or the C source files! * ** ******************************************************************** ** ******************************************************************************* */ #ifdef _NO_PROTO extern INT4 translate_logical (); #else extern INT4 translate_logical (char *name, char *trans_name, INT4 len); #endif uting Laboratory, Unisrs/src/lst.c char lst_ID[] = "$Id: lst.c,v 1.3 1997/03/17 23:24:01 srs Exp $"; /* ** ** $RCSfile: lst.c,v $ ** $Revision: 1.3 $ ** $Date: 1997/03/17 23:24:01 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** Author: Gerald Schaefer ** EMBL, Meyerhofstrasse 1 ** 69012 Heidelberg, Germany ** Tel: 06221 387372 ** Email: schaefer@embl-heidelberg.de ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** management of a list of generic objects ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include typedef int INT4; /*#include "message.h"*/ #include "lst.h" #include "sdlget.h" #if !defined(TRUE) #define TRUE 1 #define FALSE 0 #endif #define LSTxOBJNAMELEN 20 #define LSTxDEFLISTSIZE 2 #define LSTxDEFHASHSIZE 2 /* ** LSTxHFREE means that this hash table element was never used before ** LSTxHDEL means that the element was used before but deleted now */ #define LSTxHFREE (void*)1L #define LSTxHDEL (void*)0L /* ** structure definition of the manager object, each list ** has one manager */ typedef struct { void **first_list_elem; /* address of an array of void pointers */ /* pointing to the objects. The array is */ /* automatically doubled, if overflow */ INT4 max_list_elem; /* max. number of objects to be handled by the list */ INT4 last; /* index of last inserted element in the list */ INT4 current; /* index of currently active object */ INT4 flex; /* flexible names */ INT4 not_hashed; /* counter for not-hashed objects (see delete) */ void **first_hash_elem; /* address of an array of void pointers */ /* pointing to the objects. The array is */ /* automatically doubled, if overflow */ INT4 max_hash_elem; /* max. number of objects in the hash table */ INT4 cur_hash_elem; /* current number of objects in the hash table */ } LSTo; /* ** type definition of the smallest object that can be stored ** in any list. All user defined objects must have these three ** attributes before its problem specific attributes. ** The first two attributes are initialized and maintained by ** the list module. The third attribute must be initialized ** by the application modules. If the application module never ** uses a search by name this attribute may be skipped. */ typedef struct { LSTo *manager; /* the first three attributes are necessary */ INT4 type_id; /* for all objects to be managed by the list */ char name[LSTxOBJNAMELEN]; } LSToOBJ; typedef struct { LSTo *manager; /* the first three attributes are necessary */ INT4 type_id; /* for all objects to be managed by the list */ char *name; /* flexible name length */ } LSToOBJFLEXNAME; /* ** by means of the following object type, any object may be fully ** described, that should be handled by the list module. The list ** module needs for each type of object the size (for allocation) ** and the functions to initialize, delete, or dump the objects. */ typedef struct { LSTo *manager; /* manager of list of manager_objects */ INT4 type_id; /* manager_object has type_id = 0 */ char name[LSTxOBJNAMELEN]; /* unused here */ INT4 obj_id; /* object_id (i.e. type_id of object to be managed) */ /* not really necessary at the moment == manager->last */ INT4 size; /* size of object */ INT4 flex; /* flexible names (pointer instead of array) */ void (*init_f)(void *); /* pointer to initialization function */ void (*delete_f)(void *); /* pointer to destructor function */ void (*print_f)(FILE *, void *); /* pointer to dump function */ } LSToMANAGER; /* ** static function prototypes of list module */ static LSTo *LstNewList(INT4 type_id); static INT4 LstIsList(LSTo *man); static LSTo *LstGetManager(void *obj); static unsigned LstHashFunc (LSTo *man, char *s); static INT4 LstHashObject(LSTo *man, void *obj); static INT4 LstHashUpdate(LSTo *man); static INT4 LstInsert(LSTo *man, void *obj); static INT4 LstGetObjSize(INT4 type_id); static void LstDeleteOne(void *obj); static INT4 LstRemoveFromList(void **obj); /* ** info_list is the internal list of the list module, by which the ** types of that objects are managed that will be able to be inserted ** into any other list. The pointer value NULL means that the list ** has not been initialized yet. */ static LSToMANAGER *info_list = NULL; /* ** normally there are object type dependent functions used to initialize ** new objects, to delete an object or to print the attribute values of ** an object. But there could be situations were you do not need one of ** these functions (e.g., you do not need a delete function if there are ** no pointers to subobjects, which should be deleted recursively). ** To supply the application programmer with a comfortable solution when ** he does not want to provide a special function, it has been implemented ** that the application programmer may supply NULL, if he does not need ** to program a special function. To prevent a segmentation fault the ** following dummy function is used in that case. ** For better testing there are now three different dummy functions ** init_dummy, delete_dummy, print_dummy ** calling the functions supplying a NULL-Pointer as parameter should print ** the function name (for use in LstInfo) */ static void init_dummy(void *x) { if (!x) printf(" *init_dummy* "); /* see LstInfo */ #if defined(TRACE) printf("*** function init_dummy called ***\n"); #endif /* ** may be called, if nothing to initialize */ } static void delete_dummy(void *x) { if (!x) printf(" *delete_dummy* "); /* see LstInfo */ #if defined(TRACE) printf("*** function delete_dummy called ***\n"); #endif /* ** may be called, if nothing to delete */ } static void print_dummy(FILE *file, void *x) { if (!x) printf(" *print_dummy* "); /* see LstInfo */ #if defined(TRACE) printf("*** function print_dummy called ***\n"); #endif /* ** may be called, if nothing to print */ } /**api* LstInfo *********************************************************** ** ** gets the manager object of the info_list and checks it. ** Prints the information on all classes that can be managed. ** ** INPUT: ** IMPLICIT: ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstInfo() { LSTo *man; INT4 i; man = LstGetManager(info_list); if (!man) { return 0; } printf("******* List Info ***************\n"); printf("* List Module can manage %d different classes:\n", man->last + 1); /* ** print the attribute values of all objects in the ordered object list */ for (i=0; i <= man->last; i++) { printf("...Class%d: ", i); printf(" ..ObjID: %d ", ((LSToMANAGER*)man->first_list_elem[i])->obj_id); printf(" ..Size: %d ", ((LSToMANAGER*)man->first_list_elem[i])->size); ((LSToMANAGER*)man->first_list_elem[i])->init_f(NULL); ((LSToMANAGER*)man->first_list_elem[i])->delete_f(NULL); ((LSToMANAGER*)man->first_list_elem[i])->print_f(NULL, NULL); } return 1; } /**api* LstManageClass ******************************************************** ** ** registers a new class to be managed by the list module. The type_id is ** passed back to the calling function. The class description (object ** size, functions to be used to initialize, delete or print an object ** of that class) is put into the info_list as a special manager object. ** If the info list does not already exist, it will be created ** automatically. ** If size is negative, flexible names (char*) are used ! ** ** INPUT: type id of a new class to be managed by the list module [W] ** size of an object of the new class [R] ** address of a function to be called to init an object [R] ** address of a function to be called to delete an object [R] ** address of a function to be called to dump an object [R] ** IMPLICIT: ** info_list (LSToMANAGER *) [W] ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstManageClass(INT4 *newtype_id, INT4 size, void (*init_func)(void *), void (*delete_func)(void *), void (*print_func)(FILE *,void *)) { /* ** only register classes that are not already registered ** it is convenient to pass 0 as newtype_id */ if (*newtype_id > 0) return 0; /* maybe already registered */ /* ** if info list does not already exist, create info list automatically */ if (!info_list) { if (!LstNew((void**)&info_list, 0)) return 0; /* the next initializations would not be necessary */ /* the values can not be asked for during runtime, as */ /* there would result some strange side effects !! */ info_list->type_id = 0; info_list->obj_id = 0; info_list->flex = FALSE; /* default */ info_list->size = sizeof(LSToMANAGER); info_list->init_f = init_dummy; info_list->delete_f = delete_dummy; info_list->print_f = print_dummy; } /* ** create a special manager object for the new class and ** put it into info list */ if (!LstNew((void**)&info_list, 0)) return 0; info_list->type_id = 0; info_list->obj_id = info_list->manager->last; if (size>0) { info_list->size = size; info_list->flex = FALSE; } else { info_list->size = -size; info_list->flex = TRUE; } info_list->init_f = init_func ? init_func : init_dummy; info_list->delete_f = delete_func ? delete_func : delete_dummy; info_list->print_f = print_func ? print_func : print_dummy; *newtype_id = info_list->manager->last; return 1; } /**api* LstManageClassFlex ************************************************ ** ** registers a new class to be managed by the list module. The type_id is ** passed back to the calling function. ** The object names will have dynamic (flexible) names. ** More details: see LstManageClass() ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstManageClassFlex(INT4 *newtype_id, INT4 size, void (*init_func)(void *), void (*delete_func)(void *), void (*print_func)(FILE *, void *)) { return LstManageClass(newtype_id, -size, init_func, delete_func, print_func); } /****** LstNewList ************************************************************ ** ** creates and initializes a manager object for a new list and ** allocates memory for an array, later used to store addresses ** of objects. ** To increase the speed when searching for named but unordered ** objects a hash table has been implemented, too. ** ** INPUT: type_id of object to create the list for [R] ** IMPLICIT: ** ** RETURNS: address of the manager object on success, NULL otherwise */ static LSTo *LstNewList(INT4 type_id) { INT4 i; LSTo *list = (LSTo*) malloc(sizeof(LSTo)); if (!list) return NULL; /* error handling ... */ /* ** initialize list */ list->max_list_elem = LSTxDEFLISTSIZE; list->first_list_elem = (void**)malloc(list->max_list_elem*sizeof(void*)); if (!list->first_list_elem) { free(list); return NULL; /* error handling ... */ } list->last = -1; list->current = -1; list->flex = FALSE; /* default */ if (type_id > 0) list->flex = ((LSToMANAGER*)info_list->manager-> first_list_elem[type_id]) -> flex; list->not_hashed = 0; /* ** initialize hash table */ list->max_hash_elem = LSTxDEFHASHSIZE; list->first_hash_elem = (void**)malloc(list->max_hash_elem*sizeof(void*)); if (!list->first_hash_elem) { free(list->first_list_elem); /* the above allocated array */ free(list); return NULL; /* error handling ... */ } list->cur_hash_elem = 0; for (i=0; i < list->max_hash_elem; i++) list->first_hash_elem[i] = LSTxHFREE; return list; } /****** LstIsList ************************************************************* ** ** checks if the manager object exists an has convenient attribute values. ** ** INPUT: address of an existing manager object [R] ** IMPLICIT: ** ** RETURNS: 1 if manager object seems ok, 0 otherwise */ static INT4 LstIsList(LSTo *man) { /* how to look for correct initialized lists ... ??? */ if (!man) return 0; if (man->max_list_elem < LSTxDEFLISTSIZE) return 0; if (man->last < 0) return 0; if (man->current < 0) return 0; /* how to look for correct initialized hash table ... ??? */ return 1; } /****** LstGetManager ********************************************************* ** ** checks, if the object exists and if the manager attribute of the object ** points to a correct manager object. ** ** INPUT: address of an existing object [R] ** IMPLICIT: ** ** RETURNS: address of manager object on success, 0 otherwise */ static LSTo *LstGetManager(void *obj) { LSTo *man; if (!obj) return 0; man = ((LSToOBJ*)obj)->manager; if (!LstIsList(man)) return 0; return man; } /****** LstHashFunc *********************************************************** ** ** computes a hash index for a given string. Needs the manager object ** to get the current size of the hash table. ** ** INPUT: address of an existing manager object [R] ** address of an object name to hash [R] ** IMPLICIT: ** ** RETURNS: the computed hash index */ static unsigned LstHashFunc (LSTo *man, char *s) { register unsigned long h=0, g; register char *p = s; while (*p) { h= (h << 4) + *p++; if ((g= (h & 0xf0000000))) h= (h ^ (g >> 24)) ^ g; } #ifdef xxxx while (*s) h = (h<<5) + *s++; /* horner's function ...segdewick */ /* h = (h << 1) ^ *s++; */ #endif return h % man->max_hash_elem; } /****** LstHashObject ********************************************************* ** ** puts an existing object into the hash table of the specified manager, ** but only if the object has a name (i.e. name length > 0). ** If there exists a collision with the hash index the next free ** position will be occupied (round robin). ** ** INPUT: address of an existing manager object [R] ** address of an existing object [R] ** IMPLICIT: ** modifies hash table and manager ** ** RETURNS: 1 */ static INT4 LstHashObject(LSTo *man, void *obj) { INT4 i; char *key; INT4 hash_index; /* ** insert object in hash table if name is longer than 0 */ if (man->flex) key = ((LSToOBJFLEXNAME*)obj)->name; else key = ((LSToOBJ*)obj)->name; if (key && strlen(key)>0) { /* hash object */ hash_index = (INT4) LstHashFunc(man, key); #if defined(TRACE) printf("hash_index for key *%s* is %d\n", key, hash_index); #endif /* search for next free place */ for (i=hash_index; imax_hash_elem; i++) if (man->first_hash_elem[i] <= LSTxHFREE) { man->first_hash_elem[i] = obj; /* no entry yet */ man->cur_hash_elem++; return 1; } for (i=0; ifirst_hash_elem[i] <= LSTxHFREE) { man->first_hash_elem[i] = obj; /* no entry yet */ man->cur_hash_elem++; return 1; } } else return 1; return 1; } /****** LstHashUpdate ********************************************************* ** ** updates the hash table of the specified manager. All at the moment ** not-hashed objects will be hashed, if their name length is > 0. ** If the hash table is not big enough, it will be doubled before ** hashing objects. For the sake of simplicity the table will be also ** doubled, if there would be not-hashed unnamed objects. ** ** INPUT: address of an existing manager object [R] ** IMPLICIT: ** modifies hash table and manager ** ** RETURNS: 1 if all named objects have been successfully inserted, ** 0 otherwise */ static INT4 LstHashUpdate(LSTo *man) { INT4 i, rv=1; /* be sure that hash table is big enough */ if (man->cur_hash_elem + man->not_hashed > (man->max_hash_elem * 0.8)) { void **tmp; #if defined(TRACE) printf("*** INFO: Expanding hash table from %d to ", man->max_hash_elem); #endif /* extend hash table and rehash all elements in list */ while (man->cur_hash_elem + man->not_hashed > man->max_hash_elem) man->max_hash_elem = man->max_hash_elem * 2 + 7; #if defined(TRACE) printf("%d elements ***\n", man->max_hash_elem); #endif tmp = (void**) malloc(man->max_hash_elem * sizeof(void*)); if (!tmp) return 0; /* no errror message to keep list module independent from other modules */ free(man->first_hash_elem); /* free old array */ man->first_hash_elem = tmp; /* use new array */ /* mark all elements as not-hashed */ man->not_hashed = man->last +1; for (i=0; i < man->max_hash_elem; i++) man->first_hash_elem[i] = LSTxHFREE; } /* hash all elements not currently hashed */ for (i = man->last - man->not_hashed + 1; i<=man->last; i++) rv &= LstHashObject(man, man->first_list_elem[i]); man->not_hashed = 0; return rv; } /**api* LstHashSearch ********************************************************* ** ** gets the manager object of an existing object list and checks it. ** Then an object with name obj_name is searched for using the ** hash table. If there are not-hashed objects the hash table needs ** to be updated first. ** Passes the address of the found object back to the calling function. ** ** INPUT: address of an address of an existing object [R,W] ** address of an object name to search for [R] ** IMPLICIT: ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstHashSearch(void **obj, char *obj_name) { LSTo *man; LSToOBJ *tmp1; LSToOBJFLEXNAME *tmp2; INT4 i, rv = 1; INT4 stop_search = 0; INT4 hash_index; if (!strlen(obj_name)) return 0; man = LstGetManager(*obj); if (!man) return 0; /* ** if there are not-hashed objects (objects that are only ** inserted in the ordered list) update the hash table first */ if (man->not_hashed > 0) rv = LstHashUpdate(man); if (rv == 0) return 0; /* if malloc failed */ /* get hash index for object name */ hash_index = (INT4) LstHashFunc(man, obj_name); #if defined(TRACE) printf("hash_index for obj_name *%s* is %d\n", obj_name, hash_index); #endif /* search for object in hash table beginning with hash index */ if (man->flex) { for (i=hash_index; imax_hash_elem; i++) { tmp2 = (LSToOBJFLEXNAME*)man->first_hash_elem[i]; if ((void*)tmp2 == LSTxHFREE) {stop_search = 1; break;} if ((void*)tmp2 == LSTxHDEL) continue; if (!strcmp(tmp2->name, obj_name)) { /* named object found */ *obj = (void*)tmp2; return 1; } } if (!stop_search) for (i=0; ifirst_hash_elem[i]; if ((void*)tmp2 == LSTxHFREE) {stop_search = 1; break;} if ((void*)tmp2 == LSTxHDEL) continue; if (!strcmp(tmp2->name, obj_name)) { /* named object found */ *obj = (void*)tmp2; return 1; } } } else { for (i=hash_index; imax_hash_elem; i++) { tmp1 = (LSToOBJ*)man->first_hash_elem[i]; if ((void*)tmp1 == LSTxHFREE) {stop_search = 1; break;} if ((void*)tmp1 == LSTxHDEL) continue; if (!strcmp(tmp1->name, obj_name)) { /* named object found */ *obj = (void*)tmp1; return 1; } } if (!stop_search) for (i=0; ifirst_hash_elem[i]; if ((void*)tmp1 == LSTxHFREE) {stop_search = 1; break;} if ((void*)tmp1 == LSTxHDEL) continue; if (!strcmp(tmp1->name, obj_name)) { /* named object found */ *obj = (void*)tmp1; return 1; } } } return 0; /* named object not found */ } /****** LstInsert ************************************************************* ** ** inserts the address of the object into the list managed ** by the manager object. ** If the list will overflow, the array is automatically doubled in size. ** If the name of the object is not an empty string, then the object ** will be inserted into a hash table, too (see LstHashUpdate). ** ** INPUT: address of an existing manager object [R] ** address of an existing object [R] ** IMPLICIT: ** man (LSTo*) [W] ** ** RETURNS: 1 on success, 0 otherwise */ static INT4 LstInsert(LSTo *man, void *obj) { /* ** if list overflows, double object list and restore addresses */ if (man->last >= man->max_list_elem - 1) { INT4 i; void **tmp = (void**) malloc(2 * man->max_list_elem * sizeof(void*)); if (!tmp) return 0; #if defined(TRACE) printf("*** INFO: Expanding object list from %d to ", man->max_list_elem); #endif /* ** copy addresses of existing objects */ for (i=0; i < man->max_list_elem; i++) tmp[i] = man->first_list_elem[i]; free(man->first_list_elem); /* free old array */ man->first_list_elem = tmp; /* use new array */ man->max_list_elem *= 2; #if defined(TRACE) printf("%d elements ***\n", man->max_list_elem); #endif } man->last++; man->first_list_elem[man->last] = obj; man->current = man->last; ((LSToOBJ*)obj)->manager = man; /* ** update the counter of not-hashed objects */ man->not_hashed++; return 1; } /****** LstGetObjSize ********************************************************* ** ** The size of the object with type type_id is read from the info_list ** and returned. ** ** INPUT: type id of object [R] ** IMPLICIT: ** info_list (LSToMANAGER *) [R] ** ** RETURNS: size of object with type type_id; 0 if type_id incorrect */ static INT4 LstGetObjSize(INT4 type_id) { /* ** in the initialization phase info_list does not already ** exist when the size of the manager object (type_id == 0) ** has to be queried. The order of the following if-statements ** is very important to prevent a segmentation fault ! */ if (type_id == 0) return sizeof(LSToMANAGER); if (type_id < 0) return 0; if (!info_list) return 0; if (type_id > info_list->manager->last) return 0; return ((LSToMANAGER*)info_list->manager->first_list_elem[type_id])->size; } /**api* LstInsertObject ******************************************************* ** ** inserts an already existing object into an object list. ** If the object list does not already exist, it will be created ** automatically. ** Remember that the user of this function has to set the name and ** the type_id of the object correctly before inserting: there will ** be no initialization here. ** If this function fails, 0 will be returned, but the object will ** not be destroyed. ** If the complete list will be destroyed later, the object inserted ** by this function will be destroyed, too. ** If the name of the object is not an empty string, the object will ** be inserted into a hash table, if LstHashSearch will be used. ** ** INPUT: address of an address of an existing object [W] ** address of an existing object [R] ** IMPLICIT: ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstInsertObject(void **obj, void *new_obj) { LSTo *man; /* ** if the object list does already exist, get the manager, ** if not, create a new list automatically and get the manager. */ if (*obj) { man = ((LSToOBJ*)*obj)->manager; if (!LstIsList(man)) return 0; } else man = LstNewList(((LSToOBJ*)new_obj)->type_id); /* ** insert the new object into the object list. On success modify the first ** function parameter to point to the new object, and return 1 */ if (LstInsert(man, new_obj)) { *obj = new_obj; return 1; } else return 0; /* object will not be destroyed automatically */ } /**api* LstNewNamed *********************************************************** ** ** creates a new object of type type_id and inserts this object into ** a list. The size of the object (obj_size) is read from the info_list. ** If the object list does not already exist, it will be created ** automatically. ** If name is not NULL, the name will be set after initialization. ** If the name is not an empty string, the object will be inserted ** into a hash table, too. ** ** INPUT: address of an address of an existing object [W] ** type id of object to be created [R] ** address of name of object [R] ** IMPLICIT: ** info_list (LSToMANAGER *) [R] ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstNewNamed(void **obj, INT4 type_id, char *name) { LSTo *man; void *tmp; INT4 obj_size; /* ** read object size from info_list and fail if zero */ obj_size = LstGetObjSize(type_id); if (obj_size == 0) return 0; /* ** if the object list does already exist, get the manager, ** if not, create a new list automatically and get the manager. */ if (*obj) { man = ((LSToOBJ*)*obj)->manager; if (!LstIsList(man)) return 0; } else man = LstNewList(type_id); /* ** allocate memory for the new object, fail if not enough memory available. */ tmp = (void*) calloc(1, obj_size); if (!tmp) return 0; /* ** save the type_id within the new object, which is important ** for initializing, deleting, and printing of the object ** (object type dependent functions) */ ((LSToOBJ*)tmp)->type_id = type_id; if (man->flex) /* name is pointer */ ((LSToOBJFLEXNAME*)tmp)->name = NULL; /* initializing of objects depends on object type !!! */ if (type_id > 0) ((LSToMANAGER*)info_list->manager-> first_list_elem[((LSToOBJ*)tmp)->type_id]) -> init_f(tmp); /* if name is not NULL, set name */ if (name) { if (man->flex) { ((LSToOBJFLEXNAME*)tmp)->name = (char*)malloc(strlen(name)+1); strcpy(((LSToOBJFLEXNAME*)tmp)->name, name); } else strcpy(((LSToOBJ*)tmp)->name, name); } else { if (man->flex) ((LSToOBJFLEXNAME*)tmp)->name = NULL; else strcpy(((LSToOBJ*)tmp)->name, ""); } /* ** insert the new object into the object list. On success modify the first ** function parameter to point to the new object, and return 1 */ if (LstInsert(man, tmp)) { *obj = tmp; return 1; } else { free(tmp); /* release memory of object that could not be inserted */ return 0; } } /**api* LstNew **************************************************************** ** ** creates a new object of type type_id and inserts this object into ** a list. The size of the object (obj_size) is read from the info_list. ** If the object list does not already exist, it will be created ** automatically. ** ** INPUT: address of an address of an existing object [W] ** type id of object to be created [R] ** IMPLICIT: ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstNew(void **obj, INT4 type_id) { return LstNewNamed(obj, type_id, NULL); } /**api* LstNewNamedUnique ************************************************* ** ** creates a new object of type type_id and inserts this object into ** a list, if there exists no object with the specified name. ** The size of the object (obj_size) is read from the info_list. ** If the object list does not already exist, it will be created ** automatically. ** ** INPUT: address of an address of an existing object [W] ** type id of object to be created [R] ** address of the unique object name [R] ** IMPLICIT: ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstNewNamedUnique(void **obj, INT4 type_id, char *name) { void **tmp = obj; /* don't modify the object handle if no object inserted */ if (LstHashSearch(tmp, name)) return 0; return LstNewNamed(obj, type_id, name); } /**api* LstFirst ************************************************************** ** ** gets the manager object of an existing object list and checks it. ** Sets the attribute 'current' of the manager to 0 (first object). ** Passes the address of the current object back to the calling function. ** ** INPUT: address of an address of an existing object [R,W] ** IMPLICIT: ** man->current (INT4) [W] ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstFirst(void **obj) { LSTo *man; man = LstGetManager(*obj); if (!man) return 0; man->current = 0; /* it's sure that last >= 0 */ /* ** modify the object list handle to point to the new current object */ *obj = man->first_list_elem[man->current]; return 1; } /**api* LstLast *************************************************************** ** ** gets the manager object of an existing object list and checks it. ** Sets the attribute 'current' of the manager to 'last' (last object). ** Passes the address of the current object back to the calling function. ** ** INPUT: address of an address of an existing object [R,W] ** IMPLICIT: ** man->current (INT4) [W] ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstLast(void **obj) { LSTo *man; man = LstGetManager(*obj); if (!man) return 0; man->current = man->last; /* it's sure that last >= 0 */ /* ** modify the object list handle to point to the new current object */ *obj = man->first_list_elem[man->current]; return 1; } INT4 LstIsLast(void *obj) { LSTo *man; man = LstGetManager(obj); if (!man) return 0; return (man->current == man->last) ? 1 : 0; } /**api* LstNext **************************************************************** ** ** gets the manager object of an existing object list and checks it. ** Increments the attribute 'current' of the manager (next object). ** Passes the address of the current object back to the calling function. ** ** INPUT: address of an address of an existing object [R,W] ** IMPLICIT: ** man->current (INT4) [W] ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstNext(void **obj) { LSTo *man; man = LstGetManager(*obj); if (!man) return 0; if (man->current == man->last) return 0; man->current++; /* ** modify the object list handle to point to the new current object */ *obj = man->first_list_elem[man->current]; return 1; } /**api* LstPrev **************************************************************** ** ** gets the manager object of an existing object list and checks it. ** Decrements the attribute 'current' of the manager (previous object). ** Sets the attribute 'current' of the manager to 0 (first object). ** Passes the address of the current object back to the calling function. ** ** INPUT: address of an address of an existing object [R,W] ** IMPLICIT: ** man->current (INT4) [W] ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstPrev(void **obj) { LSTo *man; man = LstGetManager(*obj); if (!man) return 0; if (man->current == 0) return 0; man->current--; /* ** modify the object list handle to point to the new current object */ *obj = man->first_list_elem[man->current]; return 1; } /**api* LstGetPosition ******************************************************** ** ** gets the manager object of an existing object and checks it. ** Gets the attribute 'current' of the manager and returns it via 'n'. ** ** INPUT: address of an existing object contained in a list [R] ** address of an integer to return the current index [W] ** IMPLICIT: ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstGetPosition(void *obj, INT4 *n) { LSTo *man; man = LstGetManager(obj); if (!man) return 0; *n = man->current; return 1; } /**api* LstSetPosition ***************************************************** ** ** gets the manager object of an existing object list and checks it. ** Sets the attribute 'current' of the manager to 'n', if correct. ** Passes the address of the current object back to the calling function. ** ** INPUT: address of an address of an existing object [R,W] ** position of an existing object in manager array [R] ** IMPLICIT: ** man->current (INT4) [W] ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstSetPosition(void **obj, INT4 n) { LSTo *man; man = LstGetManager(*obj); if (!man) return 0; if (n < 0 || n > man->last) return 0; man->current = n; /* ** modify the object list handle to point to the new current object */ *obj = man->first_list_elem[man->current]; return 1; } /**api* LstSetObjCurrent *************************************************** ** ** gets the manager object of an existing object list and checks it. ** Then the object 'newcurr' is searched for in the object list. ** The search begins with the first object. ** Sets the attribute 'current' of the manager to the index of the ** object 'newcurr'. ** Passes the address of the current object back to the calling function. ** ** INPUT: address of an address of an existing object [R,W] ** address of an object to search for [R] ** IMPLICIT: ** man->current (INT4) [W] ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstSetObjCurrent(void **obj, void *newcurr) { LSTo *man; INT4 i; man = LstGetManager(*obj); if (!man) return 0; for (i=0; i <= man->last; i++) if (man->first_list_elem[i] == newcurr) { man->current = i; *obj = man->first_list_elem[man->current]; return 1; } return 0; } /**api* LstFirstNamed ********************************************************* ** ** gets the manager object of an existing object list and checks it. ** Then an object with name obj_name is searched for in the object list. ** The search begins with the first object. ** Sets the attribute 'current' of the manager to the index of the ** object found first. ** Passes the address of the current object back to the calling function. ** ** INPUT: address of an address of an existing object [R,W] ** address of an object name to search for [R] ** IMPLICIT: ** man->current (INT4) [W] ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstFirstNamed(void **obj, char *obj_name) { LSTo *man; INT4 i, startpos=0; char *name; man = LstGetManager(*obj); if (!man) return 0; for (i=startpos; i <= man->last; i++) { if (man->flex) name = ((LSToOBJFLEXNAME*)man->first_list_elem[i])->name; else name = ((LSToOBJ*)man->first_list_elem[i])->name; if (!strcmp(name, obj_name)) { man->current = i; *obj = man->first_list_elem[man->current]; return 1; } } return 0; } /**api* LstNextNamed ********************************************************** ** ** gets the manager object of an existing object list and checks it. ** Then an object with name obj_name is searched for in the object list. ** The search begins with the object after current. ** So you can't find the first object using this function ! ** Sets the attribute 'current' of the manager to the index of the ** object found first. ** Passes the address of the current object back to the calling function. ** ** INPUT: address of an address of an existing object [R,W] ** address of an object name to search for [R] ** IMPLICIT: ** man->current (INT4) [W] ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstNextNamed(void **obj, char *obj_name) { LSTo *man; INT4 i; char *name; man = LstGetManager(*obj); if (!man) return 0; for (i=man->current+1; i <= man->last; i++) { if (man->flex) name = ((LSToOBJFLEXNAME*)man->first_list_elem[i])->name; else name = ((LSToOBJ*)man->first_list_elem[i])->name; if (!strcmp(name, obj_name)) { man->current = i; *obj = man->first_list_elem[man->current]; return 1; } } return 0; } /****** LstDeleteOne ********************************************************** ** ** deletes the specified object using a special function depending on ** the object type. LstDeleteOne can be used only internally in the ** context of LstDeleteAll or LstDelete because there are no changes ** to the pointer array of the manager. ** ** INPUT: address of an existing object [R] ** IMPLICIT: ** info_list (LSToMANAGER *) [R] ** ** RETURNS: nothing */ static void LstDeleteOne(void *obj) { /* deletion of objects depends on object type !!! */ if (((LSToMANAGER*)info_list->manager-> first_list_elem[((LSToOBJ*)obj)->type_id]) -> flex) free( ((LSToOBJFLEXNAME*)obj)->name ); ((LSToMANAGER*)info_list->manager-> first_list_elem[((LSToOBJ*)obj)->type_id]) -> delete_f(obj); if (!OddIsInDepot ((char *) obj)) free(obj); } /****** LstRemoveFromList ***************************************************** ** ** gets the manager object of an existing object list and checks it. ** If the current object is not equal to the object passed as argument, ** the current index is modified first. ** The pointer array of the manager is rearranged. Also the current ** object changes. It will be the next object, that has been moved to ** the position of the deleted object. If there is a reference to the ** object in the hash table this reference is removed, too. ** IMPORTANT: if the last object is removed from the list, the ordered ** list, the hash table and the manager is removed also. ** ** INPUT: address of an address of an existing object [R,W] ** IMPLICIT: ** man->current (INT4) [W] ** ** RETURNS: 1 on success, 0 otherwise */ static INT4 LstRemoveFromList(void **obj) { LSTo *man; INT4 i; INT4 rv = 1; man = LstGetManager(*obj); if (!man) return 0; /* ** deleting an object is only possible if the object ** equals the current object in the ordered list ! ** if this is not true compute the correct current index */ if (man->first_list_elem[man->current] != *obj) { for (i=0; i <= man->last; i++) { if (man->first_list_elem[i] == *obj) { man->current = i; break; } } if (i > man->last) return 0; /* object not in ordered list */ /* -> if it should be possible to delete a hash table object, that */ /* is not in the ordered list a boolean variable is needed here */ /* -> in the current implementation this case will never arise */ } /* ** if the last object is removed from the list, free the ** administration objects, too */ if (man->last == 0) { free(man->first_list_elem); free(man->first_hash_elem); free(man); /* ** modify the object list handle to signal that list deleted; ** remember to delete the object in the calling function !!!! */ *obj = NULL; return 1; } /* ** if a hash table exists already and there are not-hashed objects ** in the ordered list, the hash table needs to be updated before ** the pointer to the object is removed */ if (man->cur_hash_elem > 0 && man->not_hashed > 0) { rv = LstHashUpdate(man); if (rv == 0) return 0; /* hash table update failed */ } if (man->cur_hash_elem > 0) { /* hash table exists */ for (i=0; i < man->max_hash_elem; i++) if (man->first_hash_elem[i] == *obj) { man->first_hash_elem[i] = LSTxHDEL; break; } } else man->not_hashed--; /* up to now hash table does not exist */ /* ** rearrange the pointer array of the manager. Be sure to do this ** after!! updating hashtable */ for (i=man->current; i < man->last; i++) man->first_list_elem[i] = man->first_list_elem[i+1]; man->first_list_elem[man->last] = 0; man->last--; if (man->current>man->last) man->current = man->last; /* if last deleted */ /* ** modify the object list handle to point to the new current object */ *obj = man->first_list_elem[man->current]; return 1; } /**api* LstDelete ************************************************************* ** ** LstDelete may be called externally. The object is removed from the list ** i.e. the pointer array of the manager is rearranged. Also the current ** object changes. It will be the next object, that has been moved to ** the position of the deleted object. If there is a reference to the ** object in the hash table this reference is removed, too. This is all ** done by LstRemoveFromList. After all the object is deleted. ** Caution: the programmer is responsible that the object has the ** correct type_id set ! ** ** INPUT: address of an address of an existing object [R,W] ** IMPLICIT: ** man->current (INT4) [W] ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstDelete(void **obj) { void *tmp; /* ** remember the object to delete */ tmp = *obj; if (!tmp) return 0; /* ** removes all references to the object */ if (!LstRemoveFromList(obj)) { fprintf(stderr, "FATAL_ERROR in LstDelete\n"); return 0; } /* ** delete the data structure of the object ** be sure that the object has the correct type_id set ! */ LstDeleteOne(tmp); return 1; } /**api* LstDeleteNamed ******************************************************** ** ** searchs for the object with the given name and deletes it, if found. ** LstDeleteNamed may be called externally to delete one named object. ** ** INPUT: address of an address of an existing object [R,W] ** address of name of object [R] ** IMPLICIT: ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstDeleteNamed(void **obj, char *name) { if (!LstFirstNamed(obj, name)) return 0; return LstDelete(obj); } /**api* LstDeleteToEndOfList ************************************************** ** ** LstDeleteToEndOfList may be called externally to delete all objects ** (including the current object) up to the end of the list. ** Warning: If the first object is the current object, the effect ** is identical to LstDeleteAll. ** ** INPUT: address of an address of an existing object [R,W] ** IMPLICIT: ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstDeleteToEndOfList(void **obj) { LSTo *man; INT4 save; INT4 rv=1; man = LstGetManager(*obj); if (!man) return 0; /* ** if current object equals first object, delete the complete list */ if (man->current == 0) return LstDeleteAll(obj); /* ** Remember index of object, that should be the last afterwards, ** and remove all objects behind */ save = man->current - 1; while (save < man->last) rv = LstDelete(obj); return rv; } /**api* LstDeleteAll ********************************************************** ** ** gets the manager object of an existing object list and checks it. ** Then deletes all data structures belonging to the list. ** LstDeleteAll may be called externally to delete all objects ** inclusive the manager. A NULL pointer is given back to the ** calling function, so that the next insertion of a new object ** will automatically generate a new list. ** ** INPUT: address of an address of an existing object [R,W] ** IMPLICIT: ** info_list (LSToMANAGER *) [R] ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstDeleteAll(void **obj) { LSTo *man; INT4 i; man = LstGetManager(*obj); if (!man) return 0; /* ** delete the data structures of all objects */ for (i=0; i <= man->last; i++) LstDeleteOne(man->first_list_elem[i]); /* ** delete the arrays of the manager and the manager itself */ free(man->first_list_elem); /* delete ordered list */ free(man->first_hash_elem); /* delete hash table */ free(man); /* ** modify the object list handle to signal that the list is empty */ *obj = NULL; return 1; } /**api* LstPrint ************************************************************** ** ** prints the attribute values of the specified object using a ** special function depending on the object type. ** ** INPUT: file descriptor [W] ** address of an existing object [R] ** IMPLICIT: ** info_list (LSToMANAGER *) [R] ** ** RETURNS: nothing */ void LstPrint(FILE *file, void *obj) { /* printing of objects depends on object type !!! */ ((LSToMANAGER*)info_list->manager-> first_list_elem[((LSToOBJ*)obj)->type_id]) -> print_f(file, obj); } /**api* LstPrintAll *********************************************************** ** ** gets the manager object of an existing object list and checks it. ** Prints the attribute values of all objects in the object list. ** ** INPUT: address of an existing object [R] ** IMPLICIT: ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstPrintAll(void *obj) { LSTo *man; INT4 i; man = LstGetManager(obj); if (!man) { #if defined(TRACE) printf("*** ERROR: no object list found !!! \n"); #endif return 0; } #if defined(TRACE) printf("* List has %d entries:\n", man->last + 1); /* test: generate hash table */ LstHashUpdate(man); #endif /* ** print the attribute values of all objects in the ordered object list */ for (i=0; i <= man->last; i++) { #if defined(TRACE) printf("...Object%d: ", i); #endif LstPrint(NULL, man->first_list_elem[i]); } #if defined(TRACE) /* ** print the attribute values of all objects in the hash table */ if (man->first_hash_elem) /* hash table exists ? */ for (i=0; i < man->max_hash_elem; i++) { if (man->first_hash_elem[i] <= LSTxHFREE) continue; printf("...HashObject%d: ", i); LstPrint(NULL, man->first_hash_elem[i]); } #endif return 1; } /**api* LstPrintAllNames ***************************************************** ** ** gets the manager object of an existing object list and checks it. ** Prints the names of all objects in the ordered object list. ** ** INPUT: address of an existing object [R] ** IMPLICIT: ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstPrintAllNames(void *obj) { LSTo *man; INT4 i; char *name; man = LstGetManager(obj); if (!man) return 0; printf("* List has %d entries:\n", man->last + 1); /* ** print the names of all objects in the ordered object list */ for (i=0; i <= man->last; i++) { if (man->flex) name = ((LSToOBJFLEXNAME*)man->first_list_elem[i])->name; else name = ((LSToOBJ*)man->first_list_elem[i])->name; printf("...Object%2d: *%s*\n", i, name); } return 1; } /**api* LstLength ************************************************************* ** ** gets the manager object of an existing object list and checks it. ** If there is a correct list, computes the number of objects in ** the list and returns it. ** ** INPUT: address of an existing object [R] ** IMPLICIT: ** ** RETURNS: length of list on success, 0 otherwise */ INT4 LstLength(void *obj) { LSTo *man; man = LstGetManager(obj); if (!man) { #if defined(TRACE) printf("*** ERROR: no object list found !!! \n"); #endif return 0; } #if defined(TRACE) printf("* List has %d entries:\n", man->last + 1); #endif return man->last + 1; } /**api* LstRelease ************************************************************ ** ** LstRelease may be called externally. The object is removed from list, ** i.e. the pointer array of the manager is rearranged. Also the current ** object changes. It will be the next object, that has been moved to ** the position of the deleted object. If there is a reference to the ** object in the hash table this reference is removed, too. This is all ** done by LstRemoveFromList. The data structures of the ** object will still survive and the address will be returned. ** ** INPUT: address of an address of an existing object [R,W] ** IMPLICIT: ** man->current (INT4) [W] ** ** RETURNS: address of released object on success, 0 otherwise */ void *LstRelease(void** obj) { void *tmp; /* ** remember the object to release */ tmp = *obj; if (!tmp) return 0; /* ** removes all references to the object */ if (!LstRemoveFromList(obj)) return 0; /* ** remove the pointer to the manager and return the address of ** the released object */ ((LSToOBJ*)tmp)->manager = NULL; return tmp; } /**api* LstMove *************************************************************** ** ** the current object of the source object list is released (see above). ** Then gets the manager object of the destination list and checks it. ** If the destination list does not already exist, it is created ** automatically. Last the released object is inserted into ** the destination object list. ** ** As a side effect the current objects of both lists change. ** In case of the destination list, it will be the inserted object. ** In case of the source list, it will be the next object that has ** been moved to the position of the released object. ** ** INPUT: address of an address of the destination object [R,W] ** address of an address of an existing source object [R,W] ** IMPLICIT: ** man->current (INT4) [W] ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstMove(void** dest, void **source) { LSTo *man; void *tmp; /* ** release the current object in the source list and save ** it in tmp. Fail, if there is no object to release. */ tmp = LstRelease(source); if (!tmp) { fprintf(stderr, "FATAL_ERROR in LstMove (1)\n"); return 0; } /* ** get the manager of the destination list; if the list does ** not already exist, create it automatically. */ if (*dest) { man = ((LSToOBJ*)*dest)->manager; if (!LstIsList(man)) { fprintf(stderr, "FATAL_ERROR in LstMove (2)\n"); return 0; } } else man = LstNewList(((LSToOBJ*)tmp)->type_id); /* ** insert released object (tmp) into destination list */ if (LstInsert(man, tmp)) { *dest = tmp; return 1; } else { LstDeleteOne(tmp); /* delete released object !!??? */ /* ** if failed to insert first object into destination list, ** delete the arrays of the manager and the manager itself */ if (man->last < 0) { /* empty list */ free(man->first_list_elem); /* delete ordered list */ free(man->first_hash_elem); /* delete hash table */ free(man); } fprintf(stderr, "FATAL_ERROR in LstMove (3)\n"); return 0; } } /**api* LstAssign ************************************************************* ** ** assigns an existing parameter list to a sublist of another object. ** If the destination sublist does already exist, the parameter ** list cannot be inserted. The case that the parameter list does ** not exist is not checked, because LstAssign changes no values ** in that case. After assignment the parameter list is reset and ** may therefore be used to initialize any other parameter list. ** ** INPUT: address of an empty destination sublist [W] ** address of an (existing) parameter list [R,W] ** IMPLICIT: ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstAssign(void** sublist, void **paramlist) { /* ** you can only assign a complete list ** no insertion is possible */ if (*sublist) return 0; *sublist = *paramlist; /* ** reset paramlist, so that it can be used for a new list later */ *paramlist = NULL; return 1; } /**api* LstChangeObjectName ******************************************** ** ** gets the manager object of an existing object list and checks it. ** Then changes the name of the specified object. ** Works for character pointer and character array! ** ** INPUT: address of an existing object [R] ** address of the new object name [R] ** IMPLICIT: ** ** RETURNS: 1 on success, 0 otherwise */ INT4 LstChangeObjectName(void *tmp, char *name) { LSTo *man; char *old_name=NULL; man = LstGetManager(tmp); if (!man) return 0; /* check, if there is an old name that must be freed */ if (man->flex) { old_name = ((LSToOBJFLEXNAME*)tmp)->name; if (old_name) free(old_name); } /* set name */ if (name) { if (man->flex) { ((LSToOBJFLEXNAME*)tmp)->name = (char*)malloc(strlen(name)+1); strcpy(((LSToOBJFLEXNAME*)tmp)->name, name); } else strcpy(((LSToOBJ*)tmp)->name, name); } else { if (man->flex) ((LSToOBJFLEXNAME*)tmp)->name = NULL; else strcpy(((LSToOBJ*)tmp)->name, ""); } return 1; } me that must be freed */ if (man->flex) { old_name = ((LSToOBJFLEXNAME*)tmp)->name; if (old_name) free(old_name); } /* set name */ if (name) { if (man->flex) { ((LSToOBJFLEXNAME*)tmp)->name = (chsrs/src/lst.h ** ** $RCSfile: lst.h,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:16:55 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** Author: Gerald Schaefer ** EMBL, Meyerhofstrasse 1 ** 69012 Heidelberg, Germany ** Tel: 06221 387451 ** Email: schaefer@embl-heidelberg.de ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** management of a list of generic objects ** contains prototypes of non-static functions of the list module ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ INT4 LstInfo(); INT4 LstManageClass(INT4 *newtype_id, INT4 size, void (*init_func)(void *), void (*delete_func)(void *), void (*print_func)(FILE *, void *)); INT4 LstManageClassFlex(INT4 *newtype_id, INT4 size, void (*init_func)(void *), void (*delete_func)(void *), void (*print_func)(FILE *,void *)); INT4 LstHashSearch(void **obj, char *obj_name); INT4 LstInsertObject(void **obj, void *new_obj); INT4 LstNewNamed(void **obj, INT4 obj_id, char *name); INT4 LstNewNamedUnique(void **obj, INT4 obj_id, char *name); INT4 LstNew(void **obj, INT4 obj_id); INT4 LstFirst(void **obj); INT4 LstLast(void **obj); INT4 LstNext(void **obj); INT4 LstPrev(void **obj); INT4 LstGetPosition(void *obj, INT4 *n); INT4 LstSetPosition(void **obj, INT4 n); INT4 LstSetObjCurrent(void **obj, void *newcurr); INT4 LstFirstNamed(void **obj, char *obj_name); INT4 LstNextNamed(void **obj, char *obj_name); INT4 LstDelete(void **obj); INT4 LstDeleteNamed(void **obj, char *name); INT4 LstDeleteToEndOfList(void **obj); INT4 LstDeleteAll(void **obj); void LstPrint(FILE *file, void *obj); INT4 LstPrintAll(void *obj); INT4 LstPrintAllNames(void *obj); INT4 LstLength(void *obj); void *LstRelease(void** obj); INT4 LstMove(void** dest, void **source); INT4 LstAssign(void** sublist, void **paramlist); INT4 LstChangeObjectName(void *obj, char *name); /* info */ INT4 LstIsLast(void *obj); /* following functions would be nice ..... INT4 LstChangeName(char *old_name, char *new_name); ************************************************************/ obj); void LstPrint(FILE *file, void *obj); INT4 LstPrintAll(void *obj); INT4 LstPrintAllNames(void *obj); INT4 LstLength(void *obj); void *LstRelease(void** obj); INT4 LstMove(void** dest, void srs/src/map.c char map_srs_ID[] = "$Id: map.c,v 1.1 1996/05/06 15:16:56 srs Exp $"; /* ** ** $RCSfile: map.c,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:16:56 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port: Lukas Rosenthaler and Reinhard Doelz ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** Requires: rtl, file, sm, message ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** maps a file to memory and provides functions for writing to ** the file, saving and delteing the mapped memory; Either a ** file can be created with specified nr. of blocks or existing ** file can be extended by nr. of blocks. ** before deleting the mapsection the memory is saved to the file ** and the unused space of it is deleted; the output file is a ** Two functions for writing are provided for assuring that ** the map section is written to in a sequential manner. ** ** map-section-file: ** 1) LF-stream file (C-stream-file) ** 2) first longword contains number of bytes written to file ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include /* services definitions */ #include #include /* RMS data structures system */ #include /* defines codes for sys$getsyiw */ #include "rtl.h" #include "message.h" #include "futil.h" #include "map.h" #ifdef __ALPHA /****** MapPageSize *********************************************************** ** ** determines system's page size at run time - for compatibility ** of vms and openvms! ** ** INPUT: address of MAPo [W] ** address of buffer [W] or NULL ** size of section in bytes [R] ** ** RETURNS: 1 ** e__allocfail + */ int MapPageSize (long *cpupage_z) { /* ** structure with item list returned from sys$getsyiw (returns ** the size of the page size at run time */ static struct itm { short int buflen; /* length of buffer in byte */ short int item_code; /* symbolic item code */ long bufadr; /* address of return value buffer */ long retlenadr; /* address of return value buffer length */ } itemlist[2]; long cpupage_zlen; int rv; itemlist[0].buflen = 4; itemlist[0].item_code = SYI$_PAGE_SIZE; itemlist[0].bufadr = cpupage_z; itemlist[0].retlenadr = &cpupage_zlen; itemlist[1].buflen = 0; itemlist[1].item_code = 0; rv = sys$getsyiw (0, 0, 0, &itemlist, 0, 0, 0); _StopIfEven(rv); return 1; } #endif /****** MapCreSec ************************************************************* ** ** creates a map section - alignes the begin of the buffer to next page ** boundary which means the buffer shrinks! make sure it is big enough! ** buffer size will be tailored so that the end of the ** buffer falls onto a page boundary as well... ** ** INPUT: address of MAPo [W] ** address of buffer [W] or NULL ** size of section in bytes [R] ** ** RETURNS: 1 ** e__allocfail + */ int MapCreSec (MAPo *m, char *buff, int buff_z) { unsigned int mapaddr[2], secmask, pagelet_n ; int rv; long pagesize; char *buff_s; /* ** get cpu specific page size first ...mapped memorymust be aligned ** on that; */ #ifdef __ALPHA MapPageSize (&pagesize); #else pagesize = 512; #endif /* ** calculate new begin of buffer -> to next block boundary ...since ** these may result in a decrease of the buffer size the amount of ** bytes shifted must be subtracted from the buffer size; */ if (buff) { buff_s = buff; buff = (char *) ((((unsigned long) buff - 1) / pagesize) * pagesize + pagesize); buff_z -= buff - buff_s; buff_z = (buff_z / pagesize) * pagesize; pagelet_n = buff_z / 512; } /* ** define start and end addresses of map section - if buff and buff_z != 0 */ mapaddr[0] = buff; mapaddr[1] = mapaddr[0] + buff_z - 1; /* MUST point to last byte in buff */ secmask = (buff ? 0 : SEC$M_EXPREG) | (m->wrt_f == TRUE ? SEC$M_WRT : 0); rv = sys$crmpsc ( &mapaddr, &(m->raddr), 0, secmask, 0, 0, 0, m->chan, pagelet_n, 0, 0, 0); _StopIfEven(rv); m->data = m->raddr[0]; m->xbyt = m->raddr[1] - (unsigned int) m->data; if (m->xbyt < buff_z -1 && buff_z != 0 && m->wrt_f) _ErrExit3 (e__crmpscfail, pagelet_n, (m->xbyt/512)); m->trnc_f = TRUE; return 1; } /**api* MapMem **************************************************************** ** ** opens file and maps it to memory for read access only; ** ** INPUT: address of map-descriptor [W] ** address of filename [R] ** address of buffer [W] or NULL ** size of buffer in bytes [R] or 0 ** IMPLICIT: ** ** RETURNS: 1 if success ** e__filopenerr + */ int MapMem (MAPo *m, char *fil_n, void *buff, int buff_z) { struct FAB fab; struct RAB rab; int k, n, rv, size = 0; fab = cc$rms_fab; /* init fab */ fab.fab$l_dna = fil_n; fab.fab$b_dns = strlen(fil_n); fab.fab$l_fop = FAB$M_UFO; /* user file open */ /* fab.fab$b_shr = FAB$M_NIL;*/ /* no sharing */ fab.fab$b_rfm = FAB$C_STMLF; /* C stream file */ rv = sys$open (&fab); /* open file + get channel */ if (!(rv % 2)) _ErrRet2 (e__filopenerr, fil_n); m->chan = fab.fab$l_stv; m->wrt_f = FALSE; rv = MapCreSec(m, buff, buff_z); m->foff = m->data; m->off = (unsigned int) m->data + *(m->foff); strcpy(m->filn, fil_n); return 1; } /**api* MapAlloc ************************************************************** ** ** allocates nr. of blocks, opens file of same size and creates map ** section; ** ** INPUT: address of MAPo ** address of file name ** nr. of blocks to be allocated ** ** OUTPUT: ** returns: 1 if success ** e__allocfail + ** e__filopenerr + */ int MapAlloc (MAPo *m, char *filn, int nbloc) { struct FAB fab; register rv; fab = cc$rms_fab; /* create file access */ fab.fab$l_dna = filn; /* block descr. of file */ /* name */ fab.fab$b_dns = strlen(filn); fab.fab$l_alq = nbloc; /* nr. of blocks to */ fab.fab$l_fop = FAB$M_UFO; /* allocate user file open */ fab.fab$b_rfm = FAB$C_STMLF; /* C stream file no */ fab.fab$b_shr = FAB$M_NIL; /* sharing */ rv = sys$create (&fab); /* open file + get channel */ if (rv % 2 == 0) _ErrRet2 (e__filopenerr, filn); m->chan = fab.fab$l_stv; m->wrt_f = TRUE; rv = MapCreSec(m, NULL, nbloc*512); strcpy(m->filn, filn); m->off = m->data + 4; /* room for offset */ m->foff = m->data; *(m->foff) = 4; return 1; } /**api* MapExtend ************************************************************* ** ** opens existing file and adds specified nr. of blocks to it - resultant ** file is mapped to memory; ** If nbloc ==0 file has to be opened in order to get the section's size; ** ** INPUT: address of MAPo ** address of filename ** nr. of blocks to add ** ** OUTPUT: ** returns: 1 ** e__filopenerr + */ int MapExtend (MAPo *m, char *filn, int nbloc) { struct FAB fab; struct RAB rab; char blocks[32767]; /* 64 blocks */ int k, n, rv, size; fab = cc$rms_fab; /* init fab */ fab.fab$l_dna = filn; fab.fab$b_dns = strlen(filn); fab.fab$b_fac = FAB$M_UPD | FAB$M_BIO | FAB$M_PUT; fab.fab$w_mrs = sizeof(blocks); /* max. record size */ rab = cc$rms_rab; /* init rab */ rab.rab$l_fab = &fab; rab.rab$l_rbf = &blocks; rab.rab$b_rac = RAB$C_RFA; /* acc. by record file */ rab.rab$l_rop = RAB$M_EOF; /* addr. pos. at EOF */ /* after open */ rab.rab$w_rsz = fab.fab$w_mrs; rv = sys$open (&fab); /* open file + get channel */ if (rv % 2 == 0) { _ErrMsg2 (e__filopenerr, filn); _StopIfEven(rv); } rv = sys$connect (&rab); if (rv % 2 == 0) _ErrRet2 (e__filopenerr, filn); rv = sys$write (&rab); /* get file siz after */ /* $write */ _StopIfEven(rv); size = 64 + (int) rab.rab$w_rfa[0] - 1; if ((nbloc = nbloc - 64) > 0) /* write more if necess. */ { n = MapMOD(nbloc, 64); for (k = 0; k < n; k++) { size += 64; rv = sys$write (&rab); _StopIfEven(rv); } } rv = sys$close (&fab); _StopIfEven(rv); fab.fab$l_fop = FAB$M_UFO; /* user file open no */ /* sharing C stream file */ if (!m->wrt_f) fab.fab$b_fac = FAB$M_GET; fab.fab$b_shr = m->wrt_f ? FAB$M_NIL : FAB$M_SHRGET; fab.fab$b_rfm = FAB$C_STMLF; /* open file + get channel */ rv = sys$open (&fab); _StopIfEven(rv); m->chan = fab.fab$l_stv; rv = MapCreSec(m, NULL, size*512); m->foff = m->data; m->off = m->data + *(m->foff); strcpy(m->filn, filn); return 1; } /**api* MapFree *************************************************************** ** ** frees map section + updates i.e. writes mapped file; ** writes two extra '\n' - the first is supposed to be the last record's ** end and the second is for rfa-access in MapTruncate - otherwise ** unpredictable positioning ** ** INPUT: address of MAPo ** ** OUTPUT: ** returns: 1 */ int MapFree(MAPo *m) { int rv; if (m->wrt_f) { *(m->off) = '\n'; /* for rfa access for rfa */ *(m->off+1) = '\n'; /* access */ } rv = sys$deltva ( /* del map sect + update */ /* fil */ &(m->raddr), 0, 0); _StopIfEven(rv); /* free(m->alloc);*/ rv = sys$dassgn (m->chan); /* close file */ _StopIfEven(rv); if (m->trnc_f && m->wrt_f) MapTruncate(m); /* cut off unused space */ return 1; } /****** MapTruncate *********************************************************** ** ** truncates a file to the size that is really used (MAPo->off); ** ** INPUT: address of MAPo ** ** OUTPUT: ** returns: 1 */ int MapTruncate (MAPo *m) { struct FAB fab; struct RAB rab; int rv, nbyte, blocn, off; fab = cc$rms_fab; /* init fab */ fab.fab$l_dna = m->filn; fab.fab$b_dns = strlen(m->filn); fab.fab$b_fac = FAB$M_TRN | FAB$M_UPD; /* truncate access trunc */ fab.fab$l_fop = FAB$M_TEF; /* alloc at EOF C stream */ fab.fab$b_rfm = FAB$C_STMLF; /* file no sharing */ fab.fab$b_shr = FAB$M_NIL; rab = cc$rms_rab; /* init rab */ rab.rab$l_fab = &fab; rab.rab$b_rac = RAB$C_RFA; /* acc. by record file */ /* addr. */ rv = sys$open (&fab); /* access file */ _StopIfEven(rv); rv = sys$connect (&rab); _StopIfEven(rv); /* goto end of file */ nbyte = (unsigned int) m->off - (unsigned int) m->data; blocn = nbyte / 512; off = nbyte - blocn * 512+1; blocn = off == 0 ? blocn: blocn + 1; rab.rab$w_rfa[0] = blocn; rab.rab$w_rfa[2] = off; rv = sys$find (&rab); _StopIfEven(rv); rv = sys$truncate (&rab); /* truncate */ _StopIfEven(rv); rv = sys$close (&fab); _StopIfEven(rv); return 1; } /****** MapNew **************************************************************** ** ** returns relative section file's address of begin of unused space; ** only MapPutS and MapWrite may be used for writing to the map-section; ** ** INPUT: address of MAPo ** address of address where to put file address ** ** OUTPUT: places file address into transm. address ** returns: 1 if success */ int MapNew (MAPo *m, unsigned int *fadd) { *fadd = *(m->foff); return 1; } /**api* MapCNew *************************************************************** ** ** returns relative file address of begin of unused space in cache; ** only MapCWrite may be used for writing to the cache; ** ** INPUT: address of MAPoCCH ** address of address where to put file address ** ** OUTPUT: places file address into transm. address ** returns: 1 if success */ int MapCNew (MAPoCCH *c, unsigned int *fadd) { *fadd = *(c->foff); return 1; } /****** MapPutS *************************************************************** ** ** puts a 0-terminated string at the end of used space in map-section ** map->off and map->foff are updated according to string length; ** ** INPUT: address of MAPo ** address of string ** ** OUTPUT: ** returns: 1 if success ** e__eom < file-name, max nr. of bytes> */ int MapPutS (MAPo *m, char *s) { int len; len = strlen(s); if (*m->foff + len + 1 > m->xbyt) return e__eom; strcpy(m->off, s); m->off = (unsigned int) m->off + len + 1; *(m->foff) = *(m->foff) + len + 1; return 1; } /****** MapWrite ************************************************************** ** ** appends specified nr. of bytes to end of used map-section; ** ** INPUT: address of MAPo ** address of source ** nr. of bytes to be transferred ** ** OUTPUT: ** returns: 1 if ok ** e__eom < file-name, max nr. of bytes> */ int MapWrite (MAPo *m, char *s, int n) { if (*m->foff + n > m->xbyt) return e__eom; memcpy(m->off, s, n); m->off = (unsigned int) m->off + n; *(m->foff) += n; return 1; } /****** MapMalloc ************************************************************* ** ** same as malloc but allocates in map-section; ** ** INPUT: address of MAPo ** nr. of bytes to be allocated ** ** OUTPUT: ** returns: address of allocated area if ok ** NULL if e__eom */ char *MapMalloc (MAPo *m, int n) { char *off_s; if (*m->foff + n > m->xbyt) return NULL; off_s = m->off; m->off = (unsigned int) m->off + n; *(m->foff) += n; return off_s; } /**api* MapCWrite ************************************************************* ** ** appends specified nr. of bytes to end of used cache; ** ** INPUT: address of MAPoCCH ** address of source ** nr. of bytes to be transferred ** ** OUTPUT: ** returns: 1 if ok ** e__eoc */ int MapCWrite (MAPoCCH *c, char *s, int n) { memcpy(c->off, s, n); c->off = (unsigned int) c->off + n; *(c->foff) = *(c->foff) + n; if (c->off > c->buff + (c->nbloc - 1) * 512) MapFlush(c); return 1; } /**api* MapInitCache ********************************************************** ** ** initializes a cache, i.e. allocates memory, opens files etc.; ** MAPoCCH->foff must be set before calling (0 = no existing file) ** ** INPUT: cache descriptor MAPoCCH [W] ** file name [R] ** address of cache's file offset [W] ** flag if new file should be opened [R] ** ** RETURNS: 1 if success ** e__allocfail + ** e__filopen + */ int MapInitCache (MAPoCCH *c, char *fil_nm, unsigned *foff, int new_f) { int nbloc; c->filn = fil_nm; c->foff = foff; if (new_f) *foff = 0; c->hbloc = MapMOD(c->nbloc, 2); c->nbloc = c->hbloc * 2; /* even number */ if ((c->buff = malloc(c->nbloc * 512)) == 0) _ErrRet2(e__allocfail, "cache buffer"); c->fab = 0; c->rab = 0; if (*(c->foff) == 0) { c->new_f = TRUE; c->off = c->buff; c->fstbloc = 1; c->coff = 0; } else { c->new_f = FALSE; nbloc = MapMOD(*(c->foff), 512); if ((c->fstbloc = nbloc - c->hbloc + 1) <= 1) { c->fstbloc = 1; c->coff = 0; } else { nbloc = c->hbloc; c->coff = (c->fstbloc-1) * 512; } c->off = c->buff + *c->foff - c->coff; MapReadBlk (c, nbloc, c->fstbloc); } return 1; } /****** MapFlush ************************************************************** ** ** closes file theat was opend for read/update access (for fseek) ** writes 1st half of cache to file, shifts 2nd half of cache to begin ** and opens file again for read/upd access (no sharing possible); ** ** INPUT: address of MAPoCCH ** ** OUTPUT: ** returns: 1 if OK */ int MapFlush (MAPoCCH *c) { int shift = c->hbloc * 512; MapWriteBlk(c, c->hbloc+1, c->fstbloc); memcpy(c->buff, c->buff + shift, shift); c->fstbloc += c->hbloc; c->off -= shift; c->coff = c->coff + shift; return 1; } /****** MapCloseCache ********************************************************* ** ** flushes cache to file and deletes memory; ** ** INPUT: address of MAPoCCH ** ** OUTPUT: ** returns: 1 if success */ int MapCloseCache (MAPoCCH *c) { int nbloc, rv; nbloc = MapMOD(*(c->foff) - c->coff, 512); MapWriteBlk(c, nbloc, c->fstbloc); rv = sys$close (c->fab); _StopIfEven(rv); return 1; } /****** MapWriteBlk *********************************************************** ** ** opens file for block-IO and writes specified number of blocks to ** block offset and closes file; ** writes in portions of 64 blocks which is the max size of block-IO; ** ** INPUT: address of MAPoCCH ** nr of blocks to write ** block offset in file ** ** OUTPUT: ** returns: 1 if OK */ int MapWriteBlk (MAPoCCH *c, int nbloc, int off) { struct FAB *fab; struct RAB *rab; char *data = c->buff; int n, rv; if (c->rab == 0) rv = MapFOpen(c, MAPxWRITE); fab = c->fab; rab = c->rab; fab->fab$w_deq = nbloc; /* extend quantity */ rab->rab$l_bkt = off; while (nbloc > 0) { n = nbloc - 64; n = n < 0 ? nbloc : 64; rab->rab$w_rsz = n * 512; rab->rab$l_rbf = data; data = (unsigned int) data + n * 512; nbloc -= n; rv = sys$write (rab); _StopIfEven(rv); rab->rab$l_bkt += n; } return 1; } /****** MapFOpen ************************************************************** ** ** opens file for block-IO, read and write access - creates a new file ** if c->fstblock = 1; ** ** INPUT: address of MAPoCCH ** access mode: MAPxWRITE, MAPxREAD ** ** OUTPUT: ** returns: 1 if success ** e__allocfail + */ int MapFOpen (MAPoCCH *c, int acc_o) { struct FAB *fab; struct RAB *rab; int rv; if ((fab = malloc(sizeof(struct FAB))) == 0) _ErrRet2(e__allocfail, "FAB"); if ((rab = malloc(sizeof(struct RAB))) == 0) _ErrRet2(e__allocfail, "RAB"); *fab = cc$rms_fab; fab->fab$l_dna = c->filn; fab->fab$b_dns = strlen(c->filn); fab->fab$b_fac = acc_o == MAPxWRITE ? FAB$M_BIO | FAB$M_GET | FAB$M_PUT : FAB$M_BIO | FAB$M_GET; fab->fab$b_rfm = FAB$C_STMLF; /* C stream file */ if (!c->new_f) fab->fab$l_fop = FAB$M_CIF; /* open existing file */ *rab = cc$rms_rab; rab->rab$l_fab = fab; rv = sys$create (fab); /* open file */ _StopIfEven(rv); rv = sys$connect (rab); _StopIfEven(rv); c->fab = fab; c->rab = rab; return 1; } /****** MapReadBlk ************************************************************ ** ** opens file for block-IO and reads specified number of blocks from ** block offset and closes file; ** reads in portions of 64 blocks which is the max size of block-IO; ** ** INPUT: address of MAPoCCH ** nr of blocks to read ** block offset in file (first block = 1) ** ** OUTPUT: ** returns: 1 if OK */ int MapReadBlk (MAPoCCH *c, int nbloc, int off) { struct FAB *fab; struct RAB *rab; char *data = c->buff; int n, rv; if (c->fab == 0) rv = MapFOpen(c, MAPxWRITE); fab = c->fab; rab = c->rab; rab->rab$l_bkt = off; while (nbloc > 0) { n = nbloc - 64; n = n < 0 ? nbloc : 64; rab->rab$w_usz = n * 512; rab->rab$l_ubf = data; data = (unsigned int) data + n * 512; nbloc -= n; rv = sys$read (rab); _StopIfEven(rv); } return 1; } /****** MapRdMem ************************************************************** ** ** reads sectin file into private memory; ** reads in portions of 64 blocks which is the max size of block-IO; ** ** INPUT: section file name ** pointer to memory block ** ** OUTPUT: ** returns: 1 if OK ** e__allocfail + */ int MapRdMem (char *fil_nm, void **p) { struct FAB *fab; struct RAB *rab; MAPoCCH *c; char *data; int n, rv, size; c = calloc (1, sizeof (MAPoCCH)); strcpy (c->filn, fil_nm); rv = MapFOpen(c, MAPxREAD); _ErrRet (rv); size = c->fab->fab$l_alq; c->rab->rab$l_bkt = 1; /* start reading with */ /* first block */ if ((data = malloc (size * 512)) == 0) _ErrExit2(e__allocfail, "memory by MapRdMem"); *p = data; while (size > 0) { n = size - 64; n = n < 0 ? size : 64; c->rab->rab$w_usz = n * 512; c->rab->rab$l_ubf = data; data = (unsigned int) data + n * 512; size -= n; rv = sys$read (c->rab); _StopIfEven(rv); } rv = sys$close (c->fab); _StopIfEven(rv); return 1; } /**api* MapCUpdate ************************************************************ ** ** overwrites an integer at desired file offset; this corresponds ** to fseek + putw, here however block-IO is used to get block, modify it ** and write it back; ** ** INPUT: address of MAPoCCH ** relative file position ** value ** ** OUTPUT: ** returns: 1 if success */ int MapCUpdate (MAPoCCH *c, unsigned int fadd, char *fip) { struct RAB *rab = c->rab; static char buffer[1024]; static char *buff = &(buffer[0]); char *updloc; int rv, blocn, nbyte, blocoff; blocn = MapMOD(fadd, 512); /* number of block */ blocoff = fadd - (fadd/512)*512; if (blocoff == 0) blocn++; nbyte = blocoff > 508 ? 1024 : 512; rab->rab$w_usz = nbyte; rab->rab$l_ubf = buff; rab->rab$w_rsz = nbyte; rab->rab$l_rbf = buff; rab->rab$l_bkt = blocn; rv = sys$read (rab); _StopIfEven(rv); updloc = buff + blocoff; memcpy (updloc, fip, 4); rab->rab$l_bkt = blocn; rv = sys$write (rab); _StopIfEven(rv); return 1; } /**api* MapInCache ************************************************************ ** ** translates relative byte offset in file into cache address if referring ** to location in cache; ** ** INPUT: address of MAPoCCH ** relative file address ** address that receives translation ** ** OUTPUT: places address into address ** returns: 1 if translation was done ** 0 if location is not in cache */ int MapInCache (MAPoCCH *c, unsigned int fadd, void **ptr) { if (fadd < c->coff) return 0; else *ptr = fadd - c->coff + (unsigned int) c->buff; return 1; } /****** MapMOD **************************************************************** ** ** ** INPUT: divident ** divisor ** ** OUTPUT: ** returns: divident MOD divisor */ int MapMOD (int a, int b) { int quot; quot = a/b; return a == quot*b ? quot : ++quot; } /**api* MapDuplicateOverlap *************************************************** ** ** Addresses that need updating may be exactly on the boundary between ** file and memory cache ...in that case both locations need updating. ** This function updates in the cache only those bytes that overlaps. ** ** INPUT: address of IDS-file object [R] ** file pointer to first ID in the list [W] ** IMPLICIT: ** ** RETURNS: length of overlap ** 0 if no overlap exists */ INT4 MapDuplicateOverlap (MAPoCCH *cache, UINT4 fip, void *buff, INT4 size) { INT4 overlapLen; overlapLen = size - (cache->coff - fip); if ((cache->coff > fip) && overlapLen > 0) { memcpy (cache->buff, (char *) buff + size - overlapLen, overlapLen); return overlapLen; } else return 0; } of IDS-file object [R] ** file pointer to first ID in the list [srs/src/map.h ** ** $RCSfile: map.h,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:16:57 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port: Lukas Rosenthaler and Reinhard Doelz ** */ #define MAPxWRITE 1 #define MAPxREAD 2 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** virtual memory (map) section */ typedef struct MAPo { char filn[FILxXNAM+1]; /* file name */ unsigned short chan; /* channel number returned by sys$create */ UINT4 xbyt; /* size of section in bytes */ UINT4 *foff; /* pointer to relative file address in section file */ char *off; /* pointer to relative file address in section file */ char *alloc; /* start address of allocated memory */ char *data; /* buffers start address */ UINT4 raddr[2]; /* array of start and end address returned by sys$crmpsc used by sys$deltva */ unsigned char trnc_f; /* TRUE: resultant file is truncated to size actually used */ unsigned char wrt_f; /* TRUE: mapsection has write access - changes are saved on disk */ unsigned char isAllocBuff; /* buffer has been allocated for section */ } MAPo; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** cache object */ typedef struct MAPoCCH { char *filn; /* file name */ #ifdef VMS struct FAB *fab; struct RAB *rab; #else INT4 fid; #endif char *buff; /* address of buffer */ INT4 nbloc; /* size of cache in blocks */ INT4 hbloc; /* half of ->nbloc */ INT4 fstbloc; /* first block of file to receive flushing */ char *off; /* current address (after last byte added) in cache */ UINT4 coff; /* rel. file address of first byte in cache */ UINT4 *foff; /* pointer to current address (after last byte added) rel. file address */ INT4 new_f; /* flag set if a new cache file is opened during program execution */ } MAPoCCH; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of exported functions */ INT4 MapMem (MAPo *m, char *fil_n, void *buff, INT4 buff_z); INT4 MapFree (MAPo *m); INT4 MapAlloc (MAPo *m, char *filn, INT4 nbloc); char *MapMalloc (MAPo *m, INT4 n); INT4 MapInitCache (MAPoCCH *c, char *fil_nm, unsigned *foff, INT4 new_f); INT4 MapCNew (MAPoCCH *c, UINT4 *fadd); INT4 MapCWrite (MAPoCCH *c, char *s, INT4 n); INT4 MapInCache (MAPoCCH *c, UINT4 fadd, void **ptr); INT4 MapCUpdate (MAPoCCH *c, UINT4 fadd, char *fip); INT4 MapCloseCache (MAPoCCH *c); INT4 MapDuplicateOverlap (MAPoCCH *cache, UINT4 fip, void *buff, INT4 size); d *buff, INT4 buff_z); INT4 MapFree (MAPo *m); INT4 MapAlloc (MAPo *m, char *filn, INT4srs/src/merge.c char merge_ID[] = "$Id: merge.c,v 1.4 1996/11/20 16:36:28 etzold Exp $"; /* ** ** $RCSfile: merge.c,v $ ** $Revision: 1.4 $ ** $Date: 1996/11/20 16:36:28 $ ** $Author: etzold $ ** ** ** Copyright by Thure Etzold ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** D-69012 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** Functions for merging indices built from parts of a databank. ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include "def.h" #include "message.h" #include "sm.h" #include "futil.h" #include "library.h" #include "ids.h" #include "idx.h" #include "btree.h" #include "merge.h" #define _SRS #define _SLB #include "srs5.h" typedef struct MERGEoPart { Int4 partNo; SLBoFIL *file; Int4 entryN; Int4 firstEntryN; IDSoFILE *ids; IDXv idx; BTRo *btree; } MERGEoPart; typedef struct MERGEoSet { SLBo *lib; char *idTypeName; MERGEoPart *part; Int4 partN; Int4 partAllocN; BTRoREC *minRecord; MERGEoPart **minPart; Int4 minPartN; Int4 minPartAllocN; } MERGEoSet; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** declaration of global or module wide variables */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of static functions */ static void MergeValue (); static BTRoREC *MergeNextRecord (MERGEoSet *merge, Int4 *recordNo); static void MergePartIndexOpen (MERGEoSet *merge, SLBoFIELD *field); static void MergePartIndexClose (MERGEoPart *part); static void MergeIds (MERGEoSet *merge, IDSoFILE *ids, BTRoREC *rec); static void MergeIdx (MERGEoSet *merge, SLBoFIELD *field); /**api* MergeGetIndexPartName ************************************************* ** ** Returns the name of the index part with the specified number. ** ** INPUT: library object [R] ** field object [R] ** the part number [R] ** option "read" or "write" [R] ** address of index name [W] or NULL (returns static string) ** ** RETURNS: address of the name */ char *MergeGetIndexPartName (SLBo *lib, SLBoFIELD *field, Int4 partN, char *mode, char *indexName) { static char statIndexName[500]; char *name, tmp[200]; LibGetIndexName (lib, field, tmp, mode); name = indexName ? indexName : statIndexName; sprintf (name, "%s_%d", tmp, partN); return name; } /**api* MergeNextPartNo ******************************************************* ** ** Returns whether the next part exists and the new part number. ** In case the databank is not partitioned returns the first time TRUE ** but sets the part number to -1. ** ** INPUT: o library object [R] ** o address of part number which must be set to 0 for ** first call [R] ** ** RETURNS: TRUE if a next part exist */ Int4 MergeNextPartNo (SLBo *lib, Int4 *partNo) { static Int4 entryN; IDXv idx; char *name; Int4 errCode; if (*partNo == 0) entryN = 0; else if (*partNo == -1) return 0; if (!LibIs (lib, "partitioned")) { *partNo = -1; return 1; } else { /* last part if less entries in part than part size */ /*if (*partNo && entryN < LibGetPartSize (lib)) return 0;*/ (*partNo)++; name = MergeGetIndexPartName (lib, LibGetIdField (lib), *partNo, "read", NULL); if ((idx = IdxOpen (name, "read", 0, &errCode))) { entryN = IdxGetRecordN (idx); return 1; } else { return 0; } } } /**api* MergeInit ************************************************************* ** ** Creates a 'merge' object for specified library. ** ** INPUT: the library object [R] ** ** RETURNS: the merge object */ MERGEoSet *MergeInit (SLBo *lib) { IDXv idx; MERGEoSet *merge; MERGEoPart *part; Int4 partNo; if ((merge = (MERGEoSet *) calloc (1, sizeof (MERGEoSet))) == NULL) _ErrExit2 (e__allocfail, "merge set"); merge->lib = lib; for (partNo=0; MergeNextPartNo (lib, &partNo); ) { part = _addObj (merge->part,merge->partN, merge->partAllocN, MERGEoPart); memset (part, 0, sizeof (MERGEoPart)); part->partNo = partNo; } return merge; } /**api* MergeIndex ************************************************************ ** ** This merges all indices for the specified field. ** it creates a new index, opens all the indices of the parts ** and iterates over the sorted value list three times. ** First for counting the number of values and second and third to ** 'feed' the B+ tree. ** ** INPUT: the merge object [W] ** the field object [R] */ void MergeIndex (MERGEoSet *merge, SLBoFIELD *field) { BTRoREC *record; IDXv idx; BTRo *btree; IDSoFILE *ids; Int4 k, errCode, recordN; char *indexName; /* open files */ indexName = LibGetIndexName (merge->lib, field, NULL, "write"); MergePartIndexOpen (merge, field); btree = BtrOpen (indexName, "merge", &errCode); BtrSetNumType (btree, BtrGetType (merge->part[0].btree)); ids = IdsOpen (indexName, "merge", 1048, merge->idTypeName, &errCode); /* merge IDX file if ID-field */ if (FieldIs (field, "id")) MergeIdx (merge, field); /* count number of different records */ for (recordN=0; MergeNextRecord (merge, &recordN);) ; BtrBuildStartPhase1 (btree, recordN); for (recordN=0; (record = MergeNextRecord (merge, &recordN));) BtrInsertRecord (record); BtrBuildStartPhase2 (); for (recordN=0; (record = MergeNextRecord (merge, &recordN));) { MergeIds (merge, ids, record); BtrInsertRecord (record); } /* close files */ BtrClose (btree); IdsClose (ids); for (k=0; k < merge->partN; k++) { MergePartIndexClose (&merge->part[k]); } } /**api* MergeNextRecord ******************************************************* ** ** Gives the next value from a list of opened indices. ** ** INPUT: the merge object [W] */ static BTRoREC *MergeNextRecord (MERGEoSet *merge, Int4 *recordNo) { MERGEoPart *part, **tmp; BTRoREC *record; Int4 k, cmp; merge->minRecord = NULL; if (!*recordNo) /* call for first element */ for (k=0; k < merge->partN; k++) BtrRecordGet (merge->part[k].btree, BTRxFIRST); else for (k=0; k < merge->minPartN; k++) BtrRecordGet (merge->minPart[k]->btree, BTRxNEXT); for (k=0; k < merge->partN; k++) { part = &merge->part[k]; if ((record = BtrRecordGet (part->btree, BTRxCURR))) { cmp = merge->minRecord ? BtrCompare (part->btree, record, merge->minRecord) : -1; /* lesser */ if (cmp < 0) { merge->minRecord = record; merge->minPartN = 0; tmp = _addObj (merge->minPart, merge->minPartN, merge->minPartAllocN, MERGEoPart*); *tmp = part; } /* equal */ else if (cmp == 0) { tmp = _addObj (merge->minPart, merge->minPartN, merge->minPartAllocN, MERGEoPart*); *tmp = part; } } } if (!merge->minRecord) /* all lists are exhausted */ return NULL; (*recordNo)++; return merge->minRecord; } /**api* MergeIds ************************************************************** ** ** Merges the Id blocks from the part indices. ** For all parts the entry IDs are recalculated since the entry-IDs for ** all parts start from entry count 1. ** ** INPUT: o the merge object [W] ** o address of the start address of the block in the ** IDS file [W] ** ** RETURNS: the number of IDs in the merged block */ static void MergeIds (MERGEoSet *merge, IDSoFILE *ids, BTRoREC *rec) { MERGEoPart *part; char buff[2000000]; BTRoREC *tmpRec; BTRoVALUE *tmp; FIP fip; Int4 k, idN; for (k=0, idN=0; k < merge->minPartN; k++) { part = merge->minPart[k]; tmpRec = BtrRecordGet (part->btree, BTRxCURR); tmp = &tmpRec->r.value; IdsGet (part->ids, (IDPTR)buff, tmp->firstIdFip, tmp->idN); /* IdsEntryIncrement (part->ids, buff, partIdN, part->firstEntryN);*/ fip = IdsPut (ids, buff, tmp->idN); if (!idN) { rec->r.value.firstIdFip = fip; rec->r.value.lastIdFip = fip; } idN += tmp->idN; } rec->r.value.idN = idN; } /**api* MergeIdx ************************************************************** ** ** INPUT: the merge object [W] ** field object ** */ static void MergeIdx (MERGEoSet *merge, SLBoFIELD *field) { IDXv idx; SMoBUFF *buff; Int4 errCode, k, c; idx = IdxOpen (LibGetIndexName (merge->lib, field, NULL, "write"), "write", merge->lib->maxNameLen, &errCode); for (k=0; k < merge->partN; k++) for (c=0; (buff = IdxNextBuff (merge->part[k].idx, &c));) IdxPutBuff (idx, buff); IdxClose (idx); } static void MergePartIndexOpen (MERGEoSet *merge, SLBoFIELD *field) { MERGEoPart *part; char *indexName; Int4 k, rv; for (k=0; kpartN; k++) { indexName=MergeGetIndexPartName (merge->lib, field, k+1, "read", NULL); part = &merge->part[k]; if (FieldIs (field, "id")) if (!(part->idx = IdxOpen (indexName, "read", 0, &rv))) _ErrExit2 (rv, indexName); part->btree = BtrOpen (indexName, "read", &rv); _ErrExit2 (rv, FileGetName (field->btree->file, "path")); if (!(part->ids = IdsOpen (indexName, "read", 0, NULL, &rv))) _ErrExit (rv); if (!k) merge->idTypeName = LibGetIdTypeName (IdsGetIdType (part->ids)); } } static void MergePartIndexClose (MERGEoPart *part) { if (part->btree) BtrClose (part->btree); if (part->ids) IdsClose (part->ids); if (part->idx) IdxClose (part->idx); part->ids = NULL; part->idx = NULL; part->btree = NULL; } e, "read", &rv); _ErrExit2 (rv, FileGetName (field->btree->file, "path")); if (!(part->ids = IdsOpen (indexName, "read", 0, NULL, &rv))) _ErrExit (rv); if (!k) merge->idTypeName = LibGetIdTypeName (IdsGetIdType (part->ids)); } } static void MergePartIndexClose (MERGEoPart *part) { if (part->btree) BtrClose (part->btree); if (part->ids) IdsClose (part->ids); if (part->idx) IdxClose (part->idx); part->ids = NULL; part->idx = NULL; srs/src/merge.h typedef struct MERGEoSet *MERGEvSet; Int4 MergeNextPartNo (struct SLBo *lib, Int4 *partNo); MERGEvSet MergeInit (struct SLBo *lib); void MergeIndex (MERGEvSet merge, struct SLBoFIELD *field); if (!k) merge->idTypeName = LibGetIdTypeName (IdsGetIdType (part->ids)); } } static void MergePartIndexClose (MERGEoPart *part) { if (part->btree) BtrClose (part->btree); if (part->ids) IdsClose (part->ids); i@>idx) IdxClose (part->idx); part->ids = NULL; pa{LL; srs/src/message.c char message_srs_ID[] = "$Id: message.c,v 1.4 1997/03/12 16:17:42 srs Exp $"; /* ** ** $RCSfile: message.c,v $ ** $Revision: 1.4 $ ** $Date: 1997/03/12 16:17:42 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port: Lukas Rosenthaler and Reinhard Doelz ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** Requires: file, sm ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** default opens "SYS$ERROR" as output file which ** receives the ** error or informational messages; output can be directed to a ** file with "MsgSetOut" at the begin of the program; ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #ifndef VMS # include #endif #include "msg.h" #include "futil.h" #include "sm.h" /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** global or module wide variables */ static int (*PrintMessage)(MSGo *) = NULL; /* pointer to print function */ static MSGo msg; /* message object - input to user specified function */ static FILEo* msgFile=NULL; /***** MsgPrintMessage ******************************************************** ** ** default function for message printing; ** ** INPUT: message object [R] ** IMPLICIT: ** ** RETURNS: 1 */ INT4 MsgPrintMessage (MSGo *msg) { if (msg->msg_t != MSGxINFO) fprintf (stderr, "%s, %s\n", msg->msg_nm, msg->primsg); if (*(msg->secmsg)) fprintf (stderr, "%s", msg->secmsg); return 1; } /**api* function ************************************************************** ** ** Returns whether specified characteristic of the message is true or ** not. ** ** INPUT: message object [R] ** characteristic: "fatal", "error", "info" ** ** RETURNS: 1: message has the characteristic ** 0: negative */ Int4 MsgIs (MSGo *msg, char *option) { switch (_Index (option[0], option[1])) { case _Index('f','a'): /* fatal */ return msg->msg_t == MSGxFATAL ? 1 : 0; case _Index('e','r'): /* error */ return msg->msg_t == MSGxERROR ? 1 : 0; case _Index('i','n'): /* info */ return msg->msg_t == MSGxINFO ? 1 : 0; } } /****** MsgInit *************************************************************** ** ** opens the message file and the output file; ** ** INPUT: ** IMPLICIT: ** msgFile (FILEo *) [W] ** ** RETURNS: 1 if success */ INT4 MsgInit () { int rv; /* ** open message file */ msgFile = FileNew (MSGxFILE); FileSetMaxLine (msgFile, 200); /* FileSetUnixIo (msgFile);*/ if (!FileOpen (msgFile)) { fprintf (stderr, "\"%s\" could not be opened\n", FileGetName (msgFile, "path")); exit(-1); } if (PrintMessage == NULL) PrintMessage = MsgPrintMessage; return 1; } /**api* MsgAnalCode ********************************************************** ** ** analyzes a message code: calculates the file pointer and finds out ** the message type ** ** INPUT: message object [W] ** message code [R] ** address of file pointer [W] ** IMPLICIT: ** ** RETURNS: 1 if a real message code ** 0 if not */ INT4 MsgAnalCode (MSGo *msg, int msg_code, unsigned int *fip) { int msg_t; if (msg_code > MSGxMAX || msg_code < MSGxMIN || msg_code == e__error) return 0; /* ** msg_code = fip + msg_t * -MSGxMAX */ msg_t = msg_code / MSGxMAX; *fip = -msg_code + MSGxMAX * msg_t; msg->msg_code = msg_code; msg->msg_t = (enum msg_typ) msg_t; return 1; } /**api* Message *************************************************************** ** ** checks if the number is really error code; ** opens file with error messages, goes to address specified in error code ** forms message object and prints it; ** if more arguments are transmitted and the next line(s) in file begins ** with a non alpha character then the line + arguments are transmitted ** to "printf". ** aborts program if MSGxEXIT ** if MSGxMSG then the line containing the message name is not printed ** note that after that line several output lines may occur - they will ** simply be concatenated to one; ** ** INPUT: o number of arguments following ** o error code ** o MSGxEXIT or MSGxNOEX or MSGxMSG ** o (optional) ** o up to 10 arguments for "printf" ** IMPLICIT: ** msg (MSGo) [W] ** msgFile (FILEo *) [W] ** ** RETURNS: 1 if success ** 0 if number is not a message code */ INT4 Message (INT4 arg_n, INT4 msg_code, INT4 opt, ...) { static int first_f=TRUE; va_list ap; unsigned int fip; int rv; char secmsg[MSGxXLN * MSGxXNLN+1], *tmp; /* ** open message file + output file */ if (first_f) { MsgInit (); first_f = FALSE; } /* ** convert message number into a file pointer and set file pointer in message ** file to this address; */ if (!MsgAnalCode (&msg, msg_code, &fip)) return 0; FileSeek (msgFile, fip); /* ** first line contains message name and primary message - extract those; ** all following lines that do not start with either of "fewi" are copied ** into one string - the secondary message; */ sscanf (FileReadLn (msgFile), "%[^,] , %[^\n]", msg.msg_nm, msg.primsg); SmEdit (msg.primsg, SMxTRIM); /* cut of trailing white space */ if (arg_n > 3) { secmsg[0] = '\0'; while (tmp = FileReadLn (msgFile)) { if (strchr ("fewio", tmp[0]) != NULL) break; SmEdit (tmp, SMxTRIM2 | SMxDECODE); strcat (secmsg, tmp); } /* ** secondary message is a format specification for printf - make final ** message line - argument list is the one given to "Message" */ va_start (ap, opt); vsprintf (msg.secmsg, secmsg, ap); va_end (ap); } else msg.secmsg[0] = '\0'; /* ** print message and exit program if requested; */ (*PrintMessage) (&msg); if (opt == MSGxEXIT) exit (256); return 1; } /**API* MsgSetFnct ************************************************************ ** ** Replaces the default function for printing error and information ** messages. ** ** INPUT: address of function [R] ** IMPLICIT: ** fnct_f (int) ** outfnct (int) [W] ** ** RETURNS: */ void MsgSetFnct (INT4 (*fnct)()) { PrintMessage = fnct; } * ** print message and exit program if requested; */ (*PrintMessage) (&msg); if (opt == MSGxEXIT) exit (256); return 1; } /**API* MsgSetFnct ************************************************************ ** ** Replaces the default funcsrs/src/message.h #define e__msgfail -3000112 #define e__allocfail -3000165 #define e__freefail -3000254 #define e__settoobig -3000332 #define e__readerr -3000375 #define e__novalop -3000415 #define e__novaltyp -3000472 #define e__nosetfree -3000569 #define e__userabort -3000601 #define e__filnotopen -3000638 #define e__filnotok -3000693 #define e__filopenerr -3000748 #define e__eof -3000805 #define e__ltoolong -3000837 #define e__invnodenum -3000889 #define e__missnode -3000954 #define e__toomansym -3001017 #define e__eot -3001082 #define e__parsefail -3001152 #define e__bldparsefail -3001219 #define e__strprsfail -3001322 #define e__lnotsaved -3001388 #define e__novalpnam -3001442 #define e__novalsnam -3001526 #define e__invalnum -3001610 #define e__procfail -3001700 #define e__symnotuniq -3001762 #define e__toomanstrct -3002220 #define e__startismiss -3002356 #define e__isnotss -3002411 #define e__novalid -3002528 #define e__missingchar -3002635 #define e__unknownnterm -3002723 #define e__charnotknown -3002795 #define e__symnotknown -3002903 #define e__novalsyminfo -3002990 #define e__novalarg -3003083 #define e__novalcommand -3003170 #define e__bnfbuildfail -3003252 #define e__wrongpartyp -3003344 #define e__novalptyp -3003437 #define e__novalopt -3003530 #define e__misscolon -3003595 #define e__nammismatch -3003653 #define e__namnotuniq -3003718 #define e__novalauthor -3003779 #define i__slbreportbeg -1003868 #define i__slbreportend -1004171 #define i__inxreport -1004297 #define i__processing -1004390 #define e__eom -3004446 #define i__inxcmprss -1004541 #define e__nofieldend -3004635 #define e__wrongfieldcnt -3004694 #define e__strtoolong -3004807 #define e__linenotexst -3004877 #define e__invalstr -3004939 #define e__invalnumber -3005011 #define e__invalifn -3005086 #define e__invalofn -3005168 #define e__activesubmenu -3005251 #define e__allwinused -3005345 #define e__exceedsize -3005385 #define e__eob -3005476 #define e__novalfield -3005510 #define e__novalnam -3005560 #define e__unexpectnum -3005687 #define e__noinit -3005765 #define e__strnotfou -3005812 #define e__strnotfound -3005875 #define e__novalstr -3005931 #define e__novalfadd -3005983 #define e__novalnum -3006049 #define e__libnotinx -3006131 #define i__wrotefile -1006210 #define i__wrotefiles -1006254 #define e__novalpos -3006313 #define e__novalseqlen -3006380 #define e__seqfrg -3006473 #define e__seekfail -3006531 #define e__crmpscfail -3006586 #define e__maxlinksexceed -3006673 #define e__unknownnam -3006757 #define e__novallink -3006810 #define e__toofew -3006873 #define e__namreserved -3006947 #define i__sdlreport -1007016 #define e__nopath -3007424 #define e__ambigouslink -3007486 #define e__badarglist -3007660 #define e__namnotdef -3007717 #define e__invaloutdir -3007779 #define i__wroteseq -1007847 #define i__wroteseqsfile -1007894 #define e__complement -3007964 #define e__novalreference -3008066 #define i__lnkreport -1008174 #define e__exceedquota -3008250 #define e__rtlfail -3008296 #define e__novalsettyp -3008362 #define e__collidsfail -3008447 #define e__inheritfail -3008535 #define e__objnotfound -3008612 #define e__objnotnhrt -3008703 #define e__missdefattr -3008823 #define e__symappendfail -3009011 #define e__exceedarr -3009094 #define e__novalterm -3009157 #define i__mappedset -1009240 #define i__loadlinkset -1009306 #define e__novalseqform -3009362 #define i__wroteseqlen -1009428 #define e__novalpar -3009582 #define e__toomanpar -3009672 #define i__procsubset -1009768 #define e__sicinvalgroups -3009852 #define e__unknowncommand -3009954 #define i__readingname -1010010 #define e__interrupt -3010073 #define i__wroteset -1010105 #define e__sftop -3010171 #define e__libnotlinked -3010250 #define e__filnotfound -3010307 #define e__filcloseerr -3010386 #define e__filwriteerr -3010440 #define i__noentriesfound -1010540 #define e__nonounix -3010576 #define i__listtolib -1010657 #define e__eostack -3010753 #define f__limitexceeded -4010778 #define e__nontermexpect -3010853 #define e__novalformat -3010900 #define e__parnottype -3010959 #define e__foundoneof -3011058 #define e__unknownoption -3011132 #define e__parisdefined -3011205 #define e__parnotdefined -3011275 #define e__notwriteopen -3011337 #define e__indexisbusy -3011415 #define e__doesnotexistfunction -3011487 #define e__overflowstack -3011560 #define f__failedtomovelist -4011634 #define e__couldnotgetsequence -3011701 #define e__nothingtoevaluate -3011788 #define e__failureinslbgetx -3011830 #define e__joinillegalpar -3011914 #define e__entryparsefail -3011979 #define e__illegalposition -3012040 #define e__illegalvalueonstack -3012124 #define e__illegalvaluesonstack -3012242 #define e__illegaldirectioninrange -3012371 #define e__operatorbeforenotallowed -3012455 #define e__operatorafternotallowed -3012512 #define e__postoohigh -3012567 #define i__entry -1012638 #define e__objectunknown -3012683 #define e__noseqinlist -3012753 #define e__noresult -3012795 #define e__illegalrangemod -3012834 #define e__illegalmodparam -3012898 #define e__illegalqueryparam -3012965 #define e__noparamlist -3013027 #define e__negativelength -3013075 #define e__incorrectlength -3013144 #define e__fnctnotdefined -3013215 #define e__btreenotprep -3013355 #define i__writeindex -1013449 #define e__invalidid -3013529 #define e__hasnotfixedrecord -3013612 #define e__fieldnotindex -3013695 #define e__iscompressed -3013761 #define e__notcompressed -3013824 #define i__processingentry -1013900 #define i__wrotebtree -1013943 #define i__wroteidfile -1014080 #define e__inxnotcompress -3014201 #define e__listnotfilled -3014265 #define e__buffexceeded -3014356 #define i__openedidpatch -1014428 #define e__dupllibid -3014521 #define e__novallibid -3014626 #define e__libidexst -3014727 #define e__libidnotknown -3014830 #define e__settoosmall -3014922 #define i__builtlink -1015032 #define i__checkinglib -1015222 #define e__novalentryidlen -3015277 #define e__indexnotuptodate -3015385 #define e__indexwrongversion -3015492 #define e__regerror -3015593 #define i__mustbuildinx -1015628 #define i__mustbuildlink -1015702 #define i__diffentrynum -1015781 #define e__labelnotfound -3015858 #define i__givinguplib -1015954 #define e__strnotinset -3016025 #define e__numnotinset -3016128 #define e__realnotinset -3016231 #define e__functionnotinset -3016331 #define e__charnotallowed -3016436 #define e__realnotinrange -3016540 #define e__checkerr -3016648 #define e__setopneedsidtype -3016706 #define e__nolinklibselected -3016806 #define i__querynegative -1016898 #define e__novalvar -3016957 #define e__novalvar2 -3017029 #define e__novalvar3 -3017102 #define e__formatnomatch -3017175 #define e__relbegandend -3017278 #define e__invalidshift -3017367 #define e__shiftseqisfrag -3017454 #define e__seqwithneglen -3017520 #define e__badfile -3017602 #define i__indexnotexist -1017651 #define i__indexnotcompleted -1017735 #define i__indexnotuptodate -1017830 #define i__indexnotcompressed -1017922 #define e__rangewithundefval -3018017 #define e__argwrongnum -3018104 #define e__argwrongtype -3018202 #define e__argsendnull -3018308 #define e__fatal -3018380 #define e__unknownarg -3018402 #define e__nocurrentcommand -3018475 #define e__onlyoneunnamed -3018561 #define e__varwrongclass -3018778 #define e__varisreadonly -3018899 #define e__seqillegallength -3019068 #define e__novalchar -3019166 #define e__missingarg -3019233 #define e__nosetorlib -3019317 #define e__functionnotexist -3019375 #define e__emptyquerystring -3019439 #define e__illegalbaseconv -3019479 #define e__dbnotlegal -3019587 #define e__noviewselect -3019709 #define e__querynotfound -3019794 #define e__dbhasnotfield -3019866 #define e__icastackempty -3019960 #define e__icaunknownattr -3020022 #define e__icaenumval -3020203 #define e__icarequiredattr -3020272 #define e__icaattrval -3020358 #define e__templNoCurrTemplate -3020411 #define e__unknownformat -3020471 #define e__templEndOfHistory -3020557 #define i__invalidentry -1020642 #define e__setnotuniqname -3020711 #define e__icainvalidselect -3020780 #define e__icainvallistassign -3020904 #define e__icaopTask -3021049 #define e__icaopEdit -3021128 #define e__icaopAssign -3021225 #define e__icaopRestrictLen -3021321 #define e__icaopMove -3021415 #define e__icabnfGetProd -3021488 #define e__icabnfExpression -3021572 #define e__icabnfProgram -3021659 #define e__icabnfLinkBnfNet -3021730 #define e__icabnfParser -3021807 #define e__icarusFatal -3021877 #define e__toklistFind -3021930 #define e__toklistReplace -3021990 #define e__toklistIsUniq -3022054 #define e__parsererror1 -3022117 #define e__parsererror2 -3022195 #define e__parsererror3 -3022272 #define e__wwwnomatchingview -3022361 #define e__nolibslct -3022528 #define e__wwwNoQueryOrEntriesSelected -3022570 #define e__wwwNoQuerySpecified -3022654 #define e__toktablenotwritable -3022719 #define i__bldReadLink -1022794 #define e__bldNoReadLinks -3022865 #define f__noVarScope -4022932 #define e__bldLibNotMerge -3023022 #define e__genNoObjWithNo -3023134 #define e__checkInvalidLibInfo -3023234 #define e__icaMissingString -3023343 #define e__duplicatekey -3023476 #define f__exception -4023545 #define e__icaUnknownClass -3023670 #define e__icaErrorsQuit -3023762 #define e__icavartype -3023814 #define e__anyIsReadOnly -3023902 #define e__toktablenotwritable -3022719 #define i__bldReadLink -1022794 #define e__bldNoReadLinks -3022865 #define f__noVarScope -4022932 #define e__bldLibNotMerge -3023022 #define e__genNoObjWithNo -3023134 #define e__checkInvalidLibInfo -3023234 #define e__icaMissingString -3023343 #define e__duplicatekey -3023476srs/src/mi.c int headTable[]={0,1,2,2,3,3,3,3}; int tailTable[]={0,0,1,0,3,2,1,0}; char* MIFromULong(ULONG x, int* len) { static char buf[16]; int l=1; char* pos=buf; ULONG r; /* get the first byte */ *pos++=x&0x3F; x>>=6; /* unsigned! */ while (x) { *pos++=(char)x; x>>=8; l++; } ASSERT(l<8,"IntTooLong"); /* get log2 lenght */ buf[0] |= headTable[l-1]<<6; r=tailTable[l-1]; /* add filling bytes */ while (r--) { *pos++=(char)x; l++; } *len=l; return buf; } ULONG MIToULong(char* buf) { ULONG n; int shift=6; /* get lenght */ int l=1<<((*buf>>6)&0x3); n=(*buf++)&0x3F; while (--l) { n|=(*buf++)<>6)&0x3); } char* MIFromLong(long x, int* len) { /* make an unsigned out of the signed, rotating right 1 */ ULONG encoded; if (x>=0) encoded=(ULONG)x<<1; else encoded=(((ULONG)-x)<<1)+1; return MIFromULong(encoded, len); } long MIToLong(char* buf) { ULONG encoded=MIToULong(buf); if (encoded&0x1) return -(encoded>>1); else return encoded>>1; } /************************************************************************** ** FLOATING-POINT CODEC */ #include typedef struct { int lMant; int lExp; } FloatFormat; FloatFormat floatFormats[]= { {1,0}, /* small int */ {1,1}, {2,1}, {3,1}, {3,2}, {7,2}, {15,2}, {7,3}, {15,3} }; #define WORD_BITS 32 void MIFromMantissa(double m, char** buf) { char* p=*buf; double mInt; WORD chunk; int bit=0; /* convert first, encoded with sign(msb:0=-,1=+) */ if (m>0) { m=modf(ldexp(m,WORD_BITS),&mInt); chunk=(WORD)mInt; } else { m=modf(ldexp(-m,WORD_BITS),&mInt); chunk=((WORD)mInt)^(1<=0; bit-=8) { *p++=(chunk>>bit)&0xFF; } while (m!=0) { m=modf(ldexp(m,WORD_BITS),&mInt); chunk=(WORD)mInt; /* convert chunk */ for (bit=WORD_BITS-8; bit>=0; bit-=8) { *p++=(chunk>>bit)&0xFF; } }; /* go back to last non-zero byte to find real lenght */ p--; while (!*p) p--; p++; *buf=p; } double MIToMantissa(char* p, int len) { double m=0; int exp; WORD chunk=0; int bit,sign; /* first chunk encodes sign */ for (bit=0; bit=-16 && mInt<16)) { /* small int, encode in 1 byte */ char c=((int)mInt)&0x1F; *p++=c; } else { char mant[20], *m=mant; int l; ULONG coded; d=frexp(d,&exp); /* code exponent */ if (exp>=0) coded=exp<<1; else coded=(-exp<<1)|0x1; *p++=coded&0x1F; coded>>=5; if (coded) {*p++=coded; coded>>=8;} if (coded) {*p++=coded; } ASSERT(!(coded>>8), "ExpOutOfRange"); /* code mantissa */ MIFromMantissa(d, &m); /* find and set format */ lMant=m-mant; lExp=p-buf; f=floatFormats+1; while (lMant>f->lMant || lExp>f->lExp) { f++; ASSERT(flExp-lExp; while (lExp--) *p++=0; /* copy mantissa */ m=mant; l=lMant; while (l--) *p++=*m++; /* adjust mant. lenght */ lMant=f->lMant-lMant; while (lMant--) *p++=0; } *len=(p-buf); return buf; } double MIToDouble(char* buf) { char* p=buf; int format; format=(*p>>5)&0x7; if (format==0) { /* small int */ int coded=*p&0x1F; /* extend sign */ if (coded&0x10) coded |= ~0x1F; return coded; } else { int exp; FloatFormat* f; ULONG coded; int lExp; double d; f=floatFormats+(*p>>5); /* get exponent */ coded=(*p++)&0x1F;lExp=f->lExp-1; if (lExp--) { coded|=(*p++)<<5; if (lExp--) coded|=(*p++)<<13; } if (coded&0x1) exp=-(coded>>1); else exp=coded>>1; /* get mantissa */ d=MIToMantissa(p, f->lMant); return ldexp(d, exp); } } int MIToDoubleSize(char head) { FloatFormat* format=floatFormats+((head>>5)&0x7); return format->lMant+format->lExp; } int esrs/src/mi.h #define _MI_H /****************************************************** ** MACHINE-INDEPENDENT CODING/DECODING of numbers ******************************************************/ /* int codec */ char* MIFromULong(unsigned long x, int* len); char* MIFromLong(long x, int* len); unsigned long MIToULong(char* buf); long MIToLong(char* buf); int MIToLongSize(char head); /* floating-point codec */ char* MIFromDouble(double d, int* len); double MIToDouble(char* buf); int MIToDoubleSize(char head); #endif ******************************************* ** MACHINE-INDEPENDENT CODING/DECODING of numbers ******************************************************/ /* int codec */ char* MIFromULong(unsigned long x, int* len); char* MIFromLong(long x, int* len); unsigned long MIToULong(char* buf); long MIToLong(char* buf); int MIToLongSize(char head); /* floating-point codec */ char* MIFromDouble(double d, int* len); double MIToDouble(char* buf); int srs/src/msg.h ** ** $RCSfile: msg.h,v $ ** $Revision: 1.3 $ ** $Date: 1996/11/20 16:36:29 $ ** $Author: etzold $ ** ** $Locker: $ ** $State: Exp $ ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port: Lukas Rosenthaler and Reinhard Doelz ** */ #define MSGxFILE "SRSDAT:message.dat" #define MSGxHHDR "msg.h" #define MSGxHDR "message.h" #define MSGxSCM "MESSAGE BUFFER" #define MSGxXNLN 5 #define MSGxXLN 132 #define MSGxXARG 10 enum msg_typ {MSGxINFO=1, MSGxWARNING, MSGxERROR, MSGxFATAL}; #define MSGxMAX -1000000 * (INT4) MSGxINFO #define MSGxMIN -1000000 * (INT4) MSGxFATAL - 100000 #define MSGxMSG 0 #define MSGxEXIT 1 #define MSGxNOEX 2 #define e__error -3000001 #include "def.h" /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Description of a message. */ typedef struct MSGo { INT4 msg_code; /* message code number */ char msg_nm[30]; /* (API) message code name */ char primsg[MSGxXLN+1]; /* (API) primary message */ char secmsg[MSGxXLN*MSGxXNLN+1]; /* (API) secondary message - additional lines that may contain arguments */ enum msg_typ msg_t; /* (API) message type: one of MSGxINFO, MSGxWARNING, MSGxERROR, MSGxFATAL */ } MSGo; #ifdef LONG_ERROR_MSG # define __ERRMSG fprintf (stderr, "File: %s, Line: %d\n", __FILE__,__LINE__); #else # define __ERRMSG #endif #define _ErrorExit() exit(-1) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** macro checks if number of arguments is correct */ #define _CheckArgN(arg_n, min, max, errmsg) \ if (((arg_n) > (max)) || ((arg_n) < (min))) return (errmsg) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** checks some return value if it is message code, prints message ** and aborts program brutally;...does it no longer! behaves like ** _ErrExit now; */ #define _ErrStop(rv)\ do {if ((((INT4) rv) < MSGxMAX) && (((INT4) rv > MSGxMIN))) { __ERRMSG \ Message (3, ((INT4) rv), MSGxEXIT); }} while (0) #define _ErrStop2(rv, p2)\ do {if (((INT4) rv) < MSGxMAX && ((INT4) rv > MSGxMIN)) { __ERRMSG \ Message (4, ((INT4) rv), MSGxEXIT, p2);}} while (0) #define _ErrStop3(rv, p2, p3)\ do {if (((INT4) rv) < MSGxMAX && ((INT4) rv > MSGxMIN)) { __ERRMSG \ Message (5, ((INT4) rv), MSGxEXIT, p2, p3);}} while (0) #define _ErrStop4(rv, p2, p3, p4)\ do {if (((INT4) rv) < MSGxMAX && ((INT4) rv > MSGxMIN)) { __ERRMSG \ Message (6, ((INT4) rv), MSGxEXIT, p2, p3, p4);}} while (0) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** checks some return value if it is message code and only prints ** message */ #define _ErrMsg(rv)\ do {if (((INT4) rv) < MSGxMAX && ((INT4) rv > MSGxMIN)) { __ERRMSG \ Message (3, ((INT4) rv), MSGxNOEX);}} while (0) #define _ErrMsg2(rv, p2)\ do {if (((INT4) rv) < MSGxMAX && ((INT4) rv > MSGxMIN)) { __ERRMSG \ Message (4, ((INT4) rv), MSGxNOEX, p2);}} while (0) #define _ErrMsg3(rv, p2, p3)\ do {if (((INT4) rv) < MSGxMAX && ((INT4) rv > MSGxMIN)) { __ERRMSG \ Message (5, ((INT4) rv), MSGxNOEX, p2, p3);}} while (0) #define _ErrMsg4(rv, p2, p3, p4)\ do {if (((INT4) rv) < MSGxMAX && ((INT4) rv > MSGxMIN)) { __ERRMSG \ Message (6, ((INT4) rv), MSGxNOEX, p2, p3, p4);}} while (0) #define _ErrMsg5(rv, p2, p3, p4, p5)\ do {if (((INT4) rv) < MSGxMAX && ((INT4) rv > MSGxMIN)) { __ERRMSG \ Message (7, ((INT4) rv), MSGxNOEX, (p2), (p3), (p4), (p5));}} while (0) #define _ErrMsg6(rv, p2, p3, p4, p5, p6)\ do {if (((INT4) rv) < MSGxMAX && ((INT4) rv > MSGxMIN)) { __ERRMSG \ Message (8, ((INT4) rv), MSGxNOEX, p2, p3, p4, p5, p6);}} while (0) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** checks some return value if it is message code, prints message ** and returns message code to calling function */ #define _ErrRet(rv) \ do {if (((INT4) rv) < MSGxMAX && ((INT4) rv > MSGxMIN)) { \ return (INT4) rv;}} while (0) #define _ErrRet1(rv)\ do {if (((INT4) rv) < MSGxMAX && ((INT4) rv > MSGxMIN)) { __ERRMSG \ if (Message (3, ((INT4) rv), MSGxNOEX)) return (INT4) rv;}} while (0) #define _ErrRet2(rv, p2)\ do {if (((INT4) rv) < MSGxMAX && ((INT4) rv > MSGxMIN)) { __ERRMSG \ if (Message (4, ((INT4) rv), MSGxNOEX, p2)) return (INT4) rv;}} while (0) #define _ErrRet3(rv, p2, p3)\ do {if (((INT4) rv) < MSGxMAX && ((INT4) rv > MSGxMIN)) { __ERRMSG \ if (Message (5, ((INT4) rv), MSGxNOEX, p2, p3)) return (INT4) rv;}} while (0) #define _ErrRet4(rv, p2, p3, p4)\ do {if (((INT4) rv) < MSGxMAX && ((INT4) rv > MSGxMIN)) { __ERRMSG \ if (Message (6, ((INT4) rv), MSGxNOEX, p2, p3, p4)) return (INT4) rv;}} while (0) #define _ErrRet5(rv, p2, p3, p4, p5)\ do {if (((INT4) rv) < MSGxMAX && ((INT4) rv > MSGxMIN)) { __ERRMSG \ if (Message (6, ((INT4) rv), MSGxNOEX, p2, p3, p4, p5)) return (INT4) rv;}} while (0) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** checks some return value if it is message code, prints message ** and exits program */ #define _ErrExit(rv)\ do {if (((INT4) rv) < MSGxMAX && ((INT4) rv > MSGxMIN)) { __ERRMSG \ if (Message (3, ((INT4) rv), MSGxNOEX)) exit(-1);}} while (0) #define _ErrExit2(rv, p2)\ do {if (((INT4) rv) < MSGxMAX && ((INT4) rv > MSGxMIN)) { __ERRMSG \ if (Message (4, ((INT4) rv), MSGxNOEX, p2)) exit(-1);}} while (0) #define _ErrExit3(rv, p2, p3)\ do {if (((INT4) rv) < MSGxMAX && ((INT4) rv > MSGxMIN)) { __ERRMSG \ {if (Message (5, ((INT4) rv), MSGxNOEX, p2, p3)) exit(-1);}}} while (0) #define _ErrExit4(rv, p2, p3, p4)\ do {if (((INT4) rv) < MSGxMAX && ((INT4) rv > MSGxMIN)) { __ERRMSG \ if (Message (6, ((INT4) rv), MSGxNOEX, p2, p3, p4)) exit(-1);}} while (0) #define _ErrExit5(rv, p2, p3, p4, p5)\ do {if (((INT4) rv) < MSGxMAX && ((INT4) rv > MSGxMIN)) { __ERRMSG \ if (Message (7, ((INT4) rv), MSGxNOEX, p2, p3, p4, p5)) exit(-1);}} while (0) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** checks some return value if it is message code */ #define _ErrIf(rv)\ if ( (INT4) rv < MSGxMAX && (INT4) rv > MSGxMIN) #define _ErrIs(rv)\ ( (INT4) rv < MSGxMAX && (INT4) rv > MSGxMIN) #define _ErrSet(errCodePtr, errCode)\ do { \ if (errCodePtr) \ *errCodePtr = (INT4) errCode; \ } while (0) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of exported functions */ INT4 Message (INT4 arg_n, INT4 msg_code, INT4 opt, ...); void MsgSetFnct (INT4 (*fnct)()); Int4 MsgIs (struct MSGo *msg, char *option); ode srs/src/msgdef.c char msgdef_srs_ID[] = "$Id: msgdef.c,v 1.2 1996/07/09 23:38:09 etzold Exp $"; /* ** ** $RCSfile: msgdef.c,v $ ** $Revision: 1.2 $ ** $Date: 1996/07/09 23:38:09 $ ** $Author: etzold $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port by Lukas Rosenthaler and Reinhard ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** Requires: none ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** this program generates the file message.h which defines ** unique values for all error messages in message.dat; ** this value is calculated as the file address (by ftell) ** multipied by -1 minus 1 000 000; (i. e. the error ** value is always smaller than -1 000 000 = MAXERR); ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include "msg.h" int main() { FILE *inf, *outf; int fip, errcode; int k; char line[MSGxXLN]; char errnam[MSGxXLN]; char dummy; inf = fopen ("../etc/message.dat", "r"); if (inf == NULL) { printf("\"%s\" could not be opened\n",MSGxFILE); exit(1); } outf = fopen("message.h", "w"); if (outf == NULL) { printf("\"%s\" could not be opened\n",MSGxHDR); exit(1); } fprintf(outf, "#include \"%s\"\n", MSGxHHDR); /* ** read file with messages until line starts with either of "iwef" ** (info, warning, error, fatal), get the fip (file pointer) multiply by ** -1 and add MSGxMAX * message type (enum msg_typ); */ while (1) { do { fip = ftell(inf); fgets(line, MSGxXLN, inf); } while (strchr ("iwef", line[0]) == NULL && !feof(inf)); if (feof(inf)) break; switch (line[0]) { case 'i': errcode = -1 * fip + (MSGxMAX * MSGxINFO); break; case 'w': errcode = -1 * fip + (MSGxMAX * MSGxWARNING); break; case 'e': errcode = -1 * fip + (MSGxMAX * MSGxERROR); break; case 'f': errcode = -1 * fip + (MSGxMAX * MSGxFATAL); break; case 'o': /* obsolete */ errcode = 0; break; default: printf ("messages starting with \"%d__\" have unknown type\n=> %s\n", line[0], line); exit(1); break; } dummy = fgetc(inf); /* for RMS to see that record end is */ ungetc(dummy, inf); /* reached otherwise ftell = bullshit */ for (k = 0; (line[k] != ',') && (k < 80) ; k++) errnam[k] = line[k]; errnam[k] = '\0'; if (k == 80) { printf("error message is in wrong format:\n %s\n", errnam); exit(1); } if (errcode != 0) fprintf(outf, "#define %s %d\n", errnam, errcode); } printf("message.h is created in the current folder\n"); exit (0); } dummy = fgetc(inf); /* for RMS to see that record end is */ ungetc(dummy, inf); /* reached otherwise ftell = bullshit */ for (k = 0; (line[k] != ',') && (k < 80) ; k++) errnam[k] = line[k]; errnam[k] = '\0'; if (k == 80) { printf("error message is in wrong format:\n %s\n", errnam); exit(1); } if (errcode != 0) srs/src/nodd.c #include #include #include #include "message.h" #include "futil.h" #include "sm.h" #include "arglist.h" #include "toklist.h" #include "icarus.h" #include "odd.h" #define _INITOBJS #define _CONSTANTS #define _SDL #define _ODD #define _FUNCTION #include "oddclass.h" /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** object wide and global variables */ typedef INT4 (*SDLoFNCTx)(); SDLoFNCTx SDL_fnctx[] = {NULL}; static INT4 PrintMessage (MSGo *msg); struct ICAoSYNTAX *IcaInitSyntax(struct ICAoSYNTAX *syntax); main(int argc, char **argv) { SDLo *odd; ARGoLIST *arglist; FILEo *file; ICAoJOB *job; ICAoSYNTAX *syntax; ParSetTable ("global", NULL, "PRIVATE"); ParInit (ODD_parTable); MsgSetFnct ((FUNC)IcaPrintMessage); argc = ArgGet (&argList[0], argc, argv); if (argc != 3) { /* process command line options */ ArgUsage (argList); exit (1); } syntax = IcaInitSyntax (NULL); /* process class information */ job = IcaCreateJob (syntax); odd = OddInit (def, 1); file = FileNew (argv[1]); if (!FileOpen (file)) _ErrExit2 (e__filnotok, argv[2]); IcaJobSetFile (job, file); IcaGetTokenList (job, "prog"); if (IcaJobIsError (job)) _ErrExit (e__icaErrorsQuit); IcaExecProg (job); /* process objects */ if (IcaJobIsError (job)) _ErrExit (e__icaErrorsQuit); job = IcaCreateJob (syntax); odd = OddInit (odd, 2); file = FileNew (argv[2]); if (!FileOpen (file)) _ErrExit2 (e__filnotok, argv[2]); IcaJobSetFile (job, file); IcaGetTokenList (job, "prog"); job->file = FileDelete (job->file); if (IcaJobIsError (job)) _ErrExit (e__icaErrorsQuit); IcaExecProg (job); if (IcaJobIsError (job)) _ErrExit (e__icaErrorsQuit); OddOut (odd); exit (0); } b); /* process objects */ if (IcaJobIsError (job)) _ErrExit (e__icaErrorsQuit); job = IcaCreateJob (syntax); odd = OddInit (odd, 2); file = FileNew (argv[2]); if (!FileOpen (file)) _Esrs/src/ntry.c #include #include #include "srs.h" #include "odd.h" #define _INITOBJS #define _CONSTANTS #define _SDL #define _ODD #define _FUNCTION #include "oddclass.h" int main(int argc, char **argv) { SETo *set; ENTRYo *entry; IDoENTRY id; INT4 i; SrsEnv (); LibOpen ("srs5"); OddInit (def, 1); IcaInitSyntax (LibObjByName ("syntax", "icarus")); MsgSetFnct ((FUNC)IcaPrintMessage); argc = ArgGet (LibObjByName ("arglist", "getz"), argc, argv); if (ParGetNum ("printLibInfo") && argc == 2) { /* print only info ? */ LibPrintInfo (argv[1]); exit (0); } else if (ParGetNum ("printLibs")) { LibPrintLibs (); exit (0); } if ((set = Query (argv[1], "Q1"))) for (i=1; i <= set->n; i++) { SetGetID (set, i, &id); entry = EntryOpen (&id); if (ParGetBool ("printEntireEntry")) EntryPrint (entry); else EntryPrintFields (entry); EntryClose (&entry); } exit (0); } glist", "getz"), argc, argv); if (ParGetNumsrs/src/objstream.c #include "listv.h" #include "strv.h" #include "dict.h" #include "blub.h" #include "objstream.h" #include /****************************************************** ** ATTRIBUTE PRINTING ACTION ******************************************************/ typedef void (*ValPrinter) (void* val); void PolyIntPrint(int* v) { printf("%d", *v); } void PolyPtrPrint(PTR* v) { printf("%p", *v); } void PolyStrPrint(STRv* v, void* nothing) { if (*v) printf("%s", Str(*v)); else printf("NULL"); } void PolyObjPrint(void** obj) { ObjPrint(*obj); } void PolyListPrint(ListAttr* l) { printf("[n:%d", displ(l->tail,l+1)); if (l->end!=l->tail) printf(" g:%d", displ(l->end,l->tail)); printf("]"); } void PolyAttrPrint(ATTRv* a) { if (a->type!=-1) { if (a->name) printf("%s:", Str(a->name)); printf("%s", Str(attrDescr[a->type].name)); printf("[o:%d]",a->offs); } } void PolyClassPrint(CLASSBODYv* c) { /*if (c->name) printf(" name:%s", Str(c->name));*/ if (c->inherits) { printf("inherits: "); ObjPrint(c->inherits); } if (c->fixed->type!=-1) { printf("list: %s",Str(attrDescr[c->fixed->type].name)); } } void AttrPrintAction(void* val, ATTRp attr, void* nothing) { static ValPrinter printOp[]={ (ValPrinter) PolyIntPrint, (ValPrinter) PolyPtrPrint, (ValPrinter) PolyStrPrint, (ValPrinter) PolyObjPrint, (ValPrinter) PolyListPrint, (ValPrinter) PolyClassPrint, (ValPrinter) PolyAttrPrint }; printf(" "); if (attr->type!=-1) { if (attr->name) printf("%s:", Str(attr->name)); call (printOp[attr->type])(val); } } /* services */ void ObjPrintDescr(CLASSv descr) { STRv name=SysToName(descr); if (name) { printf("%s",_Str(name)); } else { ObjPrintDescr(descr->inherits); printf(" with:{"); ObjDoList(descr, AttrPrintAction, NULL); printf("}"); } } void ObjPrint(void* obj) { if (obj) { ObjPrintDescr(_getObj(obj)->descr); printf("["); ObjDoAll(obj, AttrPrintAction, NULL); printf("]"); } else printf("NULL"); } void ObjDebug(void* obj) { printf("%p: ", obj); if (obj) { OBJv o=_getObj(obj); ObjPrint(obj); printf(" "); /*ObjPrint(o->descr);*/ } printf("\n"); } /********************************************************* ** OBJECT STREAM DEFINITION *********************************************************/ typedef struct MapEntry { void* val; int usage; int id; } MapEntry; void* MapEntryToKey(MapEntry** m, IntOrPtr nothing) { return (*m)->val; } typedef struct OBJoStream { FILE* file; DICTv objs; /* object value management */ DICTv strs; /* string value management */ DICTv ptrs; int idLast; void** ids; } OBJoStream; /*************************** ***************** writing */ void* ObjStreamMapDef(DICTv* map, void* val) { MapEntry **mp,*m; if (SysToId(val)!=-1) return NULL; mp=&DictSet(map, val, MapEntry*); m=*mp; if (m) { m->usage++; if (val!=m->val) return m->val; else return NULL; } else { m=*mp=_palloc(MapEntry); m->val=val; m->usage=1; m->id=0; return NULL; } } #define OBJSTREAM_ID 1 #define OBJSTREAM_DEFVALID 2 int objStreamDefineVal=0; BOOL ObjStreamVal(OBJpStream stream, DICTv* map, void* val) { int id=SysToId(val); if (id==-1) { /* not in the system culture */ MapEntry* m; Iter mi=DictWith(*map, val); objStreamDefineVal=0; if (!mi) return TRUE; m=DictIn(mi, MapEntry*); m->usage--; id=m->id; if (id==0) { if (m->usage>0) { /* define new id if first time and reused */ objStreamDefineVal=OBJSTREAM_DEFVALID; id=m->id=stream->idLast++; } else { _pfree(m); DictRemove(map, mi); } return TRUE; } if (m->usage==0) { /* remove entry */ _pfree(m); DictRemove(map, mi); } } /* now stream id */ IntStore((id<<1) | OBJSTREAM_ID, stream); return FALSE; } void ObjStreamHead(OBJpStream stream, int head) { IntStore((head<<2)|objStreamDefineVal, stream); } /******************************* ********************* reading */ UINT4 streamFirstVal; BOOL ObjStreamGetVal(OBJpStream stream, void** val) { UINT4 n=IntLoad(stream); if (n & OBJSTREAM_ID) { int sysMax=SysIdNum(); n>>=1; if (nids[n-sysMax]; return FALSE; } /* must read value */ streamFirstVal=n>>2; if (n & OBJSTREAM_DEFVALID) { void** e=&_ListApp(&stream->ids); *e=NULL; *val=e; } else *val=NULL; return TRUE; } CLASSoDICT objMapIndex = { (ValComparer) ObjEqual, (ValHasher) ObjHash, (KeyAccessor) MapEntryToKey, NULL, FALSE }; CLASSoDICT strMapIndex = { (ValComparer) StrEqual, (ValHasher) StrHash, (KeyAccessor) MapEntryToKey, NULL, FALSE }; CLASSoDICT ptrMapIndex = { (ValComparer) PtrEqual, (ValHasher) PtrHash, (KeyAccessor) MapEntryToKey, NULL, FALSE }; OBJpStream ObjStreamOpen(char* fileName,char* mode) { OBJpStream os; os=typeAlloc(OBJoStream); os->ptrs=DictCreate(&ptrMapIndex); os->strs=DictCreate(&strMapIndex); os->objs=DictCreate(&objMapIndex); os->file=fopen(fileName, mode); os->idLast=SysIdNum(); os->ids=_ListNew(10,void*); return os; } void ObjStreamClose(OBJpStream os) { /* frees elements of ptr map, removing from pos map */ DICTv map; Iter i; MapEntry* e; map=os->ptrs; for (i=DictFirst(map); i; DictNext(map,&i)) { e=DictIn(i, MapEntry*); _pfree(e); } DictDestroy(map); map=os->strs; for (i=DictFirst(map); i; DictNext(map,&i)) { e=DictIn(i, MapEntry*); _pfree(e); } DictDestroy(map); map=os->objs; for (i=DictFirst(map); i; DictNext(map,&i)) { e=DictIn(i, MapEntry*); _pfree(e); } DictDestroy(map); ListDel(os->ids); fclose(os->file); free (os); } /****************************************************** ** ATTRIBUTE MAPPING ACTION ******************************************************/ typedef void (*ValMapper)(void* val, OBJpStream s); void AttrMapAction(void* val, ATTRv* attr, void* stream); void PtrMap(PTR* val, OBJpStream s) { ObjStreamMapDef(&s->ptrs, *val); } void StrMap(STRv* val, OBJpStream stream) { if (*val && StrShared(*val)) { STRv s=(STRv)ObjStreamMapDef(&stream->strs, *val); if (s) StrSet(val, s); } } void ObjMap(void** val, OBJpStream stream) { if (*val && SysToId(*val)==-1) { void* o; CLASSv descr=ObjClass(*val); ObjMap(&descr,stream); ObjDoAll(*val, AttrMapAction, stream); o=ObjStreamMapDef(&stream->objs, *val); if (o) ObjSet(val, o); } } void ClassMap(CLASSBODYv* val, OBJpStream stream) { ObjMap(&val->inherits, stream); } void AttrMap(ATTRv* val, OBJpStream stream) { StrMap(&val->name, stream); ObjMap(&val->more, stream); } void AttrMapAction(void* val, ATTRv* attr, void* stream) { static ValMapper mapOp[]={ (ValMapper) PolyNothing, (ValMapper) PtrMap, (ValMapper) StrMap, (ValMapper) ObjMap, (ValMapper) PolyNothing, (ValMapper) ClassMap, (ValMapper) AttrMap }; call (mapOp[attr->type])(val, (OBJpStream)stream); } /*************************************************** ** ATTRIBUTE STORING ACTION ***************************************************/ typedef (*ValStorer) (void* val, OBJpStream s); void PolyIntStore(int* v, OBJpStream stream) { IntStore(*v, stream); } void PolyPtrStore(PTR* v, OBJpStream stream) { ASSERT (!ObjStreamVal(stream, &stream->ptrs,*v), "StoringUnmappedPtr"); } void PolyStrStore(STRv* v, OBJpStream stream) { StrStore(*v, stream); } void PolyObjStore(void** obj, OBJpStream stream) { ObjStore(*obj, stream); } void PolyAttrStore(ATTRv* attr, OBJpStream stream) { StrStore(attr->name, stream); IntStore(attr->type, stream); ObjStore(attr->more, stream); } void AttrStoreAction(void* val, ATTRp attr, void* stream) { static ValStorer storeOp[]={ (ValStorer) PolyIntStore, (ValStorer) PolyPtrStore, (ValStorer) PolyStrStore, (ValStorer) PolyObjStore, (ValStorer) PolyNothing, (ValStorer) PolyNothing, (ValStorer) PolyAttrStore }; call (storeOp[attr->type])(val, (OBJpStream) stream); } /**************************************************** ** STORING FUNCTIONS */ void IntStore(int i, OBJpStream stream) { int n; char* b=MIFromLong(i, &n); fwrite(b, 1, n, stream->file); } void StrStore(STRv s, OBJpStream stream) { if (ObjStreamVal(stream, &stream->strs, s)) { int len=StrLen(s); ObjStreamHead(stream, len); fwrite(Str(s), 1, len, stream->file); } } void ClassStore(CLASSv c, OBJpStream stream) { if (ObjStreamVal(stream, &stream->objs, c)) { ATTRv *a,*fixed; int nAttr; fixed=c->fixed; a=c->attrs; nAttr=fixed-a; ObjStreamHead(stream, nAttr); /* save class value */ ClassStore(c->inherits, stream); while (a!=fixed) { /* save attribute name and type name */ StrStore(a->name, stream); IntStore(a->type, stream); a++; } /* save type of fixed, not null if list */ IntStore(fixed->type, stream); } } void ObjStore(void* obj, OBJpStream stream) { if (ObjStreamVal(stream, &stream->objs, obj)) { int nElem; ObjMap(&obj,stream); nElem=ObjListCard(obj); ObjStreamHead(stream, nElem); ClassStore(_getObj(obj)->descr, stream); ObjDoAll(obj, AttrStoreAction, stream); } } /*************************************************************** ** ATTRIBUTE LOADING ACTION ***************************************************************/ typedef (*ValLoader) (void* val, OBJpStream s); void PolyIntLoad(int* v, OBJpStream stream) { *v=IntLoad(stream); } void PolyPtrLoad(PTR* v, OBJpStream stream) { ASSERT(!ObjStreamGetVal(stream,v), "StreamUnmappedPtr"); } void PolyStrLoad(STRv* v, OBJpStream stream) { *v=StrLoad(stream); } void PolyObjLoad(void** obj, OBJpStream stream) { *obj=ObjLoad(stream); } void PolyAttrLoad(ATTRv* attr, OBJpStream stream) { attr->name=StrLoad(stream); attr->type=IntLoad(stream); attr->more=ObjLoad(stream); } void AttrLoadAction(void* val, ATTRp attr, void* stream) { static ValLoader loadOp[]={ (ValLoader) PolyIntLoad, (ValLoader) PolyPtrLoad, (ValLoader) PolyStrLoad, (ValLoader) PolyObjLoad, (ValLoader) PolyNothing, (ValLoader) PolyNothing, (ValLoader) PolyAttrLoad }; call (loadOp[attr->type])(val, (OBJpStream) stream); } int IntLoad(OBJpStream stream) { int n; char buf[8]; buf[0]=getc(stream->file); n=MIToLongSize(buf[0]); fread(buf+1, 1, n-1, stream->file); return MIToLong(buf); } STRv StrLoad(OBJpStream stream) { void* val; if (ObjStreamGetVal(stream, &val)) { UINT4 len=streamFirstVal; STRv s=StrBufNew(len); s->len=len; fread(Str(s), 1, len, stream->file); Str(s)[len]='\0'; if (val) *((STRv**)val)=s; return s; } else return StrCpy((STRv)val); } CLASSv ClassLoad(OBJpStream stream) { void* val; if (ObjStreamGetVal(stream, &val)) { int nAttr=streamFirstVal; int type; CLASSv c=ClassLoad(stream); /* loads base class */ while (nAttr--) { STRv attrName=StrLoad(stream); type=IntLoad(stream); ClassAttrNew(&c, attrName, type, NULL); } type=IntLoad(stream); if (type!=-1) ClassListNew(&c, type, NULL); if (val) *((CLASSv**)val)=c; return c; } else return ObjCpy((CLASSv)val); } void* ObjLoad(OBJpStream stream) { void* val; if (ObjStreamGetVal(stream, &val)) { void* o; int numElem=streamFirstVal; CLASSv c=ClassLoad(stream); o=ClassAlloc(c, numElem); ObjDoAll(o, AttrLoadAction, stream); if (val) *((void**)val)=o; return o; } else return ObjCpy(val); } stream); ClassAttrNew(&c, attrName, tsrs/src/objstream.h /* storing/loading */ OBJpStream ObjStreamOpen(char* fileName, char* mode); void ObjStreamClose(OBJpStream stream); void ObjStore(void* obj, OBJpStream stream); void* ObjLoad(OBJpStream stream); void StrStore(STRv s, OBJpStream stream); STRv StrLoad(OBJpStream stream); void IntStore(int i, OBJpStream stream); int IntLoad(OBJpStream stream); *)val)=o; return o;@ else return ObjCpy(val); } stream); ClassAttrNew\e, tsrs/src/odd.c char readsdl_srs_ID[] = "$Id: odd.c,v 1.1 1996/05/06 15:17:00 srs Exp $"; /* ** ** $RCSfile: odd.c,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:17:00 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.x Copyright by Thure Etzold ** Unix port: Lukas Rosenthaler and Reinhard Doelz ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** Requires: ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include "message.h" #include "futil.h" #include "sm.h" #include "parser.h" #include "arglist.h" #include "par.h" #include "sdl.h" #define _INITOBJS #define _CONSTANTS #define _SDL #define _ODD #define _FUNCTION #include "sdl_def.h" /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** object wide variables */ PRSoST *gblst_s; main(int argc, char **argv) { SDLo *odd; char infil[FILxXNAM+1], outfil[FILxXNAM+1]; int opt1, opt2; #ifndef BOOTSTRAP void **o_p; int *o_n; #endif /* ** process command line options */ ParSetTable ("global", NULL, "PRIVATE"); ParInit (ODD_parTable); argc = ArgGet (&argList[0], argc, argv); if (argc != 2) { /* process command line options */ ArgUsage (argList); exit (1); } if (ParGetBool ("doInitHeader")) opt1 = SDLxNOHDR, opt2 = SDLxHDR; else if (ParGetBool ("doMetaData")) opt1 = SDLxHDR; else if (ParGetBool ("doSection") && ParGetBool ("doHeader")) opt1 = SDLxPRESEC, opt2 = SDLxHDRSEC; else if (ParGetBool ("doSection")) opt1 = SDLxNOHDR, opt2 = SDLxSECTION; else if (ParGetBool ("doHeader")) opt1 = SDLxNOHDR, opt2 = SDLxHDR2; else if (ParGetBool ("doClassInfo")) opt1 = SDLxNOHDR, opt2 = SDLxHDR2; else exit (0); #ifndef BOOTSTRAP # ifdef VMS SdlGetObjects (&o_n, &o_p, "SDL"); # else SdlGetObjects (&o_n, &o_p, "sdl"); # endif odd = (SDLo *) o_p[O_SDL]; #else odd = (&def[0]); #endif sprintf(infil, "SRSSDL:%s_def.sdl", argv[1]); sprintf(outfil, "SRSSOU:%s_def.h", argv[1]); odd->ifnam = &infil[0]; odd->ofnam = &outfil[0]; SdlProc(odd, opt1); if (opt1 == SDLxHDR) exit(0); odd = (SDLo *) odd->oc[odd->oc_n-1].s; SdlProc(odd, opt2); exit (0); } HDR2; else exit (0); #ifndef BOOTSTRAP # ifdef VMS SdlGetObjects (&o_n, &o_p, "SDL"); # else SdlGetObjects (&o_n, &o_p, "sdl"); # endif odd = (SDLo *) o_p[O_SDL]; #else odd = (&def[0]); #endif sprintf(infil, "SRSSDL:%s_def.sdl", argv[1]); sprintf(outfil, "SRSSOU:%s_def.h", argv[1]); odd->ifnam = &infil[0]; odd->ofnam = &outfil[0]; SdlProc(odd, opt1); if (optsrs/src/odd.h ** ** $RCSfile: odd.h,v $ ** $Revision: 1.6 $ ** $Date: 1997/03/12 19:07:38 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** SRS V3.x Copyright by Thure Etzold ** */ #define SDLxXSS 7 /* max nr of substrt a strct may have */ #define SDLxXNAM 15 /* maxlen of names in definition file */ #define SDLxXLN 512 /* max line len in definition file */ #define SDLxXHLN 79 /* max line len in header file */ #define SDLxXLOG 2000 /* max nr. of logicals */ #define SDLxXSYM 5000 /* max nr. of symbols per table */ #define SDLxXLSYM 132 /* max size of symbol */ #define SDLxXSYMTBL 100000 /* max size of symbol table */ #define SDLxXLOGTBL 30000 /* max size of table for logicals */ #define SDLxXASSGSTR 132 /* max length of string assignement */ #define SDLxXADDR 40000 /* max length of string assignement */ #define SDLxXOBJCLASS 255 #define SDLxXOBJ 2048 /* max nr. of objects per class */ #define SDLxXFNCT 200 /* max nr. of transm. functions */ #define SDLxNULLFNCT 10000 #define ODDxNULL 4294967295U enum ODDeAct {SDLxNOHDR, SDLxHDR, SDLxHDR2, SDLxSECTION,SDLxPRESEC,SDLxHDRSEC}; #define SDLxRD 1 /* ATTRIBUTE read */ #define SDLxNORD 2 /* ATTRIBUTE not yet read */ #define SDLxREQ 1 /* ATTRIBUTE is required */ #define SDLxNOREQ 0 /* ATTRIBUTE is not required */ #define SDLxDFLT 1 #define SDLxNODFLT 2 #define SDLxPNUM 9 #define SDLxFNCT 11 /* object type */ #define SDLxPFNCT 10 #define SDLxCLONE 20 #define SDLxOVERLAY 18 #define SDLxDEFER 16 #define SDLxBNF 21 #define SDLxVIRTUAL 1 #define SDLxGTYPDEFNAM "GenTypeDef" #define SDLxGTYPNAM "GenType" /* lm bit on: turns bit off + TRUE */ #define _SdlIsStr(x) (x != (x & SDLxLBOFF)) ? (x = x & SDLxLBOFF) : 0 #define _SdlMarkStr(x) x |= SDLxLBON /* turn leftmost bit on */ #define __SdlAddr(addr) { if (odd->section_f) SdlListAddr (addr); } #define _SdlMalloc(n) \ ((odd->section_f) ? SdlMalloc (n) : (void *) malloc (n)) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** macros for alignment */ #if defined (VMS) || defined (dos) # define ALI4 1 # define ALI8 1 #else #if defined (osf) /* columba!!!! || defined (irix64) */ # define ALI4 4 # define ALI8 8 #else # define ALI4 4 # define ALI8 4 #endif #endif #define _SdlAlignFour(off) (off) = (((off) + (ALI4-1))/ALI4)*ALI4 #define _SdlAlignEight(off) (off) = (((off) + (ALI8-1))/ALI8)*ALI8 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** pointer into the data structure built by ODD */ typedef char *SDLoPTR; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** holds pointers to addresses of both function name and argument list */ typedef struct { char **nam; char **args; char **module; char isDone; } ODDoFNCT_P; typedef struct ODDoCDEFINE { char name[80]; INT4 n; } ODDoCDEFINE; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of exported functions */ #ifndef _SDL typedef struct SDLo *dummytointroducestructtagSDLo; #endif #ifndef _ODDoHEAD typedef struct ODDoHEAD *dummytointroducestructtagODDoHEAD; #endif #ifndef _SDLoOBJ typedef struct SDLoOBJ *dummytointroducestructtagSDLoOBJ; #endif #ifndef _SDLoATTR typedef struct SDLoATTR *dummytointroducestructtagSDLoATTR; #endif void *SdlMalloc (int n); int SdlListAddr (SDLoPTR a); int SdlSaveAddr (struct SDLoOBJ *obj, SDLoPTR uobj); int SdlGenericNames (struct SDLoOBJ *obj, int typ, char *typ_nm); int SdlCheckPar (struct SDLoATTR *attr, char *s, int v); struct SDLo *OddInit (struct SDLo *oddBase, INT4 level); struct SDLoOBJ *OddGetClass (char *className); void *OddFinishObj (struct SDLoOBJ *class); void OddWriteClassInfo (struct SDLo *odd); char *OddGetClassName (struct SDLoOBJ *class); void *OddGetObjectPtr (struct SDLoOBJ *class, Int4 n); Int4 OddGetObjectN (struct SDLoOBJ *class); void OddSetObjListSize (struct SDLoOBJ *class, char *attrName, Int4 n); char *OddGetAttrDeclName (struct SDLoATTR *attr); char *OddGetClassDeclName (struct SDLoOBJ *class); struct SDLoATTR *OddGetAttribute (struct SDLoOBJ *class, char *name); struct SDLoOBJ *OddGetPartofClass (struct SDLoATTR *attr); SDLoOBJ *class); void OddWriteClassInfo (struct SDLo *odd); char *OddGetClassName (struct SDsrs/src/oddclass.h ** ** $RCSfile: oddclass.h,v $ ** $Revision: 1.4 $ ** $Date: 1997/03/03 18:20:43 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** from ODD file: "srsica:odd.i" ** date of ODD compilation: 16-SEP-1996 10:14 ** */ #define AT_CHILD 6 #define AT_PROTOFNCT 10 #define AT_FNCT 11 #define AT_CLONE 20 #if defined(_SDL) && !defined(_ODDoVAL) #define _ODDoVAL typedef struct ODDoVAL { char *nam; UINT4 val; } ODDoVAL; #endif #if defined(_SDL) && !defined(_ODDoATYP) #define _ODDoATYP typedef struct ODDoATYP { INT4 (*make) (); INT4 (*insert) (); INT4 (*size) (); INT4 (*write) (); INT4 (*declare) (); INT4 (*check) (); INT4 (*gentype) (); unsigned char save_f; char *tnam; } ODDoATYP; #endif #if defined(_SDL) && !defined(_SDLoATTR) #define _SDLoATTR typedef struct SDLoATTR { char *rem; struct SDLoOBJ *class; struct ODDoVAL *val; INT4 val_n; char *nam; char *tnam; char *sw_nm; char *alt_nm; char *dnam; INT4 unnamed; unsigned char typ; unsigned char ptyp[4]; INT4 arrsz; INT4 min; INT4 max; INT4 off; unsigned char req; unsigned char status[2]; unsigned char isrd; INT4 dfltv; char *dflts; float dfltvf; INT4 scnt; struct SDLoOBJ *obj; INT4 hasObjsN; void *hasFirstObj; } SDLoATTR; #endif #if defined(_SDL) && !defined(_SDLoOBJ) #define _SDLoOBJ typedef struct SDLoOBJ { char *nam; char *rem; char *tnam; char *pp_nm; char *dnam; unsigned char typ; unsigned char status[2]; INT4 siz; char *s; INT4 ns; char *uobj_coff; INT4 gbl_n; INT4 loc_n; unsigned char nss; unsigned char ss[7]; INT4 np; struct SDLoATTR *p; INT4 gtyp_n; char *gtypdef_nm[7]; char *gtyp_nm[7]; char *orgtyp_nm; } SDLoOBJ; #endif #if defined(_SDL) && !defined(_SDLo) #define _SDLo typedef struct SDLo { char *ifnam; char *ofnam; char *sec_nm; INT4 sec_z; INT4 oc_n; struct SDLoOBJ *oc; INT4 at_n; struct ODDoATYP *at; unsigned char error; unsigned char action; unsigned char pass_n; unsigned char keepst_f; unsigned char section_f; } SDLo; #endif #ifndef _PARo #define _PARo typedef struct PARo { char *intern; /* for internal use for the list manager */ INT4 classId; /* for internal use for the list manager */ char *name; /* name of associated global parameter */ char *str; /* Value of 'string' parameter. */ INT4 num; /* Value of 'number' parameter. */ float real; /* Value of 'real' parameter. */ INT4 (*function) (); /* Value of 'function' parameter. */ void *object; /* Value of 'object' parameter. */ unsigned char isVolatile; unsigned char type; /* Parameter type. */ char *comment; /* Short description of parameter. */ char *helpTopic; /* help topic associated to parameter */ char *key; /* keystroke associated to parameter or value */ struct PARoTYPE *parType; /* Object 'partype' for validating the parameter value. */ struct PARoTYPE *check; /* Object 'partype' for validating the parameter value. */ INT4 isLocked; /* internal use... */ char *set; /* Icarus command to set the current value. */ char *get; /* Icarus command to get the current value. */ } PARo; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Describes further a parameter type by specifying constraints or a function for checking the parameter value. */ #ifndef _PARoTYPE #define _PARoTYPE typedef struct PARoTYPE { char *intern; /* for internal use for the list manager */ INT4 classId; /* for internal use for the list manager */ char *name; /* Name of associated global parameter. */ INT4 (*check) (); /* Function that checks parameter value. */ INT4 max; /* Max value, or max length. */ INT4 min; /* Mmin value, or min length. */ float maxReal; /* Max real value. */ float minReal; /* Min real value. */ char *charSet; /* Permissible set of chars for parameter value string. */ } PARoTYPE; #endif #ifndef _PARoLIST #define _PARoLIST typedef struct PARoLIST { struct PARo *par; /* List of all predefined parameters. */ INT4 parN; /* Number of predefined parameters. */ struct PARoTYPE *parType; /* List of all predefined parameter types. */ INT4 parTypeN; /* Number of predefined parameter types. */ } PARoLIST; #endif #ifndef _arg_t #define _arg_t typedef struct arg_t { char *name; INT4 type; char *parameter; char *comment; INT4 (*check) (); INT4 defaultNum; char *defaultStr; float defaultReal; } arg_t; #endif #ifndef _ARGoLIST #define _ARGoLIST typedef struct ARGoLIST { char *name; char *usage; struct arg_t *arg; INT4 argN; } ARGoLIST; #endif #ifdef _FUNCTION #undef _FUNCTION INT4 OFInheritSize (SDLoOBJ *, SDLoATTR *); #define OFInheritSize_F (INT4(*)()) OFInheritSize INT4 OF4BArrSize (SDLoOBJ *, SDLoATTR *); #define OF4BArrSize_F (INT4(*)()) OF4BArrSize INT4 OF4BSize (SDLoOBJ *, SDLoATTR *); #define OF4BSize_F (INT4(*)()) OF4BSize INT4 OFPtrArrSize (SDLoOBJ *, SDLoATTR *); #define OFPtrArrSize_F (INT4(*)()) OFPtrArrSize INT4 OFPtrSize (SDLoOBJ *, SDLoATTR *); #define OFPtrSize_F (INT4(*)()) OFPtrSize INT4 OFBNFSize (SDLoOBJ *, SDLoATTR *); #define OFBNFSize_F (INT4(*)()) OFBNFSize INT4 OFBArrSize (SDLoOBJ *, SDLoATTR *); #define OFBArrSize_F (INT4(*)()) OFBArrSize INT4 OFMakeDefault (SDLoOBJ *, SDLoATTR *, unsigned int *); #define OFMakeDefault_F (INT4(*)()) OFMakeDefault INT4 OFMakeNoDefault (SDLoOBJ *, SDLoATTR *, unsigned int *); #define OFMakeNoDefault_F (INT4(*)()) OFMakeNoDefault INT4 OFMakeChild (SDLoOBJ *, SDLoATTR *, unsigned int *); #define OFMakeChild_F (INT4(*)()) OFMakeChild INT4 OFMakeChildN (SDLoOBJ *, SDLoATTR *, unsigned int *); #define OFMakeChildN_F (INT4(*)()) OFMakeChildN INT4 OFMakeAllObj (SDLoOBJ *, SDLoATTR *, unsigned int *); #define OFMakeAllObj_F (INT4(*)()) OFMakeAllObj INT4 OFMakeAllObjN (SDLoOBJ *, SDLoATTR *, unsigned int *); #define OFMakeAllObjN_F (INT4(*)()) OFMakeAllObjN INT4 OFDefSimple (FILE *, SDLoATTR *, char *, char *); #define OFDefSimple_F (INT4(*)()) OFDefSimple INT4 OFDefStr (FILE *, SDLoATTR *, char *, char *); #define OFDefStr_F (INT4(*)()) OFDefStr INT4 OFDefFnct (FILE *, SDLoATTR *, char *, char *); #define OFDefFnct_F (INT4(*)()) OFDefFnct INT4 OFDefHeader (FILE *, SDLoATTR *, char *, char *); #define OFDefHeader_F (INT4(*)()) OFDefHeader INT4 OFDefStructPtr (FILE *, SDLoATTR *, char *, char *); #define OFDefStructPtr_F (INT4(*)()) OFDefStructPtr INT4 OFDefGenericTyp (FILE *, SDLoATTR *, char *, char *); #define OFDefGenericTyp_F (INT4(*)()) OFDefGenericTyp INT4 OFDefUser (FILE *, SDLoATTR *, char *, char *); #define OFDefUser_F (INT4(*)()) OFDefUser INT4 OFDefEbnf (FILE *, SDLoATTR *, char *, char *); #define OFDefEbnf_F (INT4(*)()) OFDefEbnf INT4 OFInsertFloat (void *, void *, void *, void ***, char *, unsigned int, int); #define OFInsertFloat_F (INT4(*)()) OFInsertFloat INT4 OFInsertInt (void *, void *, void *, void ***, char *, unsigned int, int); #define OFInsertInt_F (INT4(*)()) OFInsertInt INT4 OFInsertUInt (void *, void *, void *, void ***, char *, unsigned int, int); #define OFInsertUInt_F (INT4(*)()) OFInsertUInt INT4 OFInsertUChar (void *, void *, void *, void ***, char *, unsigned int, int); #define OFInsertUChar_F (INT4(*)()) OFInsertUChar INT4 OFInsertUser (void *, void *, void *, void ***, char *, unsigned int, int); #define OFInsertUser_F (INT4(*)()) OFInsertUser INT4 OFInsertStr (void *, void *, void *, void ***, char *, unsigned int, int); #define OFInsertStr_F (INT4(*)()) OFInsertStr INT4 OFInsertFunction (void *, void *, void *, void ***, char *, unsigned int, int); #define OFInsertFunction_F (INT4(*)()) OFInsertFunction INT4 OFInsertObject (void *, void *, void *, void ***, char *, unsigned int, int); #define OFInsertObject_F (INT4(*)()) OFInsertObject INT4 OFInsertHeader (void *, void *, void *, void ***, char *, unsigned int, int); #define OFInsertHeader_F (INT4(*)()) OFInsertHeader INT4 OFInherit (void *, void *, void *, void ***, char *, unsigned int, int); #define OFInherit_F (INT4(*)()) OFInherit INT4 OFGeneric (void *, void *, void *, void ***, char *, unsigned int, int); #define OFGeneric_F (INT4(*)()) OFGeneric INT4 OFWrtInt (SDLoATTR *, char *, void **); #define OFWrtInt_F (INT4(*)()) OFWrtInt INT4 OFWrtUChar (SDLoATTR *, char *, void **); #define OFWrtUChar_F (INT4(*)()) OFWrtUChar INT4 OFWrtUInt (SDLoATTR *, char *, void **); #define OFWrtUInt_F (INT4(*)()) OFWrtUInt INT4 OFWrtFloat (SDLoATTR *, char *, void **); #define OFWrtFloat_F (INT4(*)()) OFWrtFloat INT4 OFWrtStr (SDLoATTR *, char *, void **); #define OFWrtStr_F (INT4(*)()) OFWrtStr INT4 OFWrtName (SDLoATTR *, char *, void **); #define OFWrtName_F (INT4(*)()) OFWrtName INT4 OFWrtNULL (SDLoATTR *, char *, void **); #define OFWrtNULL_F (INT4(*)()) OFWrtNULL INT4 OFWrtAddr (SDLoATTR *, char *, void **); #define OFWrtAddr_F (INT4(*)()) OFWrtAddr INT4 OFWrtEBNF (SDLoATTR *, char *, void **); #define OFWrtEBNF_F (INT4(*)()) OFWrtEBNF INT4 OFCheckNum (SDLoATTR *, int, char *); #define OFCheckNum_F (INT4(*)()) OFCheckNum INT4 OFCheckStr (SDLoATTR *, int, char *); #define OFCheckStr_F (INT4(*)()) OFCheckStr INT4 OFGenSimple (SDLoOBJ *, SDLoATTR *); #define OFGenSimple_F (INT4(*)()) OFGenSimple INT4 OFGenObject (SDLoOBJ *, SDLoATTR *); #define OFGenObject_F (INT4(*)()) OFGenObject typedef INT4 (*SDLoFNCT)(); SDLoFNCT SDL_fnct[] = { OFInheritSize_F, OF4BArrSize_F, OF4BSize_F, OFPtrArrSize_F, OFPtrSize_F, OFBNFSize_F, OFBArrSize_F, OFMakeDefault_F, OFMakeNoDefault_F, OFMakeChild_F, OFMakeChildN_F, OFMakeAllObj_F, OFMakeAllObjN_F, OFDefSimple_F, OFDefStr_F, OFDefFnct_F, OFDefHeader_F, OFDefStructPtr_F, OFDefGenericTyp_F, OFDefUser_F, OFDefEbnf_F, OFInsertFloat_F, OFInsertInt_F, OFInsertUInt_F, OFInsertUChar_F, OFInsertUser_F, OFInsertStr_F, OFInsertFunction_F, OFInsertObject_F, OFInsertHeader_F, OFInherit_F, OFGeneric_F, OFWrtInt_F, OFWrtUChar_F, OFWrtUInt_F, OFWrtFloat_F, OFWrtStr_F, OFWrtName_F, OFWrtNULL_F, OFWrtAddr_F, OFWrtEBNF_F, OFCheckNum_F, OFCheckStr_F, OFGenSimple_F, OFGenObject_F }; #endif #ifdef _INITOBJS ODDoVAL defval[] = { {"y", 1}, {"n", 0}, {"y", 1}, {"n", 0}, {"int", 1}, {"string", 2}, {"strv", 9}, {"object", 3}, {"real", 4}, {"var", 6}, {"list", 16}, {"n", 0}, {"y", 1}, {"int", 1}, {"string", 2}, {"strv", 9}, {"object", 3}, {"real", 4}, {"var", 6}, {"list", 16}, {"init", 2}, {"pre", 4}, {"initpre", 6}, {"post", 8}, {"prepost", 12}, {"direct", 1}, {"interface", 0}, {"yes", 1}, {"no", 0}, {"y", 1}, {"n", 0}, {"int", 2}, {"uint", 3}, {"uchar", 1}, {"string", 4}, {"protofunction", 10}, {"function", 11}, {"child", 6}, {"nr_of_childs", 7}, {"object", 9}, {"clone", 20}, {"defer", 16}, {"inherit", 17}, {"user", 12}, {"float", 0}, {"allobjects", 5}, {"nr_of_objects", 8}, {"generic", 15}, {"generic_typ", 13}, {"generic_obj", 14}, {"overload", 18}, {"store", 19}, {"bnf", 21}, {"num", 9}, {"name", 10}, {"text", 11}, {"constant", 12}, {"y", 1}, {"n", 0}, {"obsolete", 1}, {"system", 2}, {"api", 3}, {"obsolete", 1}, {"system", 2}, {"api", 3} }; ODDoATYP defatyp[] = { {OFMakeDefault, OFInsertFloat, OF4BArrSize, OFWrtFloat, OFDefSimple, OFCheckNum, OFGenSimple, 0, "float"}, {OFMakeDefault, OFInsertUChar, OFBArrSize, OFWrtUChar, OFDefSimple, OFCheckNum, NULL, 0, "unsigned char"}, {OFMakeDefault, OFInsertInt, OF4BArrSize, OFWrtInt, OFDefSimple, OFCheckNum, OFGenSimple, 0, "INT4"}, {OFMakeDefault, OFInsertUInt, OF4BArrSize, OFWrtUInt, OFDefSimple, OFCheckNum, NULL, 0, "UINT4"}, {OFMakeDefault, OFInsertStr, OFPtrArrSize, OFWrtStr, OFDefStr, OFCheckStr, OFGenSimple, 1, "char"}, {OFMakeAllObj, NULL, OFPtrSize, OFWrtAddr, OFDefStructPtr, NULL, NULL, 1, ""}, {OFMakeChild, NULL, OFPtrSize, OFWrtAddr, OFDefStructPtr, NULL, NULL, 1, ""}, {OFMakeChildN, NULL, OF4BSize, OFWrtInt, OFDefSimple, NULL, NULL, 0, "INT4"}, {OFMakeAllObjN, NULL, OF4BSize, OFWrtInt, OFDefSimple, NULL, NULL, 0, "INT4"}, {OFMakeDefault, OFInsertObject, OFPtrArrSize, OFWrtAddr, OFDefStructPtr, NULL, OFGenObject, 1, ""}, {OFMakeNoDefault, OFInsertStr, OFPtrSize, OFWrtName, NULL, OFCheckStr, NULL, 0, ""}, {OFMakeDefault, OFInsertFunction, OFPtrSize, OFWrtName, OFDefFnct, NULL, NULL, 1, ""}, {OFMakeDefault, OFInsertUser, OFPtrArrSize, OFWrtNULL, OFDefUser, NULL, NULL, 1, ""}, {NULL, OFGeneric, NULL, NULL, NULL, NULL, NULL, 0, ""}, {NULL, OFGeneric, NULL, NULL, NULL, NULL, NULL, 0, ""}, {NULL, NULL, OFPtrArrSize, NULL, OFDefGenericTyp, NULL, NULL, 1, ""}, {NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, ""}, {OFMakeNoDefault, OFInherit, OFInheritSize, NULL, NULL, NULL, NULL, 0, ""}, {NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, ""}, {OFMakeDefault, OFInsertHeader, OFPtrArrSize, OFWrtNULL, OFDefHeader, NULL, NULL, 1, ""}, {OFMakeDefault, OFInsertObject, OFPtrArrSize, NULL, OFDefStructPtr, NULL, NULL, 1, ""}, {NULL, NULL, OFBNFSize, OFWrtEBNF, OFDefEbnf, NULL, NULL, 0, ""} }; SDLoATTR defpar[] = { {"", NULL, &defval[0], 0, "name", "", "", "", "fnctnam", 0, 10, 11, 11, 11, 11, 1, -1000000000, 30, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[0], 0, "args", "", "", "", "args", 0, 4, 11, 11, 11, 11, 1, -1000000000, 132, 0, 1, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[0], 0, "module", "", "", "", "module", 0, 4, 11, 10, 10, 10, 1, -1000000000, 30, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"Name of value.", NULL, &defval[0], 0, "name", "", "", "", "name", 1, 4, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 1, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"Number value.", NULL, &defval[0], 0, "n", "", "", "", "n", 0, 2, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 1, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"Comment field.", NULL, &defval[0], 0, "rem", "", "", "", "rem", 0, 4, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"Name of the argument in an Icarus program.", NULL, &defval[0], 0, "name", "", "", "", "name", 1, 4, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"Comment field.", NULL, &defval[0], 0, "rem", "", "", "", "rem", 0, 4, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"Defines if parameter may be unnamed.", NULL, &defval[0], 2, "unnamed", "", "", "", "isUnnamed", 0, 1, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"Defines if parameter is required.", NULL, &defval[2], 2, "required", "", "", "", "isRequired", 0, 1, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"Type of the argument", NULL, &defval[4], 7, "t", "", "", "", "type", 0, 1, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 2, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[11], 0, "class", "", "", "", "className", 0, 4, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"Default value of type 'int' arguments.", NULL, &defval[11], 0, "defInt", "", "", "", "defInt", 0, 2, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"Default value of type 'string' arguments.", NULL, &defval[11], 0, "defStr", "", "", "", "defaultStr", 0, 4, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[11], 0, "enum", "", "", "", "vals", 0, 6, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 1, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[11], 0, "", "", "", "", "valsN", 0, 7, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 1, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[11], 0, "", "", "", "", "isSet", 0, 1, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[11], 0, "", "struct VARo", "", "", "*val", 0, 12, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"Name of command in Icarus programs.", NULL, &defval[11], 0, "name", "", "", "", "name", 1, 4, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 1, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"C function that implements the command.", NULL, &defval[11], 0, "f", "", "", "", "functionName", 0, 4, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"Determines whether the command should appear in the \nIcarus functions reference list.\n", NULL, &defval[11], 2, "show", "", "", "", "isShow", 0, 2, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"Comment field.", NULL, &defval[13], 0, "rem", "", "", "", "rem", 0, 4, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"Type of value to be returned (if any).", NULL, &defval[13], 7, "return", "", "", "", "returnType", 0, 1, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 2, "", 0.000000, 0, NULL, -1, NULL}, {"Execution time of command.", NULL, &defval[20], 5, "time", "", "", "", "time", 0, 2, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 8, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[25], 0, "returnClass", "", "", "", "returnClass", 0, 4, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"Call function directly or via C-interface.", NULL, &defval[25], 2, "call", "", "", "", "isDirectCall", 0, 1, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"normal function.", NULL, &defval[27], 0, "methodOf", "", "", "", "methodOf", 0, 4, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[27], 0, "args", "", "", "", "args", 0, 6, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 2, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[27], 0, "", "", "", "", "argsN", 0, 7, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 2, "", 0.000000, 0, NULL, -1, NULL}, {"Function to be executed for command.", NULL, &defval[27], 0, "", "INT4", "", "", "(*function)()", 0, 12, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"Number of arguments ordered from C function (via 'IargGetArgs').", NULL, &defval[27], 0, "", "", "", "", "orderN", 0, 2, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"Number of orders currently allocated.", NULL, &defval[27], 0, "", "", "", "", "orderAllocN", 0, 2, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"Array with a list of argument orders.", NULL, &defval[27], 0, "", "struct IARGoVALUE", "", "", "**order", 0, 12, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[27], 0, "name", "", "", "", "nam", 1, 4, 10, 10, 10, 10, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[27], 0, "val", "", "", "", "val", 0, 3, 9, 12, 12, 12, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[27], 0, "make", "", "", "", "make", 0, 11, 12, 12, 12, 12, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "(struct SDLoOBJ *, struct SDLoATTR *, unsigned int *)", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[27], 0, "insert", "", "", "", "insert", 0, 11, 12, 12, 12, 12, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "(void *, void *, void *, void ***, char *, unsigned int,int)", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[27], 0, "calcsize", "", "", "", "size", 0, 11, 12, 12, 12, 12, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "(struct SDLoOBJ *, struct SDLoATTR *)", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[27], 0, "write", "", "", "", "write", 0, 11, 12, 12, 12, 12, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "(void)", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[27], 0, "declare", "", "", "", "declare", 0, 11, 12, 12, 12, 12, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "(FILE *, struct SDLoATTR *, char *, char *)", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[27], 0, "check", "", "", "", "check", 0, 11, 12, 12, 12, 12, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "(struct SDLoATTR *, int, char *)", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[27], 0, "gentype", "", "", "", "gentype", 0, 11, 12, 12, 12, 12, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "(struct SDLoOBJ *, struct SDLoATTR *)", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[27], 2, "save_address", "", "", "", "save_f", 0, 1, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[29], 0, "typname", "", "", "", "tnam", 0, 4, 0, 0, 0, 0, 1, -1000000000, 20, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[29], 0, "rem", "", "", "", "rem", 0, 4, 10, 11, 11, 11, 1, 0, 512, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[29], 0, "", "", "", "", "class", 0, 9, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 7, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[29], 0, "enum", "", "", "", "val", 0, 6, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 4, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[29], 0, "", "", "", "", "val_n", 0, 7, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 4, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[29], 0, "name", "", "", "", "nam", 1, 4, 10, 11, 11, 11, 1, 0, 25, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[29], 0, "typname", "", "", "", "tnam", 0, 4, 10, 11, 11, 11, 1, 0, 25, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[29], 0, "switchname", "", "", "", "sw_nm", 0, 4, 10, 11, 11, 11, 1, 0, 25, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[29], 0, "alttypname", "", "", "", "alt_nm", 0, 4, 10, 11, 11, 11, 1, 0, 25, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[29], 0, "declname", "", "", "", "dnam", 0, 4, 10, 11, 11, 11, 1, 0, 25, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[29], 2, "unnamed", "", "", "", "unnamed", 0, 2, 0, 0, 0, 0, 1, 0, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[31], 22, "type", "", "", "", "typ", 0, 1, 10, 10, 10, 10, 1, -1000000000, 1000000000, 0, 1, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[53], 4, "valtype", "", "", "", "ptyp", 0, 1, 10, 10, 10, 10, 4, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[57], 0, "repeat", "", "", "", "arrsz", 0, 2, 9, 12, 12, 12, 1, 1, 10000, 0, 0, 0, 0, 0, 1, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[57], 0, "min", "", "", "", "min", 0, 2, 9, 12, 12, 12, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, -1000000000, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[57], 0, "max", "", "", "", "max", 0, 2, 9, 12, 12, 12, 1, 0, 1000000000, 0, 0, 0, 0, 0, 1000000000, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[57], 0, "", "", "", "", "off", 0, 2, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[57], 2, "required", "", "", "", "req", 0, 1, 10, 10, 10, 10, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[59], 3, "status", "", "", "", "status", 0, 1, 10, 10, 10, 10, 2, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[62], 0, "", "", "", "", "isrd", 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[62], 0, "defaultval", "", "", "", "dfltv", 0, 2, 9, 12, 12, 12, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[62], 0, "defaultstr", "", "", "", "dflts", 0, 4, 10, 12, 11, 11, 1, 0, 132, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[62], 0, "defaultvalf", "", "", "", "dfltvf", 0, 0, 9, 9, 9, 9, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[62], 0, "", "", "", "", "scnt", 0, 2, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[62], 0, "objectclass", "", "", "", "obj", 0, 9, 12, 12, 12, 12, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 7, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[62], 0, "", "", "", "", "hasObjsN", 0, 2, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, -1, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[62], 0, "", "void", "", "", "*hasFirstObj", 0, 12, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[62], 0, "name", "", "", "", "nam", 1, 4, 10, 11, 11, 11, 1, 0, 25, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[62], 0, "rem", "", "", "", "rem", 0, 4, 10, 11, 11, 11, 1, 0, 512, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[62], 0, "typname", "", "", "", "tnam", 0, 4, 10, 11, 11, 11, 1, 0, 25, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[62], 0, "ppname", "", "", "", "pp_nm", 0, 4, 10, 11, 11, 11, 1, 0, 25, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[62], 0, "declname", "", "", "", "dnam", 0, 4, 10, 11, 11, 11, 1, 0, 25, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[62], 0, "type", "", "", "", "typ", 0, 1, 9, 12, 12, 12, 1, 0, 12, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[62], 3, "status", "", "", "", "status", 0, 1, 10, 10, 10, 10, 2, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "", "", "", "", "siz", 0, 2, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "", "", "", "", "s", 0, 4, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "", "", "", "", "ns", 0, 2, 0, 0, 0, 0, 1, 0, 10000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "", "", "", "", "uobj_coff", 0, 4, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "", "", "", "", "gbl_n", 0, 2, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "", "", "", "", "loc_n", 0, 2, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "nchilds", "", "", "", "nss", 0, 1, 9, 9, 9, 9, 1, -1000000000, 7, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "child", "", "", "", "ss", 0, 1, 12, 12, 12, 12, 7, 0, 255, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "", "", "", "", "np", 0, 7, 0, 0, 0, 0, 1, 1, 256, 0, 0, 0, 0, 0, 6, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "attrs", "SDLoATTR", "", "", "p", 0, 6, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 6, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "", "", "", "", "gtyp_n", 0, 2, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "", "", "", "", "gtypdef_nm", 0, 4, 0, 0, 0, 0, 7, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "", "", "", "", "gtyp_nm", 0, 4, 0, 0, 0, 0, 7, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "orgtypname", "", "", "", "orgtyp_nm", 0, 4, 11, 10, 10, 10, 1, -1000000000, 40, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "infile", "", "", "", "ifnam", 0, 4, 12, 11, 11, 11, 1, 1, 132, 0, 1, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "outfile", "", "", "", "ofnam", 0, 4, 12, 11, 11, 11, 1, 1, 132, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "section_name", "", "", "", "sec_nm", 0, 4, 10, 11, 11, 11, 1, 0, 50, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "section_size", "", "", "", "sec_z", 0, 2, 9, 9, 9, 9, 1, 1, 100000, 0, 0, 0, 0, 0, 1000, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "", "", "", "", "oc_n", 0, 8, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 7, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "", "", "", "", "oc", 0, 5, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 7, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "", "", "", "", "at_n", 0, 8, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 5, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "", "", "", "", "at", 0, 5, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 5, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "", "", "", "", "error", 0, 1, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "", "", "", "", "action", 0, 1, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "", "", "", "", "pass_n", 0, 1, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "", "", "", "", "keepst_f", 0, 1, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL}, {"", NULL, &defval[65], 0, "", "", "", "", "section_f", 0, 1, 0, 0, 0, 0, 1, -1000000000, 1000000000, 0, 0, 0, 0, 0, 0, "", 0.000000, 0, NULL, -1, NULL} }; SDLoOBJ defstrct[] = { {"function", "", "", "", "X", 11, 2, 2, 0, "", 0, "", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, &defpar[0], 0, "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""}, {"val", "Value in an enumeration", "ODDoVALUE", "", "ODDValue", 0, 0, 0, 0, "", 0, "", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, &defpar[3], 0, "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""}, {"var", "Argument of Icarus command.", "IARGoVALUE", "", "IARGVALUE", 0, 0, 0, 0, "", 0, "", 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 12, &defpar[6], 0, "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""}, {"com", "", "IARGoCOM", "", "IARGCOM", 0, 0, 0, 0, "", 0, "", 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 15, &defpar[18], 0, "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""}, {"value", "", "ODDoVAL", "SDL", "defval", 0, 0, 0, 0, "", 0, "", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, &defpar[33], 0, "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""}, {"attrtype", "", "ODDoATYP", "SDL", "defatyp", 0, 0, 0, 0, "", 0, "", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, &defpar[35], 0, "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""}, {"attribute", "", "SDLoATTR", "SDL", "defpar", 0, 0, 0, 0, "", 0, "", 0, 0, 2, 4, 6, 0, 0, 0, 0, 0, 26, &defpar[44], 0, "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""}, {"object", "", "SDLoOBJ", "SDL", "defstrct", 0, 0, 0, 0, "", 0, "", 0, 0, 1, 6, 0, 0, 0, 0, 0, 0, 21, &defpar[70], 0, "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""}, {"def", "", "SDLo", "SDL", "def", 0, 0, 0, 0, "", 0, "", 0, 0, 1, 7, 0, 0, 0, 0, 0, 0, 13, &defpar[91], 0, "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""} }; SDLo def[] = { {"SRSICA:sdl.sdl", "SRSSOU:odd5.h", "sdl", 50, 9, &defstrct[0], 22, &defatyp[0], 0, 0, 0, 0, 0} }; SDLo *oddObjs = &def[0]; PARo ODD_par[] = { {NULL, 0, "doInitHeader", "", 0, 0.000000, NULL, NULL, 0, 16, "h-file with struct declaration and initialization", "", "", NULL, NULL, 0, "", ""}, {NULL, 0, "doHeader", "", 0, 0.000000, NULL, NULL, 0, 16, "h-file with struct declaration", "", "", NULL, NULL, 0, "", ""}, {NULL, 0, "doSection", "", 0, 0.000000, NULL, NULL, 0, 16, "binary section file (can be combined with '-h')", "", "", NULL, NULL, 0, "", ""}, {NULL, 0, "doMetaData", "", 0, 0.000000, NULL, NULL, 0, 16, "h-file with meta data initialization", "", "", NULL, NULL, 0, "", ""}, {NULL, 0, "doClassInfo", "", 0, 0.000000, NULL, NULL, 0, 16, "file with class information", "", "", NULL, NULL, 0, "", ""}, {NULL, 0, "printProgress", "", 0, 0.000000, NULL, NULL, 0, 16, "print a line for each ODD-file read", "", "", NULL, NULL, 0, "", ""}, {NULL, 0, "printProgress", "", 0, 0.000000, NULL, NULL, 0, 16, "print a line for each ODD-file read", "", "", NULL, NULL, 0, "", ""}, {NULL, 0, "printDots", "", 0, 0.000000, NULL, NULL, 0, 16, "print a dot for each ODD-file read", "", "", NULL, NULL, 0, "", ""} }; PARoTYPE Odd_parType[] = { {NULL, 0, "boolean", NULL, 3, 0, 0.000000, 0.000000, "yYnN01oOfFjJ"} }; PARoLIST ODD_parTable[] = { {&ODD_par[0], 8, &Odd_parType[0], 1} }; arg_t args[] = { {"-help", 1, "", "this message", NULL, 0, "", 0.000000}, {"-i", 0, "doInitHeader", "", NULL, 0, "", 0.000000}, {"-h", 0, "doHeader", "", NULL, 0, "", 0.000000}, {"-s", 0, "doSection", "", NULL, 0, "", 0.000000}, {"-m", 0, "doMetaData", "", NULL, 0, "", 0.000000}, {"-c", 0, "doClassInfo", "", NULL, 0, "", 0.000000}, {"-r", 0, "printProgress", "", NULL, 0, "", 0.000000}, {"-d", 0, "printDots", "", NULL, 0, "", 0.000000} }; ARGoLIST argList[] = { {"odd", "sectionName", &args[0], 8} }; #endif his message", NULL, 0, "", 0.000000}, {"-i", 0, "doInitHeader", "", NULL, 0, "", 0.000000}, {"-h", 0, "doHeader", "", NULL, 0, "", 0.000000}, {"-s", 0, "doSection", "", NULL, 0, "", 0.000000}, {"-m", 0, "doMetaData", "", NULL, 0, "", 0.000000}, {"-c", 0, "doClassInfo", "", NULL, 0, "", 0.000000}, {"-r", 0, "printProgress", "", NULL, 0, "", 0.000000}, {"-d", 0, "printDots", "", NULL, 0, "", 0.000000} }; ARGoLIST argList[] = { {"odd", "sesrs/src/oddfncts.c char oddfncts_srs_ID[] = "$Id: oddfncts.c,v 1.3 1997/03/12 16:17:42 srs Exp $"; /* ** ** $RCSfile: oddfncts.c,v $ ** $Revision: 1.3 $ ** $Date: 1997/03/12 16:17:42 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** Copyright by Thure Etzold ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include "message.h" #include "sm.h" #include "futil.h" #include "sdl.h" #include "strv.h" #define _CONSTANTS #define _SDL #define _ODD #include "sdl_def.h" typedef int (*SDLoFNCT)(); INT4 OddIsAttr (SDLoATTR *attr, char *option); INT4 OddIsClass (SDLoOBJ *class, char *option); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** object wide variables */ extern SDLo *odd; extern SDLoFNCT SDL_fnct[]; extern ODDoFNCT_P function[SDLxXFNCT]; extern FILo *f; /****************************************************************************** ****** Group of functions calculating object size ***************************** ******************************************************************************* ** ** INPUT: address of parent object [R] ** address of attribute [R] ** address of offset within structure [W] ** IMPLICIT: ** odd (SDLo *) */ int OFInheritSize (SDLoOBJ *obj, SDLoATTR *attr, int *off) { #ifdef nhrt (obj->nhrt)[obj->nhrt_n] = &((odd->oc)[attr->dfltv]); (obj->nhrt_offp)[obj->nhrt_n] = &(attr->off); obj->nhrt_n++; #endif return 0; } int OF4BArrSize (SDLoOBJ *obj, SDLoATTR *attr, int *off) { _SdlAlignFour (*off); return 4 * attr->arrsz; } int OF4BSize (SDLoOBJ *obj, SDLoATTR *attr, int *off) { _SdlAlignFour (*off); return 4; } int OFPtrArrSize (SDLoOBJ *obj, SDLoATTR *attr, int *off) { _SdlAlignEight (*off); return (sizeof (char *) * attr->arrsz); } int OFPtrSize (SDLoOBJ *obj, SDLoATTR *attr, int *off) { _SdlAlignEight (*off); return sizeof (char *); } int OFBNFSize (SDLoOBJ *obj, SDLoATTR *attr, int *off) { _SdlAlignEight (*off); return (sizeof (char *) + sizeof (int)); } int OFBArrSize (SDLoOBJ *obj, SDLoATTR *attr, int *off) { return 1 * attr->arrsz; } /****************************************************************************** ****** group of functions for posprocesssing attributes *********************** ******************************************************************************* ** ** ** INPUT: address of parent object [R] ** address of attribute [R] ** address of header [W] ** address of current offset in target structure [W] ** IMPLICIT: ** odd (SDLo *) [R] ** ** RETURNS: e__parismiss + ** 1 */ int OFMakeDefault (SDLoOBJ *obj, SDLoATTR *attr, SDLoPTR *off) { int (*insert)(); int l, rv; if (!(attr->isrd)) { if (attr->req) _ErrRet (e__parismiss); else if ((insert = odd->at[attr->typ].insert) != NULL) for (l = 0; l < attr->arrsz; l++) { rv = (*insert) (obj, attr, attr, off, 0, ODDxNULL, TRUE); _ErrRet (rv); } } return 1; } int OFMakeNoDefault (SDLoOBJ *obj, SDLoATTR *attr, SDLoPTR *off) { if (!(attr->isrd)) _ErrRet (e__parismiss); return 1; } int OFMakeChildN (SDLoOBJ *obj, SDLoATTR *attr, SDLoPTR *off) { memcpy (*off, &((odd->oc)[attr->dfltv].loc_n), sizeof (int)); return 1; } int OFMakeAllObjN (SDLoOBJ *obj, SDLoATTR *attr, SDLoPTR *off) { memcpy (*(int **) off, &((odd->oc)[attr->dfltv].gbl_n), sizeof (int)); return 1; } int OFMakeChild (SDLoOBJ *obj, SDLoATTR *attr, SDLoPTR *off) { SDLoOBJ *referredClass; SDLoPTR tmp; int rv, fst_x, l, i; referredClass = &(odd->oc[attr->dfltv]); fst_x = referredClass->gbl_n - referredClass->loc_n; /* inx of first obj */ attr->dflts = &(referredClass->dnam[0]); attr->tnam = &(referredClass->tnam[0]); if (odd->action != SDLxNOHDR) memcpy (*(int **) off, &fst_x, sizeof (int)); else { SDLoPTR tmp; tmp = referredClass->s + (referredClass->siz * fst_x); memcpy (*off, &tmp, sizeof (SDLoPTR)); } return 1; } int OFMakeAllObj (SDLoOBJ *obj, SDLoATTR *attr, SDLoPTR *off) { SDLoOBJ *referredClass; referredClass = & (odd->oc[attr->dfltv]); if (odd->action != SDLxNOHDR) memset (*off, 0, sizeof (SDLoPTR)); else memcpy (*off, &(referredClass->s), sizeof (SDLoPTR)); attr->dflts = &(referredClass->dnam[0]); attr->tnam = &(referredClass->tnam[0]); return 1; } /****** OfArraySiz ***********************************************************/ /** ** returns string with array size for declaration of arrays ** if not array string is empty; ** ** INPUT: attribute object [R] ** IMPLICIT: ** ** RETURNS: address of string **/ char *OFArraySiz (SDLoATTR *attr) { static char as[10]; if (attr->arrsz > 1) sprintf(as, "[%d]", attr->arrsz); else as[0] = '\0'; return &as[0]; } /****************************************************************************** ***** group of functions for writing attribute definition to header file ****** ******************************************************************************* ** ** ** INPUT: attribute object [R] ** generic type [R] ** generic object type [R] ** IMPLICIT: ** odd (SDLo *) [R] ** ** RETURNS: ** */ char *OddRemark (SDLoATTR *attr) { static char remark[550]; if (!*attr->rem) remark[0] = '\0'; else sprintf (remark, " /*%s %s */", OddIsAttr (attr, "api") ? "API" : "", attr->rem); return remark; } char *OddAddRemark (char *ln, SDLoATTR *attr) { static char newLn[600]; char remark[550]; char *lastBlankPtr; int l, k, lSave; if (!*attr->rem) return ln; else { sprintf (newLn, "%-40s ", ln); sprintf (remark, "/*%s %s */", OddIsAttr (attr, "api") ? "API" : "", attr->rem); l = 0; while (1) { for (k=strlen (newLn); (k % 80) && remark[l]; k++, l++) { newLn[k] = remark[l]; if (newLn[k] == ' ') { lastBlankPtr = &newLn[k]; lSave = l; } } if (remark[l]) { /* comment string is not yet finished */ *lastBlankPtr = '\0'; sprintf (newLn, "%s\n%43s", newLn, " "); l = lSave; } else { newLn[k] = '\0'; break; } } } return newLn; } int OFDefSimple (FILE *fil, SDLoATTR *attr, char *gtyp_nm, char *typdef_nm) { char l[133]; sprintf(l, " %-24s%s%s;", odd->at[attr->typ].tnam, attr->dnam, OFArraySiz (attr)); fprintf (fil, "%s\n", OddAddRemark (l, attr)); return 1; } int OFDefStr (FILE *fil, SDLoATTR *attr, char *gtyp_nm, char *typdef_nm) { char l[133]; sprintf (l, " %-24s*%s%s;", "char", attr->dnam, OFArraySiz (attr)); fprintf (fil, "%s\n", OddAddRemark (l, attr)); return 1; } int OFDefFnct (FILE *fil, SDLoATTR *attr, char *gtyp_nm, char *typdef_nm) { char l[133]; char tnam[80], args[80], tmp[80]; strcpy (args, attr->dflts); if (gtyp_nm != NULL) { /* generic argument type */ if (typdef_nm != NULL) { sprintf (tmp, "struct %s", typdef_nm); SmSwapS (args, SDLxGTYPDEFNAM, tmp); } SmSwapS (args, SDLxGTYPNAM, gtyp_nm); } else SmSwapS (args, SDLxGTYPDEFNAM, "void"); /* generic return val type */ if (strcmp (SDLxGTYPNAM, attr->tnam) == 0 && gtyp_nm != NULL) sprintf (tnam, "%-24s*", gtyp_nm); else strcpy (tnam, "INT4"); sprintf (l, " %-24s(*%s)%s;", tnam, attr->dnam, " ()" /*args*/ ); fprintf (fil, "%s\n", OddAddRemark (l, attr)); return 1; } int OFDefHeader (FILE *fil, SDLoATTR *attr, char *gtyp_nm, char *typdef_nm) { char l[133]; sprintf (l, " %-24s*%s;", attr->tnam, attr->dnam); fprintf (fil, "%s\n", OddAddRemark (l, attr)); return 1; } int OFDefStructPtr (FILE *fil, SDLoATTR *attr, char *gtyp_nm, char *typdef_nm) { char l[133]; char tnam[80]; sprintf (tnam, "struct %s", attr->tnam); sprintf (l, " %-24s*%s%s;", tnam, attr->dnam, OFArraySiz (attr)); fprintf (fil, "%s\n", OddAddRemark (l, attr)); return 1; } int OFDefGenericTyp (FILE *fil, SDLoATTR *attr, char *gtyp_nm, char *typdef_nm) { char l[133]; if (gtyp_nm == NULL) sprintf (l, " %-24s*%s;", "void", attr->dnam); else sprintf(l, " %-24s*%s;", gtyp_nm, attr->dnam); fprintf (fil, "%s\n", OddAddRemark (l, attr)); return 1; } int OFDefUser (FILE *fil, SDLoATTR *attr, char *gtyp_nm, char *typdef_nm) { char l[133]; int pp_f; pp_f = *(attr->sw_nm) != '\0' ? TRUE : FALSE; if (pp_f) /* if preprocessor switch */ fprintf(fil, "#ifdef %s\n", attr->sw_nm); sprintf (l, " %-24s%s%s;", attr->tnam, attr->dnam, OFArraySiz (attr)); fprintf (fil, "%s\n", OddAddRemark (l, attr)); if (pp_f) { fprintf(fil, "#else\n"); fprintf(fil, " %-24s%s%s;%s\n", (*attr->alt_nm == '\0') ? "unsigned int" : attr->alt_nm, attr->dnam, OFArraySiz (attr), OddRemark (attr)); fprintf(fil, "#endif\n"); } return 1; } int OFDefEbnf (FILE *fil, SDLoATTR *attr, char *gtyp_nm, char *typdef_nm) { fprintf(fil, " %-24s%s;\n", "char", "**ebnfln"); fprintf(fil, " %-24s%s;\n", "INT4", "nebnfln"); return 1; } /****************************************************************************** ****** group of functions for inserting attribute values ********************** ******************************************************************************* ** ** ** INPUT: address of parent object [R] ** address of attribute [R] ** address of header [W] ** address of current offset in target structure [W] ** IMPLICIT: ** odd (SDLo *) [R] ** f (FILo *) [R] ** ** RETURNS: e__parismiss + ** e__parnotok + ** e__allocfail + ** e__objnotfound + ** 1 */ int OFInsertFloat (SDLoOBJ *obj, SDLoATTR *attr, SDLoATTR *dfltattr, float **dest, char *tokstr, unsigned int tokval, int dflt_f) { float value; if (dflt_f) value = dfltattr->dfltvf; else sscanf (tokstr, "%f", &value); _ErrRet (SdlCheckPar (attr, 0, value)); memcpy (*dest, &value, sizeof (float)); *dest += 1; return 1; } int OFInsertInt (SDLoOBJ *obj, SDLoATTR *attr, SDLoATTR *dfltattr, int **dest, char *tokstr, unsigned int tokval, int dflt_f) { int value; if (tokval == ODDxNULL) value = dflt_f ? dfltattr->dfltv : atoi(tokstr); else value = tokval; _ErrRet (SdlCheckPar (attr, 0, value)); memcpy (*dest, &value, sizeof (int)); *dest += 1; return 1; } int OFInsertUInt (SDLoOBJ *obj, SDLoATTR *attr, SDLoATTR *dfltattr, unsigned int **dest, char *tokstr, unsigned int tokval, int dflt_f) { unsigned int value; if (tokval == ODDxNULL) value = dflt_f ? dfltattr->dfltv : atoi(tokstr); else value = tokval; _ErrRet (SdlCheckPar (attr, 0, value)); memcpy (*dest, &value, sizeof (unsigned int)); *dest += 1; return 1; } int OFInsertUChar (SDLoOBJ *obj, SDLoATTR *attr, SDLoATTR *dfltattr, unsigned char **dest, char *tokstr, unsigned int tokval, int dflt_f) { unsigned char value; if (tokval == ODDxNULL) value = dflt_f ? dfltattr->dfltv : atoi(tokstr); else value = tokval; _ErrRet (SdlCheckPar (attr, 0, value)); memcpy (*dest, &value, sizeof (char)); *dest += 1; return 1; } int OFInsertUser (SDLoOBJ *obj, SDLoATTR *attr, SDLoATTR *dfltattr, void ***dest, char *tokstr, unsigned int tokval, int dflt_f) { memset (*dest, 0, sizeof (char *)); *dest += 1; return 1; } int OFInsertStr (SDLoOBJ *obj, SDLoATTR *attr, SDLoATTR *dfltattr, char ***dest, char *tokstr, unsigned int tokval, int dflt_f) { char *newvalue, *value = NULL; int rv; /* if (tokval == ODDxNULL) ...does this ever happen? */ value = dflt_f ? &((dfltattr->dflts)[0]) : tokstr; /* else value += _SdlIsStr (tokval); */ rv = SdlCheckPar (attr, value, 0); _ErrRet (rv); /* insert into user-object */ if ((newvalue = (char *) _SdlMalloc (strlen (value) + 1)) == 0) _ErrRet2(e__allocfail, "symbol string"); memcpy (*dest, &newvalue, sizeof (char *)); if (attr->typ == AT_PROTOFNCT) /* copy function to array */ OddAddFunction (*dest); *dest = *dest + 1; strcpy (newvalue, value); /* if (odd->action == SDLxNOHDR) SmEdit (newvalue, SMxDECODE); */ return 1; } int OFInsertFunction (SDLoOBJ *obj, SDLoATTR *attr, SDLoATTR *dfltattr, unsigned int **dest, char *tokstr, unsigned int tokval, int dflt_f) { unsigned int value; SDLoPTR tmp=NULL; value = dflt_f ? SDLxNULLFNCT : tokval; if (odd->action == SDLxNOHDR) { if (odd->section_f) { /* function index */ tmp += dflt_f ? SDLxXFNCT : value; memcpy (*dest, &tmp, sizeof (SDLoPTR)); } else { /* function address */ tmp = dflt_f ? NULL : (SDLoPTR) SDL_fnct[value]; memcpy (*dest, &tmp, sizeof (SDLoPTR)); } } else { /* function name */ tmp = dflt_f ? "NULL" : *(function[value].nam); memcpy (*(char ***) dest, &tmp, sizeof (SDLoPTR));} if (!dflt_f) attr->dflts = *(function[value].args); *dest += 1; return 1; } int OFInsertObject (SDLoOBJ *obj, SDLoATTR *attr, SDLoATTR *dfltattr, void ***dest, char *tokstr, unsigned int tokval, int dflt_f) { SDLoOBJ *refClass; SDLoPTR obj_p; int rv; refClass = &(odd->oc[attr->dfltv]); /*tokval = atoi (tokstr);*/ if (!dflt_f) { if (attr->typ == AT_CLONE) { if ((obj_p = (SDLoPTR) _SdlMalloc (refClass->siz)) == 0) _ErrRet2(e__allocfail, "object clone"); memcpy (obj_p, (void *) (refClass->s + refClass->siz * tokval), refClass->siz); } else obj_p = (void *) (refClass->s + refClass->siz * tokval); } else obj_p = NULL; /* ** copy object address into output object */ if (odd->action == SDLxNOHDR) memcpy (*dest, &obj_p, sizeof (SDLoPTR)); else memcpy (*dest, &tokval, sizeof (SDLoPTR)); (*dest)++; attr->dflts = &(refClass->dnam[0]); /* declaration name */ /* ** give attribute a type definition name */ if (refClass->gtyp_n == 0 || tokval == SDLxXOBJ) attr->tnam = refClass->tnam; else if (tokval != ODDxNULL) attr->tnam = (refClass->gtypdef_nm)[tokval]; return 1; } int OFInsertHeader (SDLoOBJ *obj, SDLoATTR *attr, SDLoATTR *dfltattr, unsigned int **dest, char *tokstr, unsigned int tokval, int dflt_f) { #ifdef org ODDoHEAD *head; if (!dflt_f) { if ((head = (ODDoHEAD *) _SdlMalloc (sizeof (ODDoHEAD))) == 0) _ErrRet2(e__allocfail, "object clone"); memcpy (head, &ODD_headers[tokval], sizeof (ODDoHEAD)); } else head = NULL; memcpy (*dest, &head, sizeof (int *)); *dest += 1; #endif return 1; } int OFInherit (SDLoOBJ *obj, SDLoATTR *attr, SDLoATTR *dfltattr, unsigned int **dest, char *tokstr, unsigned int tokval, int dflt_f) { SDLoOBJ *inherit_obj; void *obj_p; inherit_obj = &(odd->oc[attr->dfltv]); if (tokval >= inherit_obj->gbl_n) _ErrRet4 (e__objnotfound, f->n, f->nam, tokstr); obj_p = (void *) (inherit_obj->s + tokval * inherit_obj->siz); memcpy (*dest, obj_p, inherit_obj->siz); if (odd->section_f) SdlSaveAddr (inherit_obj, (SDLoPTR) *dest); return 1; } int OFGeneric (SDLoOBJ *obj, SDLoATTR *attr, SDLoATTR *dfltattr, void ***dest, char *tokstr, unsigned int tokval, int dflt_f) { _ErrRet (SdlGenericNames (&(odd->oc[O_HEAD]), attr->typ, tokstr)); return 1; } /****************************************************************************** ******** group of functions for writing attribute value to header file ******** ******************************************************************************* ** ** ** INPUT: attribute object [R] ** destination string [W] ** address of source [W] ** IMPLICIT: ** ** RETURNS: ** */ int OFWrtInt (SDLoATTR *attr, char *s, int **source) { sprintf (s, "%d", **source); (*source)++; return 1; } int OFWrtUChar (SDLoATTR *attr, char *s, unsigned char **source) { sprintf (s, "%d", **source); (*source)++; return 1; } int OFWrtUInt (SDLoATTR *attr, char *s, unsigned int **source) { sprintf (s, "%u", **source); (*source)++; return 1; } int OFWrtFloat (SDLoATTR *attr, char *s, float **source) { sprintf (s, "%f", **source); (*source)++; return 1; } int OFWrtStr (SDLoATTR *attr, char *s, char ***source) { static STRv str; if (!str) str = StrNew (); StrSetS (str, **source); StrEncode (str); sprintf (s, "\"%s\"", _Str (str)); (*source)++; return 1; } int OFWrtName (SDLoATTR *attr, char *s, char ***source) { sprintf (s, "%s", **source); (*source)++; return 1; } int OFWrtNULL (SDLoATTR *attr, char *s, void ***source) { sprintf (s, "NULL"); (*source)++; return 1; } int OFWrtAddr (SDLoATTR *attr, char *s, unsigned int **source) { if (**source == ODDxNULL) sprintf(s, "NULL"); else sprintf(s, "&%s[%d]", attr->dflts, **source); (*source)++; return 1; } int OFWrtEBNF (SDLoATTR *attr, char *s, char ***source) { sprintf(s, "&%s[0], %d", **source, ** (int **) (source+sizeof (char *))); (*source) += 8; return 1; } /****************************************************************************** ******* group of functions for checking attribute values ********************** ******************************************************************************* ** ** ** INPUT: ** address of attribute [R] ** address of value ** IMPLICIT: ** f (FILo *) [R] ** ** RETURNS: ** e__parnotok + ** 1 */ int OFCheckNum (SDLoATTR *attr, int v, char *s) { char errmsg[MSGxXLN]; if (v > attr->max) sprintf(errmsg, "Attribute: %s, value: %d, max: %d", attr->nam, v, attr->max); else if (v < attr->min) sprintf(errmsg, "Attribute: %s, value: %d, min: %d", attr->nam, v, attr->min); else return 1; _ErrRet4 (e__parnotok, f->n, f->nam, errmsg); return 1; } int OFCheckStr (SDLoATTR *attr, int v, char *s) { char errmsg[MSGxXLN]; int len; len = strlen (s); if (len > attr->max) sprintf (errmsg, "Attribute: %s, string: %s, maxlen: %d", attr->nam, s, attr->max); else if (len < attr->min) sprintf (errmsg, "Attribute: %s, string: %s, minlen: %d", attr->nam, s, attr->min); else return 1; _ErrRet4 (e__parnotok, f->n, f->nam, errmsg); return 1; } /****************************************************************************** ******* group of functions for generating generic types ******************** ******************************************************************************* ** ** ** INPUT: ** address of attribute [R] ** address of value ** IMPLICIT: ** odd (SDLo *) [R] ** ** RETURNS: ** e__parnotok + ** 1 */ int OFGenSimple (SDLoOBJ * headobj, SDLoATTR *attr) { SdlGenericNames (headobj, AT_GENERIC_TYP, odd->at[attr->typ].tnam); return 1; } int OFGenObject (SDLoOBJ * headobj, SDLoATTR *attr) { SDLoOBJ *ref_obj; char gtyp_nm[SDLxXLSYM+1]; ref_obj = &(odd->oc[attr->dfltv]); sprintf (gtyp_nm, "struct %s *", ref_obj->tnam); SdlGenericNames (headobj, AT_GENERIC_TYP, gtyp_nm); return 1; } : ** odd (SDLo *) [R] ** ** RETURNS: ** e__parnotok + ** 1 */ int srs/src/oddfnctsnew.c char oddfncts_ID[] = "$Id: oddfnctsnew.c,v 1.5 1997/03/12 16:17:44 srs Exp $"; /* ** ** $RCSfile: oddfnctsnew.c,v $ ** $Revision: 1.5 $ ** $Date: 1997/03/12 16:17:44 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** Copyright by Thure Etzold ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include "message.h" #include "sm.h" #include "futil.h" #include "strv.h" #include "odd.h" #define _SDL #define _ODD #include "oddclass.h" typedef int (*SDLoFNCT)(); INT4 OddIsAttr (SDLoATTR *attr, char *option); INT4 OddIsClass (SDLoOBJ *class, char *option); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** object wide variables */ extern SDLo *odd; extern SDLoFNCT SDL_fnct[]; extern ODDoFNCT_P function[SDLxXFNCT]; extern FILo *f; /****************************************************************************** ****** Group of functions calculating object size ***************************** ******************************************************************************* ** ** INPUT: address of parent object [R] ** address of attribute [R] ** address of offset within structure [W] ** IMPLICIT: ** odd (SDLo *) */ int OFInheritSize (SDLoOBJ *obj, SDLoATTR *attr, int *off) { return 0; } int OF4BArrSize (SDLoOBJ *obj, SDLoATTR *attr, int *off) { _SdlAlignFour (*off); return 4 * attr->arrsz; } int OF4BSize (SDLoOBJ *obj, SDLoATTR *attr, int *off) { _SdlAlignFour (*off); return 4; } int OFPtrArrSize (SDLoOBJ *obj, SDLoATTR *attr, int *off) { _SdlAlignEight (*off); return (sizeof (char *) * attr->arrsz); } int OFPtrSize (SDLoOBJ *obj, SDLoATTR *attr, int *off) { _SdlAlignEight (*off); return sizeof (char *); } int OFBNFSize (SDLoOBJ *obj, SDLoATTR *attr, int *off) { _SdlAlignEight (*off); return (sizeof (char *) + sizeof (int)); } int OFBArrSize (SDLoOBJ *obj, SDLoATTR *attr, int *off) { return 1 * attr->arrsz; } /****************************************************************************** ****** group of functions for posprocesssing attributes *********************** ******************************************************************************* ** ** INPUT: address of parent object [R] ** address of attribute [R] ** address of header [W] ** address of current offset in target structure [W] ** IMPLICIT: ** odd (SDLo *) [R] ** ** RETURNS: e__icarequiredattr + ** 1 */ int OFMakeDefault (SDLoOBJ *obj, SDLoATTR *attr, SDLoPTR *off) { int (*insert)(); int l, rv; if (!(attr->isrd)) { if (attr->req) _ErrRet (e__icarequiredattr); else if ((insert = odd->at[attr->typ].insert) != NULL) for (l = 0; l < attr->arrsz; l++) { rv = (*insert) (obj, attr, attr, off, 0, ODDxNULL, TRUE); _ErrRet (rv); } } return 1; } int OFMakeNoDefault (SDLoOBJ *obj, SDLoATTR *attr, SDLoPTR *off) { if (!(attr->isrd)) _ErrRet (e__icarequiredattr); return 1; } int OFMakeChildN (SDLoOBJ *obj, SDLoATTR *attr, SDLoPTR *off) { Int4 n; n = (attr->hasObjsN!=-1) ? attr->hasObjsN : odd->oc[attr->dfltv].loc_n; memcpy (*off, &n, sizeof (int)); return 1; } int OFMakeAllObjN (SDLoOBJ *obj, SDLoATTR *attr, SDLoPTR *off) { memcpy (*(int **) off, &((odd->oc)[attr->dfltv].gbl_n), sizeof (int)); return 1; } int OFMakeChild (SDLoOBJ *obj, SDLoATTR *attr, SDLoPTR *off) { SDLoOBJ *refClass; SDLoPTR tmp; int rv, firstX, l, i; refClass = OddGetPartofClass (attr); firstX = refClass->gbl_n - refClass->loc_n; if (attr->hasObjsN != -1) refClass->loc_n -= attr->hasObjsN; attr->dflts = OddGetClassDeclName (refClass); attr->tnam = &(refClass->tnam[0]); if (odd->action != SDLxNOHDR && !odd->section_f) memcpy (*(int **) off, &firstX, sizeof (int)); else { SDLoPTR tmp; if (attr->hasObjsN == -1) tmp = refClass->s + (refClass->siz * firstX); else tmp = attr->hasFirstObj; memcpy (*off, &tmp, sizeof (SDLoPTR)); } return 1; } int OFMakeAllObj (SDLoOBJ *obj, SDLoATTR *attr, SDLoPTR *off) { SDLoOBJ *refClass; refClass = OddGetPartofClass (attr); if ((odd->action != SDLxNOHDR) && !odd->section_f) memset (*off, 0, sizeof (SDLoPTR)); else memcpy (*off, &(refClass->s), sizeof (SDLoPTR)); attr->dflts = OddGetClassDeclName (refClass); attr->tnam = &(refClass->tnam[0]); return 1; } /****** OfArraySiz ***********************************************************/ /** ** returns string with array size for declaration of arrays ** if not array string is empty; ** ** INPUT: attribute object [R] ** IMPLICIT: ** ** RETURNS: address of string **/ char *OFArraySiz (SDLoATTR *attr) { static char as[10]; if (attr->arrsz > 1) sprintf(as, "[%d]", attr->arrsz); else as[0] = '\0'; return &as[0]; } /****************************************************************************** ***** group of functions for writing attribute definition to header file ****** ******************************************************************************* ** ** ** INPUT: attribute object [R] ** generic type [R] ** generic object type [R] ** IMPLICIT: ** odd (SDLo *) [R] ** ** RETURNS: */ char *OddRemark (SDLoATTR *attr) { static char remark[550]; if (!*attr->rem) remark[0] = '\0'; else sprintf (remark, " /*%s %s */", OddIsAttr (attr, "api") ? "API" : "", attr->rem); return remark; } char *OddAddRemark (char *ln, SDLoATTR *attr) { static char newLn[600]; char remark[550]; char *lastBlankPtr; int l, k, lSave; if (!*attr->rem) return ln; else { sprintf (newLn, "%-40s ", ln); sprintf (remark, "/*%s %s */", OddIsAttr (attr, "api") ? "API" : "", attr->rem); l = 0; while (1) { for (k=strlen (newLn); (k % 80) && remark[l]; k++, l++) { newLn[k] = remark[l]; if (newLn[k] == ' ') { lastBlankPtr = &newLn[k]; lSave = l; } } if (remark[l]) { /* comment string is not yet finished */ *lastBlankPtr = '\0'; sprintf (newLn, "%s\n%43s", newLn, " "); l = lSave; } else { newLn[k] = '\0'; break; } } } return newLn; } int OFDefSimple (FILE *fil, SDLoATTR *attr, char *gtyp_nm, char *typdef_nm) { char l[133]; sprintf(l, " %-24s%s%s;", odd->at[attr->typ].tnam, OddGetAttrDeclName (attr), OFArraySiz (attr)); fprintf (fil, "%s\n", OddAddRemark (l, attr)); return 1; } int OFDefStr (FILE *fil, SDLoATTR *attr, char *gtyp_nm, char *typdef_nm) { char l[133]; sprintf (l, " %-24s*%s%s;", "char", OddGetAttrDeclName (attr), OFArraySiz (attr)); fprintf (fil, "%s\n", OddAddRemark (l, attr)); return 1; } int OFDefFnct (FILE *fil, SDLoATTR *attr, char *gtyp_nm, char *typdef_nm) { char l[133]; char tnam[80], args[80], tmp[80]; strcpy (args, attr->dflts); if (gtyp_nm != NULL) { /* generic argument type */ if (typdef_nm != NULL) { sprintf (tmp, "struct %s", typdef_nm); SmSwapS (args, SDLxGTYPDEFNAM, tmp); } SmSwapS (args, SDLxGTYPNAM, gtyp_nm); } else SmSwapS (args, SDLxGTYPDEFNAM, "void"); /* generic return val type */ if (strcmp (SDLxGTYPNAM, attr->tnam) == 0 && gtyp_nm != NULL) sprintf (tnam, "%-24s*", gtyp_nm); else strcpy (tnam, "INT4"); sprintf (l, " %-24s(*%s)%s;", tnam, attr->dnam, " ()" /*args*/ ); fprintf (fil, "%s\n", OddAddRemark (l, attr)); return 1; } int OFDefHeader (FILE *fil, SDLoATTR *attr, char *gtyp_nm, char *typdef_nm) { char l[133]; sprintf (l, " %-24s*%s;", attr->tnam, attr->dnam); fprintf (fil, "%s\n", OddAddRemark (l, attr)); return 1; } int OFDefStructPtr (FILE *fil, SDLoATTR *attr, char *gtyp_nm, char *typdef_nm) { char l[133]; char tnam[80]; sprintf (tnam, "struct %s", odd->oc[attr->dfltv].tnam); sprintf (l, " %-24s*%s%s;", tnam, OddGetAttrDeclName (attr), OFArraySiz (attr)); fprintf (fil, "%s\n", OddAddRemark (l, attr)); return 1; } int OFDefGenericTyp (FILE *fil, SDLoATTR *attr, char *gtyp_nm, char *typdef_nm) { char l[133]; if (gtyp_nm == NULL) sprintf (l, " %-24s*%s;", "void", attr->dnam); else sprintf(l, " %-24s*%s;", gtyp_nm, attr->dnam); fprintf (fil, "%s\n", OddAddRemark (l, attr)); return 1; } int OFDefUser (FILE *fil, SDLoATTR *attr, char *gtyp_nm, char *typdef_nm) { char l[133]; int pp_f; pp_f = *(attr->sw_nm) != '\0' ? TRUE : FALSE; if (pp_f) /* if preprocessor switch */ fprintf(fil, "#ifdef %s\n", attr->sw_nm); sprintf (l, " %-24s%s%s;", attr->tnam, attr->dnam, OFArraySiz (attr)); fprintf (fil, "%s\n", OddAddRemark (l, attr)); if (pp_f) { fprintf(fil, "#else\n"); fprintf(fil, " %-24s%s%s;%s\n", (*attr->alt_nm == '\0') ? "unsigned int" : attr->alt_nm, attr->dnam, OFArraySiz (attr), OddRemark (attr)); fprintf(fil, "#endif\n"); } return 1; } int OFDefEbnf (FILE *fil, SDLoATTR *attr, char *gtyp_nm, char *typdef_nm) { fprintf(fil, " %-24s%s;\n", "char", "**ebnfln"); fprintf(fil, " %-24s%s;\n", "INT4", "nebnfln"); return 1; } /****************************************************************************** ****** group of functions for inserting attribute values ********************** ******************************************************************************* ** ** ** INPUT: address of parent object [R] ** address of attribute [R] ** address of header [W] ** address of current offset in target structure [W] ** IMPLICIT: ** odd (SDLo *) [R] ** f (FILo *) [R] ** ** RETURNS: e__icarequiredattr + ** e__icaattrval + ** e__allocfail + ** e__objnotfound + ** 1 */ int OFInsertFloat (SDLoOBJ *obj, SDLoATTR *attr, SDLoATTR *dfltattr, float **dest, char *tokstr, unsigned int tokval, int dflt_f) { float value; if (dflt_f) value = dfltattr->dfltvf; else sscanf (tokstr, "%f", &value); _ErrRet (SdlCheckPar (attr, 0, value)); memcpy (*dest, &value, sizeof (float)); *dest += 1; return 1; } int OFInsertInt (SDLoOBJ *obj, SDLoATTR *attr, SDLoATTR *dfltattr, int **dest, char *tokstr, unsigned int tokval, int dflt_f) { int value; if (tokval == ODDxNULL) value = dflt_f ? dfltattr->dfltv : atoi(tokstr); else value = tokval; _ErrRet (SdlCheckPar (attr, 0, value)); memcpy (*dest, &value, sizeof (int)); *dest += 1; return 1; } int OFInsertUInt (SDLoOBJ *obj, SDLoATTR *attr, SDLoATTR *dfltattr, unsigned int **dest, char *tokstr, unsigned int tokval, int dflt_f) { unsigned int value; if (tokval == ODDxNULL) value = dflt_f ? dfltattr->dfltv : atoi(tokstr); else value = tokval; _ErrRet (SdlCheckPar (attr, 0, value)); memcpy (*dest, &value, sizeof (unsigned int)); *dest += 1; return 1; } int OFInsertUChar (SDLoOBJ *obj, SDLoATTR *attr, SDLoATTR *dfltattr, unsigned char **dest, char *tokstr, unsigned int tokval, int dflt_f) { unsigned char value; if (tokval == ODDxNULL) value = dflt_f ? dfltattr->dfltv : atoi(tokstr); else value = tokval; _ErrRet (SdlCheckPar (attr, 0, value)); memcpy (*dest, &value, sizeof (char)); *dest += 1; return 1; } int OFInsertUser (SDLoOBJ *obj, SDLoATTR *attr, SDLoATTR *dfltattr, void ***dest, char *tokstr, unsigned int tokval, int dflt_f) { memset (*dest, 0, sizeof (char *)); *dest += 1; return 1; } int OFInsertStr (SDLoOBJ *obj, SDLoATTR *attr, SDLoATTR *dfltattr, char ***dest, char *tokstr, unsigned int tokval, int dflt_f) { char *newvalue, *value = NULL; int rv; /* if (tokval == ODDxNULL) ...does this ever happen? */ value = dflt_f ? &((dfltattr->dflts)[0]) : tokstr; /* else value += _SdlIsStr (tokval); */ rv = SdlCheckPar (attr, value, 0); _ErrRet (rv); /* insert into user-object */ if ((newvalue = (char *) _SdlMalloc (strlen (value) + 1)) == 0) _ErrRet2(e__allocfail, "symbol string"); memcpy (*dest, &newvalue, sizeof (char *)); if (attr->typ == AT_PROTOFNCT) /* copy function to array */ OddAddFunction (*dest); *dest = *dest + 1; strcpy (newvalue, value); /* if (odd->action == SDLxNOHDR || odd->section_f) SmEdit (newvalue, SMxDECODE); */ return 1; } int OFInsertFunction (SDLoOBJ *obj, SDLoATTR *attr, SDLoATTR *dfltattr, unsigned int **dest, char *tokstr, unsigned int tokval, int dflt_f) { unsigned int value; SDLoPTR tmp=NULL; value = dflt_f ? SDLxNULLFNCT : atoi (tokstr); if (odd->action == SDLxNOHDR || odd->section_f) { if (odd->section_f) { /* function index */ tmp += dflt_f ? SDLxXFNCT : value; memcpy (*dest, &tmp, sizeof (SDLoPTR)); } else { /* function address */ tmp = dflt_f ? NULL : (SDLoPTR) SDL_fnct[value]; memcpy (*dest, &tmp, sizeof (SDLoPTR)); } } else { /* function name */ tmp = dflt_f ? "NULL" : *(function[value].nam); memcpy (*(char ***) dest, &tmp, sizeof (SDLoPTR));} if (!dflt_f) attr->dflts = *(function[value].args); *dest += 1; return 1; } int OFInsertObject (SDLoOBJ *obj, SDLoATTR *attr, SDLoATTR *dfltattr, void ***dest, char *tokstr, unsigned int tokval, int dflt_f) { SDLoOBJ *refClass; SDLoPTR obj_p; int rv, objX; refClass = OddGetPartofClass (attr); if (tokstr) objX = atoi (tokstr); else if (tokval == ODDxNULL) objX = -1; else objX = tokval; /* possibly never occurs */ if (!dflt_f && objX != -1) { obj_p = (void *) (refClass->s + refClass->siz * objX); } else obj_p = NULL; /* copy object address into output object */ if (odd->action == SDLxNOHDR || odd->section_f) memcpy (*dest, &obj_p, sizeof (SDLoPTR)); else memcpy (*dest, &objX, sizeof (SDLoPTR)); (*dest)++; attr->dflts = OddGetClassDeclName (refClass); /* declaration name */ /* give attribute a type definition name */ attr->tnam = refClass->tnam; return 1; } int OFInsertHeader (SDLoOBJ *obj, SDLoATTR *attr, SDLoATTR *dfltattr, unsigned int **dest, char *tokstr, unsigned int tokval, int dflt_f) { return 1; } int OFInherit (SDLoOBJ *obj, SDLoATTR *attr, SDLoATTR *dfltattr, unsigned int **dest, char *tokstr, unsigned int tokval, int dflt_f) { return 1; } int OFGeneric (SDLoOBJ *obj, SDLoATTR *attr, SDLoATTR *dfltattr, void ***dest, char *tokstr, unsigned int tokval, int dflt_f) { return 1; } /****************************************************************************** ******** group of functions for writing attribute value to header file ******** ******************************************************************************* ** ** ** INPUT: attribute object [R] ** destination string [W] ** address of source [W] ** IMPLICIT: ** ** RETURNS: ** */ int OFWrtInt (SDLoATTR *attr, char *s, int **source) { sprintf (s, "%d", **source); (*source)++; return 1; } int OFWrtUChar (SDLoATTR *attr, char *s, unsigned char **source) { sprintf (s, "%d", **source); (*source)++; return 1; } int OFWrtUInt (SDLoATTR *attr, char *s, unsigned int **source) { sprintf (s, "%u", **source); (*source)++; return 1; } int OFWrtFloat (SDLoATTR *attr, char *s, float **source) { sprintf (s, "%f", **source); (*source)++; return 1; } int OFWrtStr (SDLoATTR *attr, char *s, char ***source) { static STRv str; if (!str) str = StrNew (); StrSetS (&str, **source); StrEncode (&str); sprintf (s, "\"%s\"", _Str (str)); (*source)++; return 1; } int OFWrtName (SDLoATTR *attr, char *s, char ***source) { sprintf (s, "%s", **source); (*source)++; return 1; } int OFWrtNULL (SDLoATTR *attr, char *s, void ***source) { sprintf (s, "NULL"); (*source)++; return 1; } int OFWrtAddr (SDLoATTR *attr, char *s, unsigned int **source) { if (**source == ODDxNULL) sprintf(s, "NULL"); else sprintf(s, "&%s[%d]", attr->dflts, **source); (*source)++; return 1; } int OFWrtEBNF (SDLoATTR *attr, char *s, char ***source) { return 1; } /****************************************************************************** ******* group of functions for checking attribute values ********************** ******************************************************************************* ** ** INPUT: address of attribute [R] ** address of value ** IMPLICIT: ** f (FILo *) [R] ** ** RETURNS: e__icaattrval + ** 1 */ int OFCheckNum (SDLoATTR *attr, int v, char *s) { char errmsg[MSGxXLN]; if (v > attr->max) sprintf(errmsg, "Attribute: %s, value: %d, max: %d", attr->nam, v, attr->max); else if (v < attr->min) sprintf(errmsg, "Attribute: %s, value: %d, min: %d", attr->nam, v, attr->min); else return 1; _ErrRet2 (e__icaattrval, errmsg); return 1; } int OFCheckStr (SDLoATTR *attr, int v, char *s) { char errmsg[MSGxXLN]; int len; len = strlen (s); if (len > attr->max) sprintf (errmsg, "Attribute: %s, string: %s, maxlen: %d", attr->nam, s, attr->max); else if (len < attr->min) sprintf (errmsg, "Attribute: %s, string: %s, minlen: %d", attr->nam, s, attr->min); else return 1; _ErrRet2 (e__icaattrval, errmsg); return 1; } int OFGenSimple (SDLoOBJ * headobj, SDLoATTR *attr) { return 1; } int OFGenObject (SDLoOBJ * headobj, SDLoATTR *attr) { return 1; } r errmsg[MSGxXLN]; int len; len = strlen (s); if (len > attr->max) sprintf (errmsg, "Attribute: %s, string: %s, maxlen: %d", attr->nam, s, attr->max); else if (len < attr->min) sprintf (errmsg, "Attribute: %s, string: %s, minlen: %d", attr->nam, s, attr->min); else return 1; srs/src/oddtools.c char oddtools_srs_ID[] = "$Id: oddtools.c,v 1.1 1996/05/06 15:17:04 srs Exp $"; /* ** ** $RCSfile: oddtools.c,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:17:04 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.x Copyright by Thure Etzold ** Unix port: Lukas Rosenthaler and Reinhard Doelz ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** Requires: ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include "message.h" #include "oddtools.h" #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif typedef struct ODDooQ_P { struct ODDooQ_P *dn ,*up; int data; } ODDoQ_P; typedef struct ODDooL_P { struct ODDooL_P *dn; int data; } ODDoL_P; typedef struct ODDooT_P { struct ODDooT_P *left, *right; char bal; int data; } ODDoT_P; typedef struct ODDoHEAD_ { void *dn; void *up; void *null; int cx; unsigned char init_f; int n; void *current; void *new; unsigned char off; int (*getnew)(struct ODDoHEAD *, int); int (*add)(struct ODDoHEAD *); int (*search)(struct ODDoHEAD *, void *, char *); int (*delete)(struct ODDoHEAD *); void *(*position)(struct ODDoHEAD *,int); int (*clear)(struct ODDoHEAD *); } ODDoHEAD; /***********************************/ /****** OBJECT WIDE VARIABLES ******/ /***********************************/ extern char *section; extern int section_z; /****** OddQInit ************************************************************** ** ** inititalizes data-structure queue; ** ** INPUT: queue-header [W] ** IMPLICIT: ** ** RETURNS: 1 */ int OddQInit (ODDoHEAD *hd) { hd->null = (void *) &(hd->dn); hd->up = (void *) hd->null; hd->dn = (void *) hd->null; hd->n = 0; hd->init_f = TRUE; return 1; } /**api* OddLAdd *************************************************************** ** ** adds new item to linked list; ** ** INPUT: queue-dscr. [W] ** IMPLICIT: ** ** RETURNS: 1 if success ** 0 if head->new is NULL */ int OddLAdd (ODDoHEAD *hd) { ODDoL_P *new, *lst; if (!hd->init_f) OddQInit (hd); /* use same function as for queue */ if (hd->new == NULL) return 0; new = (ODDoL_P *) ((char *) hd->new - hd->off); new->dn = (ODDoL_P *) hd->null; lst = (ODDoL_P *) hd->up; lst->dn = new; hd->up = new; hd->n++; if (hd->n == 1) { /* first element */ hd->cx = 0; hd->current = &(new->data); } hd->new = NULL; return 1; } /**api* OddNew **************************************************************** ** ** allocates memory for new element and places address to i ** into header->new; ** ** INPUT: address of header [W] ** size of item ** IMPLICIT: ** ** RETURNS: 1 ** e__allocfail + */ int OddNew (ODDoHEAD *hd, int size) { if ((hd->new = (void *) malloc (size + hd->off)) == NULL) _ErrRet2(e__allocfail, "item by OddNew"); hd->new = (char *) hd->new + hd->off; /* shift offset */ return 1; } /**api* OddQAdd ************************************************************** ** ** places item that header->new points to at end of queue; ** initializes queue if necessary; ** ** INPUT: queue-header [W] ** IMPLICIT: ** ** RETURNS: 1 if success ** 0 if header->new not defined ** */ int OddQAdd (ODDoHEAD *hd) { ODDoQ_P *new; if (!hd->init_f) OddQInit (hd); if (hd->new == NULL) return 0; new = (ODDoQ_P *) ((char *) hd->new - hd->off); new->up = (ODDoQ_P *) hd->up; new->dn = (ODDoQ_P *) hd->null; new->up->dn = new; new->dn->up = new; hd->n++; if (hd->n == 1) { hd->cx = 0; hd->current = &(new->data); } hd->new = NULL; return 1; } /**api* OddQPosition ********************************************************** ** ** positions cursor to element with specified number ** ** INPUT: list-dscr. [W] ** index of item [R] first element has index 1 !!! ** or ODDxNEXT, ODDxPREV, ODDxFIRST, ODDxLAST ** IMPLICIT: ** ** RETURNS: pointer to object ** NULL if index larger than actual count or queue empty */ void *OddQPosition (ODDoHEAD *hd, int x) { ODDoQ_P *nxt; int k; if (x > 0) x--; if (x == ODDxNEXT) x = hd->cx+1; if (x == ODDxPREV) x = hd->cx-1; if (x >= hd->n || x == -1 || hd->n == 0) return NULL; if (x == hd->cx) return hd->current; if (x != ODDxFIRST && x != ODDxLAST) { nxt = (ODDoQ_P *) ((char *) hd->current - hd->off); if (x > hd->cx) for (k=hd->cx; k < x; nxt = nxt->dn, k++) ; else for (k=hd->cx; k > x; nxt = nxt->up, k--) ; } else if (x == ODDxFIRST) nxt = hd->dn, x = 0; else if (x == ODDxLAST) nxt = hd->up, x = hd->n -1; hd->current = &(nxt->data); hd->cx = x; return hd->current; } /**api* OddLPosition ************************************************************** ** ** positions cursor to element with specified number in linked list; ** ** INPUT: list-dscr. [W] ** index of item [R] first element has index 1 !!! ** or ODDxNEXT, ODDxPREV, ODDxFIRST, ODDxLAST ** IMPLICIT: ** ** RETURNS: pointer to object ** NULL if index larger than actual count or queue empty */ void *OddLPosition (ODDoHEAD *hd, int x) { ODDoL_P *nxt; int k; if (x > 0) x--; if (x == ODDxNEXT) x = hd->cx+1; if (x == ODDxPREV) x = hd->cx-1; if (x >= hd->n || x == -1 || hd->n == 0) return NULL; if (x == hd->cx) return hd->current; if (x != ODDxFIRST && x != ODDxLAST) { if (x > hd->cx) k = hd->cx, nxt = (ODDoL_P *) ((char *) hd->current - hd->off); else k = 0, nxt = hd->dn; for (; k < x; nxt = nxt->dn, k++) ; } else if (x == ODDxFIRST) nxt = hd->dn, x = 0; else nxt = hd->up, x = hd->n - 1; hd->current = &(nxt->data); hd->cx = x; return hd->current; } /**api* OddLInsert **************************************************************** ** ** inserts element in linked list either left or right of current; ** new element becomes then current element; ** ** INPUT: address of list header [W] ** ODDxLEFT or ODDxRIGHT [R] ** IMPLICIT: ** ** RETURNS: 1 */ int OddLInsert (ODDoHEAD *hd, int pos) { ODDoL_P *tmp, *new; if (!hd->init_f || !hd->n) { OddLAdd (hd); return 1; } else { new = (ODDoL_P *) ((char *) hd->new - hd->off); if (pos == ODDxRIGHT) { tmp = (ODDoL_P *) ((char *) hd->current - hd->off); hd->cx++; } else if (pos == ODDxLEFT) { if (hd->cx > 0) { OddLPosition (hd, hd->cx); hd->cx++; tmp = (ODDoL_P *) ((char *) hd->current - hd->off); } else { hd->cx = 0; tmp = (ODDoL_P *) hd; } } new->dn = tmp->dn; tmp->dn = new; } hd->n++; hd->current = &(new->data); return 1; } /**api* OddLDelete **************************************************************** ** ** Deletes an entry from a list - current entry will be the one after ** the deleted one; ** ** INPUT: address of header-dsc. [W] ** IMPLICIT: ** ** RETURNS: 1 ** 0 if list empty */ int OddLDelete (ODDoHEAD *hd) { ODDoL_P *prev, *tmp; int *rv, fst_f = FALSE; if (hd->n == 0) return 0; tmp = (ODDoL_P *) ((char *) hd->current - hd->off); if (hd->cx > 0) { OddLPosition (hd, hd->cx); prev = (ODDoL_P *) ((char *) hd->current - hd->off); } else prev = (ODDoL_P *) hd, fst_f = TRUE; prev->dn = tmp->dn; OddFree (tmp); if (hd->n == 1) OddQInit (hd); else { hd->n--; if (hd->cx == hd->n) hd->current = &(prev->data); else { hd->current = &(prev->dn->data); if (!fst_f) hd->cx++; } } return 1; } /****** OddFree ******************************************************************* ** ** frees memory - does it only if memory is not within the ODD-section; ** ** INPUT: pointer to memory to be freed [W] ** IMPLICIT: ** section (void *) [R] ** section_z (int) [R] ** ** RETURNS: 1 if freed ** 0 if not */ int OddFree (char *p) { if (p >= section && p <= section + section_z) return 0; else free (p); p = NULL; return 1; } ->cx++; } } return 1; } /****** OddFree ******************************************************************* ** ** frees memory - does it only if memory is not within the ODD-section; ** ** INPUT: pointer to memory to be freed [W] ** IMPLICIT: ** section (void *) [R] ** section_z (int) [R] ** ** RETURNS: 1 if freed ** 0 if not */ int OddFree (char *p) { if (p >= section && p <= section + section_z) srs/src/oddtools.h ** ** $RCSfile: oddtools.h,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:17:05 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** SRS V3.0 Copyright by Thure Etzold ** */ #define ODDxNEXT -2 #define ODDxPREV -3 #define ODDxFIRST -4 #define ODDxLAST -5 #define ODDxRIGHT 0 #define ODDxLEFT 1 #define ODDxFORWARD 2 #define ODDxREVERSE 4 #define ODDxCURRENT 8 ) srs/src/oldlistbuf.c ** C list management *****************************************************************************/ #include #include #include "def.h" #include "oldlistbuf.h" /* creation/deletion */ void ListBufCreate(LISTBUFv* list, LISTBUFoINFO* i, int dim) { int memSize=sizeof(LISTBUFo)+(i->elemSize)*dim; *list=malloc(memSize); (*list)->info=i; (*list)->num=0; (*list)->size=memSize; } void ListBufDelete(LISTBUFv* list) { free(*list); /* I know the size of it! */ *list=NULL; } /* insertion/removal */ void ListBufAppend(LISTBUFv* list, void* val) { Iter i=NULL; ListBufAdd(list, &i, val); } void ListBufInsert(LISTBUFv* list, void* val) { Iter i=ListBufFirst(list); ListBufAdd(list,&i,val); } void ListBufAdd (LISTBUFv* list, Iter* i, void* val) { int num=((*list)->num++); int elemSize=(*list)->info->elemSize; int last=sizeof(LISTBUFo)+num*elemSize; int offset; num++; /* append if i invalid */ if (!*i) *i=cast(*list,BYTE*)+last; offset=cast(*i,BYTE*)-cast(*list,BYTE*); if (last>=(*list)->size) { /* grow the list, copy elements inserting new */ LISTBUFo* oldListBuf=*list; BYTE* oldIter=cast(*i,BYTE*); int newSize=sizeof(LISTBUFo)+2*num*elemSize; *list=malloc(newSize); *i=cast(*list,BYTE*)+offset; memcpy(cast(*list,BYTE*),cast(oldListBuf,BYTE*),offset); memcpy(cast(*i,BYTE*)+elemSize,oldIter,last-offset); memcpy(cast(*i,BYTE*),val,elemSize); (*list)->size=newSize; free(oldListBuf); } else { /* move the elements after (including) insertion point */ memmove(cast(*i,BYTE*)+elemSize,cast(*i,BYTE*),last-offset); memcpy(*i,val,elemSize); } } void ListBufRemove(LISTBUFv* list, Iter* i) { int num=(--(*list)->num); int elemSize= (*list)->info->elemSize; int last=sizeof(LISTBUFo)+num*elemSize; int offset; /* append if i invalid */ ASSERT(*i,RemoveInvalid); offset=cast(*i,BYTE*)-cast(*list,BYTE*); if ((*list)->size>last+2*num*elemSize) { /* shrink the list, copy elements removing */ LISTBUFv oldListBuf=*list; BYTE* oldIter=cast(*i,BYTE*); int newSize=sizeof(LISTBUFo)+num*elemSize; *list=malloc(newSize); *i=cast(*list,BYTE*)+offset; memcpy(cast(*list,BYTE*),cast(oldListBuf,BYTE*),offset); memcpy(cast(*i,BYTE*),oldIter+elemSize,last-offset); cast(*list,LISTBUFo*)->size=newSize; free(oldListBuf); if (cast(*i, BYTE*)>=cast(*list, BYTE*)+newSize) *i=NULL; } else { /* move the elements after removal point */ memmove(cast(*i,BYTE*),cast(*i,BYTE*)+elemSize,last-offset); } } void ListBufClear (LISTBUFv* list) { (*list)->num=0; } /* access */ void* ListBufAtPos (LISTBUFv* list, int pos) { return ListBufAt(list,ListBufInPos(list,pos)); } void* ListBufAt (LISTBUFv* list, Iter i) { ASSERT(i,InvalidIter); return i; } /* iterator support */ Iter ListBufInPos(LISTBUFv* list, int pos) { if (pos<(*list)->num) return cast(*list,BYTE*)+sizeof(LISTBUFo)+ pos*(*list)->info->elemSize; else return NULL; } int ListBufPosAt(LISTBUFv* list, Iter i) { ASSERT(i,InvalidIter); return (cast(i,BYTE*)-(cast(*list,BYTE*)+sizeof(LISTBUFo)))/ (*list)->info->elemSize; } Iter ListBufFirst(LISTBUFv* list) { return ListBufInPos(list,0); } void* ListBufNext (LISTBUFv* list, Iter* i) { if (!*i) *i=ListBufFirst(list); else { int elemSize=(*list)->info->elemSize; *i=cast(*i,BYTE*)+elemSize; if (cast(*i,BYTE*)>=cast(*list,BYTE*)+sizeof(LISTBUFo)+(*list)->num*elemSize) { *i=NULL; return NULL; } } return *i; } Iter ListBufLast (LISTBUFv* list) { int num=(*list)->num; if (num) return cast(*list,BYTE*)+(*list)->info->elemSize*(num-1); else return NULL; } void* ListBufPrev (LISTBUFv* list, Iter* i) { if (!*i) i=ListBufLast(list); else { int elemSize=(*list)->info->elemSize; *i=cast(*i,BYTE*)-elemSize; if (cast(*i,BYTE*)num; } BOOL ListBufEmpty(LISTBUFv* list) { return (*list)->num==0; } (*list,BYTE*)+(*list)->info->elemSize*(num-1); else return NULL; } void* ListBufPrev (LISTBUFv* list, Iter* i) { if (!*i) i=ListBufLast(list); else { int elemSize=(*list)->info->elemSize; *i=cast(*i,BYTE*)-elemSisrs/src/oldlistbuf.h #define _LISTBUF_H /******************************************************************************* ** C generic ListBuf management **/ /* will be class of value */ typedef struct LISTBUFoINFO { int elemSize; } LISTBUFoINFO; typedef struct LISTBUFo { LISTBUFoINFO* info; int size; int num; } LISTBUFo; /* a list of values */ typedef LISTBUFo* LISTBUFv; /************************************ ** ITERATOR ** ** USE ONLY ONE iterator with add,remove: ** other iterators become invalid ** NULL iterator is position without value: ** access: invalid ** add: identifies position AFTER last element (append) ** next: starts from first again ** prev: starts from last again */ /************************************ ** LISTBUF API */ /* creation/deletion */ void ListBufCreate(LISTBUFv* list, LISTBUFoINFO* i, int dim); void ListBufDelete(LISTBUFv* list); /* insertion/removal */ void ListBufAppend(LISTBUFv* list, void* val); void ListBufInsert(LISTBUFv* list, void* val); void ListBufClear (LISTBUFv* list); /* iterator mantains position after operation */ void ListBufAdd (LISTBUFv* list, Iter* i, void* val); void ListBufRemove(LISTBUFv* list, Iter* i); /* access */ void* ListBufAtPos (LISTBUFv* list, int pos); void* ListBufAt (LISTBUFv* list, Iter i); /* iterator support */ Iter ListBufInPos (LISTBUFv* list, int pos); int ListBufPosAt (LISTBUFv* list, Iter i); Iter ListBufFirst(LISTBUFv* list); void* ListBufNext (LISTBUFv* list, Iter* i); Iter ListBufLast (LISTBUFv* list); void* ListBufPrev (LISTBUFv* list, Iter* i); /* information */ int ListBufCard (LISTBUFv* list); BOOL ListBufEmpty(LISTBUFv* list); /************************************************************************ ** specialized list declarations (good for debugging) */ typedef struct LISTBUFoChar { LISTBUFo head; char arr[100]; } LISTBUFoChar; typedef LISTBUFoChar STRINGo; typedef struct LISTBUFoInt { LISTBUFo head; int arr[10]; } LISTBUFoInt; typedef struct LISTBUFoPtr { LISTBUFo head; BYTE* arr[10]; } LISTBUFoPtr; #endif i); /* information */ int ListBufCard (LISTBUFv* list); BOOL ListBufEmpty(LISTBUFv* list); /************************************************************************ ** specialized list declarations (good for debugging) */ typedef struct LISTBUFoChar { LISTBUFo head; char arr[100]; } LISTBUFoChar; typedef LISTBUFoChar STRINGo; typedef struct LISTBUFoInt { LISTBUFo head; int arr[10]; } LISTBUFoInt; typedef strusrs/src/omtest/ gcc -g -w -o try blub.c tryblub.c strv.c parse.c mi.c dict.c def.c trygen: blub.c trygen.c mystr.c parse.c mi.c dict.c /home/srs/srs5/src/def.c gcc -g -w -o trygen -I/home/srs/srs5/src blub.c trygen.c mystr.c parse.c mi.c dict.c /home/srs/srs5/src/def.c tryget: blub.c tryget.c mystr.c parse.c mi.c dict.c /home/srs/srs5/src/def.c gcc -O3 -w -o tryget -I/home/srs/srs5/src blub.c tryget.c mystr.c parse.c mi.c dict.c /home/srs/srs5/src/def.c slist: slist.c tryslist.c cc -g -o try -I/home/srs/srs5/src slist.c tryslist.c mycomdef.c yblub.c strv.c parse.c mi.c dict.c def.c trygen: blub.c trygen.c mystr.c parse.c mi.c dict.c /home/srs/srs5/src/def.c gcc -g -w -o trygen -I/home/srs/srs5/src blub.c trygen.c mystr.c parse.c mi.c dict.c /home/srs/srs5/src/def.c tryget: blub.c tryget.c mystr.c parse.c mi.c dict.c /home/srs/srs5/src/def.c gcc -O3 -w -o tryget -I/home/srs/srs5/src blub.c tryget.c mystr.c parse.c mi.c dict.c /home/srs/srs5/src/def.c slistsrs/src/omtest/tryblub.c #include "strv.h" #include "blub.h" typedef struct TRYOBJ { OBJo head; int a; STRv b; struct TRYOBJ* part; } TRYOBJ; typedef struct TRYMORE { TRYOBJ head; STRv more; ListAttr list; int arr[10]; } TRYMORE; int main() { TRYOBJ* o=ObjCpy(Object); TRYOBJ* o1,*oc; TRYMORE* o2; void *r1, *r2, *r3,*a1; AttrIter ai; Iter i; int* list; OBJpStream s; ObjInit(); ObjAttrNew(&o, StrTemp("a"), int)=3; ObjAttrNew(&o, StrTemp("b"), STRv)=StrCpyS("ciao"); ObjAttrNewRef(&o, StrTemp("part"),TRYOBJ*)=NULL; ObjPrint(o); printf("\n"); ObjMakeClass(o,StrTemp("TRYOBJ")); o1=ObjCpy(o); ObjChange(&o1,TRYOBJ*); o1->part=ObjCpy(o); ObjChange(&ObjChange(&o1, TRYOBJ*)->part, TRYOBJ*)->a=10; o1->a=5; StrSetS(&o1->b,"containing"); o2=ObjCpy(o1); ObjAttrNew(&o2,StrTemp("more"),STRv)=StrCpyS("someMore"); list=&ObjListNew(&o2,4,int); *list++=1; *list++=2; *list++=3; *list++=4; ObjDebug(o); ObjDebug(o1); ObjDebug(o2); ObjMakeClass(o2,StrTemp("TRYMORE")); ObjListApp(&o2,int)=6; ObjListApp(&o2,int)=7; ObjDebug(o2); ObjListCut((void**)&o2,ObjListWith(o2,1),3); ObjDebug(o2); /* try access by name */ printf("%d %s\n", ObjAttr(o,StrTemp("a"),int), Str(ObjAttr(o,StrTemp("b"),STRv))); printf("%d %s\n", ObjAttr(o1,StrTemp("a"),int), Str(ObjAttr(o1,StrTemp("b"),STRv))); printf("%d %s\n", ObjAttr(o2,StrTemp("2"),int), Str(ObjAttr(o2,StrTemp("more"),STRv))); /* attribute iteration */ printf("iterating:\n"); for (ai=ObjAttrFirst(o2); ai; ObjAttrNext(o2,&ai)) { STRv name=ObjAttrName(o2,ai); printf("%s\n",Str(name)); StrDel(name); } /* testing list iteration */ printf("list:\n"); for (i=ObjListFirst(o2);i;ObjListNext(o2,&i)) { printf("%i:%i\n",ObjListPos(o2,i),ObjListIn(i,int)); } printf("%d",ObjListCard(o2)); PathInit(); oc=ObjCpy(o1); r1=PathStaticImpl(theRoot,StrTemp("o"),&o,OBJvClass,NULL); r2=PathStaticImpl(theRoot,StrTemp("o1"),&o1,OBJvClass,NULL); r3=PathStaticImpl(theRoot,StrTemp("o2"),&o2,OBJvClass,NULL); a1=Path("o1.part.a"); PathCompileImpl(a1); PathChange(a1, int)=6; ObjDebug(o1); ObjDebug(oc); /* try stream output */ printf("\n-----------------saving\n"); ObjDebug(o); ObjDebug(o1); ObjDebug(o2); ObjDebug(oc); PathPrint(a1); s=ObjStreamOpen("blabla","wb",TRUE); ObjStore(o, s); ObjStore(o1, s); ObjStore(o2, s); ObjStore(oc, s); RefStore(a1,s); ObjStreamClose(s); /* try stream input */ s=ObjStreamOpen("blabla","rb",TRUE); ObjSet(&o, ObjLoad(s)); ObjSet(&o1, ObjLoad(s)); ObjSet(&o2, ObjLoad(s)); ObjSet(&oc,ObjLoad(s)); ObjSet(&a1,RefLoad(s)); ObjStreamClose(s); ObjDebug(o); ObjDebug(o1); ObjDebug(o2); ObjDebug(oc); PathPrint(a1); /* release everything */ ObjDel(o); ObjDel(o1); ObjDel(o2); ObjDel(oc); ObjDel(a1); ObjDel(r1); } jStore(o2, s); ObjStorsrs/src/par.c char parameter_srs_ID[] = "$Id: par.c,v 1.8 1997/03/18 18:45:32 srs Exp $"; /* ** $RCSfile: par.c,v $ ** $Revision: 1.8 $ ** $Date: 1997/03/18 18:45:32 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.0 Copyright by Thure Etzold ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** Requires: file, sm, message, rtl, sdl, sdlget, oddfncts ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Description ** =========== ** ** management of user defined variables ** if the variable is a number or real then the value is 0 if undefined - ** which means that every parameter has a default value of 0! ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include "message.h" #include "sm.h" #include "strv.h" #include "futil.h" #include "sdlget.h" #include "lst.h" #include "regexp.h" #include "par.h" #include SRSINCLUDE #define PARxXNAM 80 #define PARxXSTR 5000 /* ** name of the ODD file with the user definitions */ #define SRSDEFAULTS "SRSDAT:srsparam.dat" #ifdef VMS # define USERDEFAULTS "SYS$LOGIN:srsparam.dat" #else # define USERDEFAULTS "HOME/.srsparam" #endif enum tableType {PARxPRIVATE=1,PARxLAYERED}; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** parameter list object (parameter table) */ typedef struct PARoTABLE { char *list; /* for usage of module "list" only! */ INT4 classId; /* for "list" module */ char name[132]; /* name of the parameter table */ struct PARo *par; /* list of all predefined parameters */ INT4 parN; /* number of predefined parameters */ struct PARoTYPE *parType; /* list of all predefined parameter types */ INT4 parTypeN; /* number of predefined parameter types */ INT4 parClassId; /* for the /lst/ module */ INT4 parTypeClassId; /* for the /lst/ module */ char isModified; /* has one of the parameters in the table been modified? */ struct PARoTABLE *up; /* Upper or outer parameter list */ enum tableType type; /* type of the table */ } PARoTABLE; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** global and module wide variables */ static PARoTABLE *parTable=NULL; INT4 changepar_f; /* tells if any parameter in the list was changed */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** internal functions */ int ParOCheckFunction (PARo *par, INT4 (*function) ()); int ParOCheckReal (PARo *par, float real); int ParOCheckNum (PARo *par, int num); int ParOCheckStr (PARo *par, char *str); static INT4 ParODefBool (PARo *par, char *str); static void ParTableNew (void *obj); static void ParTableKill (void *obj); static void ParNew (void *obj); static void ParDump (FILE *file, void *obj); /***** ParTableNew ************************************************************ ** ** Initializes a new parameter table object. ** ** INPUT: pointer to memory location [W] ** IMPLICIT: ** ** RETURNS: */ static void ParTableNew (void *obj) { static INT4 parClassId=0, parTypeClassId=0; PARoTABLE *table = (PARoTABLE *) obj; if (!parClassId) { LstManageClassFlex (&parClassId, sizeof (PARo), ParNew, NULL, ParDump); LstManageClassFlex (&parTypeClassId, sizeof (PARoTYPE), NULL, NULL, NULL); } table->parClassId = parClassId; table->parTypeClassId = parTypeClassId; table->parN = 0; table->parTypeN = 0; table->par = NULL; table->parType = NULL; } /***** ParTableKill *********************************************************** ** ** Deletes a parameter table object. ** ** INPUT: pointer to memory location [W] ** IMPLICIT: ** ** RETURNS: */ static void ParTableKill (void *obj) { PARoTABLE *table = (PARoTABLE *) obj; if (table->par) LstDeleteAll ((void **)&table->par); if (table->parType) LstDeleteAll ((void **)&table->parType); } /**api* ParGetTable *********************************************************** ** ** Returns table object for specified name. ** ** INPUT: table name [R] ** IMPLICIT: ** parTable [W] ** ** RETURNS: ** address of parameter table object */ PARoTABLE *ParGetTable (char *name) { PARoTABLE *tmp = parTable; if (!LstHashSearch ((void **) &tmp, name)) _ErrExit3 (e__objectunknown, "parameter table", name); return tmp; } /***** ParSetTable ************************************************************ ** ** ** INPUT: o table name [R] ** o table name of table that the new table is added to [R] ** if omitted then the currently active table is used ** o option: "private", "layered" [R] ** IMPLICIT: ** parTable [W] ** ** RETURNS: ** address of parameter table object */ PARoTABLE *ParSetTable (char *name, char *upName, char *option) { static INT4 classId=0; static PARoTABLE *table=NULL; PARoTABLE *upTable = parTable; if (!classId) LstManageClass (&classId, sizeof (PARoTABLE), ParTableNew, ParTableKill, NULL); if (upName) if (!LstHashSearch ((void **) &upTable, upName)) _ErrExit3 (e__objectunknown, "parameter table", upName); if (!LstHashSearch ((void **) &table, name)) { LstNewNamed ((void **) &table, classId, name); table->up = upTable; table->type = SmEqs (option, "private") ? PARxPRIVATE : PARxLAYERED; } parTable = table; return table; } /***** ParUnsetTable ************************************************************ ** Sets table that has been set prior to the current one. ** ** INPUT: ** IMPLICIT: ** parTable [W] ** ** RETURNS: ** address of parameter table object */ PARoTABLE *ParUnsetTable () { if (parTable->up) parTable = parTable->up; return parTable; } void ParDeleteTable (char *name) { PARoTABLE *table=parTable; if (!LstHashSearch ((void **) &table, name)) _ErrExit3 (e__objectunknown, "table", name); if (parTable == table) parTable = table->up; LstDelete ((void **) &table); } /***** ParNew ***************************************************************** ** ** initializes parameter list; this is only necessary if predefined ** parameter's + parameter types exists ... ** ** INPUT: parameter name [R] ** IMPLICIT: ** parClassId (int) [W] ** parTypeClassId (int) [W] ** ** RETURNS: address of parameter object */ static void ParNew (void *obj) { PARo *par=(PARo *) obj; memset (par, 0, sizeof (PARo)); par->type = PARxNEW; } /***** ParDump **************************************************************** ** ** initializes parameter list; this is only necessary if predefined ** parameter's + parameter types exists ... ** ** INPUT: file pointer [W] or NULL ** parameter name [R] ** IMPLICIT: ** parClassId (int) [W] ** parTypeClassId (int) [W] ** ** RETURNS: address of parameter object */ static void ParDump (FILE *file, void *obj) { PARo *par=(PARo *) obj; if (!file) file = stderr; switch (par->type) { case PARxNUM: case PARxBOOL: fprintf (file, "#par /name=%s /num=%d\n", par->name, par->num); break; case PARxREAL: fprintf (file, "#par /name=%s /real=%f\n", par->name, par->real); break; case PARxSTR: fprintf (file, "#par /name=%s /str=%s\n", par->name, par->str); break; default: break; } } void ParDumpAll () { LstPrintAll ((void *) parTable->par); } /**api* ParInit *************************************************************** ** ** Initializes parameter table with a predifined parameter table. ** ** INPUT: address of parameter list object [R] ** IMPLICIT: ** parTable (PARoTABLE *) [W] ** ** RETURNS: */ void ParInit (PARoLIST *parList) { PARo *par=NULL; PARoTYPE *parType=NULL; char tmp[256]; int k, len; /* ** Copy parameters from the Parameter list (ODD) to the parameter table. */ LstNewNamed ((void **) &par, parTable->parClassId, "__dummy__"); for (k=0; k < parList->parN; k++) { parList->par[k].classId = parTable->parClassId; LstInsertObject ((void **) &par, &parList->par[k]); } parTable->par = par; /* ** Do the same for the list of parameter types. */ LstNewNamed ((void **) &parType, parTable->parTypeClassId, "__dummy__"); for (k=0; k < parList->parTypeN; k++) { parList->parType[k].classId = parTable->parTypeClassId; LstInsertObject ((void **) &parType, &parList->parType[k]); if (*parType->charSet) { /* expand permissive character set */ strcpy (tmp, parType->charSet); SmCharSet (tmp); parType->charSet = (char *) malloc (strlen (tmp) + 1); strcpy (parType->charSet, tmp); } } parTable->parType = parType; } /***** ParFind **************************************************************** ** ** searches a parameter by name; if not found a new parameter is inserted ** in the list with parameter type PARxNEW and returned; ** ** INPUT: parameter name [R] ** IMPLICIT: ** parTable (PARoTABLE *) [W] ** ** RETURNS: address of parameter object */ PARo *ParFind (char *parName) { if (!parTable) ParInit (NULL); if (!LstHashSearch ((void **) &parTable->par, parName)) LstNewNamed ((void **) &parTable->par, parTable->parClassId, parName); return parTable->par; } /**api* ParGetRead ************************************************************ ** ** Searches a parameter for read access. ** If the table is not specified then the one currently active is used. ** ** INPUT: parameter name [R] ** parameter table [R] or NULL ** IMPLICIT: ** parTable (PARoTABLE *) [W] ** ** RETURNS: address of parameter object ** NULL if not found */ PARo *ParGetRead (char *parName, PARoTABLE *table) { PARo *getPar=NULL; if (!table) table = parTable; for (; table; table=table->up) if (LstHashSearch ((void **) &table->par, parName)) { getPar = table->par; break; } return getPar; } /**api* ParGetWrite *********************************************************** ** ** Retrieves a parameter for write access. ** If the table is not specified then the one currently active is used. ** ** INPUT: parameter name [R] ** parameter table [W] or NULL ** IMPLICIT: ** parTable (PARoTABLE *) [W] ** ** RETURNS: address of parameter object ** NULL if not found */ PARo *ParGetWrite (char *parName, PARoTABLE *table) { PARoTABLE *tmp; PARo *getPar=NULL; char *intern; if (!table) table = parTable; for (tmp=parTable; tmp; tmp=tmp->up) { if (LstHashSearch ((void **) &tmp->par, parName)) { /* if found in upper table than copy it to current table */ if (tmp != table) { LstNewNamed ((void **) &table->par, table->parClassId, parName); getPar = table->par; intern = getPar->intern; /* save the pointer to the list */ memcpy (getPar, tmp->par, sizeof (PARo)); getPar->intern = intern; if (tmp->par->str) { getPar->str = (char *) malloc (strlen (tmp->par->str) + 1); strcpy (getPar->str, tmp->par->str); } } else getPar = tmp->par; break; } } /* create new parameter in current table if not found */ if (!getPar) { LstNewNamed ((void **) &table->par, table->parClassId, parName); getPar = table->par; } return getPar; } /**API* ParDelete ************************************************************* ** ** Deletes parameter with specified name. ** ** INPUT: parameter name [R] ** IMPLICIT: ** parTable (PARoTABLE *) [W] ** ** RETURNS: 1 if parameter was found and deleted ** 0 if parameter was not found */ INT4 ParDelete (char *parName) { PARo *par; if (!(par = ParGetRead (parName, parTable))) return 0; parTable->par = par; LstDelete ((void**) &parTable->par); return 1; } /**API* ParDeleteMatch ******************************************************** ** ** Searches all parameters for regular expression and delete all that ** match. ** ** INPUT: regular expression [R] ** IMPLICIT: ** ** RETURNS: number of parameters deleted */ INT4 ParDeleteMatch (char *reStr) { regexp *re; INT4 k=0; re = RegComp (reStr); LstFirst ((void **) &parTable->par); do { if (RegExec (re, parTable->par->name)) { LstDelete ((void**) &parTable->par); k++; } else LstNext ((void **) &parTable->par); } while (!LstIsLast ((void *) parTable->par)); if (RegExec (re, parTable->par->name)) { LstDelete ((void**) &parTable->par); k++; } free (re); return k; } INT4 ParDeleteAssign (char *s) { if (*s) ParDeleteMatch (s); } /**API* ParDefNum ************************************************************* ** ** Inserts or modifies a "number" parameter. ** ** INPUT: parameter name [R] ** parameter value [R] ** IMPLICIT: ** ** RETURNS: 1 if parameter was found ** 0 if it has been inserted ** invalid value: e__parnottype + */ INT4 ParDefNum (char *parName, INT4 num) { PARo *par; par = ParGetWrite (parName, parTable); return ParODefNum (par, num); } /**API* ParDefBool ************************************************************** ** Inserts or modifies a "boolean" parameter. ** ** INPUT: parameter name [R] ** parameter value [R] ** IMPLICIT: ** ** RETURNS: 1 if parameter was found ** 0 if it has been inserted ** invalid value: e__parnottype + */ INT4 ParDefBool (char *parName, INT4 num) { PARo *par; par = ParGetWrite (parName, parTable); return ParODefNum (par, num); } /**API* ParDefReal ************************************************************ ** ** Inserts or modifies a "real" parameter. ** ** INPUT: parameter name [R] ** parameter value [R] ** IMPLICIT: ** parTable (PARoTABLE *) [W] ** ** RETURNS: 1 if parameter was found ** 0 if it has been inserted ** invalid value: e__parnottype + */ INT4 ParDefReal (char *parName, float real) { PARo *par; par = ParGetWrite (parName, parTable); return ParODefReal (par, real); } /**API* ParDefStr ************************************************************* ** ** Inserts or modifies a "string" parameter. ** ** INPUT: parameter name [R] ** parameter value [R] ** IMPLICIT: ** parTable (PARoTABLE *) [W] ** ** RETURNS: 1 if parameter was found ** 0 if it has been inserted ** invalid value: e__parnottype + */ INT4 ParDefStr (char *parName, char *str) { PARo *par; par = ParGetWrite (parName, parTable); return ParODefStr (par, str); } /**API* ParDefFunction ******************************************************** ** ** Inserts or modifies a "function" parameter. ** ** INPUT: parameter name [R] ** parameter value [R] ** IMPLICIT: ** parTable (PARoTABLE *) [W] ** ** RETURNS: 1 if parameter was found ** 0 if it has been inserted ** invalid value: e__parnottype + */ INT4 ParDefFunction (char *parName, INT4 (*function) ()) { PARo *par; par = ParGetWrite (parName, parTable); return ParODefFunction (par, function); } /**api* ParGetNumF ************************************************************ ** ** Calls ParGetNum with variable length argument lists ** ** ** INPUT: pointer to string ** ** ** RETURNS: modified string ** **/ INT4 ParIsDefinedF(char *strfmt, ...) { char parName[200]; va_list args; va_start(args,strfmt); vsprintf(parName,strfmt,args); va_end(args); return ParIsDefined (parName); } /**api* ParGetNumF ************************************************************ ** ** Calls ParGetNum with variable length argument lists ** ** ** INPUT: pointer to string ** ** ** RETURNS: modified string ** **/ INT4 ParGetNumF(char *strfmt, ...) { char parName[200]; va_list args; va_start(args,strfmt); vsprintf(parName,strfmt,args); va_end(args); return ParGetNum (parName); } /**api* function ************************************************************** ** ** Does a ParGetStr with variable length argument lists ** ** INPUT: pointer to string ** ** ** RETURNS: modified string ** ** */ char *ParGetStrF (char *strfmt, ...) { char parName[200]; va_list args; va_start(args,strfmt); vsprintf(parName,strfmt,args); va_end(args); return ParGetStr(parName); } /** RParGetBool ********************************************************************** ** ** Does a ParGetBool with variable length argument lists ** ** INPUT: pointer to string ** ** ** RETURNS: modified string ** ** ** ** */ INT4 ParGetBoolF(char *strfmt, ...) { char parName[200]; va_list args; va_start(args,strfmt); vsprintf(parName,strfmt,args); va_end(args); return ParGetBool(parName); } /**api* function ************************************************************** ** ** Does a variable format ParDefStr ** ** INPUT: pointer to string ** ** ** RETURNS: modified string ** ** */ INT4 ParDefStrF (char *str, char *parNameF, ...) { char parName[200]; va_list args; va_start (args, parNameF); vsprintf (parName, parNameF, args); va_end (args); return ParDefStr (parName, str); } /** RParDelete *********************************************************** ** ** Variable format ParDelete ** ** INPUT: pointer to string ** ** RETURNS: modified string ** ** */ INT4 ParDeleteF (char *strfmt, ...) { char parName[200]; va_list args; va_start(args,strfmt); vsprintf(parName,strfmt,args); va_end(args); return ParDelete(parName); } /**API* ParDefObject ********************************************************** ** ** Inserts or modifies an "object" parameter. ** ** INPUT: parameter name [R] ** parameter value [R] ** IMPLICIT: ** parTable (PARoTABLE *) [W] ** ** RETURNS: 1 if parameter was found ** 0 if it has been inserted ** invalid value: e__parnottype + */ INT4 ParDefObject (char *parName, void *object) { PARo *par; par = ParGetWrite (parName, parTable); return ParODefObject (par, object); } /**API* ParGetNum ************************************************************* ** ** Retrieves the value of a "number" parameter. ** ** INPUT: parameter name [R] ** IMPLICIT: ** ** RETURNS: value if parameter found ** 0 if not (default value) */ INT4 ParGetNum (char *parName) { PARo *par; if ((par = ParGetRead (parName, parTable))) return ParOGetNum (par); else return 0; } /**API* ParGetBool ************************************************************ ** ** Retrieves the value of a "boolean" parameter. ** parameter may be a number or string ("1", "yes", "ja", "on"). ** ** INPUT: parameter name [R] ** IMPLICIT: ** ** RETURNS: value if parameter found ** 0 if not */ INT4 ParGetBool (char *parName) { PARo *par; if ((par = ParGetRead (parName, parTable))) return ParOGetBool (par); else return 0; } /**API* ParGetReal ************************************************************ ** ** Retrieves the value of a "real" parameter. ** ** INPUT: parameter name [R] ** IMPLICIT: ** ** RETURNS: value if parameter found ** 0 if not (default value) */ float ParGetReal (char *parName) { PARo *par; if ((par = ParGetRead (parName, parTable))) return ParOGetReal (par); else return 0; } /**API* ParGetStr ************************************************************* ** ** Retrieves the value of a "string" parameter. ** ** INPUT: parameter name [R] ** IMPLICIT: ** ** RETURNS: value if parameter found ** address to empty string if not */ char *ParGetStr (char *parName) { static char nullString[1]=""; PARo *par; if ((par = ParGetRead (parName, parTable))) return ParOGetStr (par); else return nullString; } /**API* ParGetFunction ******************************************************** ** ** Retrieves the value of a "function" parameter. ** ** INPUT: parameter name [R] ** IMPLICIT: ** ** RETURNS: value if parameter found ** NULL if not */ INT4 (*ParGetFunction (char *parName))() { PARo *par; if ((par = ParGetRead (parName, parTable))) return ParOGetFunction (par); else return NULL; } /**API* ParGetObject ********************************************************** ** ** Retrieves the value of an "object" parameter. ** ** INPUT: parameter name [R] ** IMPLICIT: ** ** RETURNS: value if parameter found ** NULL if not */ void *ParGetObject (char *parName) { PARo *par; if ((par = ParGetRead (parName, parTable))) return ParOGetObject (par); else return NULL; } /**api* ParIsModified ********************************************************* ** ** returns TRUE if any of the parameters was changed since reading into ** memory ** ** INPUT: ** IMPLICIT: ** table (PARoTABLE *) [R] ** ** RETURNS: TRUE if at least one parameter is changed ** FALSE if not */ INT4 ParIsModified () { return parTable->isModified; } /**api* ParIsDefined ********************************************************** ** ** returns TRUE if the parameter exists already ** ** INPUT: ** IMPLICIT: ** parTable (PARoTABLE *) [R] ** ** RETURNS: TRUE if exists ** FALSE if not */ INT4 ParIsDefined (char *parName) { return ParGetRead (parName, parTable) ? 1 : 0; } /**api************************************************************************* ** ** functions that get single descriptive values in the parameter object ** ** INPUT: address of parameter object [W] ** ... ** IMPLICIT: ** ** RETURNS: */ char *ParOGetHelpTopic (PARo *par) { return par->helpTopic; } char *ParOGetComment (PARo *par) { return par->comment; } char *ParOGetKey (PARo *par) { return par->key; } char *ParOCharSet (PARo *par) { return par->parType ? par->parType->charSet : NULL; } INT4 ParOGetNum (PARo *par) { /* convert string to integer */ if (par->type & PARxSTR && !(par->type & PARxNUM)) { par->num = atoi (par->str); par->type = par->type | PARxNUM; } if (!(par->type & PARxNUM || par->type & PARxBOOL)) _ErrExit3 (e__parnottype, par->name, "number"); return par->num; } INT4 ParOGetBool (PARo *par) { /* a boolean may be stored as a string parameter: "yes", "ja", "on" */ if (par->type == PARxSTR) { if (strchr ("yj", tolower (par->str[0])) || strchr ("n", tolower (par->str[1]))) { par->num = 1; par->type = par->type | PARxBOOL; } else if (!(par->type & PARxNUM || par->type & PARxBOOL)) _ErrExit3 (e__parnottype, par->name, "number/boolean/string"); } return par->num; } float ParOGetReal (PARo *par) { if (!(par->type & PARxREAL)) _ErrExit3 (e__parnottype, par->name, "real"); return par->real; } char *ParOGetStr (PARo *par) { char s[20]; if (!(par->type & PARxSTR) && par->type & PARxNUM) { sprintf (s, "%d", par->num); par->type = par->type | PARxSTR; ParODefStr (par, s); } else if (!(par->type & PARxSTR)) _ErrExit3 (e__parnottype, par->name, "string"); return par->str; } INT4 (*ParOGetFunction (PARo *par))() { if (par->type != PARxFUNCTION) _ErrExit3 (e__parnottype, par->name, "function"); return par->function; } void *ParOGetObject (PARo *par) { if (par->type != PARxOBJECT) _ErrExit3 (e__parnottype, par->name, "object"); return par->object; } INT4 ParOGetType (PARo *par) { return par->type; } /**api************************************************************************* ** ** functions that set single descriptive values in the parameter object ** ** INPUT: address of parameter object [W] ** ... ** IMPLICIT: ** ** RETURNS: */ void ParODefHelpTopic (PARo *par, char *helpTopic) { par->helpTopic = helpTopic; } void ParODefComment (PARo *par, char *comment) { par->comment = comment; } void ParODefKey (PARo *par, char *key) { par->key = key; } void ParODefCharSet (PARo *par, char *charSet) { if (par->parType) par->parType->charSet = charSet; } void ParODefType (PARo *par, char *parTypeName) { LstFirstNamed ((void **) &parTable->parType, parTypeName); par->parType = parTable->parType; } INT4 ParODefNum (PARo *par, INT4 num) { /* _ErrRet (ParOCheckNum (par, num)); */ if (par->isLocked) return 0; if (par->type & PARxSTR) par->type = PARxNUM; /* forces implicit conversion next time accessed as str */ else par->type |= PARxNUM; if (!par->num != num) parTable->isModified = 1; /* record change */ par->num = num; return 1; } INT4 ParODefStr (PARo *par, char *str) { int rv; if (par->isLocked) return 0; if (!str) return 0; if (par->type == PARxNUM){ /* string should be tested if contains digits */ return ParODefNum (par, atoi (str)); } if (par->type == PARxBOOL) return ParODefBool (par, str); if (par->type & PARxNUM) par->type = PARxSTR; /* forces implicit conversion next time accessed as num */ else par->type |= PARxSTR; if (par->set && *par->set) { char com[200]; sprintf (com, par->set, str); IcaEval (NULL, com); } rv = ParOCheckStr (par, str); _ErrRet (rv); if (!par->str || strcmp (par->str, str)) { /** record change */ parTable->isModified = 1; if (par->str && !OddIsInDepot (par->str)) free (par->str); /* delete ...new string could be larger */ par->str = (char *) malloc (strlen (str) + 1); strcpy (par->str, str); } return 1; } INT4 ParODefReal (PARo *par, float real) { if (par->isLocked) return 0; par->type |= PARxREAL; par->real = real; return 1; } INT4 ParODefFunction (PARo *par, INT4 (*function)()) { if (par->isLocked) return 0; par->type |= PARxFUNCTION; par->function = function; return 1; } INT4 ParODefObject (PARo *par, void *object) { if (par->isLocked) return 0; par->type = PARxOBJECT; par->object = object; return 1; } static INT4 ParODefBool (PARo *par, char *str) { INT4 val; if (par->isLocked) return 0; if (strchr ("yj", tolower (str[0]))) /* yes, ja */ val = 1; else if (strchr ("n", tolower (str[1]))) /* on */ val = 1; else val = 0; par->type |= PARxBOOL; if (!par->num != val) parTable->isModified = 1; /* record change */ ParODefNum (par, val); return 1; } /**API* ParSetVolatile ******************************************************** ** ** Sets the parameter so that it does not get saved by ParSave. ** ** INPUT: parameter name [R] ** IMPLICIT: ** ** RETURNS: */ void ParSetVolatile (char *parName) { PARo *par; if ((par = ParGetRead (parName, parTable))) par->isVolatile = 1; } /**API* ParLock *************************************************************** ** ** Locks a parameter to prevent modification until unlocked again. ** ** INPUT: parameter name [R] ** IMPLICIT: ** ** RETURNS: */ void ParLock (char *parName) { PARo *par; if ((par = ParGetRead (parName, parTable))) par->isLocked = 1; } /**API* ParUnlock ************************************************************* ** ** Unlocks a parameter. ** ** INPUT: parameter name [R] ** IMPLICIT: ** ** RETURNS: */ void ParUnlock (char *parName) { PARo *par; if ((par = ParGetRead (parName, parTable))) par->isLocked = 0; } /**api************************************************************************* ** ** checks a 'string' value ** ** INPUT: parameter object [R] ** string [R] ** IMPLICIT: ** ** RETURNS: ** 1 if value OK ** e__parnottype + ** e__checkfunctionerr <> ** e__strnotinset + ** e__charnotallowed + */ int ParOCheckStr (PARo *par, char *str) { PARoTYPE *parType; int isFound=0, len, k; if (!(par->type & PARxSTR || par->type & PARxBOOL)) /* parameter type */ _ErrRet3 (e__parnottype, par->name, "string"); if ((parType = par->parType)) { /* now use parType object... */ len = strlen (str); if (parType->charSet) /* test character set */ for (k=0; k < len; k++) if (!strchr (parType->charSet, str[k])) _ErrRet3 (e__charnotallowed, str[k], par->name); if (parType->max) { if (len > parType->max || len < parType->min) /* string length */ _ErrRet3 (e__invalstr, parType->min, parType->max); } if (parType->check) /* user check function */ if (!(*parType->check) (str)) return e__checkerr; } return 1; } /**api************************************************************************* ** ** checks a 'num' value ** ** INPUT: parameter object [R] ** number [R] ** IMPLICIT: ** ** RETURNS: ** 1 if value OK ** e__parnottype + ** e__checkfunctionerr <> ** e__numnotinset + */ int ParOCheckNum (PARo *par, int num) { PARoTYPE *parType; int isFound=0; if (par->type != PARxNUM && par->type != PARxBOOL) /* parameter type */ _ErrRet3 (e__parnottype, par->name, "number"); if ((parType = par->parType)) { if (num > parType->max || num < parType->min) /* number range */ _ErrRet3 (e__invalnumber, parType->min, parType->max); if (parType->check) /* user check function */ if (!(*parType->check) (num)) return e__checkerr; } return 1; } /**api************************************************************************* ** ** checks a 'real' value ** ** INPUT: parameter object [R] ** real [R] ** IMPLICIT: ** ** RETURNS: ** 1 if value OK ** e__parnottype + ** e__checkfunctionerr <> ** e__realnotinset + */ int ParOCheckReal (PARo *par, float real) { PARoTYPE *parType; int isFound=0; if (par->type != PARxREAL) /* parameter type */ _ErrRet3 (e__parnottype, par->name, "real"); if ((parType = par->parType)) { if (real > parType->maxReal || real < parType->minReal) /* range */ _ErrRet5 (e__realnotinrange, real, parType->minReal, parType->maxReal, par->name); if (!parType->check) /* user check function */ if (!(*parType->check) (real)) return e__checkerr; } return 1; } /**api************************************************************************* ** ** checks a 'function' value ** ** INPUT: parameter object [R] ** function pionter [R] ** IMPLICIT: ** ** RETURNS: ** 1 if value OK ** e__parnottype + ** e__checkfunctionerr <> ** e__functionnotinset + */ int ParOCheckFunction (PARo *par, INT4 (*function) ()) { PARoTYPE *parType; int isFound=0; if (par->type != PARxFUNCTION) /* parameter type */ _ErrRet3 (e__parnottype, par->name, "function"); if ((parType = par->parType)) { if (!parType->check) /* user check function */ if (!(*parType->check) (function)) return e__checkerr; } return 1; } /**api* ParSave *************************************************************** ** ** saves parameters in ODD-file; ** ** INPUT: file name of output file [R] ** IMPLICIT: ** ** RETURNS: */ void ParSave (char *fileName) { FILE *file; INT4 errCode, context; file = (FILE *) FilOpenW (fileName, &errCode); _ErrExit2 (errCode, fileName); for (context=0; ParPrintNext (file, &context, "odd");) ; fclose (file); } /**api* ParIsVolatileName ***************************************************** ** ** Analyses if the name has the 'volatile' mark at the end, removes it ** and sets the parameter volatile. ** ** INPUT: parameter name [W] ** IMPLICIT: ** ** RETURNS: 1 or 0 */ Int4 ParIsVolatileName (char *name) { Int4 len=strlen(name); if (name[len-1] == '~') { name[len-1] = '\0'; ParSetVolatile (name); } } /**api* ParRead *************************************************************** ** ** reads user defined parameters from SRSPARAM in either the user's home ** directory, or if it does not exist there in SRSDAT ** ** INPUT: file of input file [R] ** IMPLICIT: ** ** RETURNS: 1 if successful ** e__filnotok */ INT4 ParRead (char *fileName) { STRv str=StrNew (); FILo file; INT4 num, rv; float real; char s[PARxXSTR+1], parName[PARxXNAM+1]; rv = FilUOpen (&file, fileName, PARxXSTR+20, 0); _ErrRet (rv); while (!FilEof (&file)) { if (sscanf (file.ln, "#par /name=%[^ /] /num=%d", parName, &num) == 2) { ParIsVolatileName (parName); ParDefNum (parName, num); } else if (sscanf (file.ln, "#par /name=%[^ /] /bool=%d", parName, &num)==2){ ParIsVolatileName (parName); ParDefBool (parName, num); } else if (sscanf (file.ln, "#par /name=%[^ /] /real=%f", parName,&real)==2){ ParIsVolatileName (parName); ParDefReal (parName, real); } else if ((rv = (sscanf(file.ln, "#par /name=%[^ /] /str=%[^\n]", parName, s))) >= 1) { StrSetS (&str, s); StrDecode (&str); ParIsVolatileName (parName); if (rv == 2) ParDefStr (parName, _Str(str)); else ParDefStr (parName, ""); } else _ErrMsg2 (e__novalformat, file.ln); FilURead (&file); } FilUClose (&file); return 1; } /**api* ParPrintNext ********************************************************** ** ** prints the next (or first if context=0) parameter in various formats; ** ** INPUT: output file [W] ** address of context [W] ** IMPLICIT: ** ** RETURNS: 1 if successful ** 0 if last parameter was reached */ INT4 ParPrintNext (FILE *file, INT4 *context, char *option) { static PARo *par=NULL; static STRv str=NULL; if (!str) str = StrNew (); if (!*context || !par) { par = parTable->par; LstFirst ((void **) &par); *context = 1; } else if (!LstNext ((void **) &par)) { *context = 0; /* list is exhausted */ par = NULL; return 0; } while (1) { if (par->isVolatile) return 1; else if (par->type & PARxBOOL ) { fprintf (file, "#par /name=%s /bool=%d\n", par->name, par->num); break; } else if (par->type & PARxSTR ) { StrSetS (&str, par->str); StrEncode (&str); fprintf (file, "#par /name=%s /str=%s\n", par->name, _Str (str)); break; } else if (par->type & PARxNUM ) { fprintf (file, "#par /name=%s /num=%d\n", par->name, par->num); break; } else if (par->type & PARxREAL ) { fprintf (file, "#par /name=%s /real=%f\n", par->name, par->real); break; } else { if (!LstNext ((void **) &par)) { *context = NULL; par = NULL; return 0; } } } return 1; } , par->str); StrEncode (&str); fprintf (file, "#par /name=%s /str=%s\n", par->name, _Str (str)); break; } else if (par->type & PARxNUM ) { fprintf (file, "#par /name=%s /num=%d\n", par->name, par->num); break; } else if (par->type & PARxREAL ) { fprintf (file, "#par /name=%s /real=%f\n", par->nsrs/src/par.h ** ** $RCSfile: par.h,v $ ** $Revision: 1.2 $ ** $Date: 1996/07/14 16:21:24 $ ** $Author: etzold $ ** ** $Locker: $ ** $State: Exp $ ** */ enum par_type {PARxNEW=0, PARxSTR=1, PARxNUM=2, PARxREAL=4, PARxFUNCTION=8, PARxBOOL=16, PARxOBJECT=32}; #define PARxPARNOTDEF 100000 #define PARxPARNULL 99999 #define PARxON 1 #define PARxOFF 0 #ifndef _PARoTABLE typedef struct PARoLIST *dummytointroducestructtagPARoLIST; #endif #ifndef PARoTABLE typedef struct PARoTABLE *dummytointroducestructtagPARoTABLE; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of exported functions */ /* acting on the parameter table */ void ParInit (struct PARoLIST *parList); INT4 ParIsModified (); void ParDumpAll (); INT4 ParRead (char *fileName); void ParSave (char *fileName); INT4 ParPrintNext (FILE *file, INT4 *context, char *option); INT4 ParDelete (char *parName); INT4 ParDeleteMatch (char *reStr); struct PARoTABLE *ParSetTable (char *name, char *upName, char *option); void ParDeleteTable (char *name); struct PARoTABLE *ParUnsetTable (); struct PARoTABLE *ParGetTable (char *name); /* define parameters */ INT4 ParDefNum (char *par_nm, INT4 num); INT4 ParDefBool (char *par_nm, INT4 num); INT4 ParDefReal (char *par_nm, float real); INT4 ParDefStr (char *par_nm, char *str); INT4 ParDefFunction (char *par_nm, INT4 (*function) ()); INT4 ParDefObject (char *par_nm, void *object); /* retrieve parameter values */ INT4 ParGetNum (char *par_nm); INT4 ParGetBool (char *parName); float ParGetReal (char *par_nm); char *ParGetStr (char *par_nm); INT4 (*ParGetFunction (char *par_nm))(); void *ParGetObject (char *par_nm); INT4 ParIsDefinedF(char *strfmt, ...); INT4 ParGetNumF(char *strfmt, ...); INT4 ParGetBoolF(char *strfmt, ...); char *ParGetStrF(char *strfmt, ...); INT4 ParDeleteF (char *strfmt, ...); INT4 ParDefStrF (char *parName, char *strfmt, ...); /* get a pointer to parameter of various types */ struct PARo *ParGetRead (char *parName, struct PARoTABLE *table); struct PARo *ParGetWrite (char *parName, struct PARoTABLE *table); struct PARo *ParFind (char *parName); struct PARo *ParGetDefault (char *parName); struct PARo *ParNextValue (struct PARo *par, INT4 *context); struct PARo *ParGetNeighbour (char *parName); /* info from parameter using parameter pointer */ INT4 ParOGetState (struct PARo *par); char *ParOGetHelpTopic (struct PARo *par); char *ParOGetComment (struct PARo *par); char *ParOGetKey (struct PARo *par); char *ParOGetCharSet (struct PARo *par); INT4 ParOGetType (struct PARo *par); INT4 ParOGetNum (struct PARo *par); char *ParOGetStr (struct PARo *par); float ParOGetReal (struct PARo *par); INT4 (*ParOGetFunction (struct PARo *par))(); void *ParOGetObject (struct PARo *par); /* manipulate parameter using parameter pointer */ void ParODefState (struct PARo *par, INT4 state); void ParODefHelpTopic (struct PARo *par, char *helpTopic); void ParODefComment (struct PARo *par, char *comment); void ParODefKey (struct PARo *par, char *key); void ParODefCharSet (struct PARo *par, char *charSet); void ParODefType (struct PARo *par, char *parTypeName); INT4 ParODefNeighbour (struct PARo *par, char *parName); void ParODefValue (struct PARo *par, struct PARo *valPar); INT4 ParODefNum (struct PARo *par, INT4 num); INT4 ParODefStr (struct PARo *par, char *str); INT4 ParODefReal (struct PARo *par, float real); INT4 ParODefFunction (struct PARo *par, INT4 (*function) ()); INT4 ParODefObject (struct PARo *par, void *object); /* others */ INT4 ParIsDefined (char *par_nm); void ParUnlock (char *parName); void ParLock (char *parName); void ParSetVolatile (char *parName); ghbour (struct PARo *par, char *parName); void ParODefValue (struct PARo *par, struct PARo *valPar); INT4 ParODefNum (struct PARo *par, INT4 num); INT4 ParODefStr (struct PARo *par, char *str); INT4 ParODefReal (struct PARo *par, float real); INT4 ParODefFunction (struct PARo srs/src/print.c #include #include #include "def.h" #include "print.h" #include "oldlistbuf.h" #include "string.h" /***************************************************************** ** IMPLEMENTATION utilities */ PRINTv Active[20]; PRINTv* LastActive=Active; PRINTv Printer=NULL; void NoFormat(PRINTv out, char command, ...) { /* command does nothing */ } void PushPrinter() { *(LastActive++)=Printer; } void PopPrinter() { Printer=*(--LastActive); } PRINTv CopyPrinter(PRINTv p) { p->usage++; return p; } /***************************************************************** ** API functions - no context */ void xPrintBuf(PRINTv out, BYTE* buf, int n) { do { int want=n; BYTE* s=call(out->book)(out, &want); n-=want; while (want--) *s++=*buf++; } while (n); } void xPrintClose(PRINTv* out) { PRINTv p=*out; if (!--p->usage) {call (p->close) (p, NULL, 0); } *out=NULL; } void xPrintBufClose(PRINTv* out, BYTE* s, int n) { PRINTv p=*out; if (!--p->usage) call (p->close) (p, s, n); *out=NULL; } void xPrintFormat(PRINTv out, char comm, ...) { va_list l; va_start(l, comm); call (out->format)(out, comm, l); va_end(l); } void xPrintInt(PRINTv out, int i) { char buf[20]; char* p=buf; xPrintFormat(out, '['); sprintf(buf, "%d", i); while (*p) xPrint(out, *p++); xPrintFormat(out, ']'); } void xPrintS(PRINTv out, char* s) { xPrintFormat(out, '['); xPrintBuf(out, s, strlen(s)); xPrintFormat(out, ']'); } void xPrintStr(PRINTv out, STRv s) { xPrintS(out, Str(s)); } /***************************************************************** ** API functions - contextual */ PRINTv PrintGet() { Printer->usage++; return Printer; } void PrintClose() { xPrintClose(&Printer); PopPrinter(); } void PrintBufClose(BYTE* s, int n) { xPrintBufClose(&Printer, s, n); PopPrinter(); } void PrintBuf(BYTE* buf, int n) { xPrintBuf(Printer, buf, n); } void PrintInt(int i) { xPrintInt(Printer, i); } void PrintS(char* s) { xPrintS(Printer, s); } void PrintStr(STRv s) { xPrintStr(Printer, s); } void PrintFormat(char comm, ...) { va_list l; va_start(l, comm); call (Printer->format)(Printer, comm, l); va_end(l); } /************************************************************ ** output to STRING */ /* string writer */ #define PRINT_BUF_DIM 256 typedef struct PRINToBUF { BYTE buf[PRINT_BUF_DIM]; struct PRINToBUF* next; } PRINToBUF; /* buffered string writer */ typedef struct PRINToSTR { PRINTo head; STRv* dest; BYTE* pos; BYTE* stop; PRINToBUF* beg; PRINToBUF* buf; int len; } PRINToSTR; /************************************************************ ** BUFFERED output to string */ void PrintBufOverflow(PRINToSTR* out) { /* allocate new buffer */ BYTE* s; PRINToBUF* buf=typeAlloc(PRINToBUF); buf->next=NULL; out->buf->next=buf; out->buf=buf; s=buf->buf; out->pos=s; out->stop=s+PRINT_BUF_DIM; out->len+=PRINT_BUF_DIM; } void StrPrintBufPut(PRINToSTR* out, BYTE c) { if (out->pos!=out->stop) *(out->pos++)=c; else { PrintBufOverflow(out); *(out->pos++)=c; } } BYTE* StrPrintBufBook(struct PRINToSTR* out, int* n) { BYTE* s=out->pos; if (s+*nstop) { out->pos+=*n; return s; } else if (s!=out->stop) { /* ask to fill buffer */ *n=out->stop-s; out->pos=out->stop; return s; } else { PrintBufOverflow(out); return StrPrintBufBook(out, n); } } void StrPrintBufClose(struct PRINToSTR* out, BYTE* src, int n) { int lastLen=out->pos - out->buf->buf; int dlen=out->len+lastLen; STRv val=*out->dest; BYTE* s; PRINToBUF *buf, *next; /* reallocate the string */ if (val) { int len=val->len; StrBufChange(&val,len,len+dlen); s=val->arr+len; } else { val=StrBufNew(dlen); val->len=dlen; s=val->arr; *(s+dlen)='\0'; } *out->dest=val; /* now copy the BYTEs from the buffers */ buf=out->beg; while ((next=buf->next)) { memcpy(s, buf->buf, PRINT_BUF_DIM); free(buf); buf=next; s+=PRINT_BUF_DIM; } /* copy last (not full) buffer */ memcpy(s, buf->buf, lastLen); free(buf); /* kill myself */ free(out); } /*************************************************************** ** UNBUFFERED output to string */ void PrintStrOverflow(PRINToSTR* out) { /* string space exceeded: go to buffered management */ BYTE* s; PRINToBUF* buf; STRv val=*out->dest; if (val) val->len=(char *)out->pos-val->arr; out->head.put=(Putter)StrPrintBufPut; out->head.book=(Booker)StrPrintBufBook; out->head.close=(Closer)StrPrintBufClose; buf=typeAlloc(PRINToBUF); buf->next=NULL; out->beg=out->buf=buf; s=buf->buf; out->pos=s; out->stop=s+PRINT_BUF_DIM; out->len=0; } void PrintStrPut(PRINToSTR* out, BYTE c) { if (out->pos!=out->stop) *(out->pos++)=c; else { PrintStrOverflow(out); *(out->pos++)=c; } } BYTE* PrintStrBook(struct PRINToSTR* out, int* n) { BYTE* s=out->pos; if (s+*nstop) { out->pos+=*n; return s; } else if (s!=out->stop && *out->dest) { /* ask to fill string */ *n=out->stop-s; out->pos=out->stop; return s; } else { PrintStrOverflow(out); return StrPrintBufBook(out, n); } } void PrintStrClose(struct PRINToSTR* out, BYTE* src, int n) { BYTE* s=out->pos; STRv val=*out->dest; if (val) { int len; *s='\0'; len=val->len=(char *)s-val->arr; StrBufChange(&val, len, len+n); memcpy(val->arr+len, src, n); } else { val=StrBufNew(n); val->len=n; memcpy(val->arr, src, n); } *out->dest=val; free(out); } void PrintOpenStr(STRv* out) { PRINToSTR* s=typeAlloc(PRINToSTR); STRv val=*out; PushPrinter(); Printer=(PRINTv)s; s->head.usage=1; s->dest=out; s->head.put=(Putter)PrintStrPut; s->head.book=(Booker)PrintStrBook; s->head.close=(Closer)PrintStrClose; s->head.format=(Formatter)NoFormat; if (val->usage==1 && val->lendim) { s->pos=val->arr; s->stop=val->arr+val->dim; } else { StrDel(val); *out=NULL; s->pos=s->stop=NULL; } } /************************************************************ ** output to FILE */ /* file writer */ #define PRINT_FILE_DIM 256 typedef struct PRINToFILE { PRINTo head; FILE* dest; BYTE buf[PRINT_FILE_DIM]; int num; } PRINToFILE; void PrintFilePut(struct PRINToFILE* out, BYTE c) { if (out->num) { fwrite(out->buf, 1, out->num, out->dest); out->num=0; } putc(c, out->dest); } BYTE* PrintFileBook(struct PRINToFILE* out, int* n) { if (out->num) fwrite(out->buf, 1, out->num, out->dest); if ((out->num=*n)>PRINT_FILE_DIM) out->num=*n=PRINT_FILE_DIM; return out->buf; } void PrintFileClose(struct PRINToFILE* out, BYTE* src, int n) { if (out->num) fwrite(out->buf, 1, out->num, out->dest); fwrite(src, 1, n, out->dest); fclose(out->dest); free(out); } void PrintOpenFileImpl(FILE* file) { PRINToFILE* s=typeAlloc(PRINToFILE); PushPrinter(); Printer=(PRINTv)s; s->head.usage=1; s->dest=file; s->head.put=(Putter)PrintFilePut; s->head.book=(Booker)PrintFileBook; s->head.close=(Closer)PrintFileClose; s->head.format=(Formatter)NoFormat; s->num=0; } void PrintOpenFile(char* fileName) { PrintOpenFileImpl(fopen(fileName, "wb")); } void PrintStdoutClose(struct PRINToFILE* out, BYTE* src, int n) { if (out->num) fwrite(out->buf, 1, out->num, out->dest); fwrite(src, 1, n, out->dest); free(out); } void PrintOpen() { PrintOpenFileImpl(stdout); Printer->close=(Closer)PrintStdoutClose; } /*************************************************************** ** PRETTY PRINTING filter */ /* parses the result, pretty-printing it ** breakAt suggests where to cut lines (no indentation) ** indent, unindent are matching pairs */ #define PRETTY_MASK 0xFF #define PRETTY_BUF_SIZE (PRETTY_MASK+1) #define PRETTY_NOEND 0x7FFF typedef struct PRETTYoBLOCK { LISTBUFv comm; struct PRETTYoBLOCK* up; int end; BOOL broken; } PRETTYoBLOCK; typedef struct PRETTYoCOMMAND { char command; int start; struct PRETTYoBLOCK* block; } PRINToCOMMAND; LISTBUFoINFO PrettyCommandListInfo = { sizeof(PRINToCOMMAND) }; /*CLASSoLISTBUF PrettyCommandListInfo= { sizeof(PRINToCOMMAND), sizeof(LISTBUFo), DefElemCopier, DefElemDeleter, 0, NoHeadCopier, NoHeadDeleter, 0 };*/ typedef struct PRINToPRETTY { /* global state */ PRINTo head; PRINTv out; char line[256]; int width; int minWidth; int step; /* state of delayed output */ int last; int lastIndent; int lastBreak; struct PRETTYoBLOCK* lastBlock; /* state of current output */ int pos; struct PRETTYoBLOCK* currBlock; } PRINToPRETTY; PRINToPRETTY* PrettyCx; /********************************************************************** ** the real printing.. */ void PrettyIndent() { int num=PrettyCx->lastIndent; PRINTv out=PrettyCx->out; PrettyCx->lastBreak=PrettyCx->last+PrettyWidth()-PrettyCx->lastIndent; call (out->put)(out, '\n'); do { int want=num; BYTE* s=call(out->book)(out, &want); num-=want; while (want--) *s++=' '; } while (num); } void PrettyOut(PRINTv out, char c) { if (c=='\n') PrettyIndent(); else call(out->put)(out, c); } /********************************************************************** ** INDENTATION MANAGEMENT */ int PrettyWidth() { if (PrettyCx->width-PrettyCx->lastIndentminWidth) return PrettyCx->lastIndent+PrettyCx->minWidth; else return PrettyCx->width; } BOOL PrettyInNextLine() { int nextWidth=PrettyWidth()-PrettyCx->lastIndent; if (PrettyCx->lastBlock->end-PrettyCx->last<=nextWidth) { PrettyIndent(); return TRUE; } return FALSE; } void PrettyCommand(char command) { switch(command) { case 'N': { PrettyIndent(); } break; case 'I': { PrettyCx->lastIndent += PrettyCx->step; } break; case 'U': { PrettyCx->lastIndent -= PrettyCx->step; } break; } } /*********************************************************************** ** BLOCK PRINTING MANAGEMENT */ void PrettySkip(PRETTYoBLOCK* bl) { Iter comm=bl->comm; PRINToCOMMAND* curr; while (curr=ListBufNext(&bl->comm, &comm)) { if (curr->command=='[') { PrettySkip(curr->block); free(curr->block); } } } BOOL PrettyBlock() { PRETTYoBLOCK* bl=PrettyCx->lastBlock; PRINTv out=PrettyCx->out; BOOL doBreak=TRUE; if (!bl->broken) { if (bl->end==PRETTY_NOEND) { if (PrettyCx->poslastBreak) return FALSE; } else if (bl->endlastBreak || PrettyInNextLine()) doBreak=FALSE; } if (doBreak) { PRINToCOMMAND* curr; Iter comm=NULL; bl->broken=TRUE; comm=ListBufFirst(&bl->comm); while (comm) { curr=(PRINToCOMMAND*)ListBufAt(&bl->comm,comm); while (PrettyCx->last!=curr->start) { if (PrettyCx->last==PrettyCx->pos) return FALSE; if (PrettyCx->last==PrettyCx->lastBreak) PrettyIndent(); PrettyOut(out,PrettyCx->line[PrettyCx->last++&PRETTY_MASK]); } if (curr->command=='[') { PrettyCx->lastBlock=curr->block; ListBufRemove(&bl->comm, &comm); if (!PrettyBlock()) return FALSE; } else { PrettyCommand(curr->command); ListBufRemove(&bl->comm, &comm); } } /* finish block */ while (PrettyCx->last!=bl->end) { if (PrettyCx->last==PrettyCx->pos) return FALSE; if (PrettyCx->last==PrettyCx->lastBreak) PrettyIndent(); PrettyOut(out, PrettyCx->line[PrettyCx->last++&PRETTY_MASK]); } } else { /* if new block fits in PrettyCx->line, print it all */ while (PrettyCx->lastend) PrettyOut(out, PrettyCx->line[PrettyCx->last++&PRETTY_MASK]); PrettySkip(bl); } PrettyCx->lastBlock=bl->up; ListBufDelete(&bl->comm); free(bl); return TRUE; } /**************************************************************** ** PRINTING API */ void PrintPrettyPut(struct PRINToPRETTY* out, BYTE c) { if (out->pos>out->last+out->width) { /* print line, formatting it */ PrettyCx=out; while (PrettyBlock()); } out->line[out->pos++&PRETTY_MASK]=c; } BYTE* PrintPrettyBook(struct PRINToPRETTY* out, int* n) { int avail, pos, toBufEnd; if (out->pos>out->last+out->width) { /* print line, formatting it */ PrettyCx=out; while (PrettyBlock()); } avail=(out->last-out->pos)&PRETTY_MASK; if (!avail) avail=PRETTY_BUF_SIZE; toBufEnd=PRETTY_BUF_SIZE-(out->pos&PRETTY_MASK); if (avail>toBufEnd) avail=toBufEnd; if (*n<=avail) { pos=out->pos; out->pos+=*n; return out->line+(pos&PRETTY_MASK); } else { *n=avail; pos=out->pos; out->pos+=avail; return out->line+(pos&PRETTY_MASK); } } void PrintPrettyFlush(struct PRINToPRETTY* out); void PrintPrettyFormat(struct PRINToPRETTY* out, char command, ...) { PRINToCOMMAND c; switch (command) { case ']': { out->currBlock->end=out->pos; out->currBlock=out->currBlock->up; } break; case '[': { PRETTYoBLOCK* bl=typeAlloc(PRETTYoBLOCK); bl->up=out->currBlock; ListBufCreate(&bl->comm,&PrettyCommandListInfo,5); bl->end=PRETTY_NOEND; bl->broken=FALSE; c.command=command; c.start=out->pos; c.block=bl; if (out->currBlock) ListBufAppend(&out->currBlock->comm, &c); out->currBlock=c.block; } break; case 'I': case 'U': case 'N': { c.command=command; c.start=out->pos; if (out->currBlock) ListBufAppend(&out->currBlock->comm, &c); } break; case 'F': { PrintPrettyFlush(out); PrintPrettyFormat(out, '['); out->lastBlock=out->currBlock; } break; default: { va_list l; va_start(l, command); call(out->out->format)(out->out,command, l); va_end(l); } } } void PrintPrettyFlush(struct PRINToPRETTY* out) { PrettyCx=out; while (out->currBlock) PrintPrettyFormat(out,']'); while (out->lastBlock) PrettyBlock(); } void PrintPrettyClose(struct PRINToPRETTY* out, BYTE* src, int n) { while (n) { int want=n; BYTE* s=PrintPrettyBook(out, &want); n-=want; } /* flush now */ xPrintBuf((PRINTv)out, src, n); PrintPrettyFlush(out); xPrintClose(&out->out); free(out); } PRINToPRETTY* PrintPrettyImpl(int width, int minWidth, int step) { PRINToPRETTY* p=PrettyCx=typeAlloc(PRINToPRETTY); p->head.usage=1; p->head.put=(Putter)PrintPrettyPut; p->head.book=(Booker)PrintPrettyBook; p->head.close=(Closer)PrintPrettyClose; p->head.format=(Formatter)PrintPrettyFormat; p->width=width; p->minWidth=minWidth; p->step=step; p->pos=0; p->currBlock=NULL; PrintPrettyFormat(p,'['); p->last=0; p->lastIndent=0; p->lastBreak=p->width; p->lastBlock=p->currBlock; return p; } void PrintPretty(int width, int minWidth, int step) { PRINToPRETTY* p=PrintPrettyImpl(width, minWidth, step); p->out=Printer; Printer=(PRINTv)p; } void xPrintPretty(PRINTv* out, int width, int minWidth, int step) { PRINToPRETTY* p=PrintPrettyImpl(width, minWidth, step); p->out=*out; *out=(PRINTv)p; } /************************************************************************/ ['); p->last=0; p->lastIndent=0; p->lastBreak=p->width; p->lastBlock=p->currBlock; return p; } void PrintPretty(int width, int minWidth, int step) { PRINToPRETTY* p=PrintPrettyImpl(widsrs/src/print.h #define _MYSTREAM_H #include "strv.h" typedef struct PRINTo* PRINTv; typedef void (*Putter)(PRINTv out, BYTE c); typedef BYTE* (*Booker)(PRINTv out, int* n); typedef void (*Closer)(PRINTv out, BYTE* src, int n); typedef void (*Formatter)(PRINTv out, char command, ...); typedef struct PRINTo { int usage; Putter put; Booker book; Closer close; Formatter format; } PRINTo; extern PRINTv Printer; /* PUBLIC OPERATIONS */ /* stream management operations */ void PrintOpen(); void PrintOpenStr(STRv* out); void PrintOpenFile(char* fileName); /* gets an external copy of the current stream */ PRINTv PrintGet(); /* contextual operations */ void PrintPretty(int width, int minWidth, int step); void PrintClose(); void PrintBufClose(BYTE* s, int n); void PrintFormat(char command, ...); #define Print(char) call(Printer->put)(Printer,char) void PrintBuf(BYTE* buf, int n); void PrintS(char* s); void PrintStr(STRv s); void PrintInt(int i); /* not contextual operations */ void xPrintPretty(PRINTv* out, int width, int minWidth, int step); void xPrintClose(PRINTv* out); void xPrintBufClose(PRINTv* out, BYTE* s, int n); void xPrintFormat(PRINTv out, char comm, ...); #define xPrint(out, char) call(out->put)(out, char) void xPrintBuf(PRINTv out, BYTE* buf, int n); void xPrintInt(PRINTv out, int i); void xPrintS(PRINTv out, char* s); void xPrintStr(PRINTv out, STRv s); #endif n); void PrintS(char* s); void PrintStr(STRv s); void PrintInt(int i); /* not contextual operationssrs/src/query.c char query_srs_ID[] = "$Id: query.c,v 1.12 1997/03/03 18:20:45 srs Exp $"; /* ** ** $RCSfile: query.c,v $ ** $Revision: 1.12 $ ** $Date: 1997/03/03 18:20:45 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port by Lukas Rosenthaler and Reinhard ** ** Author: Gerald Schaefer ** EMBL, Meyerhofstrasse 1 ** D-69012 Heidelberg, Germany ** Tel: 06221 387372 ** Email: schaefer@embl-heidelberg.de ** ** ** Requires: ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include "message.h" #include "futil.h" #include "sm.h" #include "lst.h" #include "strv.h" #include "par.h" #include "regexp.h" #include "ids.h" #include "btree.h" #include "tm.h" #include "library.h" #include "id.h" #include "entry.h" #include "set.h" #include "link.h" #include "seqlib.h" #include "query.h" #include "icarus.h" #include "icaarg.h" #define _CONSTANTS #define _SRS #define _SLB #define _INDEX #include SRSINCLUDE #ifdef sun extern INT4 printf (); #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** constants and enums */ #define QRYxXFIL 10 /* max no of indices opened */ #define QRYxXSNLN 255 #define QRYxXSYM 300 /* max no of tokens in token list */ #define QRYxXST 3000 /* max no of characters allocated for token list */ enum qry_tok {QRYxKEY=1, QRYxNAME, QRYxINDEX, QRYxLPAR, QRYxRPAR, QRYxLBRK, QRYxRBRK, QRYxOP}; /* all token types in the query */ #define QRYxSETOP 32 /* log op have 6th + 4th bit set */ #define QRYxLINK 16 /* link op have 5th + 4th bit set */ #define QRYxLLINK 24 #define QRYxRLINK 25 #define QRYxOR 40 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Describes the external parameter context which determines the ** 'behaviour' of this module. */ typedef struct QUERYoInfo { char doReport; char doListValues; char doRetrieve; char doListFromMatch; char isErrWrongField; char isWWW; Int4 valN; Int4 maxValN; Int4 minValN; Int4 printValN; Int4 printFirstValN; /* retrieving subentries */ SLBo *subEntryLib; Int4 subEntryNo; } QUERYoInfo; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of static functions */ INT4 QueryRangeSearchIndex (SLBo *lib, SLBoFIELD *field, INT4 low, INT4 high, double lowReal, double highReal, INT4 isReal, INT4 isLE, INT4 isRE, INT4 isFirst, INT4 isLast, SETo *set); static INT4 QueryGet ( LIBoINDEX *openinx, SETo *set_p, char *key); static INT4 QueryGetWild (LIBoINDEX *libIndex, SETo *set, char *str, char *wildStr, INT4 cmpLen); static INT4 QryCollectIds (SETo *set, LIBoINDEX *libInx, BTRoREC *record, FIP idFip); static INT4 QryGoGcgDots (FILo *file); static INT4 QrySetSearch (char *s); static INT4 QryKey (char *set_nm); static INT4 QryRetrieveRange (LIBoINDEX *libIndex, SETo *set); static INT4 QryIndexRetrieve (SLBo *lib, SRSoFLD *fieldType, SETo *set); static SETo* QueryDo (char *s, char *name, INT4 isRecursive); static SETo *QueryGetWholeLib (char *libName, SETo *set); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** external, global and module wide variables */ static SETo* resultSet = NULL; static QUERYoInfo queryInfoBuff; static QUERYoInfo* queryInfo=&queryInfoBuff; static INT4 (*print)(char *, ...); void (*QueryPrintValue)()=NULL; /* prints information if result_name is a set */ /* returns: 1 if set, 0 if none */ int dump_info(char *result_name) { SETo *set; set = (SETo*) SetGet(result_name); if (set) { printf("*** Set \"%s\": total of %d entries ***\n", result_name ,set->n); return 1; } return 0; } #define NAMELEN 40 typedef char FILENAME[FILxXNAM+1]; #define MAXNAMES 20 void QuerySetPrintValue (void (*func)()) { if (func) QueryPrintValue = func; } static INT4 qryprintferr (char *ln,...) { va_list ap; va_start (ap, ln); vfprintf (stderr, ln, ap); va_end (ap); return 1; } /****** QueryGet ************************************************************** ** ** searches a key in index and retrieves block of pointers; ** ** INPUT: index object [W] ** set object [W] ** search value [R] ** IMPLICIT: ** ** RETURNS: 1 if key found ** 0 if not */ static INT4 QueryGet ( LIBoINDEX *libInx, SETo *set, char *value) { BTRoREC *record; FIP idFip; if ((record = BtrSearch (libInx->btree, value, &idFip, 0))) { QryCollectIds (set, libInx, record, idFip); return 1; } else return 0; } /****** QueryGetWild ************************************************************ ** ** same as QryGet but takes keys with wildcard at end; ** ** INPUT: address of index-descriptor [W] ** address of set-descriptor [W] ** address of search key [R] ** length of string before wildcard [R] ** IMPLICIT: ** ** RETURNS: 1 if key found ** 0 if not */ static INT4 QueryGetWild (LIBoINDEX *libInx, SETo *set, char *str, char *regexpStr, INT4 cmpLen) { regexp *regExp; BTRoREC *record; FIP idFip; SETo *setTmp; char tmpStr[133]; char setName[SETxXNAM+1]; INT4 rv, maxValN, valCount=0; /* ** compile the regular expression and get the first record to start ** the search */ regExp = RegComp (regexpStr); if (regExp == NULL) _ErrRet2 (e__regerror, "regcomp failure"); if ((--cmpLen)) { /* is 1 if wildcard is at begin ...set to 0 */ if (!(record = BtrSearch (libInx->btree, str, &idFip, cmpLen))) { if (queryInfo->doListFromMatch) record = BtrRecordGet (libInx->btree, BTRxCURR); else return 0; } } else if (!(record = BtrRecordGet (libInx->btree, BTRxFIRST))) return 0; /* ** now iterate over this and following records and try to match ** regular expression */ while (1) { strcpy (tmpStr, record->str); if (FieldIsKeyConvert (libInx->field)) SmEdit (tmpStr, SMxLOWCASE); if (!queryInfo->doListFromMatch && (cmpLen) && memcmp (tmpStr, str, cmpLen) != 0) break; /* string begin not found any more */ if (queryInfo->valN > queryInfo->printValN) break; if (queryInfo->doListFromMatch || RegExec (regExp, tmpStr)) { if (queryInfo->doRetrieve) setTmp = SetNew (setName, "temp"); QryCollectIds (setTmp, libInx, record, idFip); if (queryInfo->doRetrieve) { rv = SetOp (set, setTmp, NULL, QRYxOR); SetDelete (setName); _ErrRet(rv); } } idFip++; /* next entries idFip...if ID index */ if (!(record = BtrRecordGet (libInx->btree, BTRxNEXT))) break; /* no more records */ } free (regExp); return 1; } /****** QryCollectIds ********************************************************* ** ** retrieves id-descriptor in index-file, accesses the ids-file ** and retrieves all ids; ** ** INPUT: library index object [R] ** value record [R] ** set object [W] ** IMPLICIT: ** ** RETURNS: 1 if success */ static INT4 QryCollectIds (SETo *set, LIBoINDEX *libInx, BTRoREC *record, FIP idFip) { BTRoVALUE *valRec; INT4 n; if (queryInfo->doListValues) { n = record->r.value.idN; if (queryInfo->minValN <= n) { if (++queryInfo->valN >= queryInfo->printFirstValN) { if (QueryPrintValue) QueryPrintValue (LibName (libInx->lib), LibGetFieldName (libInx->field), record->str, queryInfo->valN - queryInfo->printFirstValN+1, n); else TemplPrint ("value", record->str, n); } } if (!queryInfo->doRetrieve) return; } set->idType = libInx->field->indexId; valRec = &record->r.value; _ErrStop (SetAlloc (set, valRec->idN, set->idType)); IdsGet (libInx->idsFile, set->id_p, valRec->firstIdFip, valRec->idN); set->n = valRec->idN; if (queryInfo->subEntryNo) { IDoENTRY id, idSub; SetRealloc (set, 2, NULL); /* double in size - enough for subentry-ID */ SetGetID (set, 1, &id); IdBuildSub (&idSub, &id, queryInfo->subEntryNo); set->n = 0; set->idType = idSub.idType; SetAddID (set, &idSub); } return 1; } /****** QryCheckNam *********************************************************** ** ** checks a name within an expression ** ** INPUT: address of name [R] ** IMPLICIT: ** ** RETURNS: 1 if ok ** 0 if not */ INT4 QryCheckNam (char *nam) { return SetTestName (nam); } INT4 QryReadName (SETo *set, char *ln) { return 1; } INT4 QryReadNames (char *fil_nm, char *set_nm) { return 1; } /**API* QrySetToList ********************************************************** ** ** Prints a set as a list of entry names which can be read again ** by "QryReadNames". The format is compatible with the ** GCG file of names. If the global boolean parameter "fosnWithPos" ** is set to 1 and the set contains subentry-IDs (sequence features) ** then the begin and end positions within the parent entry's sequence ** are added. ** function prints to STDOUT unless a print function is defined using ** the global parameter "printf". ** ** INPUT: set name [R] ** IMPLICIT: ** ** RETURNS: no of entries printed ** e__novalnam + */ INT4 QrySetToList (char *set_nm) { SETo *set; ENTRYv entry; IDoENTRY id; char hexnumstr[20], source_nm[40], ln[133]; INT4 k,(*print)(char*, ...)=(INT4(*)(char*,...))ParGetFunction("printf"); if ((set = SetGet (set_nm)) == NULL) _ErrRet2 (e__novalnam, set_nm); /* ** get for every ID in the set the logical name of the flat file (GCG) or the ** library ..or if not available just the library name, the entry name ** and the hexnum string of the entry ID and write them out; */ for (k=1; k <= set->n; k++) { SetGetID (set, k, &id); entry = EntryOpen (&id); IdToStr (&id, hexnumstr); EntrySourceName (entry, source_nm); if (IdIsSub (EntryGetId (entry)) && ParGetBool ("fosnWithPos")) ;/*SlbGetFeature (entry, NULL, NULL);*/ else { sprintf (ln, "%s:%s ! ID: %s\n", source_nm, EntryGetName (entry), hexnumstr); if (!(*print) (ln)) break; } EntryClose (&entry); } return k-1; } /**API* QryLinkOne ************************************************************ ** ** Links a single one entry-ID to a library. ** ** INPUT: o address of ID object [R] ** o library name [R] ** o name of result set [W] if NULL string then a name is ** created and written into char array ** IMPLICIT: ** ** RETURNS: ** 1 ** output set name exists: e__namnotunique + */ INT4 QryLinkOne (IDoENTRY *id, char *lib_nm, char *out_nm) { SETo *tmp, *outset; char tmp_nm[QRYxXNAM+1]; INT4 rv; /* ** new set that contains the one ID to be linked */ tmp = SetNew (tmp_nm, "temp"); tmp->id_p = id->id; tmp->n = 1; rv = SetMakeOwn (tmp, id->idType); _ErrRet(rv); /* ** create output set - name can be optionally supplied but must be unique */ if (*out_nm == '\0') outset = SetNew (out_nm, "temp"); else if (!(outset = SetNew (out_nm, NULL))) return 0; /* ** do the link, delete temporary set and output set if link was not ** successful */ LinkMap (lib_nm, tmp_nm, outset); SetDelete (tmp_nm); if (outset->n) return 1; else { SetDelete (out_nm); return 0; } } #ifdef xxx /**API* QryFindID ************************************************************* ** ** Retrieves a single entry from specified library by searching a word ** in the specified index. ** Returns first ID of the set. This function should be only applied ** where no more than one entry can be found (eg, searching entry names, ** primary accession numbers). ** ** INPUT: name of library [R] ** name of data-field [R] ** search word [R] ** IMPLICIT: ** ** RETURNS: address of ID object ** NULL if no success */ IDoENTRY *QryFindID (char *libName, char *fieldName, char *word) { static IDoENTRY id, *idPtr=NULL; char query[1024], *setName = "__fromQueryFindId__"; if (!LibGetLibGroup (libName, NULL, NULL)) { _ErrMsg3 (e__unknownnam, "Library", libName ); return NULL; } if (LibGetFieldType (libName, fieldName) == NULL) { _ErrMsg3 (e__namnotdef, "Index", fieldName); return NULL; } sprintf (query, "[%s-%s:%s]", libName, fieldName, word); if (QryDo (query, setName)) { SetGetID (SetGet (setName), 1, &id); idPtr = &id; } SetDelete (setName); return idPtr; } #endif /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ /***** QuerySetBehave ********************************************************* ** ** Populates the "queryInfo" object with flags determining the behaviour ** of some of the functions in this module which is determined by ** the global parameters (module "par"). ** ** INPUT: ** IMPLICIT: ** queryInfo (QUERYoInfo *) [W] ** */ static void QuerySetBehave () { memset (queryInfo, 0, sizeof (QUERYoInfo)); queryInfo->isWWW = ParGetBool ("isHTMLFormat") ? 1 : 0; if (ParGetBool ("queryDoReport")) queryInfo->doReport = 1; if (ParGetBool ("queryListValues") || ParGetBool ("queryListFromMatch")) { queryInfo->doListValues = 1; queryInfo->doRetrieve = 0; } else queryInfo->doRetrieve = 1; if (queryInfo->doListValues) { if (ParGetBool ("queryListFromMatch")) queryInfo->doListFromMatch = 1; queryInfo->printFirstValN = ParGetNum ("printIndexFirstValN") ? ParGetNum ("printIndexFirstValN") : 1; queryInfo->valN = 0; queryInfo->maxValN = ParGetNum ("maxIndexValN"); queryInfo->minValN = ParGetNum ("minIndexValN"); if (!ParGetNum ("printIndexValN")) queryInfo->printValN = 2000000000; /* max num will never be reached */ else queryInfo->printValN = ParGetNum ("printIndexValN") + queryInfo->printFirstValN; } } /**API* QueryMakeWild ********************************************************* ** ** Adds wildcards ('*') to the search strings of the query if the ** parameter "makeWild" is ON. ** ** INPUT: STRv with query string [W] ** ** RETURNS: query string with wildcards added */ char *QueryMakeWild (STRv *s) { static ICAoSYNTAX *syntax=NULL; static ICAoJOB *job=NULL; if (!syntax) { syntax = (ICAoSYNTAX *) LibObjByName ("syntax", "makeWild"); job = IcaCreateJob (syntax); } IcaJobSetString (job, _Str(*s)); IcaDoJob (job, "query"); StrSetS (s, IcaGetInputString (job)); IcaEndJob (job); return _Str (*s); } /**api* Query ***************************************************************** ** ** Performs the specified query. If no query name is specified a ** unique temporary name will be used. ** ** INPUT: the SRS query string [R] ** the query name (or NULL) [R] ** ** RETURNS: */ SETo *Query (char *s, char *name) { SETo *set; QuerySetBehave (); set = QueryDo (s, name, 0); return (set && set->n) ? set : NULL; } SETo *QueryRecursive (char *s, char *name) { return QueryDo (s, name, 1); } static SETo *QueryDo (char *s, char *name, INT4 isRecursive) { static ICAoSYNTAX *syntax=NULL; static ICAoJOB *jobStatic=NULL; static INT4 uniqueSetN=0; SETo *resultSetSave, *tmp; ICAoJOB *job; char uniqueName[100]; if (!syntax) { syntax = (ICAoSYNTAX *) LibObjByName ("syntax", "srsquery"); jobStatic = IcaCreateJob (syntax); } if (isRecursive) { resultSetSave = resultSet; job = IcaCreateJob (syntax); } else job = jobStatic; if (!name) { sprintf (uniqueName, "Q_%d", ++uniqueSetN); name = uniqueName; } resultSet = SetNew (name, NULL); IcaJobSetString (job, s); if (queryInfo->doListValues) TemplPrint ("head"); IcaDoJob (job, "query"); IcaEndJob (job); tmp = resultSet; if (queryInfo->doListValues) TemplPrint ("tail", SetGetQueryStr (name)); if (isRecursive) resultSet = resultSetSave; return tmp; } static SETo *QueryGetWholeLib (char *libName, SETo *set) { SETo *tmp; SLBo *lib; LIBoINDEX *libInx; IDoENTRY id; Int4 entryN, libId, k; memset (&id, 0, sizeof (IDoENTRY)); if ((tmp = SetGet (libName)) && !SetIsDB (tmp)) return tmp; lib = (SLBo *) LibObjByName ("library", libName); libInx = LibIndexOpen (lib, LibGetIdField (lib), 0); entryN = BtrGetRecordN (libInx->btree); libId = LibToId (lib); SetAlloc (set, entryN, LibGetIdType (NULL, libId, 4)); for (k=1; k<=entryN; k++) { IdBuild (&id, libId, k, 0); SetAddID (set, &id); } SetSetIsDB (set, 0); printf ("%s ------> %d\n", libName, set->n); return set; } void QuerySetGet () { LINKo *link; SLBo *lib; SETo *set; Int4 isLink, c; char name[132]; IargGetArgs ("name", name); if (!(set = SetGet (name))) { if (!(lib = (SLBo *) LibObjByName ("library", name)) && !SmEqs (name, "parent")) { for (c=0, isLink=0; (link=LibNextLink (&c));) if (SmEqs (name, LibGetLinkFromName (link)) || SmEqs (name, LibGetLinkToName (link))) { isLink=1; break; } if (!isLink) _ErrExit2 (e__nosetorlib, name); } set = SetNew (name, NULL); SetSetIsDB (set, 1); } IcaReturn ("set", set); } void QueryDBGroup () { SRSoGROUP *group, *tmp; SLBo *lib; char libName[132], groupName[132]; IargGetArgs ("init|db|group", groupName, libName, &group); if (*groupName) { /* initialize new or already existing group */ if (!(group = (SRSoGROUP *) LibObjByName ("group", groupName))) group = LibGroupNew (groupName); group->libraryN = 0; } /* databank name could be a group name! */ else if ((tmp = (SRSoGROUP*) LibObjByName ("group", libName))) group = tmp; else { /* add a new databank to the group */ if (!(lib = (SLBo *) LibObjByName ("library", libName))) { _ErrMsg3 (e__objectunknown, "data bank", libName); return; } else LibGroupAddDb (group, lib); } IcaReturn ("group", (void*) group); } void QuerySaveResult (Int4 runTime, SETo *set, STRv q) { if (runTime) IargGetArgs ("set|q", &set, &q); if (SetIsDB (set)) set = QueryGetWholeLib (SetGetName (set), set); SetOp (resultSet, set, NULL, QRYxOR); resultSet->queryStr = q; } void QueryStrSearch () { SRSoGROUP *group; SRSoFLD *fieldType; SLBoFIELD *field, *f; SLBo *lib; SETo *tmp, *tmpSub, *set; STRv s; char indexName[40]; INT4 c, k; IargGetArgs ("group|index|s", &group, indexName, &s); set = SetNew (NULL, "temp"); for (c=0; lib = LibNextLib (group, &c);) { if (queryInfo->doListValues) TemplPrint ("library", LibName (lib)); if ((field = LibHasFieldNamed (lib, indexName))) { if (FieldIs (field, "group")) /* field is field group (eg, "all") */ for (k=0; (f = LibNextFieldInGroup (lib, field, &k));) { tmp = SetNew (NULL, "temp"); if (QueryStrSearchIndex (&s, lib, f, tmp)) { if (SetIsSubEntry (SetGetName (tmp))) { /* set of subentries */ tmpSub = tmp; tmp = SetNew (NULL, "temp"); LinkToParent ("PARENT", SetGetName (tmpSub), tmp); SetDel (tmpSub); } SetOp (set, tmp, NULL, QRYxOR); } SetDel (tmp); } else { tmp = SetNew (NULL, "temp"); if (QueryStrSearchIndex (&s, lib, field, tmp)) SetOp (set, tmp, NULL, QRYxOR); SetDel (tmp); } } } IcaReturn ("set", set); } void QueryRangeSearch () { SRSoGROUP *group; SRSoFLD *fieldType; SLBoFIELD *field; SLBo *lib; SETo *tmp, *set; char indexName[40], l[40], h[40]; INT4 c, le, re, rv, isFirst, isLast; IargGetArgs ("group|index|l|h|le|re", &group, indexName, l, h, &le, &re); set = SetNew (NULL, "temp"); isFirst = SmEqs (l, "min") ? 1 : 0; isLast = SmEqs (h, "max") ? 1 : 0; for (c=0; lib = LibNextLib (group, &c);) { if ((field = LibHasFieldNamed (lib, indexName))) { tmp = SetNew (NULL, "temp"); if (FieldIs (field, "real")) rv = QueryRangeSearchIndex (lib, field, 0, 0, isFirst ? 0 : strtod (l, NULL), isLast ? 0 : strtod (h, NULL), 1, re, le, isFirst, isLast, tmp); else if (FieldIs (field, "num")) rv = QueryRangeSearchIndex (lib, field, isFirst ? 0 : atoi(l), isLast ? 0 : atoi(h), 0, 0, 0, le, re, isFirst, isLast, tmp); else continue; if (rv) SetOp (set, tmp, NULL, QRYxOR); SetDel (tmp); } } IcaReturn ("set", set); } SETo *QuerySetAssign (Int4 runTime, STRv name, SETo *set) { SETo *tmp; if (runTime) IargGetArgs ("name|s", &name, &set); if ((tmp = SetNew (_Str (name), NULL))) { if (SetIsDB (set)) set = QueryGetWholeLib (SetGetName (set), set); SetOp (tmp, set, NULL, SETxOR); } if (runTime) IcaReturn ("set", tmp); else return set; } void QueryLinkOp () { SETo *set, *s1, *s2; char op[10], s1Name[100], s2Name[100]; IargGetArgs ("op|s1|s2", op, &s1, &s2); set = SetNew (NULL, "temp"); switch (*op) { case '>': LinkMap (SetGetName (s1), SetGetName (s2), set); break; case '<': LinkMap (SetGetName (s2), SetGetName (s1), set); break; default: _ErrExit2 (e__unknownoption, "op in QuerySetOp"); } IcaReturn ("set", set); } void QueryLogOp () { SETo *set, *s1, *s2; char op[10], s1Name[100], s2Name[100]; IargGetArgs ("op|s1|s2", op, &s1, &s2); if (SetIsDB (s1)) s1 = QueryGetWholeLib (SetGetName (s1), s1); if (SetIsDB (s2)) s2 = QueryGetWholeLib (SetGetName (s2), s2); set = SetNew (NULL, "temp"); switch (*op) { case '&': SetOp (s1, s2, set, SETxAND); break; case '|': SetOp (s1, s2, set, SETxOR); break; case '!': SetOp (s2, s1, set, SETxNOT); break; default: _ErrExit2 (e__unknownoption, "op in QuerySetOp"); } IcaReturn ("set", set); } INT4 QueryStrSearchIndex (STRv *str, SLBo *lib, SLBoFIELD *field, SETo *set) { LIBoINDEX *libIndex; char sWild[255]; INT4 len; if (!(libIndex = LibIndexOpen (lib, field, 0))) return 0; if (LibIs (lib, "subentries")) { queryInfo->subEntryLib = lib; queryInfo->subEntryNo = QueryGetAndDeleteSubEntryNo (_Str(*str)); } else { queryInfo->subEntryLib = NULL; queryInfo->subEntryNo = 0; } StrDecode (str); StrLower (str); StrTrim (str, NULL); if ((len = RegWildToRegexp (_Str(*str), sWild, 1))) { if (queryInfo->doReport) print (" ...searching \"%s\"\n", _Str(*str)); QueryGetWild (libIndex, set, _Str(*str), sWild, len); } else QueryGet (libIndex, set, _Str(*str)); return SetGetSize (set); } Int4 QueryGetAndDeleteSubEntryNo (char *s) { Int4 k; for (k=strlen(s)-1; k > 0 && s[k] != '_'; k--) ; if (s[k] == '_') { s[k] = '\0'; return atoi (&s[k+1]); } else return 0; } STRv QueryOpMakeWild (INT4 runTime, STRv s) { if (runTime) IargGetArgs ("s", &s); if (!strchr ("*", _Str(s)[StrLen(s)-1]) && StrLen (s) > 1) StrAppS (&s, "*"); if (runTime) IcaReturn ("strv", s); return s; } INT4 QueryRangeSearchIndex (SLBo *lib, SLBoFIELD *field, INT4 low, INT4 high, double lowReal, double highReal, INT4 isReal, INT4 isLE, INT4 isRE, INT4 isFirst, INT4 isLast, SETo *set) { BTRoVALUE begin, end, *val; LIBoINDEX *libIndex; BTRo *btree; INT4 idN; if (!(libIndex = LibIndexOpen (lib, field, 0))) return 0; btree = libIndex->btree; /* ** get record for low value in range */ if (isFirst) begin = (BtrRecordGet(btree, BTRxFIRST))->r.value; else { val = isReal ? BtrSearchReal(btree, lowReal) : BtrSearchNum(btree, low); if (BtrIsSearchGreaterMaxVal (btree)) return 0; if (val && isLE) begin = (BtrRecordGet (btree, BTRxNEXT))->r.value; else begin = (BtrRecordGet (btree, BTRxCURR))->r.value; } /* ** get record for high value in range */ if (isLast) end = (BtrRecordGet(btree, BTRxLAST))->r.value; else { val = isReal ? BtrSearchReal(btree, highReal) : BtrSearchNum(btree, high); if (BtrIsSearchLessMinVal (btree)) return 0; else if (BtrIsSearchGreaterMaxVal (btree)) end = (BtrRecordGet(btree, BTRxLAST))->r.value; if (val && isRE) end = (BtrRecordGet (btree, BTRxPREV))->r.value; else end = (BtrRecordGet (btree, BTRxCURR))->r.value; } if (begin.firstIdFip > end.firstIdFip) return 0; /* nothing found */ /* ** get the set of IDs */ idN = IdsGetRange (libIndex->idsFile, (IDPTR) NULL, begin.firstIdFip, end.firstIdFip, begin.idN, end.idN); _ErrStop (SetAlloc (set, idN, libIndex->field->indexId)); /* alloc id-buff */ /* read id's */ set->n = IdsGet (libIndex->idsFile, set->id_p, begin.firstIdFip, idN); SetSort (set); /* sorting is necessary for set operations */ } void QuerySetFunctions () { IcaSetFunction ("QuerySetGet", (FUNC)QuerySetGet); IcaSetFunction ("QueryDBGroup", (FUNC)QueryDBGroup); IcaSetFunction ("QueryStrSearch", (FUNC)QueryStrSearch); IcaSetFunction ("QueryRangeSearch", (FUNC)QueryRangeSearch); IcaSetFunction ("QueryLogOp", (FUNC)QueryLogOp); IcaSetFunction ("QueryLinkOp", (FUNC)QueryLinkOp); IcaSetFunction ("QueryOpMakeWild", (FUNC)QueryOpMakeWild); IcaSetFunction ("QuerySaveResult", (FUNC)QuerySaveResult); IcaSetFunction ("QuerySetAssign", (FUNC)QuerySetAssign); IcaSetFunction ("QueryMakeWild", (FUNC)QueryMakeWild); } unction ("QueryDBGroup", (FUNC)QueryDBGroup); IcaSetFunction ("QueryStrSearch", (FUNC)QueryStrSearch); IcaSetFunction ("QueryRangeSearch", (FUNC)QueryRangeSearch); IcaSetFunction ("QueryLogOp", (FUNC)QueryLogOp); IcaSetFunction ("QueryLinkOp", (FUNC)QueryLinkOp); IcaSetFunction ("QueryOpMakeWild", (FUNC)QueryOpMakeWild); IcaSetFunction ("QuerySaveResult", (FUNC)QuerySaveResult); IcaSetFunction ("QuerySetAssign", (FUNC)QuerySetAssign); IcaSetFunction (srs/src/query.h ** ** $RCSfile: query.h,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:17:10 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port: Lukas Rosenthaler and Reinhard Doelz ** */ #define QRYxXNAM 30 /* max length of names for ? */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of exported functions */ #ifndef _PRSoST typedef struct PRSoST *dummytointroducestructtagPRSoST; #endif #ifndef _SETo typedef struct SETo *dummytointroducestructtagSETo; #endif /* functions for retrieval */ struct SETo *Query (char *s, char *name); struct SETo *QueryRecursive (char *s, char *name); INT4 QryReadNames (char *fil_nm, char *set_nm); INT4 QryListToSet (struct PRSoST *tokstack, FILo *file); INT4 QryLinkOne (IDoENTRY *id, char *lib_nm, char *set_nm); /* IDoENTRY *QryFindID (char *lib_nm, char *field_nm, char *value);*/ /* check or transform query */ /* others */ INT4 QrySetToList (char *set_nm); f struct SETo *dummytointroducestructtagSETo; #endif /* functions for retrieval */ struct SETo *Query (char *s, char *name); struct SETo *QueryRecursive (char *s, char *name); INT4 QryReadNames (char *fil_nm, char *set_nm); INT4 QryListToSet (struct PRSoST *tokstack, FILo *file); INT4 QryLinkOne (IDoENTRY *id, char *lib_nm, char *set_nm); /* IDoENTRY *QryFindID (char *lib_nm, char *field_nsrs/src/queryass.c char queryass_ID[] = "$Id: queryass.c,v 1.9 1997/03/03 18:20:46 srs Exp $"; /* ** ** $Source: /homes/srs/cvsroot/srs/src/queryass.c,v $ ** $Revision: 1.9 $ ** $Date: 1997/03/03 18:20:46 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port: Lukas Rosenthaler and Reinhard Doelz ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include "message.h" #include "futil.h" #include "strv.h" #include "library.h" #include "queryass.h" #define _CONSTANTS #define _SRS #define _SLB #include "srs5.h" /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Describes a library or group to be queried. */ typedef struct QASoLibOrGroup { STRv name; SLBo *lib; SRSoGROUP *group; Int4 isGroup; } QASoLibOrGroup; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** describes a retrieve command from any index ** + two functions for creating and deleting instances */ typedef struct QASoRETRIEVE { STRv fieldName; STRv search; STRv query; char rangeBegin[20]; char rangeEnd[20]; INT4 isRangeBeginExcl; INT4 isRangeEndExcl; INT4 isSubEntry; INT4 doSubEntry; INT4 isRange; Int4 isAll; } QASoRETRIEVE; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** The query 'object'. */ typedef struct QASoQUERY { char name[80]; Int4 isMakeWild; Int4 isLink; Int4 tmpSetNum; /* used to create set names */ struct STRo *linkWith[100]; struct STRo *queryToLink; Int4 linkWithN; QASeLinkType linkType; char subEntryType[80]; enum QASeOP op; char opName[10]; QASoRETRIEVE *retrieve; Int4 retrieveN; Int4 retrieveAllocN; QASoLibOrGroup *lib; Int4 libN; Int4 libAllocN; struct SRSoFLD *subEntryFieldType; Int4 opndN; Int4 opndAllocN; STRv *opnd; } QASoQUERY; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** static functions */ static Int4 QasIsSubentryLink (QASoQUERY *query); static QASoRETRIEVE *QasSetRetrieve (QASoQUERY *query, char *fieldName); static STRv QasGetLibNames (QASoQUERY *query); static Int4 QasMakeRetrievals (QASoQUERY *query, STRv libNames, INT4 doLink); static STRv QasGetRetrieveString (QASoQUERY *qas); static STRv QasGetOpString (QASoQUERY *qas); static STRv QasGetLinkString (QASoQUERY *qas); static Int4 QasIsSubEntry (QASoQUERY *qas, QASoRETRIEVE *r); static void QasClear (QASoQUERY *qas); static int QasInitRetrieve (QASoRETRIEVE *r) { r->rangeBegin[0] = r->rangeEnd[0] = '\0'; r->isRangeBeginExcl = r->isRangeEndExcl = 0; r->isSubEntry = r->doSubEntry = 0; r->search = StrNew (20); r->query = StrNew (20); r->isRange = 0; } static int QasDeleteRetrieve (QASoRETRIEVE *r) { if (r->search) StrDel (r->search); if (r->query) StrDel (r->query); } /**API* QasNew **************************************************************** ** ** Get a new query object. ** ** INPUT: ** IMPLICIT: ** ** RETURNS: new query object */ QASoQUERY *QasNew () { QASoQUERY *query; query = (QASoQUERY *) calloc (sizeof (QASoQUERY), 1); query->op = QASxAND; strcpy (query->opName, "&"); return query; } /**API* QasNew **************************************************************** ** ** Deletes a query object. ** ** INPUT: query object [W] ** IMPLICIT: ** ** RETURNS: NULL */ QASoQUERY *QasDelete (QASoQUERY *query) { if (query) { QasClear (query); free (query); } return NULL; } /**API* QasInitLink *********************************************************** ** ** Sets the query to be a link from an arbitrary query expression ** to one or more ** databanks. The query must be further defined with QasSetQueryToLink, ** QasSetLinkLib, QasSetLinkType before obtaining the query string ** from QasGetQueryString. ** The input query object can be obtained from QasNew. ** ** INPUT: query object [W] ** */ void QasInitLink (QASoQUERY *qas) { QasClear (qas); qas->isLink = 1; qas->linkWithN = 0; } /**API* QasSetTmpSetNum ******************************************************* ** ** Sets the start number for the query assistant to use as part of ** names generated for temporary sets. ** ** INPUT: query object [W] ** the number [R] ** */ void QasSetTmpSetNum (QASoQUERY *qas, Int4 n) { qas->tmpSetNum = n; } /**API* QasSetQueryToLink ***************************************************** ** ** Sets the query expression to be linked with one or more libraries. ** Query must be initialized with QasInitLink. ** ** INPUT: link object [W] ** library name [R] ** */ void QasSetQueryToLink (QASoQUERY *query, char *s) { query->queryToLink = StrCpyS (s); } /**API* QasSetLinkWith ******************************************************** ** ** Sets the library or expression to be linked with the linkQuery. Several ** 'with' expressions can be set. ** Query must be initialized with QasInitLink. ** ** INPUT: link object [W] ** library name [R] ** */ void QasSetLinkWith (QASoQUERY *query, char *with) { query->linkWith[query->linkWithN++] = StrCpyS (with); } /**API* QasSetLinkType ******************************************************** ** ** Sets the type of the link query. Query must be initialized with ** QasInitLink. ** ** INPUT: link object [W] ** option: "toSet", "toLibs", "notToSet" [R] ** */ void QasSetLinkType (QASoQUERY *qas, char *option) { switch (option[2]) { case 'S': qas->linkType = QASxToSet; break; case 'L': qas->linkType = QASxToLibs; break; case 't': qas->linkType = QASxToSetNot; break; default: _ErrExit2 (e__unknownoption, option); } } /**API* QasReset ************************************************************* ** ** Resets a query object to initial state. ** ** INPUT: query object [W] ** IMPLICIT: ** ** RETURNS: */ void QasReset (QASoQUERY *query) { QasClear (query); query->op = QASxAND; strcpy (query->opName, "&"); query->isMakeWild = 0; query->subEntryFieldType = NULL; } /**API* QasSetRetrieveStr ***************************************************** ** ** Sets a databank to be searched. More than one can be set. ** ** INPUT: query object [W] ** databank (library) name [R] ** IMPLICIT: ** ** RETURNS: 1: success ** e__objectunknown+: databank name unknown */ INT4 QasSetLibrary (QASoQUERY *qas, char *libName) { QASoLibOrGroup *tmp; SRSoGROUP *group; SLBo *lib; tmp = _addObj (qas->lib, qas->libN, qas->libAllocN, QASoLibOrGroup); if ((tmp->lib = (SLBo *) LibObjByName ("library", libName))) tmp->name = StrCpyS (LibName (tmp->lib)); else if ((tmp->group = (SRSoGROUP *) LibObjByName ("group", libName))) { tmp->name = StrCpyS (LibGetGroupName (group, "full")); tmp->isGroup = 1; } else _ErrRet3 (e__objectunknown, "databank (group)", libName); return 1; } /****** QasSetRetrieve ******************************************************** ** ** Returns a "retrieve" object or creates a new one. ** ** INPUT: query object [W] ** field name [R] ** low boundary string (maybe int or real) [R] ** IMPLICIT: ** ** RETURNS: retrieve object if success ** NULL if field name unknown */ static QASoRETRIEVE *QasSetRetrieve (QASoQUERY *query, char *fieldName) { SRSoFLD *fieldType; QASoRETRIEVE *retrieve; if (!(fieldType = (SRSoFLD *) LibObjByName ("fieldtype", fieldName))) { _ErrMsg3 (e__objectunknown, "data-field", fieldName); return NULL; } fieldName = fieldType->nam; return _addObj (query->retrieve, query->retrieveN, query->retrieveAllocN, QASoRETRIEVE); return query->retrieve; } /**API* QasNewRetrieve ******************************************************* ** ** Creates a new 'Retrieval object' which can be used to further ** define an index search. The Retrieval object is managed by the ** query object and needs not to be deleted. ** ** INPUT: query object [W] ** field name [R] ** IMPLICIT: ** ** RETURNS: a handle to the Retrieval object */ QASoRETRIEVE *QasNewRetrieve (QASoQUERY *query, char *fieldName) { QASoRETRIEVE *r; r = QasSetRetrieve (query, fieldName); if (r->fieldName) StrDel (r->fieldName); r->fieldName = StrCpyS (fieldName); return r; } /**API* function ************************************************************** ** ** Creates an expression to retrieve all entries of all libraries ** selected by QasSetLibrary. **

    ** function has not yet been tested! ** ** INPUT: query object [W] */ void QasSetRetrieveAll (QASoQUERY *query) { QASoRETRIEVE *r; Int4 k; r = _addObj (query->retrieve, query->retrieveN, query->retrieveAllocN, QASoRETRIEVE); r->isAll = 1; r->search = StrCpyS ("("); for (k=0; k < query->libN; k++) StrPrintf (&r->search, "%s |", _Str (query->lib[k].name)); StrCut (&r->search, StrLen (r->search)-2, 2); StrAppS (&r->search, ")"); StrLower (&r->search); } /**API* QasSetRetrieveStr ***************************************************** ** ** Sets a search string for specified index. ** ** INPUT: query object [W] ** retrieval object [W] ** search string [R] ** IMPLICIT: ** ** RETURNS: */ void QasSetRetrieveStr (QASoQUERY *query, QASoRETRIEVE *retrieve, char *str) { if (retrieve->search) StrDel (retrieve->search); retrieve->search = StrCpyS (str); } /**API* QasSetRangeBegin ****************************************************** ** ** Sets the lower boundary of a range retrieval. ** ** INPUT: query object [W] ** retrieval object [W] ** low boundary string (maybe int or real) [R] ** IMPLICIT: ** ** RETURNS: number of query in history if success ** 0 if not */ void QasSetRangeBegin (QASoQUERY *query, QASoRETRIEVE *retrieve, char *begin) { strcpy (retrieve->rangeBegin, begin); retrieve->isRange = 1; } /**API* QasSetRangeEnd ******************************************************** ** ** Sets the upper boundary of a range retrieval. ** ** INPUT: query object [W] ** retrieval object [W] ** low boundary string (maybe int or real) [R] ** IMPLICIT: ** ** RETURNS: number of query in history if success ** 0 if not */ void QasSetRangeEnd (QASoQUERY *query, QASoRETRIEVE *retrieve, char *end) { strcpy (retrieve->rangeEnd, end); retrieve->isRange = 1; } /**API* QasSetRangeBeginExcl ************************************************** ** ** Sets the lower boundary not to be included in range. ** ** INPUT: query object [W] ** field name [R] ** low boundary string (maybe int or real) [R] ** IMPLICIT: ** ** RETURNS: number of query in history if success ** 0 if not */ void QasSetRangeBeginExcl (QASoQUERY *query, QASoRETRIEVE *retrieve) { retrieve->isRangeBeginExcl = 1; retrieve->isRange = 1; } /**API* QasSetRangeEndExcl **************************************************** ** ** Sets the upper boundary not to be included in range. ** ** INPUT: query object [W] ** field name [R] ** low boundary string (maybe int or real) [R] ** IMPLICIT: ** ** RETURNS: number of query in history if success ** 0 if not */ void QasSetRangeEndExcl (QASoQUERY *query, QASoRETRIEVE *retrieve) { retrieve->isRangeEndExcl = 1; retrieve->isRange = 1; } /**API* QasSetMakeWild ******************************************************* ** ** Sets the flag to add to all search words a terminal wildcard "*". ** ** INPUT: query object [W] ** IMPLICIT: ** ** RETURNS: */ void QasSetMakeWild (QASoQUERY *query) { query->isMakeWild = 1; } /**API* QasSetSubEntries ****************************************************** ** ** Sets the query to return subentries found by specified field. This ** works only if the fields of different entry types are combined ** with logical AND. ** ** INPUT: query object [W] ** field name [R] ** IMPLICIT: ** ** RETURNS: */ void QasSetSubEntries (QASoQUERY *query, QASoRETRIEVE *retrieve) { if (!(query->subEntryFieldType = (SRSoFLD *) LibObjByName ("fieldtype", _Str (retrieve->fieldName)))) { _ErrMsg3 (e__objectunknown, "fieldType", _Str (retrieve->fieldName)); } retrieve->doSubEntry = 1; } /**API* QasSetOp ************************************************************** ** ** Sets the operator that combines the separate retrieval commands. ** ** INPUT: query object [W] ** operator name: "or", "and", "butnot" [R] ** IMPLICIT: ** ** RETURNS: */ void QasSetOp (QASoQUERY *query, char *opName) { switch (tolower (opName[0])) { case '|': case 'o': /* or */ query->op = QASxOR; strcpy (query->opName, "|"); break; case '!': case 'b': /* butnot */ query->op = QASxBUTNOT; strcpy (query->opName, "!"); break; case '&': case 'a': /* and */ query->op = QASxAND; strcpy (query->opName, "&"); break; default: _ErrExit2 (e__unknownoption, opName); } } /**API* QasMakeOperand ***************************************************** ** ** Creates the query string built sofar and makes it a single operand ** which can be used to create further queries using QasAddOperand ** QasSetOp and QasGetQueryString. ** ** INPUT: query object [W] ** */ void QasMakeOperand (QASoQUERY *qas) { STRv s, expr; s = StrCpyS (QasGetQueryString (qas)); QasClear (qas); expr = StrNew (expr); StrPrintf (&expr, "(%s)", _Str (s)); QasAddOperand (qas, _Str (expr)); StrDel (s); StrDel (expr); } static void QasClear (QASoQUERY *qas) { QASoRETRIEVE *r; QASoLibOrGroup *l; Int4 k; if (qas->retrieveN) { for (k=0; k < qas->retrieveN; k++) { r = &qas->retrieve[k]; StrDel (r->fieldName); StrDel (r->search); StrDel (r->query); } free (qas->retrieve); qas->retrieveN = 0; qas->retrieveAllocN = 0; } if (qas->libN) { for (k=0; k < qas->libN; k++) { l = &qas->lib[k]; StrDel (l->name); } free (qas->lib); qas->libN = 0; qas->libAllocN = 0; } if (qas->opndN) { for (k=0; k < qas->opndN; k++) { StrDel (qas->opnd[k]); } free (qas->opnd); qas->opndN = 0; qas->opndAllocN = 0; } } /**API* QasAddOperand ***************************************************** ** ** Adds a set name as operand to the current list of operands which ** will be combined using the operator specified by QasSetOp. ** ** INPUT: query object [W] ** operand name (set name) [R] ** */ void QasAddOperand (QASoQUERY *query, char *name) { STRv s; s = StrCpyS (name); *(_addObj (query->opnd, query->opndN, query->opndAllocN, STRv)) = s; } /**API* QasGetQueryString ***************************************************** ** ** Build a query string from all the information accumulated so far. ** This function can be called at any point during query building. ** The function might generate names of intermediate sets for later ** reference in the query, eg, "(L1=[a-b:c]) ! L1retrieveN) return _Str (QasGetRetrieveString (query)); else if (query->opndN) return _Str (QasGetOpString (query)); else if (query->isLink) return _Str (QasGetLinkString (query)); else return NULL; } static STRv QasGetOpString (QASoQUERY *qas) { STRv str=StrNew (); Int4 k; for (k=0; k < qas->opndN; k++) { if (!k) StrPrintf (&str, "%s", _Str (qas->opnd[k])); else StrPrintf (&str, " %s %s", qas->opName, _Str (qas->opnd[k])); } return str; } static STRv QasGetRetrieveString (QASoQUERY *qas) { STRv libNames, query, seQuery; QASoRETRIEVE *retrieve; Int4 rv, k, doLink=0, makeWildSave; libNames = QasGetLibNames (qas); doLink = QasIsSubentryLink (qas); if (!QasMakeRetrievals (qas, libNames, doLink)) { StrDel (libNames); return NULL; } query=StrNew (); seQuery=StrNew (); /* Now combine all retrievals to one big query string */ if (doLink) StrAppS (&query, "("); for (k=0; k < qas->retrieveN; k++) { retrieve = &qas->retrieve[k]; if (retrieve->doSubEntry && doLink) { if (StrLen (seQuery)) StrPrintf (&seQuery, "%s %s ", qas->opName, _Str (retrieve->query)); else StrPrintf (&seQuery, "%s ", _Str (retrieve->query)); } else { if (StrLen (query) > 1) StrPrintf (&query, "%s %s ", qas->opName, _Str (retrieve->query)); else StrPrintf (&query, "%s ", _Str (retrieve->query)); } } /* if retrieval of subentries requires link */ if (doLink) StrPrintf (&query, ") > (%s)", _Str (seQuery)); if (qas->isMakeWild) { Int4 save = ParGetNum ("makeWild"); ParDefNum ("makeWild", 1); QueryMakeWild (&query); ParDefNum ("makeWild", save); } StrDel (seQuery); StrDel (libNames); return query; } static STRv QasGetLinkString (QASoQUERY *qas) { static Int4 count; STRv query1, query2, str; Int4 k; count = qas->tmpSetNum; str = StrNew (); query1 = StrNew (); query2 = StrNew (); if (qas->linkWithN > 1 || qas->linkType == QASxToSetNot) { StrPrintf (&query1, "(L%d=%s)", ++count, _Str(qas->queryToLink)); StrPrintf (&query2, "L%d", count); } else { StrPrintf (&query1, "(%s)", _Str(qas->queryToLink)); StrPrintf (&query2, "(%s)", _Str(qas->queryToLink)); } ASSERT (qas->linkType, "wrong link type"); if (qas->linkType == QASxToSet) { for (k=0; k < qas->linkWithN; k++) if (!k) StrPrintf (&str, "(%s < %s)", _Str(query1), _Str(qas->linkWith[k])); else StrPrintf (&str, " & (%s < %s)", _Str(query2), _Str(qas->linkWith[k])); } else if (qas->linkType == QASxToLibs) { for (k=0; k < qas->linkWithN; k++) if (!k) StrPrintf (&str, "(%s > %s)", _Str(query1), _Str(qas->linkWith[k])); else StrPrintf (&str, " | (%s > %s)", _Str(query2), _Str(qas->linkWith[k])); } else if (qas->linkType == QASxToSetNot) { for (k=0; k < qas->linkWithN; k++) if (!k) StrPrintf (&str, "%s ! (%s < %s)", _Str(query1), _Str(query2), _Str(qas->linkWith[k])); else StrPrintf (&str, " ! (%s < %s)", _Str(query2), _Str(qas->linkWith[k])); } StrDel (query1); StrDel (query2); return str; } /****** QasIsSubentryLink ***************************************************** ** ** Finds out if the current query contains a mixture of subentry and ** entry retrievals so that a link operation between the two will be ** necessary. ** ** INPUT: query object [W] ** ** RETURNS: 1: link is necessary ** 0: not */ static Int4 QasIsSubentryLink (QASoQUERY *qas) { QASoRETRIEVE *retrieve; Int4 k, isSubentry=0, isEntry=0; for (k=0; k < qas->retrieveN; k++) { retrieve = &qas->retrieve[k]; if (QasIsSubEntry (qas, retrieve) && retrieve->doSubEntry) isSubentry = 1; else isEntry = 1; } return isSubentry && isEntry; } static Int4 QasIsSubEntry (QASoQUERY *qas, QASoRETRIEVE *r) { SLBo *lib; SLBoFIELD *field; QASoLibOrGroup *tmp; Int4 k, c, isSubEntry=0; for (k=0; k < qas->libN; k++) { tmp = &qas->lib[k]; if (tmp->isGroup) { for (c=0; (lib = LibNextLib (tmp->group, &c));) if (field = LibHasFieldNamed (lib, _Str (r->fieldName))) if (FieldIs (field, "subentry")) isSubEntry = 1; } else { if (field = LibHasFieldNamed (tmp->lib, _Str (r->fieldName))) if (FieldIs (field, "subentry")) isSubEntry = 1; } } r->isSubEntry = isSubEntry; return isSubEntry; } /****** QasGetLibNames ******************************************************* ** ** Prints the list of selected databanks into a string using a ** space as separator. ** ** INPUT: query object [W] ** ** RETURNS: library names list */ static STRv QasGetLibNames (QASoQUERY *query) { STRv libNames; SRSoGROUP *group; SLBo *lib; char *libName; INT4 k; libNames = StrNew (); for (k=0; k < query->libN; k++) StrPrintf (&libNames, "%s ", _Str (query->lib[k].name)); StrCut (&libNames, StrLen (libNames)-1, 1); StrLower (&libNames); return libNames; } /****** QasGetLibsAndDoLink *************************************************** ** ** Writes the list of selected libraries and groups into a buffer ** marks retrieval commands that lead to subentries and determines if ** the desired ouput is a list of subentries and if a link to subentries ** must be performed. ** ** INPUT: o query object [W] ** o string list of library names to be queried [W] ** o flag if a link between entries and subentries needs ** to be performed (QasIsSubentryLink) ** ** RETURNS: 1: successful ** 0: no retrieval was set */ static Int4 QasMakeRetrievals (QASoQUERY *query, STRv libNames, Int4 isSubentryLink) { SRSoFLD *fieldType; QASoRETRIEVE *r; INT4 k, isFirst; if (!query->retrieveN) return 0; for (isFirst=1, k=0; k < query->retrieveN; k++) { r = &query->retrieve[k]; r->query = StrNew (); /* convert subentries to PARENT */ if (r->isSubEntry && !r->doSubEntry) r->query = StrCpyS ("("); /* databank names */ if (query->libN == 1) StrPrintf (&r->query, "[%s-", _Str (libNames)); else if (isFirst && !(isSubentryLink && r->doSubEntry)) { StrPrintf (&r->query, "[libs={%s}-", _Str (libNames)); isFirst=0; } else StrAppS (&r->query, "[libs-"); if (!(fieldType = (SRSoFLD *) LibObjByName ("fieldtype", _Str (r->fieldName)))) _ErrExit3 (e__objectunknown, "data-field", _Str (r->fieldName)); /* get all - string already exists */ if (r->isAll) ; /* string search */ else if (!r->isRange) StrPrintf (&r->query, "%s: %s]", _Str (r->fieldName), _Str (r->search)); /* range retrieval */ else StrPrintf (&r->query, "%s# %s%s:%s%s]", _Str (r->fieldName), r->isRangeBeginExcl ? "!" : "", r->rangeBegin, r->isRangeEndExcl ? "!" : "", r->rangeEnd); /* convert subentries to PARENT */ if (r->isSubEntry && !r->doSubEntry) StrAppS (&r->query, " > parent)"); } return 1; } if (r->isAll) ; /* string search */ else if (!r->isRange) srs/src/queryass.h ** ** $Source: /homes/srs/cvsroot/srs/src/queryass.h,v $ ** $Revision: 1.4 $ ** $Date: 1997/03/03 18:20:46 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** Copyright by Thure Etzold ** */ typedef enum QASeOP {QASxOR=1, QASxAND, QASxBUTNOT} QASeOP; typedef enum QASeLinkType {QASxToSet=1, QASxToLibs, QASxToSetNot} QASeLinkType; typedef struct QASoQUERY *QASvQUERY; typedef struct QASoRETRIEVE *QASvRETRIEVE; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of exported functions */ /* construct and destruct */ QASvQUERY QasNew (); QASvQUERY QasDelete (QASvQUERY query); QASvRETRIEVE QasNewRetrieve (QASvQUERY query, char *fieldName); /* set attributes */ INT4 QasSetLibrary (QASvQUERY query, char *libName); void QasSetRetrieveStr (QASvQUERY query, QASvRETRIEVE retrieve, char *str); void QasSetRangeBegin (QASvQUERY query, QASvRETRIEVE retrieve, char *begin); void QasSetRangeEnd (QASvQUERY query, QASvRETRIEVE retrieve, char *end); void QasSetRangeBeginExcl (QASvQUERY query, QASvRETRIEVE retrieve); void QasSetRangeEndExcl (QASvQUERY query, QASvRETRIEVE retrieve); void QasSetOp (QASvQUERY query, char *opName); void QasSetMakeWild (QASvQUERY query); void QasSetSubEntries (QASvQUERY query, QASvRETRIEVE retrieve); void QasSetTmpSetNum (QASvQUERY qas, Int4 n); void QasAddOperand (QASvQUERY query, char *name); void QasSetRetrieveAll (QASvQUERY query); /* get attributes */ char *QasGetQueryString (QASvQUERY query); eve, char *end); void QasSetRangeBeginExcl (QASvQUERY query, QASvRETRIEVE retrieve); void QasSetRangeEndExcl (QASvQUERY query, QASvRETRIEVE retrieve); void QasSetOp (QASvQUERY query, char *opName); void QasSetMakeWild (QASvQUERY query); void QasSetSubEntries (QASvQUERY query, QASvRETRIEVE retrieve); void QasSetTmpSetNum (QASvQUERY qas, Int4 n); void QasAddOperand (QASvQUERY query, char *name); void QasSetRetrieveAll (QASvQUERY query); srs/src/regexp.c * regcomp and regexec -- regsub and regerror are elsewhere * @(#)regexp.c 1.3 of 18 April 87 * * Copyright (c) 1986 by University of Toronto. * Written by Henry Spencer. Not derived from licensed software. * * Permission is granted to anyone to use this software for any * purpose on any computer system, and to redistribute it freely, * subject to the following restrictions: * * 1. The author is not responsible for the consequences of use of * this software, no matter how awful, even if they arise * from defects in it. * * 2. The origin of this software must not be misrepresented, either * by explicit claim or by omission. * * 3. Altered versions must be plainly marked as such, and must not * be misrepresented as being the original software. * * Beware that some of this code is subtly aware of the way operator * precedence is structured in regular expressions. Serious changes in * regular-expression syntax might require a total rethink. */ #include #include #include "regexp.h" #include "regmagic.h" #include "message.h" /* added */ /* * The "internal use only" fields in regexp.h are present to pass info from * compile to execute that permits the execute phase to run lots faster on * simple cases. They are: * * regstart char that must begin a match; '\0' if none obvious * reganch is the match anchored (at beginning-of-line only)? * regmust string (pointer into program) that match must include, or NULL * regmlen length of regmust string * * Regstart and reganch permit very fast decisions on suitable starting points * for a match, cutting down the work a lot. Regmust permits fast rejection * of lines that cannot possibly match. The regmust tests are costly enough * that regcomp() supplies a regmust only if the r.e. contains something * potentially expensive (at present, the only such thing detected is * or + * at the start of the r.e., which can involve a lot of backup). Regmlen is * supplied because the test in regexec() needs it and regcomp() is computing * it anyway. */ /* * Structure for regexp "program". This is essentially a linear encoding * of a nondeterministic finite-state machine (aka syntax charts or * "railroad normal form" in parsing technology). Each node is an opcode * plus a "next" pointer, possibly plus an operand. "Next" pointers of * all nodes except BRANCH implement concatenation; a "next" pointer with * a BRANCH on both ends of it is connecting two alternatives. (Here we * have one of the subtle syntax dependencies: an individual BRANCH (as * opposed to a collection of them) is never concatenated with anything * because of operator precedence.) The operand of some types of node is * a literal string; for others, it is a node leading into a sub-FSM. In * particular, the operand of a BRANCH node is the first node of the branch. * (NB this is *not* a tree structure: the tail of the branch connects * to the thing following the set of BRANCHes.) The opcodes are: */ /* definition number opnd? meaning */ #define END 0 /* no End of program. */ #define BOL 1 /* no Match "" at beginning of line. */ #define EOL 2 /* no Match "" at end of line. */ #define ANY 3 /* no Match any one character. */ #define ANYOF 4 /* str Match any character in this string. */ #define ANYBUT 5 /* str Match any character not in this string. */ #define BRANCH 6 /* node Match this alternative, or the next... */ #define BACK 7 /* no Match "", "next" ptr points backward. */ #define EXACTLY 8 /* str Match this string. */ #define NOTHING 9 /* no Match empty string. */ #define STAR 10 /* node Match this (simple) thing 0 or more times. */ #define PLUS 11 /* node Match this (simple) thing 1 or more times. */ #define OPEN 20 /* no Mark this point in input as start of #n. */ /* OPEN+1 is number 1, etc. */ #define CLOSE 30 /* no Analogous to OPEN. */ /* * Opcode notes: * * BRANCH The set of branches constituting a single choice are hooked * together with their "next" pointers, since precedence prevents * anything being concatenated to any individual branch. The * "next" pointer of the last BRANCH in a choice points to the * thing following the whole choice. This is also where the * final "next" pointer of each individual branch points; each * branch starts with the operand node of a BRANCH node. * * BACK Normal "next" pointers all implicitly point forward; BACK * exists to make loop structures possible. * * STAR,PLUS '?', and complex '*' and '+', are implemented as circular * BRANCH structures using BACK. Simple cases (one character * per match) are implemented with STAR and PLUS for speed * and to minimize recursive plunges. * * OPEN,CLOSE ...are numbered at compile time. */ /* * A node is one char of opcode followed by two chars of "next" pointer. * "Next" pointers are stored as two 8-bit pieces, high order first. The * value is a positive offset from the opcode of the node containing it. * An operand, if any, simply follows the node. (Note that much of the * code generation knows about this implicit relationship.) * * Using two bytes for the "next" pointer is vast overkill for most things, * but allows patterns to get big without disasters. */ #define OP(p) (*(p)) #define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377)) #define OPERAND(p) ((p) + 3) /* * See regmagic.h for one further detail of program structure. */ /* * Utility definitions. */ #ifndef CHARBITS #define UCHARAT(p) ((int)*(unsigned char *)(p)) #else #define UCHARAT(p) ((int)*(p)&CHARBITS) #endif #define FAIL(m) { regerror(m); return(NULL); } #define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?') #define META "^$.[()|?+*\\" /* * Flags to be passed up and down. */ #define HASWIDTH 01 /* Known never to match null string. */ #define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */ #define SPSTART 04 /* Starts with * or +. */ #define WORST 0 /* Worst case. */ /* * Global work variables for regcomp(). */ static char *regparse; /* Input-scan pointer. */ static int regnpar; /* () count. */ static char regdummy; static char *regcode; /* Code-emit pointer; ®dummy = don't. */ static long regsize; /* Code size. */ /* * Forward declarations for regcomp()'s friends. */ #ifndef STATIC #define STATIC static #endif STATIC char *reg(); STATIC char *regbranch(); STATIC char *regpiece(); STATIC char *regatom(); STATIC char *regnode(); STATIC char *regnext(); STATIC void regc(); STATIC void reginsert(); STATIC void regtail(); STATIC void regoptail(); #ifdef STRCSPN STATIC int strcspn(); #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** the error reporting functions are located elsewhere in the original ** distribution.. the macro _ErrMsg replaces the original function "regerror" ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int errreport = 0; /* Report errors via errseen? */ char *errseen = NULL; /* Error message. */ /* void error (char *s1, char *s2) { fprintf(stderr, "regexp: "); fprintf(stderr, s1, s2); fprintf(stderr, "\n"); exit(1); }*/ void regerror (char *s) { if (errreport) errseen = s; else _ErrMsg2 (e__regerror, s); } /* - regcomp - compile a regular expression into internal code * * We can't allocate space until we know how big the compiled form will be, * but we can't compile it (and thus know how big it is) until we've got a * place to put the code. So we cheat: we compile it twice, once with code * generation turned off and size counting turned on, and once "for real". * This also means that we don't allocate space until we are sure that the * thing really will compile successfully, and we never have to move the * code and thus invalidate pointers into it. (Note that it has to be in * one piece because free() must be able to free it all.) * * Beware that the optimization-preparation code in here knows about some * of the structure of the compiled regexp. */ regexp * RegComp(exp) /* formerly "regcomp" */ char *exp; { register regexp *r; register char *scan; register char *longest; register int len; int flags; extern char *malloc(); if (exp == NULL) FAIL("NULL argument"); /* First pass: determine size, legality. */ regparse = exp; regnpar = 1; regsize = 0L; regcode = ®dummy; regc(MAGIC); if (reg(0, &flags) == NULL) return(NULL); /* Small enough for pointer-storage convention? */ if (regsize >= 32767L) /* Probably could be 65535L. */ FAIL("regexp too big"); /* Allocate space. */ r = (regexp *)malloc(sizeof(regexp) + (unsigned)regsize); if (r == NULL) FAIL("out of space"); /* Second pass: emit code. */ regparse = exp; regnpar = 1; regcode = r->program; regc(MAGIC); if (reg(0, &flags) == NULL) return(NULL); /* Dig out information for optimizations. */ r->regstart = '\0'; /* Worst-case defaults. */ r->reganch = 0; r->regmust = NULL; r->regmlen = 0; scan = r->program+1; /* First BRANCH. */ if (OP(regnext(scan)) == END) { /* Only one top-level choice. */ scan = OPERAND(scan); /* Starting-point info. */ if (OP(scan) == EXACTLY) r->regstart = *OPERAND(scan); else if (OP(scan) == BOL) r->reganch++; /* * If there's something expensive in the r.e., find the * longest literal string that must appear and make it the * regmust. Resolve ties in favor of later strings, since * the regstart check works with the beginning of the r.e. * and avoiding duplication strengthens checking. Not a * strong reason, but sufficient in the absence of others. */ if (flags&SPSTART) { longest = NULL; len = 0; for (; scan != NULL; scan = regnext(scan)) if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) { longest = OPERAND(scan); len = strlen(OPERAND(scan)); } r->regmust = longest; r->regmlen = len; } } return(r); } /* - reg - regular expression, i.e. main body or parenthesized thing * * Caller must absorb opening parenthesis. * * Combining parenthesis handling with the base level of regular expression * is a trifle forced, but the need to tie the tails of the branches to what * follows makes it hard to avoid. */ static char * reg(paren, flagp) int paren; /* Parenthesized? */ int *flagp; { register char *ret; register char *br; register char *ender; register int parno; int flags; *flagp = HASWIDTH; /* Tentatively. */ /* Make an OPEN node, if parenthesized. */ if (paren) { if (regnpar >= NSUBEXP) FAIL("too many ()"); parno = regnpar; regnpar++; ret = regnode(OPEN+parno); } else ret = NULL; /* Pick up the branches, linking them together. */ br = regbranch(&flags); if (br == NULL) return(NULL); if (ret != NULL) regtail(ret, br); /* OPEN -> first. */ else ret = br; if (!(flags&HASWIDTH)) *flagp &= ~HASWIDTH; *flagp |= flags&SPSTART; while (*regparse == '|') { regparse++; br = regbranch(&flags); if (br == NULL) return(NULL); regtail(ret, br); /* BRANCH -> BRANCH. */ if (!(flags&HASWIDTH)) *flagp &= ~HASWIDTH; *flagp |= flags&SPSTART; } /* Make a closing node, and hook it on the end. */ ender = regnode((paren) ? CLOSE+parno : END); regtail(ret, ender); /* Hook the tails of the branches to the closing node. */ for (br = ret; br != NULL; br = regnext(br)) regoptail(br, ender); /* Check for proper termination. */ if (paren && *regparse++ != ')') { FAIL("unmatched ()"); } else if (!paren && *regparse != '\0') { if (*regparse == ')') { FAIL("unmatched ()"); } else FAIL("junk on end"); /* "Can't happen". */ /* NOTREACHED */ } return(ret); } /* - regbranch - one alternative of an | operator * * Implements the concatenation operator. */ static char * regbranch(flagp) int *flagp; { register char *ret; register char *chain; register char *latest; int flags; *flagp = WORST; /* Tentatively. */ ret = regnode(BRANCH); chain = NULL; while (*regparse != '\0' && *regparse != '|' && *regparse != ')') { latest = regpiece(&flags); if (latest == NULL) return(NULL); *flagp |= flags&HASWIDTH; if (chain == NULL) /* First piece. */ *flagp |= flags&SPSTART; else regtail(chain, latest); chain = latest; } if (chain == NULL) /* Loop ran zero times. */ (void) regnode(NOTHING); return(ret); } /* - regpiece - something followed by possible [*+?] * * Note that the branching code sequences used for ? and the general cases * of * and + are somewhat optimized: they use the same NOTHING node as * both the endmarker for their branch list and the body of the last branch. * It might seem that this node could be dispensed with entirely, but the * endmarker role is not redundant. */ static char * regpiece(flagp) int *flagp; { register char *ret; register char op; register char *next; int flags; ret = regatom(&flags); if (ret == NULL) return(NULL); op = *regparse; if (!ISMULT(op)) { *flagp = flags; return(ret); } if (!(flags&HASWIDTH) && op != '?') FAIL("*+ operand could be empty"); *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH); if (op == '*' && (flags&SIMPLE)) reginsert(STAR, ret); else if (op == '*') { /* Emit x* as (x&|), where & means "self". */ reginsert(BRANCH, ret); /* Either x */ regoptail(ret, regnode(BACK)); /* and loop */ regoptail(ret, ret); /* back */ regtail(ret, regnode(BRANCH)); /* or */ regtail(ret, regnode(NOTHING)); /* null. */ } else if (op == '+' && (flags&SIMPLE)) reginsert(PLUS, ret); else if (op == '+') { /* Emit x+ as x(&|), where & means "self". */ next = regnode(BRANCH); /* Either */ regtail(ret, next); regtail(regnode(BACK), ret); /* loop back */ regtail(next, regnode(BRANCH)); /* or */ regtail(ret, regnode(NOTHING)); /* null. */ } else if (op == '?') { /* Emit x? as (x|) */ reginsert(BRANCH, ret); /* Either x */ regtail(ret, regnode(BRANCH)); /* or */ next = regnode(NOTHING); /* null. */ regtail(ret, next); regoptail(ret, next); } regparse++; if (ISMULT(*regparse)) FAIL("nested *?+"); return(ret); } /* - regatom - the lowest level * * Optimization: gobbles an entire sequence of ordinary characters so that * it can turn them into a single node, which is smaller to store and * faster to run. Backslashed characters are exceptions, each becoming a * separate node; the code is simpler that way and it's not worth fixing. */ static char * regatom(flagp) int *flagp; { register char *ret; int flags; *flagp = WORST; /* Tentatively. */ switch (*regparse++) { case '^': ret = regnode(BOL); break; case '$': ret = regnode(EOL); break; case '.': ret = regnode(ANY); *flagp |= HASWIDTH|SIMPLE; break; case '[': { register int class; register int classend; if (*regparse == '^') { /* Complement of range. */ ret = regnode(ANYBUT); regparse++; } else ret = regnode(ANYOF); if (*regparse == ']' || *regparse == '-') regc(*regparse++); while (*regparse != '\0' && *regparse != ']') { if (*regparse == '-') { regparse++; if (*regparse == ']' || *regparse == '\0') regc('-'); else { class = UCHARAT(regparse-2)+1; classend = UCHARAT(regparse); if (class > classend+1) FAIL("invalid [] range"); for (; class <= classend; class++) regc(class); regparse++; } } else regc(*regparse++); } regc('\0'); if (*regparse != ']') FAIL("unmatched []"); regparse++; *flagp |= HASWIDTH|SIMPLE; } break; case '(': ret = reg(1, &flags); if (ret == NULL) return(NULL); *flagp |= flags&(HASWIDTH|SPSTART); break; case '\0': case '|': case ')': FAIL("internal urp"); /* Supposed to be caught earlier. */ case '?': case '+': case '*': FAIL("?+* follows nothing"); case '\\': if (*regparse == '\0') FAIL("trailing \\"); ret = regnode(EXACTLY); regc(*regparse++); regc('\0'); *flagp |= HASWIDTH|SIMPLE; break; default: { register int len; register char ender; regparse--; len = strcspn(regparse, META); if (len <= 0) FAIL("internal disaster"); ender = *(regparse+len); if (len > 1 && ISMULT(ender)) len--; /* Back off clear of ?+* operand. */ *flagp |= HASWIDTH; if (len == 1) *flagp |= SIMPLE; ret = regnode(EXACTLY); while (len > 0) { regc(*regparse++); len--; } regc('\0'); } break; } return(ret); } /* - regnode - emit a node */ static char * /* Location. */ regnode(op) char op; { register char *ret; register char *ptr; ret = regcode; if (ret == ®dummy) { regsize += 3; return(ret); } ptr = ret; *ptr++ = op; *ptr++ = '\0'; /* Null "next" pointer. */ *ptr++ = '\0'; regcode = ptr; return(ret); } /* - regc - emit (if appropriate) a byte of code */ static void regc(b) char b; { if (regcode != ®dummy) *regcode++ = b; else regsize++; } /* - reginsert - insert an operator in front of already-emitted operand * * Means relocating the operand. */ static void reginsert(op, opnd) char op; char *opnd; { register char *src; register char *dst; register char *place; if (regcode == ®dummy) { regsize += 3; return; } src = regcode; regcode += 3; dst = regcode; while (src > opnd) *--dst = *--src; place = opnd; /* Op node, where operand used to be. */ *place++ = op; *place++ = '\0'; *place++ = '\0'; } /* - regtail - set the next-pointer at the end of a node chain */ static void regtail(p, val) char *p; char *val; { register char *scan; register char *temp; register int offset; if (p == ®dummy) return; /* Find last node. */ scan = p; for (;;) { temp = regnext(scan); if (temp == NULL) break; scan = temp; } if (OP(scan) == BACK) offset = scan - val; else offset = val - scan; *(scan+1) = (offset>>8)&0377; *(scan+2) = offset&0377; } /* - regoptail - regtail on operand of first argument; nop if operandless */ static void regoptail(p, val) char *p; char *val; { /* "Operandless" and "op != BRANCH" are synonymous in practice. */ if (p == NULL || p == ®dummy || OP(p) != BRANCH) return; regtail(OPERAND(p), val); } /* * regexec and friends */ /* * Global work variables for regexec(). */ static char *reginput; /* String-input pointer. */ static char *regbol; /* Beginning of input, for ^ check. */ static char **regstartp; /* Pointer to startp array. */ static char **regendp; /* Ditto for endp. */ /* * Forwards. */ STATIC int regtry(); STATIC int regmatch(); STATIC int regrepeat(); #ifdef DEBUG int regnarrate = 0; void regdump(); STATIC char *regprop(); #endif /* - regexec - match a regexp against a string */ int RegExec(prog, string) /* formerly "regexec" */ register regexp *prog; register char *string; { register char *s; /* Be paranoid... */ if (prog == NULL || string == NULL) { regerror("NULL parameter"); return(0); } /* Check validity of program. */ if (UCHARAT(prog->program) != MAGIC) { regerror("corrupted program"); return(0); } /* If there is a "must appear" string, look for it. */ if (prog->regmust != NULL) { s = string; while ((s = strchr(s, prog->regmust[0])) != NULL) { if (strncmp(s, prog->regmust, prog->regmlen) == 0) break; /* Found it. */ s++; } if (s == NULL) /* Not present. */ return(0); } /* Mark beginning of line for ^ . */ regbol = string; /* Simplest case: anchored match need be tried only once. */ if (prog->reganch) return(regtry(prog, string)); /* Messy cases: unanchored match. */ s = string; if (prog->regstart != '\0') /* We know what char it must start with. */ while ((s = strchr(s, prog->regstart)) != NULL) { if (regtry(prog, s)) return(1); s++; } else /* We don't -- general case. */ do { if (regtry(prog, s)) return(1); } while (*s++ != '\0'); /* Failure. */ return(0); } /* - regtry - try match at specific point */ static int /* 0 failure, 1 success */ regtry(prog, string) regexp *prog; char *string; { register int i; register char **sp; register char **ep; reginput = string; regstartp = prog->startp; regendp = prog->endp; sp = prog->startp; ep = prog->endp; for (i = NSUBEXP; i > 0; i--) { *sp++ = NULL; *ep++ = NULL; } if (regmatch(prog->program + 1)) { prog->startp[0] = string; prog->endp[0] = reginput; return(1); } else return(0); } /* - regmatch - main matching routine * * Conceptually the strategy is simple: check to see whether the current * node matches, call self recursively to see whether the rest matches, * and then act accordingly. In practice we make some effort to avoid * recursion, in particular by going through "ordinary" nodes (that don't * need to know whether the rest of the match failed) by a loop instead of * by recursion. */ static int /* 0 failure, 1 success */ regmatch(prog) char *prog; { register char *scan; /* Current node. */ char *next; /* Next node. */ scan = prog; #ifdef DEBUG if (scan != NULL && regnarrate) fprintf(stderr, "%s(\n", regprop(scan)); #endif while (scan != NULL) { #ifdef DEBUG if (regnarrate) fprintf(stderr, "%s...\n", regprop(scan)); #endif next = regnext(scan); switch (OP(scan)) { case BOL: if (reginput != regbol) return(0); break; case EOL: if (*reginput != '\0') return(0); break; case ANY: if (*reginput == '\0') return(0); reginput++; break; case EXACTLY: { register int len; register char *opnd; opnd = OPERAND(scan); /* Inline the first character, for speed. */ if (*opnd != *reginput) return(0); len = strlen(opnd); if (len > 1 && strncmp(opnd, reginput, len) != 0) return(0); reginput += len; } break; case ANYOF: if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL) return(0); reginput++; break; case ANYBUT: if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL) return(0); reginput++; break; case NOTHING: break; case BACK: break; case OPEN+1: case OPEN+2: case OPEN+3: case OPEN+4: case OPEN+5: case OPEN+6: case OPEN+7: case OPEN+8: case OPEN+9: { register int no; register char *save; no = OP(scan) - OPEN; save = reginput; if (regmatch(next)) { /* * Don't set startp if some later * invocation of the same parentheses * already has. */ if (regstartp[no] == NULL) regstartp[no] = save; return(1); } else return(0); } case CLOSE+1: case CLOSE+2: case CLOSE+3: case CLOSE+4: case CLOSE+5: case CLOSE+6: case CLOSE+7: case CLOSE+8: case CLOSE+9: { register int no; register char *save; no = OP(scan) - CLOSE; save = reginput; if (regmatch(next)) { /* * Don't set endp if some later * invocation of the same parentheses * already has. */ if (regendp[no] == NULL) regendp[no] = save; return(1); } else return(0); } case BRANCH: { register char *save; if (OP(next) != BRANCH) /* No choice. */ next = OPERAND(scan); /* Avoid recursion. */ else { do { save = reginput; if (regmatch(OPERAND(scan))) return(1); reginput = save; scan = regnext(scan); } while (scan != NULL && OP(scan) == BRANCH); return(0); /* NOTREACHED */ } } break; case STAR: case PLUS: { register char nextch; register int no; register char *save; register int min; /* * Lookahead to avoid useless match attempts * when we know what character comes next. */ nextch = '\0'; if (OP(next) == EXACTLY) nextch = *OPERAND(next); min = (OP(scan) == STAR) ? 0 : 1; save = reginput; no = regrepeat(OPERAND(scan)); while (no >= min) { /* If it could work, try it. */ if (nextch == '\0' || *reginput == nextch) if (regmatch(next)) return(1); /* Couldn't or didn't -- back up. */ no--; reginput = save + no; } return(0); } case END: return(1); /* Success! */ default: regerror("memory corruption"); return(0); } scan = next; } /* * We get here only if there's trouble -- normally "case END" is * the terminating point. */ regerror("corrupted pointers"); return(0); } /* - regrepeat - repeatedly match something simple, report how many */ static int regrepeat(p) char *p; { register int count = 0; register char *scan; register char *opnd; scan = reginput; opnd = OPERAND(p); switch (OP(p)) { case ANY: count = strlen(scan); scan += count; break; case EXACTLY: while (*opnd == *scan) { count++; scan++; } break; case ANYOF: while (*scan != '\0' && strchr(opnd, *scan) != NULL) { count++; scan++; } break; case ANYBUT: while (*scan != '\0' && strchr(opnd, *scan) == NULL) { count++; scan++; } break; default: /* Oh dear. Called inappropriately. */ regerror("internal foulup"); count = 0; /* Best compromise. */ break; } reginput = scan; return(count); } /* - regnext - dig the "next" pointer out of a node */ static char * regnext(p) register char *p; { register int offset; if (p == ®dummy) return(NULL); offset = NEXT(p); if (offset == 0) return(NULL); if (OP(p) == BACK) return(p-offset); else return(p+offset); } #ifdef DEBUG STATIC char *regprop(); /* - regdump - dump a regexp onto stdout in vaguely comprehensible form */ void regdump(r) regexp *r; { register char *s; register char op = EXACTLY; /* Arbitrary non-END op. */ register char *next; extern char *strchr(); s = r->program + 1; while (op != END) { /* While that wasn't END last time... */ op = OP(s); printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */ next = regnext(s); if (next == NULL) /* Next ptr. */ printf("(0)"); else printf("(%d)", (s-r->program)+(next-s)); s += 3; if (op == ANYOF || op == ANYBUT || op == EXACTLY) { /* Literal string, where present. */ while (*s != '\0') { putchar(*s); s++; } s++; } putchar('\n'); } /* Header fields of interest. */ if (r->regstart != '\0') printf("start `%c' ", r->regstart); if (r->reganch) printf("anchored "); if (r->regmust != NULL) printf("must have \"%s\"", r->regmust); printf("\n"); } /* - regprop - printable representation of opcode */ static char * regprop(op) char *op; { register char *p; static char buf[50]; (void) strcpy(buf, ":"); switch (OP(op)) { case BOL: p = "BOL"; break; case EOL: p = "EOL"; break; case ANY: p = "ANY"; break; case ANYOF: p = "ANYOF"; break; case ANYBUT: p = "ANYBUT"; break; case BRANCH: p = "BRANCH"; break; case EXACTLY: p = "EXACTLY"; break; case NOTHING: p = "NOTHING"; break; case BACK: p = "BACK"; break; case END: p = "END"; break; case OPEN+1: case OPEN+2: case OPEN+3: case OPEN+4: case OPEN+5: case OPEN+6: case OPEN+7: case OPEN+8: case OPEN+9: sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN); p = NULL; break; case CLOSE+1: case CLOSE+2: case CLOSE+3: case CLOSE+4: case CLOSE+5: case CLOSE+6: case CLOSE+7: case CLOSE+8: case CLOSE+9: sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE); p = NULL; break; case STAR: p = "STAR"; break; case PLUS: p = "PLUS"; break; default: regerror("corrupted opcode"); break; } if (p != NULL) (void) strcat(buf, p); return(buf); } #endif /* * The following is provided for those people who do not have strcspn() in * their C libraries. They should get off their butts and do something * about it; at least one public-domain implementation of those (highly * useful) string routines has been published on Usenet. */ #ifdef STRCSPN /* * strcspn - find length of initial segment of s1 consisting entirely * of characters not from s2 */ static int strcspn(s1, s2) char *s1; char *s2; { register char *scan1; register char *scan2; register int count; count = 0; for (scan1 = s1; *scan1 != '\0'; scan1++) { for (scan2 = s2; *scan2 != '\0';) /* ++ moved down. */ if (*scan1 == *scan2++) return(count); count++; } return(count); } #endif /****** RegWildToRegexp ******************************************************* ** ** converts a string containing wildcards into a regular expression; ** the world can contain ** the wildcards '*' (any number of chars) and '?' (any single character); ** the function returns the position of the first wildcard within the ** word (first position is 1!); ** "." is converted to "\." ** expression will begin with '^' and end with '$'; ** ** INPUT: o string containing wildcards [R] ** o pointer to output regular expression [R] ** o flag if wildcards (see above) are to be recognized as ** such and be replaced within a regular expression ** IMPLICIT: ** ** RETURNS: 0 if word contains no wildcards ** position of first wildcard in string (1=string begin) */ int RegWildToRegexp (char *s, char *reStr, INT4 isWild) { int firstWildLoc=0, k; char c, tmp[512]; char *reStrPtr=tmp; /* tmp str so that output can be written to input str */ /* ** a full regular expression is given between two '/' s */ if (*s == '/' && *(s + strlen (s) - 1) == '/') { strcpy (tmp, s+1); /* remove left '/'*/ tmp[ strlen (tmp) - 1 ] = '\0'; /* ...and right '/' */ strcpy (reStr, tmp); return 1; } if (isWild) { *reStrPtr++ = '^'; /* begin of line */ for (k=0; (c = s[k]); k++) { switch (c) { case '*': case '?': if (!firstWildLoc) firstWildLoc = k+1; *reStrPtr++ = '.'; if (c == '*') { *reStrPtr++ = '*'; } break; case '.': case '|': case '(': case ')': case '+': case '[': *reStrPtr++ = '\\'; *reStrPtr++ = c; break; default: *reStrPtr++ = s[k]; } } *reStrPtr++ = '$'; /* end of line */ *reStrPtr = '\0'; if (reStr) strcpy (reStr, tmp); } return firstWildLoc; } (c = s[k]); k++) { switch (c) { case '*': case '?': if (!firstWildLoc) firstWildLoc = k+1; *reStrPtr++ = '.'; if (c == '*') { *reStrPtr++ = '*'; } break; case '.': case '|': case '(': case ')': case '+': case '[': *reStrPtr++ = '\\'; *reStrPtr++ = c; break; default: *reStrPtr++ = s[k]; } } *reStrPtr++ = '$'; /* end of line */ *reStrPtr = '\srs/src/regexp.h * Definitions etc. for regexp(3) routines. * * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof], * not the System V one. */ #define NSUBEXP 10 typedef struct regexp { char *startp[NSUBEXP]; char *endp[NSUBEXP]; char regstart; /* Internal use only. */ char reganch; /* Internal use only. */ char *regmust; /* Internal use only. */ int regmlen; /* Internal use only. */ char program[1]; /* Unwarranted chumminess with compiler. */ } regexp; extern regexp *RegComp(); extern int RegExec(); extern void regsub(); extern void regerror(); extern int RegWildToRegexp (char *str, char *reStr, int isWild); ot the System V one. */ #define NSUBEXP 10 typedef struct regexp { char *startp[NSUBEXP]; char *endp[NSUBEXP]; char regstart; /* Internal use only. */ char reganch; /* Internal use only. */ char *regmust; /* Internal use only. */ int regmlen; /* Internal use only. */ char program[1]; /* Unwarranted chumminess with compiler. */ } regexp; extern regexp *RegComp(); externsrs/src/regmagic.h * The first byte of the regexp internal "program" is actually this magic * number; the start node begins in the second byte. */ #define MAGIC 0234 define NSUBEXP 10 typedef struct regexp { char *startp[NSUBEXP]; char *endp[NSUBEXP]; char regstart; /* Internal use only. */ char reganch; /* Internal use only. */ char *regmust; /* Internal use only. */ int regmlen; /* Internal use only. */ char program[1]; /* Unwarranted chumminess with compiler. */ } regexp; extern regexp *R; externsrs/src/regsub.c * regsub * @(#)regsub.c 1.3 of 2 April 86 * * Copyright (c) 1986 by University of Toronto. * Written by Henry Spencer. Not derived from licensed software. * * Permission is granted to anyone to use this software for any * purpose on any computer system, and to redistribute it freely, * subject to the following restrictions: * * 1. The author is not responsible for the consequences of use of * this software, no matter how awful, even if they arise * from defects in it. * * 2. The origin of this software must not be misrepresented, either * by explicit claim or by omission. * * 3. Altered versions must be plainly marked as such, and must not * be misrepresented as being the original software. */ #include #include #include "regmagic.h" #ifndef CHARBITS #define UCHARAT(p) ((int)*(unsigned char *)(p)) #else #define UCHARAT(p) ((int)*(p)&CHARBITS) #endif /* - regsub - perform substitutions after a regexp match */ void regsub(prog, source, dest) regexp *prog; char *source; char *dest; { register char *src; register char *dst; register char c; register int no; register int len; extern char *strncpy(); if (prog == NULL || source == NULL || dest == NULL) { regerror("NULL parm to regsub"); return; } if (UCHARAT(prog->program) != MAGIC) { regerror("damaged regexp fed to regsub"); return; } src = source; dst = dest; while ((c = *src++) != '\0') { if (c == '&') no = 0; else if (c == '\\' && '0' <= *src && *src <= '9') no = *src++ - '0'; else no = -1; if (no < 0) { /* Ordinary character. */ if (c == '\\' && (*src == '\\' || *src == '&')) c = *src++; *dst++ = c; } else if (prog->startp[no] != NULL && prog->endp[no] != NULL) { len = prog->endp[no] - prog->startp[no]; (void) strncpy(dst, prog->startp[no], len); dst += len; if (len != 0 && *(dst-1) == '\0') { /* strncpy hit NUL. */ regerror("damaged match string"); return; } } } *dst++ = '\0'; } && '0' <= *src && *src <= '9') no = *src++ - '0'; esrs/src/sdlget.c char sdlget_ID[] = "\n$Id: sdlget.c,v 1.1 1996/05/06 15:17:15 srs Exp $"; /* ** ** $RCSfile: sdlget.c,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:17:15 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.x Copyright by Thure Etzold ** Unix port: Lukas Rosenthaler and Reinhard Doelz ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include "message.h" #include "futil.h" #include "odd.h" #define _SDL #define _ODD #include "oddclass.h" /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** object wide variables */ #ifndef BOOTSTRAP typedef int (*SDLoFNCT)(); extern SDLoFNCT SDL_fnctx[]; #endif SDLoPTR section; INT4 section_z; /**api* SdlGetObjects ********************************************************* ** ** expands name to "SRSSEC:name.SEC" and "... .PTR" reads these files ** using block-IO into newly allocated memory; addresses in ref-list ** are corrected for the difference of location of section-block; ** ** INPUT: address of array of array of objects [W] ** address of array of sizes of above array [W] ** address of section name [R] ** IMPLICIT: ** SDL_fnct (SDLoFNCT[]) [R] ** section (void *) [W] ** section_z (int) [W] ** ** RETURNS: 1 */ INT4 SdlGetObjects (long int **obj_n, void ***obj_p, char *sec_nm) { FILE *sec_fd, *ptr_fd; char fil_nm[FILxXNAM+1]; SDLoPTR *ptr, *ptrlist, data, *addr, sec, *o_p, *ptr_p; long int addr_n, *o_n; int diff, k, objc_n, rv, sec_z, ptr_z; /* ** open file with the data (*.sec) and the file with a list of pointers ** int the data file to be updated (*.ptr) */ sprintf (fil_nm, "SRSSEC:%s.sec", sec_nm); sec_fd = FilOpenR (fil_nm, &rv); _ErrExit2 (rv, fil_nm); sprintf (fil_nm, "SRSSEC:%s.ptr", sec_nm); ptr_fd = FilOpenR (fil_nm, &rv); _ErrExit2 (rv, fil_nm); /* ** get the sizes of both files, allocate memory accordingly and read the ** files in one go */ rv = fread (&sec_z, sizeof(int), 1, sec_fd); if (sizeof (char *) != sizeof (int)) fseek (sec_fd, sizeof (char *) - sizeof (int), 1); /** 1 == SEEK_CUR */ rv = fread (&ptr_z, sizeof(int), 1, ptr_fd); if ((sec = (SDLoPTR) malloc (sec_z)) == NULL) _ErrExit2(e__allocfail, "section by SdlGetObjects"); section = sec; /** global variables */ section_z = sec_z; if ((ptrlist = (SDLoPTR *) malloc (ptr_z)) == 0) _ErrExit2(e__allocfail, "pointer array by SdlGetObjects"); fread (sec, 1, sec_z, sec_fd); fread (ptrlist, 1, ptr_z, ptr_fd); ptr = ptrlist; /* ** get the following info from begin of .ptr file: ** o address of section begin (at the time section was built) ** o number of object classes represented in the section ** o for each class the number of instances + offset of its array in ** the section */ data = (char *) *ptr++; /** addr of section begin */ objc_n = (long) *ptr++; /** number of objects */ o_n = (long *) malloc (objc_n * sizeof (int *)); o_p = (SDLoPTR *) malloc (objc_n * sizeof (unsigned int *)); diff = (int) (sec - data); for (k=0; k < objc_n; k++) { o_p[k] = (SDLoPTR) (*ptr++) + diff; /** address of obj-array */ o_n[k] = (long) *ptr++; /** size of obj-array */ } /* ** then read the number of references */ addr_n = (long) *ptr++; /** number of references */ addr = ptr; /** ref list */ for (k=0; k < addr_n; k++) { ptr_p = (SDLoPTR *) (addr[k] + diff); if ((long) *ptr_p <= SDLxXFNCT) { #ifndef BOOTSTRAP if ((long) *ptr_p < 0) *ptr_p = 0; else *ptr_p = (long) *ptr_p == SDLxXFNCT ? NULL : (SDLoPTR) SDL_fnctx[(long)*ptr_p]; #else ; #endif } else *ptr_p = *ptr_p + diff; } /* ** delete list of pointers to be relocated and return info to caller */ free (ptrlist); *obj_p = (void **) o_p; *obj_n = o_n; return objc_n; } /**api* SdlGetObj ************************************************************* ** ** gets pointer to objects of a type and the number; ** ** INPUT: address of SDL descr. [R] ** object-class ID [R] ** address of object pointer [W] ** address of object count [W] ** IMPLICIT: ** ** RETURNS: 1 */ INT4 SdlGetObj (SDLo *sdl, int class_x, void **obj_p, int *obj_n) { *obj_p = (void *) (sdl->oc[class_x].s); *obj_n = sdl->oc[class_x].ns; return 1; } /**api* OddIsInDepot ********************************************************** ** ** returns 1 if pointer points within a depot with defined ODD objects ** ...means that that ** cannot be freed because the whole depot is allocated as one big block ** ** INPUT: address [R] ** IMPLICIT: ** ** RETURNS: 1 */ INT4 OddIsInDepot (char *p) { return (p >= section && p < section + section_z) ? 1 : 0; } = (void *) (sdl->oc[class_x].s); *obj_n = sdl->oc[class_x].ns; return 1; } /**api* OddIsInDepot ********************************************************** ** ** returns 1 if pointer posrs/src/sdlget.h ** ** $RCSfile: sdlget.h,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:17:15 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** Copyright by Thure Etzold ** */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** list of functions exported by module "seqlib" */ INT4 OddIsInDepot (char *p); ******************************************** ** ** returnsinter posrs/src/sdlnew.c char sdl_ID[] = "$Id: sdlnew.c,v 1.14 1997/03/18 22:52:32 srs Exp $"; /* ** ** $RCSfile: sdlnew.c,v $ ** $Revision: 1.14 $ ** $Date: 1997/03/18 22:52:32 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** Copyright by Thure Etzold ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include "message.h" #include "futil.h" #include "sm.h" #include "strv.h" #include "tm.h" #include "map.h" #include "par.h" #include "templ.h" #include "dict.h" #include "variable.h" #define _SDL #define _ODD #include "oddclass.h" #include "odd.h" /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** macros and enums */ enum status {ODDxOBSOLETE=1, ODDxSYSTEM, ODDxAPI}; enum linebreak {SDLxFIRST=1, SDLxLAST=2, SDLxBREAK=4, SDLxBOUND=8}; typedef INT4 (*SDLoFNCT)(); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** object wide variables */ static int addr_n = 0; static SDLoPTR *addr; static FILo file; static int fnct_x; SDLo *odd=NULL; ODDoFNCT_P function[SDLxXFNCT]; FILo *f = &file; static MAPo map; ODDoCDEFINE cDefine[100]; INT4 cDefineN=0; #ifndef BOOTSTRAP extern SDLoFNCT SDL_fnct[]; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of static functions */ static void OddSetFlags (int opt); static int OddObjSizes (void); static int SdlAlloc (void); int SdlWrtHdr (SDLo *d, int opt); static int SdlCloseSec (); static int SdlObjInx (char *nam); int OddRegisterObj (SDLoOBJ *obj); static int SdlIsChild (int p_x, int ch_x); void *OddFinishObj (SDLoOBJ *obj); static int OddResetObj (SDLoOBJ *obj); static int OddGetValue (SDLoATTR *attr, char **tokstr, unsigned *tokval, VARo *value); static int SdlCopySec (char **s); static int SdlWrtTtl (FILE *f, char *in, char *out); static int SdlWrtTypDef (FILE *fil, SDLoOBJ *s, int ns); static int OddWrtInit (FILE *fil, SDLoOBJ *s, int ns); static void OddWrtInitExtern (FILE *file, SDLoOBJ *class, int classN); static int SdlWrtAttr (FILE *fil, SDLoOBJ *obj, char *typdef_nm, char *gtyp_nm); static int SdlWrtFnct (FILE *f, SDLoOBJ *s); void OddWriteClassInfo (SDLo *odd); INT4 OddIsAttr (SDLoATTR *attr, char *option); INT4 OddIsClass (SDLoOBJ *class, char *option); /**api* OddInit *************************************************************** ** ** ** INPUT: ODD data base object [W] ** ** IMPLICIT: ** odd (SDLo *) [W] ** ** RETURNS: 1 */ SDLo *OddInit (SDLo *oddBase, INT4 level) { ODDoATYP *at; INT4 atN; if (level == 1) { odd = oddBase; } else if (level == 2) { at = oddBase->at; atN = oddBase->at_n; odd = (SDLo *) oddBase->oc[odd->oc_n-1].s; odd->at = at; odd->at_n = atN; odd->action |= SDLxHDR; } odd->pass_n = 1; OddSetFlags (level); OddObjSizes (); return odd; } Int4 OddIsActive () { return odd ? 1 : 0; } /**api* OddInit *************************************************************** ** ** ** INPUT: ODD data base object [W] ** ** IMPLICIT: ** odd (SDLo *) [W] ** ** RETURNS: 1 */ void OddInitDepot () { if (odd->pass_n == 1) { odd->pass_n = 2; SdlAlloc (); } } /****** SdlMalloc ************************************************************* ** ** same as malloc but creates a mapsection initially ** ** INPUT: nr. of bytes to allocate [R] ** IMPLICIT: ** addr (unsigned int) ** odd (SDLo *) ** map (MAPo) ** ** RETURNS: address of allocated area ** NULL if none available */ void *SdlMalloc (int siz) { static int init_f = FALSE; char fil_nm[FILxXNAM+1]; int shiftalign, rv; if (!init_f) /* init_f is FALSE on first call, else TRUE */ { /* ** this part of the code is only execute the first time this ** function is called. It then allocates a map section of ** size given by odd->sec_z */ sprintf (fil_nm, "SRSSEC:%s.sec", odd->sec_nm); rv = MapAlloc (&map, fil_nm, odd->sec_z); _ErrExit (rv); /* ** first int in section has the file offset after the last byte written ** to same section...this int + some bytes (for alignment) must be skipped ** before starting to write to the section */ shiftalign = (sizeof (char *) - sizeof (unsigned int)); map.off += shiftalign; *(map.foff) += shiftalign; if ((addr = (SDLoPTR *) malloc (sizeof (SDLoPTR) * SDLxXADDR)) == NULL) _ErrExit2(e__allocfail, "array addr"); init_f = TRUE; } return (void *) MapMalloc (&map, siz); } /****** OddSetFlags *********************************************************** ** ** sets global flags; ** ** INPUT: compilation level (1 or 2) [R] ** IMPLICIT: ** odd (SDLo *) [W] ** ** RETURNS: 1 */ static void OddSetFlags (INT4 level) { odd->error = FALSE; if (level == 1) { if (ParGetBool ("doMetaData")) odd->action = SDLxHDR; else odd->action = SDLxNOHDR; } else if (level == 2) { if (ParGetBool ("doInitHeader")) odd->action = SDLxHDR; else if (ParGetBool ("doSection") && ParGetBool ("doHeader")) odd->action = SDLxHDRSEC; else if (ParGetBool ("doSection")) odd->action = SDLxSECTION; else if (ParGetBool ("doHeader")) odd->action = SDLxHDR2; else if (ParGetBool ("doClassInfo")) odd->action = SDLxHDR2; } odd->section_f = (odd->action == SDLxSECTION || odd->action == SDLxHDRSEC); } /**new* OddGetClass *********************************************************** ** ** Returns the class object which has the specified name. ** ** INPUT: name of the class [W] ** IMPLICIT: ** odd (SDLo *) ** ** ** RETURNS: ** class object ** NULL if specified class does not exist */ SDLoOBJ *OddGetClass (char *className) { SDLoOBJ *class; INT4 classIndex; classIndex = SdlObjInx (className); _ErrIf (classIndex) return NULL; else return &(odd->oc[classIndex]); } void *OddGetCurrObj (SDLoOBJ *class) { return class->uobj_coff; } char *OddGetClassName (SDLoOBJ *class) { return class->nam; } SDLoOBJ *OddGetPartofClass (SDLoATTR *attr) { return &(odd->oc[attr->dfltv]); } void *OddGetObjectPtr (SDLoOBJ *class, Int4 n) { Int4 firstX; firstX = (n < 0) ? class->gbl_n + n : n; return (void *) (class->s + (class->siz * firstX)); } Int4 OddGetObjectN (SDLoOBJ *class) { return (class->ns); } void OddSetObjListSize (SDLoOBJ *class, char *attrName, Int4 n) { SDLoOBJ *refClass; SDLoATTR *attr; char tmp[100]; sprintf (tmp, "%sN", attrName); if ((attr = OddGetAttribute (class, tmp))) { attr->hasObjsN = n; if (!(attr = OddGetAttribute (class, attrName))) _ErrExit3 (e__icaunknownattr, OddGetClassName (class), attrName); attr->hasObjsN = n; refClass = OddGetPartofClass (attr); attr->hasFirstObj = OddGetObjectPtr (refClass, -n); } } /****** OddFinishObj *********************************************************** ** ** does post processing of object i.e. checks whether all required ** attributes have been read, fills non read attributes with defaults; ** ** INPUT: object ID [W] ** IMPLICIT: ** odd (SDLo *) [W] ** f (FILo *) [R] ** ** RETURNS: 1 if success ** e__icarequiredattr + ** e__parnotok + ** e__noss + */ void *OddFinishObj (SDLoOBJ *class) { SDLoATTR *attr; SDLoPTR off; int rv, k; int (*make) (SDLoOBJ *, SDLoATTR *, SDLoPTR *); for (k = 0; k < class->np; k++) { attr = &(class->p[k]); off = class->uobj_coff + attr->off; /* off to place prmtr */ if ((make = odd->at[attr->typ].make) != NULL) { rv = (*make) (class, attr, &off); } _ErrIf (rv) { if (rv == e__icarequiredattr) _ErrMsg3(e__icarequiredattr, attr->nam, OddGetClassName (class)); odd->error = TRUE; continue; } } if (odd->section_f && class->typ != SDLxVIRTUAL) SdlSaveAddr (class, class->uobj_coff); /* save pointers */ OddResetObj (class); return class->uobj_coff; } /****** OddResetObj ********************************************************** ** ** after a object has been read along with all child-objects ** some attributes of SDLoOBJ and SDLoATTR have to be reset before ** working on the next object on the same level; this is ** what is done here; ** ** INPUT: object ID [W] ** IMPLICIT: ** odd (SDLo *) [W] ** ** RETURNS: 1 */ static int OddResetObj (SDLoOBJ *obj) { SDLoOBJ *tmp; SDLoATTR *attr; int k; for (k = 0; k < obj->np; k++) { attr = &obj->p[k]; attr->isrd = FALSE; attr->hasObjsN = -1; } for (k = 0; k < obj->nss; k++) { /* child-objects */ tmp = &odd->oc[ (obj->ss)[k] ]; if (tmp != obj) tmp->loc_n = 0; } return 1; } /****** OddRegisterObj ******************************************************** ** ** increments counter for a specific object and calculates offset ** of new target object; ** counters gbl_n and loc_n must be initialized with 0 ** ** INPUT: address of object-descriptor (SDLoOBJ) [W] ** IMPLICIT: ** odd (SDLo *) ** ** RETURNS: 1 if success ** e__toomanstrct */ int OddRegisterObj (SDLoOBJ *obj) { (obj->gbl_n)++; (obj->loc_n)++; if (obj->gbl_n > obj->ns && odd->pass_n == 2) return e__toomanstrct; if (obj->gbl_n != 1) obj->uobj_coff += obj->siz; else obj->uobj_coff = obj->s; return 1; } /******************* odd ids ************************************************/ typedef struct ODDoID { char name[80]; SDLoOBJ *class; INT4 objX; } ODDoID; static void* OddIdToKey (DictElem* e) { return (*(ODDoID **)e)->name; } static CLASSoDICT idDictClass = { (ValComparer)strequal, (ValHasher)strhash, (KeyAccessor)OddIdToKey, NULL, 0 }; static DICTv idDict=NULL; void OddIdInit () { if (idDict) DictDestroy (idDict); idDict = DictCreate (&idDictClass); } int OddIdRetrieve (char *idName, INT4 isOptional) { Iter i; ODDoID *id; if (i = DictWith (idDict, idName)) { id = DictIn (i, ODDoID*); return id->objX; } else { if (!isOptional) _ErrMsg3 (e__objectunknown, "object-ID", idName); return -1; } } void OddIdRegister (SDLoOBJ *class, char *idName) { ODDoID *id; if ((id = (ODDoID *) malloc (sizeof (ODDoID))) == NULL) _ErrExit2 (e__allocfail, "object-Id"); strcpy (id->name, idName); id->class = class; id->objX = class->gbl_n-1; if (!idDict) OddIdInit (); if (DictWith (idDict, idName)) _ErrMsg2 (e__duplicatekey, idName); DictSet (&idDict, idName, ODDoID*) = id; } /****** OddObjSizes *********************************************************** ** ** calculates offsets of attributes in all objects described ** in array of object definitions and calculates ** the objects sizes; objects that inherit others get size of inherited ** object added - inherited objects are appended; ** ** INPUT: ** IMPLICIT: ** odd (SDLo *) [W] ** gblerr (int) [W] ** ** RETURNS: 1 if success ** e__novalptyp + */ static int OddObjSizes (void) { SDLoOBJ *obj, *iobj; SDLoATTR *attr; int n, k, attr_n, off, member_z, maxmember_z; int (*calcsize) (); for (n = 0; n < odd->oc_n; n++) { obj = &((odd->oc)[n]); attr_n = obj->np; off = 0; for (k=0, maxmember_z=0; k < attr_n; k++) { attr = &(obj->p)[k]; /* ** calculate the size of the data member that will correspond ** to the attribute....assuming that the data structure itself is ** optimally aligned some invidual members have to be aligned within the ** structure ...this is also done by the function "calcsize" which ** sets the offset to the begin of the data member */ if ((calcsize = odd->at[attr->typ].size) != NULL) { member_z = (*calcsize) (obj, attr, &off); if (member_z > maxmember_z) maxmember_z = member_z; attr->off = off; off += member_z; } } /* ** calc. size of structure until begin of next ...this depends on the ** alignment which is to the size of the largest member; eg, on osf, a ** structure that has a pointer (size 8byte) is always aligned to an 8 byte ** boundary */ if (maxmember_z >= 8) _SdlAlignEight (off); else if (maxmember_z >= 4) _SdlAlignFour (off); obj->siz = off; } return 1; } /****** SdlAlloc ************************************************************** ** ** allocates storage for all counted objects and sets counters back to 0; ** if object is to be organized in a data structure (such as a list) ** then the size has to be increased by the size of the pointers needed. ** - the needed space is given by org->off. ** This additional space is always at the beginning of a user block! ** So by shifting the whole array of user-objects by org->off ** obj->s points to the begin of the user-block as seen from the user ** and so it can be treated as any other user-object. ** ** INPUT: ** IMPLICIT: ** odd (SDLo *) [W] ** ** RETURNS: 1 if successfull */ static int SdlAlloc (void) { SDLoOBJ *obj; int allsiz, k; for (k=0; k < odd->oc_n; k++) { obj = &(odd->oc[k]); if (obj->gbl_n == 0) continue; obj->ns = obj->gbl_n; allsiz = obj->siz * obj->ns; obj->s = _SdlMalloc (allsiz); if (!obj->s) _ErrExit2 (e__allocfail, "array of objects by SdlAlloc"); obj->gbl_n = obj->loc_n = 0; /* reset counter */ } return 1; } /****** SdlIsChild ************************************************************ ** ** finds out if object with second index is a child of object ** with first index; ** ** INPUT: ID of parent object [R] ** ID of child object [R] ** IMPLICIT: ** odd (SDLo *) ** ** RETURNS: 1 if child ** 0 if not */ static int SdlIsChild (int p_x, int ch_x) { SDLoOBJ *obj = &(odd->oc[p_x]); int k; for (k = 0; k < obj->nss; k++) if (ch_x == obj->ss[k]) return 1; return 0; } /****** SdlObjInx ************************************************************* ** ** takes a "DEFINE" name, checks whether this name corresponds to a ** object to be processed and returns the offset of the object ** description in global array of SDLoOBJ; ** ** INPUT: address of object name [R] ** IMPLICIT: ** odd (SDLo *) ** ** RETURNS: object ID (offset in array of object-descriptors) ** e__novalsnam */ static int SdlObjInx (char *nam) { SDLoOBJ *obj; int k, inx; for (k = 0, inx = -1; k < odd->oc_n; k++) { obj = &(odd->oc)[k]; if (SmEqs (obj->nam, nam)) inx = k; } if (inx == -1) return e__novalsnam; return inx; } /****** OddGetAttribute ******************************************************* ** ** Returns the attribute description with specified name for specified ** class; ** ** INPUT: class object [R] ** attribute name [R] ** ** RETURNS: ** attribute type object ** NULL if attribute with specified name was not found */ SDLoATTR *OddGetAttribute (SDLoOBJ *class, char *name) { SDLoATTR *attr; INT4 k; for (k = 0; k < class->np; k++) { attr = &class->p[k]; /* unnamed attributes start with ':' */ if (SmEqs (attr->nam, name) || (*name == ':' && attr->unnamed)) return attr; } return NULL; } INT4 OddIsPartOfList (SDLoOBJ *class, char *attrName) { SDLoATTR *attr; if (!(attr = OddGetAttribute (class, attrName))) _ErrRet3 (e__icaunknownattr, OddGetClassName (class), attrName); return attr->typ == AT_CHILD ? 1 : 0; } void OddInstallClasses () { odd = (SDLo *)odd->oc[odd->oc_n-1].s; } /****** OddObjAttribute ****************************************************** ** ** Replaces SdlAttribute; ** ** INPUT: class object [W] ** attribute name [R] ** IMPLICIT: ** odd (SDLo *) ** ** RETURNS: e__icaunknownattr + ** e__parnotok + ** e__symnotuniq + ** e__novalid + ** e__bnfbuildfail + ** e__allocfail + ** e__objnotfound + ** e__objnotnhrt + ** 1 if successful */ INT4 OddObjAttribute (SDLoOBJ *class, char *attrName, VARo *value) { VARo *varList=NULL; char *tokstr; SDLoATTR *attr, *defaultAttr; SDLoPTR off; unsigned tokval; int (*insert) (), k, rv, isDefault=0, c=0; if (!(attr = OddGetAttribute (class, attrName))) _ErrRet3 (e__icaunknownattr, OddGetClassName (class), attrName); defaultAttr = attr; off = ((SDLoPTR) class->uobj_coff + attr->off); if (VarType (value) == VARxLIST) { /* first in list - if list */ varList = value; value = AnyNextInList (varList, &c); } for (k=0; k < attr->arrsz; k++) { if (!isDefault) { rv = (k && !varList) ? 0 : OddGetValue (attr, &tokstr, &tokval, value); if (!rv) isDefault = 1; /* now enter default value */ _ErrIf (rv) odd->error = TRUE; } if ((insert = odd->at[attr->typ].insert) != NULL) { rv =(*insert)(class, attr, defaultAttr, &off, tokstr, tokval, isDefault); _ErrIf (rv) odd->error = TRUE; } if (varList && !isDefault) /* next in list - if list */ if (!(value = AnyNextInList (varList, &c))) isDefault = 1; attr->isrd = TRUE; } attr->isrd = TRUE; return 1; } /****** SdlParTyp ************************************************************* ** ** checks whether ATTRIBUTE value type is one of declared types: ** SDLxPNUM, SDLxPNAM, SDLxPTXT, SDLxPCNST; ** ** INPUT: address of ATTRIBUTE name ** address of array of alowed types ** actual type ** IMPLICIT: ** f (FILo *) ** ** OUTPUT: ** returns: 1 if ok ** e__wrongpartyp (line nr., msg-line) + */ int SdlParTyp (char *nam, unsigned char *ptyp, unsigned int typ) { static char *typn[4] = {", number", ", name", ", text", ", constant"}; char errs[MSGxXLN], errln[MSGxXLN]; int k, err_f = FALSE; (void) strcpy (errs, ""); for (k = 0; k < 4 && ptyp[k] != 0; k++) if (ptyp[k] == typ) { err_f = FALSE; break; } else { err_f = TRUE; strcat(errs, typn[ptyp[k] - SDLxPNUM]); } if (!err_f) return 1; errs[0] = ' '; /* remove ',' */ sprintf(errln, "ATTRIBUTE: %s, expected type: %s", nam, errs); _ErrRet4(e__wrongpartyp, f->n, f->nam, errln); return 1; } /****** OddIsOfVal ************************************************************ ** ** checks list of values if specified string is OK; ** ** INPUT: address of attribute-dsc. [R] ** string read [R] ** address of value [W] ** IMPLICIT: ** ** RETURNS: 1 if found ** 0 else */ int OddIsOfVal (SDLoATTR *attr, char *tokstr, unsigned int *val) { int k; SmEdit (tokstr, SMxLOWCASE); for (k=0; k < attr->val_n && strcmp (tokstr, attr->val[k].nam) != 0; k++) ; if (k==attr->val_n) return 0; else *val = attr->val[k].val; return 1; } /****** OddGetValue *********************************************************** ** ** gets next value from the symbol table, tests it and gets symbol value ** if it is a constant, or number if enumerated type; ** ** INPUT: ** attribute descriptor [R] ** address of token string [W] ** address of token value [W] ** IMPLICIT: ** ** RETURNS: 1 if value could be read ** 0 there was no token in token table ** e__icaenumval + ** e__symnotknown + ** e__symnotuniq + */ static int OddGetValue (SDLoATTR *attr, char **tokstr, unsigned *tokval, VARo *value) { static STRv str=NULL; int rv; if (str) StrDel (str); *tokval = ODDxNULL; str = VarGetStrv (value); *tokstr = _Str(str); /* rv = SdlParTyp (attr->nam, &attr->ptyp[0], *tokval); _ErrRet (rv);*/ *tokval = ODDxNULL; if (attr->val_n) /* check if value is one of the list */ if (!OddIsOfVal (attr, *tokstr, tokval)) _ErrRet3(e__icaenumval, *tokstr, attr->nam); return 1; } /****** SdlSaveAddr *********************************************************** ** ** Processes each attribute in a user-object and in case it is an ** address saves it in global array ** ** INPUT: object-descriptor [R] ** start address of user-object [W] ** IMPLICIT: ** addr_n (int) [W] ** addr (unsigned int *) [W] ** odd (SDLo *) [R] ** ** RETURNS: 1 */ int SdlSaveAddr (SDLoOBJ *obj, SDLoPTR uobj) { SDLoATTR *attr; SDLoPTR **off; int k, l; for (k=0; k < obj->np;) { attr = &((obj->p)[k++]); off = (SDLoPTR **) (uobj + attr->off); if (odd->at[attr->typ].save_f) for (l=0; l < attr->arrsz; l++, off++) if (*off != 0 || attr->typ == AT_FNCT) __SdlAddr ((SDLoPTR) off); } return 1; } /****** SdlCheckPar *********************************************************** ** ** tests an attribute value; ** ** INPUT: address of ATTRIBUTE description (SDLoATTR) ** address of string 0 if an int or char ** int or char ** IMPLICIT: ** ** OUTPUT: ** returns: 1 if parameter ok ** e__parnotok + */ int SdlCheckPar (SDLoATTR *attr, char *s, int v) { int (*check) (SDLoATTR *, int, char *); if ((check = odd->at[attr->typ].check) != NULL) { return (*check) (attr, v, s); } return 1; } /****** OddWriteCDefines ****************************************************** ** ** writes constant definitions into header ** ** INPUT: address of file descriptor [W] ** ** RETURNS: */ static void OddWriteCDefines (FILE *file) { ODDoCDEFINE *tmp; INT4 k; for (k=0, tmp=cDefine; k < cDefineN; k++, tmp++) fprintf(file, "#define %-16s %d\n", tmp->name, tmp->n); } /****** SdlWrtHdr ************************************************************* ** ** writes a header file that contains constant definitions, type ** declarations, and declaration + init of OBJECT s; ** ** INPUT: address of SDLo ** option: SDLxHDR, SDLxHDR2 ** ** OUTPUT: ** returns: 1 if success ** e__filopenerr, */ int SdlWrtHdr (SDLo *d, int opt) { FILE *fil; int errCode; fil = FilOpenW (d->ofnam, &errCode); _ErrExit2 (errCode, d->ofnam); SdlWrtTtl(fil, d->ifnam, d->ofnam); OddWriteCDefines (fil); SdlWrtTypDef(fil, &(d->oc[0]), d->oc_n); if (opt == SDLxHDR) { OddWrtInitExtern (fil, &(d->oc[0]), d->oc_n); OddWrtInit (fil, &(d->oc[0]), d->oc_n); } fclose(fil); return 1; } /****** OddGetAttrDeclName **************************************************** ** ** Returns the name to be used for declaring a member of a C struct for ** specified attribute object. ** ** INPUT: attribute object [R] ** ** RETURNS declaration name [R] */ char *OddGetAttrDeclName (SDLoATTR *attr) { return (*attr->dnam ? attr->dnam : attr->nam); } /****** OddGetClassDeclName *************************************************** ** ** Returns the name to be used for declaring a C struct. ** ** INPUT: class object [R] ** ** RETURNS declaration name [R] */ char *OddGetClassDeclName (SDLoOBJ *class) { return (*class->dnam ? class->dnam : class->nam); } /****** SdlWrtTtl ************************************************************* ** ** writes a title to a header file; ** ** INPUT: address of file descr. ** name of DDL- language input file ** name of output file ** ** OUTPUT: ** returns: 1 */ static int SdlWrtTtl (FILE *f, char *in, char *out) { char *time; SmEdit(in, SMxLOWCASE); SmEdit(out, SMxLOWCASE); time = SmTime (0); fprintf(f, "/******************************************************************************\n"); fprintf(f, "**\n\ ** $RCSfile: sdlnew.c,v $\n\ ** $Revision: 1.14 $\n\ ** $Date: 1997/03/18 22:52:32 $\n\ ** $Author: srs $\n\ **\n\ ** $Locker: $\n\ ** $State: Exp $\n\ **\n"); fprintf(f,"** from ODD file: \"%s\"\n", in); fprintf(f,"** date of ODD compilation: %s\n", time); fprintf(f,"**\n"); fprintf(f,"*/\n\n\n"); return 1; } /****** SdlWrtTypDef ********************************************************** ** ** writes type definitions of all objects in header file; ** puts typdefs with #ifndef-#endif clause this allows the OBJECT ** to be defined else where; the identifier is the same as in the ** typdef but in uppercase; ** writes typdef only if at least one object of class has been ** defined; ** ** INPUT: address of file descr. [W] ** base address of array of strct defs. (SDLoOBJ) [R] ** number of strct defs. [R] ** ** RETURNS: 1 */ static int SdlWrtTypDef (FILE *fil, SDLoOBJ *s, int ns) { SDLoOBJ *obj; char *typdef_nm, *gtyp_nm = NULL; int k, l, i, gentype_f; for (k = 1; k < ns; k++) { /** for every object-class */ obj = &(s[k]); if (obj->typ == SDLxVIRTUAL) continue; else { gentype_f = obj->gtyp_n == 0 ? FALSE : TRUE; /* ** for every distinct generic type ...if any */ for (l=gentype_f ? obj->gtyp_n-1 : 0; l >= 0; l--) { if (!gentype_f) typdef_nm = obj->tnam; else { gtyp_nm = (obj->gtyp_nm)[l]; typdef_nm = (obj->gtypdef_nm)[l]; for (i=0; i < obj->gtyp_n; i++) { if (strcmp ((obj->gtyp_nm)[i], gtyp_nm) == 0) break; } if (i < l) continue; /* typedef was already written */ } /* ** write title: comment (if available) ... */ if (*obj->rem) { fprintf (fil, "\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n"); fprintf (fil, "** %s\n*/\n", obj->rem); } if (*(obj->pp_nm) != '\0') /* preprocessor switch */ fprintf (fil, "\n#if defined(_%s) && !defined(_%s)\n", obj->pp_nm, typdef_nm); else fprintf (fil, "\n#ifndef _%s\n", typdef_nm); fprintf(fil, "#define _%s\n", typdef_nm); /* ...to prevent redefinit */ fprintf(fil, "typedef struct %s {\n", typdef_nm); SdlWrtAttr (fil, obj, typdef_nm, gtyp_nm); /* ** process attribues of inherited objects */ fprintf(fil, "} %s;\n#endif\n", typdef_nm); } } } /* ** print all funtion info at the end of all typdefs...function class - if ** present is the first of all classes (index=0) -> C compilers like ** that better... */ obj = &(s[0]); if (obj->typ == SDLxFNCT) SdlWrtFnct (fil, obj); return 1; } /****** SdlWrtAttr ************************************************************ ** ** Writes declaration for all attributes within a struct typedef; ** ** INPUT: address of file-dsc [W] ** address of object-dsc [R] ** address of typedef name [R] ** address of generic type [R] or NULL ** IMPLICIT: ** ** RETURNS: 1 */ static int SdlWrtAttr (FILE *fil, SDLoOBJ *obj, char *typdef_nm, char *gtyp_nm) { SDLoATTR *attr; int (*declare) (FILE *, SDLoATTR *, char *, char *); int l; for (l = 0; l < obj->np; l++) { attr = &((obj->p)[l]); if ((declare = odd->at[attr->typ].declare) != NULL) { (*declare) (fil, attr, gtyp_nm, typdef_nm); } } return 1; } /****** OddAddFunction ******************************************************** ** ** adds a new function to the list; ** ** INPUT: address of location of object function [R] ** IMPLICIT: ** function (struct []) [W] ** ** RETURNS: */ void OddAddFunction (char **loc) { function[fnct_x].nam = loc; function[fnct_x].args = loc + 1; function[fnct_x].module = loc + 2; function[fnct_x++].isDone = 0; } /****** OddOutput ************************************************************* ** ** Performs selected output operations. ** ** INPUT: odd base object [W] ** IMPLICIT: ** ** RETURNS: */ void OddOut (SDLo *odd) { if (odd->error) _ErrExit (e__procfail); if (ParGetBool ("doClassInfo")) { OddWriteClassInfo ((SDLo *) odd->oc[odd->oc_n-1].s ); } else if (odd->action != SDLxNOHDR && odd->action != SDLxSECTION && odd->action != SDLxPRESEC) { SdlWrtHdr (odd, odd->action); } if (odd->section_f) SdlCloseSec (); } /****** SdlWrtVal ************************************************************* ** ** writes a single value in header file for init. arrays of OBJECTs; ** ** INPUT: address of file descr. ** address of attribute object (SDLoATTR) ** address of current offset in target object ** address of flag saying SDLxFIRST, SDLxLAST, SDLxNORMAL ** OUTPUT: ** returns: 1 */ int SdlWrtVal (FILE *fil, SDLoATTR *attr, SDLoPTR *off, int *item_f) { static char ln[SDLxXLN], str[SDLxXLN]; int (*writeval) (); if (*item_f & SDLxLAST) { fprintf(fil, "%s%s", ln, *item_f & SDLxBOUND ? "}" : ""); *item_f = 0; return 1; } if ((writeval = odd->at[attr->typ].write) != NULL) { (*writeval) (attr, str, off); } if (*item_f & SDLxFIRST) { /* print first item */ sprintf(ln, " %s%s", *item_f & SDLxBOUND ? "{" : "", str); *item_f = 0; } else { if (*item_f & SDLxBREAK) { fprintf(fil, "%s%s,\n", ln, *item_f & SDLxBOUND ? "}" : ""); sprintf(ln, " %s%s", *item_f & SDLxBOUND ? "{" : "", str); *item_f = 0; } else if (strlen(ln) + strlen(str) + 2 >= SDLxXHLN) { fprintf(fil, "%s,\n", ln); sprintf(ln, " %s", str); } else sprintf(ln, "%s, %s", ln, str); } return 1; } /****** SdlWrtFnct ************************************************************ ** ** writes typedef for function pointer, prototypes of functions ** and array of function pointers; ** ** INPUT: output-file [W] ** Object-descriptor [R] ** IMPLICIT: ** function (struct *) [R] ** ** RETURNS: 1 ** 0 if no functions defined */ static int SdlWrtFnct (FILE *f, SDLoOBJ *s) { char args[132], *moduleName, *fnctName, tmp[80]; char *tmpPtr = tmp, **tmpPPtr, *tmpFnctName[100]; int item_f, k, i, l, n; if (s->gbl_n == 0) return 0; /* nothing to initialize */ fprintf(f, "\n#ifdef _FUNCTION\n#undef _FUNCTION\n"); /* ** define a constant with the function name - if module name is defined ** otherwise assign dummy function - defines are grouped by module name */ if (1/*odd->action != SDLxHDR*/) { for (i=0; i < s->gbl_n; i++) { for (k=i, moduleName=NULL, l=0; k < s->gbl_n; k++) { if (!function[k].isDone) { if (!moduleName) { /* new module name */ moduleName = *function[k].module; if (*moduleName) fprintf (f, "\n#ifdef %s_M\n", moduleName); else fprintf (f, "\n"); } if (!(strcmp (moduleName, *function[k].module))) { /* ** write function prototype */ fnctName = *function[k].nam; strcpy (args, *(function[k].args)); SmSwapS (args, SDLxGTYPDEFNAM, "void"); SmSwapS (args, SDLxGTYPNAM, "void"); fprintf (f, "INT4 %s ", fnctName); fprintf (f, "%s;\n", args); tmpFnctName[l++] = fnctName; /* save for "#else" */ fprintf (f, "#%sdefine %s_F (INT4(*)()) %s\n", *moduleName ? " " : "", fnctName, fnctName); function[k].isDone = 1; } } } if (moduleName && *moduleName) { fprintf (f, "#else\n"); fprintf (f,"void Dummy%s () {_ErrExit2 (e__fnctnotdefined, \"%s\");}\n", moduleName, moduleName); for (n=0; n < l; n++) fprintf (f, "# define %s_F (INT4(*)()) Dummy%s\n", tmpFnctName[n], moduleName); fprintf (f, "#endif\n"); } } } /* ** write array of function pointers - or rather with the macros ** defined just above */ if (1/*odd->action != SDLxHDR*/) { fprintf (f, "typedef INT4 (*SDLoFNCT)();\n\n"); fprintf (f, "\nSDLoFNCT SDL_fnct[] = {\n"); item_f = SDLxFIRST; for (k=0; k < s->gbl_n; k++) { tmpPPtr = &tmpPtr; sprintf (*tmpPPtr, "%s_F", *function[k].nam); SdlWrtVal (f, &(s->p[0]), (SDLoPTR *) &tmpPPtr, &item_f); } item_f = SDLxLAST; SdlWrtVal (f, &(s->p[0]), NULL, &item_f); fprintf (f, "\n};\n"); } fprintf (f, "#endif\n"); return 1; } /****** function ***************************************************************** ** ** initializes arrays of objects with values; ** ** INPUT: address of file descr. ** base address of array of strct defs. (SDLoOBJ) ** number of strct defs. ** ** RETURNS: 1 */ static int OddWrtInit (FILE *fil, SDLoOBJ *s, int ns) { SDLoOBJ *obj; SDLoATTR *pptr; SDLoPTR off, trgts; int k, l, m, n, item_f; fprintf (fil, "\n#ifdef _INITOBJS\n"); for (k = 0; k < ns; k++) { /* all strct types */ obj = &s[k]; if (obj->gbl_n == 0) /* nothing to initialize */ continue; if (obj->typ == SDLxFNCT) continue; fprintf(fil, "\n%s %s[] = {\n", obj->tnam, OddGetClassDeclName (obj)); item_f = SDLxFIRST | SDLxBOUND; for (n = 0; n < obj->gbl_n; n++) { /* all alloc. strct */ trgts = obj->s + (n * obj->siz); item_f |= SDLxBREAK | SDLxBOUND; for (l = 0; l < obj->np; l++) { /* all attributes */ pptr = &(obj->p[l]); off = trgts + pptr->off; for (m = 0; m < pptr->arrsz; m++) /* all vals. in par */ /* array */ SdlWrtVal(fil, pptr, &off, &item_f); } } item_f |= SDLxLAST | SDLxBOUND; SdlWrtVal(fil, pptr, &off, &item_f); fprintf(fil, "\n};\n"); } fprintf (fil, "\n#endif\n"); return 1; } /****** function **************************************************************** ** ** Lists names of arrays to be initialized as extern variables so that ** they can be used for cross-referencing before they are actually ** initialized (forward references). ** ** INPUT: file descr. [W] ** array of class descriptors [R] ** number of class descriptors [R] ** */ static void OddWrtInitExtern (FILE *file, SDLoOBJ *classList, int classN) { SDLoOBJ *class; Int4 k; fprintf (file, "\n"); for (k=0; k < classN; k++) { class = &classList[k]; if (class->gbl_n == 0 || class->typ == SDLxFNCT) continue; fprintf (file, "extern %s %s[];\n", class->tnam, OddGetClassDeclName (class)); } } /****** SdlListAddr *********************************************************** ** ** ** INPUT: address to be put on list [R] ** IMPLICIT: ** addr_n (int) ** addr (unsigned int) ** ** RETURNS: 1 */ int SdlListAddr (SDLoPTR a) { addr[addr_n++] = a; if (addr_n > SDLxXADDR) _ErrExit3 (e__exceedsize, "array addr", SDLxXADDR); return 1; } /****** SdlCopySec ************************************************************ ** ** copies string into map-section and outputs new address ** ** INPUT: address of pointer to string [W] ** IMPLICIT: ** ** RETURNS: 1 */ static int SdlCopySec (char **s) { char *p; p = (char *) SdlMalloc (strlen (*s) + 1); strcpy (p, *s); *s = p; return 1; } /****** SdlCloseSec *********************************************************** ** ** closes a map-section and writes out file of addresses; ** ** INPUT: ** IMPLICIT: ** odd (SDLo *) ** map (MAPo) ** addr_n (int) ** addr (unsigned int) ** ** RETURNS: 1 */ static int SdlCloseSec () { FILE *fil; char ptr_nm[FILxXNAM+1], sec_nm[FILxXNAM+1]; long tmp; int rv, k, obj_n, size; sprintf (ptr_nm, "SRSSEC:%s.ptr", odd->sec_nm); sprintf (sec_nm, "SRSSEC:%s.sec", odd->sec_nm); fil = FilOpenW (ptr_nm, &rv); _ErrExit2 (rv, ptr_nm); size = (addr_n + (odd->oc_n*2) + 3) * sizeof (SDLoPTR) + sizeof (int); fwrite (&size, sizeof (int), 1, fil); /* size of ptr file */ tmp = (long) map.data + sizeof (char *); fwrite (&tmp, sizeof (SDLoPTR), 1, fil); /* addr of section begin */ tmp = odd->oc_n; fwrite (&tmp, sizeof (long), 1, fil); /* number of objects */ /* ** for each class represented in the section, write the pointer to its ** array of instances within the section and the number of instances */ for (k=0; k < odd->oc_n; k++) { fwrite (&((odd->oc)[k].s), sizeof (SDLoPTR), 1, fil); tmp = odd->oc[k].ns; fwrite (&tmp, sizeof (long), 1, fil); } tmp = addr_n; fwrite (&tmp, sizeof (long), 1, fil); /* number of references */ fwrite (addr, sizeof (SDLoPTR), addr_n, fil); /* ref. list */ fclose (fil); size = *(map.foff); rv = MapFree (&map); _ErrExit (rv); for (k=0, obj_n=0; k < odd->oc_n; obj_n += (odd->oc)[k++].ns) ; Message (9, i__sdlreport, 0, sec_nm, size / 512, ptr_nm, addr_n / 512*4, odd->ifnam, obj_n, odd->oc_n); return 1; } /****** OddWriteClassInfo ***************************************************** ** ** writes a text file with meta info about all defined classes; ** ** INPUT: address of odd base [W] ** IMPLICIT: ** ** RETURNS: */ void OddWriteClassInfo (SDLo *odd) { TEMPLv templ; SDLoOBJ *class; SDLoATTR *attr; char *typeName[30]={"real", "number", "number", "", "string", "", "list of", "", "", "pointer to", "", "function", "", "", "", "", "", "", "", "", "", "BNF-productions", "", "", "", "", "", "", "" }; int i, k, l, isPointer; /* ** open script and print first a directory of all classes */ templ = TemplOpen ("SRSICA:srswww.i", NULL); TemplWith (templ, "$classInfo"); /* TemplPrint ("dir.head", TimeToString (0, "date")); for (k=0; k < odd->oc_n; k++) { class = &(odd->oc[k]); if (OddIsClass (class, "system") || OddIsClass (class, "obsolete")) continue; SmEdit (class->nam, SMxLOWCASE); class->nam[0] = toupper (class->nam[0]); TemplPrint ("dir.class", k, class->nam); } TemplPrint ("dir.tail"); */ /* ** then the classes + attributes */ TemplPrint ("head", TimeToString (0, "date")); for (k=0; k < odd->oc_n; k++) { class = &(odd->oc[k]); if (OddIsClass (class, "system") || OddIsClass (class, "obsolete")) continue; TemplPrint ("class.head", k, class->nam); TemplPrint ("class.remark", class->rem); /* ** attribute information */ TemplWith (templ, "class.attrib"); for (l=0; l < class->np; l++) { attr = &(class->p[l]); if (*attr->nam && !OddIsAttr (attr, "obsolete") && ! OddIsAttr (attr, "system")) { SmEdit (attr->nam, SMxLOWCASE); TemplPrint ("head", attr->nam); /* print comment */ TemplPrint (*attr->rem ? "remark" : "empty", attr->rem); /* unnamed */ TemplPrint (attr->unnamed ? "unnamed" : "empty"); /* required */ TemplPrint (attr->req ? "required" : "empty"); /* attribute type */ isPointer = 0; TemplPrint ("typeHead"); if (attr->val_n) { /* list of string values */ TemplPrint ("optionList.head"); for (i=0; i < attr->val_n; i++) TemplPrint ("optionList.option", attr->val[i].nam); TemplPrint ("optionList.tail"); } else if (*typeName[attr->typ] == 'p') { /* pointer */ TemplPrint ("ptrType",typeName[attr->typ], odd->oc[attr->dfltv].nam); isPointer = 1; } else if (*typeName[attr->typ] == 'l') { TemplPrint ("listType", odd->oc[attr->dfltv].nam); isPointer = 1; } else if (*typeName[attr->typ] == 'p') { TemplPrint ("ptrType",typeName[attr->typ], odd->oc[attr->dfltv].nam); isPointer = 1; } else if (*typeName[attr->typ]) TemplPrint ("type", typeName[attr->typ]); /* min + max */ if (attr->min != -1000000000 && attr->max != 1000000000) { if (attr->typ == 4) TemplPrint ("minmaxStr", attr->min, attr->max); else TemplPrint ("minmaxNum", attr->min, attr->max); } /* array of max number of elements */ if (attr->arrsz > 1) TemplPrint ("arrSize", attr->arrsz); TemplPrint ("typeTail"); /* default value */ if (attr->val_n) { for (i=0; i < attr->val_n; i++) if (attr->val[i].val == attr->dfltv) { TemplPrint ("default.option", attr->val[i].nam); break; } if (i >= attr->val_n) TemplPrint ("empty"); } else if (*attr->dflts) TemplPrint ("default.string", attr->dflts); else if (attr->dfltv != 0 && !isPointer) TemplPrint ("default.num", attr->dfltv); else if (attr->dfltvf != 0) TemplPrint ("default.num", attr->dfltvf); else TemplPrint ("empty", attr->dfltvf); TemplPrint ("tail"); TemplPrint ("infoEnd"); } } TemplEndWith (); TemplPrint ("class.tail"); } TemplEndWith (); } /**api* OddIsAttr ************************************************************* ** ** returns some boolean information about the attribute; ** ** INPUT: attribute object [R] ** option: "obsolete", "system", "api" [R] ** IMPLICIT: ** ** RETURNS: 1 ** 0 */ INT4 OddIsAttr (SDLoATTR *attr, char *option) { int k; switch (tolower (option[0])) { case 'a': /* api */ for (k=0; k < 2; k++) if (attr->status[k] == (unsigned char) ODDxAPI) return 1; break; case 'o': /* obsolete */ for (k=0; k < 2; k++) if (attr->status[k] == (unsigned char) ODDxOBSOLETE) return 1; break; case 's': /* system */ for (k=0; k < 2; k++) if (attr->status[k] == (unsigned char)ODDxSYSTEM) return 1; break; default: _ErrExit2 (e__unknownoption, option); } return 0; } /**api* OddIsClass ************************************************************ ** ** returns some boolean information about the class; ** ** INPUT: class object [R] ** option: "obsolete", "system", "api" [R] ** IMPLICIT: ** ** RETURNS: 1 ** 0 */ INT4 OddIsClass (SDLoOBJ *class, char *option) { int k; switch (tolower (option[0])) { case 'a': /* api */ for (k=0; k < 2; k++) if (class->status[k] == (unsigned char) ODDxAPI) return 1; break; case 'o': /* obsolete */ for (k=0; k < 2; k++) if (class->status[k] == (unsigned char) ODDxOBSOLETE) return 1; break; case 's': /* system */ for (k=0; k < 2; k++) if (class->status[k] == (unsigned char)ODDxSYSTEM) return 1; break; default: _ErrExit2 (e__unknownoption, option); } return 0; } n) { int k; switch (tolower (option[0])) { case 'a': /* api */ for (k=0; k < 2; k++) if (class->status[k] == (unsigned char) ODDxAPI) return 1; break; case 'o': /* obsolete */ for (ksrs/src/seq.c /*****************************************************************************/ char seq_srs_ID[] = "$Id: seq.c,v 1.14 1997/03/20 12:08:04 srs Exp $"; /* ** ** $RCSfile: seq.c,v $ ** $Revision: 1.14 $ ** $Date: 1997/03/20 12:08:04 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port: Lukas Rosenthaler and Reinhard Doelz ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** D-69012 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** Requires: file, sm, message, list ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include "message.h" #include "sm.h" #include "strv.h" #include "futil.h" #include "lst.h" #include "par.h" #include "icarus.h" #include "icaarg.h" #define _INITOBJS #include "seq.h" #ifdef sun extern INT4 printf (); #endif typedef char TABLE[4][4][4]; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** static functions */ static char SeqTranslCodon (char *triplett, SEQoTranslTable *transTable, INT4 isStartCodon); static void SeqTranslTableEdit (SEQoTranslTable *tTable, SEQoTranslCodon *tCodon); static void SeqTranslTableRevert (SEQoTranslTable *tTable); static INT4 *SeqGetTranslNtOrder (); static void SeqDump (FILE *file, void *obj); static void SeqInit (void *obj); static void SeqKill (void *obj); static void SeqBinToAscii (SEQo *seq); static INT4 SeqTest (FILo *file); static INT4 SeqCopy (SEQo *seq, char *s, INT4 read_o); static INT4 SeqReadPirSeq (SEQo **seq, FILo *file); static INT4 SeqReadEMBLSeq (SEQo **seq, FILo *file); static INT4 SeqReadGCGSeq (SEQo **seq, FILo *file); static INT4 SeqReadMSFSeq (SEQo **seq, FILo *file); static INT4 SeqMSFNam (char *name, char *file_nm, char *seq_nm); static INT4 SeqGCGCheck(char *seq, INT4 len); static INT4 SeqWrite (char *seq, INT4 len, INT4 line_n, INT4 block_n, INT4 format_o, INT4 (*print)(char*,...)); static void SeqAlloc (SEQo *seq, INT4 len); static void SeqMakeOwn (SEQo *seq); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** global variables */ INT4 global_before_f; INT4 global_after_f; static INT4 recordSeparatorLength=0; /**api* SeqNew *************************************************************** ** ** gets a new initialized sequence object; ** ** INPUT: pointer to address of sequence object [W] ** IMPLICIT: ** ** RETURNS: */ INT4 SeqNew (SEQo **seq) { static INT4 seqtype_id=0; if (!seqtype_id) LstManageClass (&seqtype_id, sizeof (SEQo), SeqInit, SeqKill, SeqDump); return LstNew ((void **) seq, seqtype_id); } /****** SeqDump ************************************************************** ** ** dumps all information belonging to the specified object. ** This is the print function set through LstManageClass ** for seq_type objects (see SeqNew). ** ** INPUT: address of an object [R] ** file pointer [W] or NULL ** IMPLICIT: ** ** RETURNS: nothing */ static void SeqDump (FILE *file, void *obj) { SEQo *tmp = (SEQo*)obj; if (!file) file = stderr; fprintf (file, "*%s*\n", tmp->name); fprintf (file, "......accno: %10s bpos %d epos %d compl_f %d\n", tmp->accno, tmp->bpos, tmp->epos, (INT4)tmp->compl_f); if (tmp->seq) printf ("......*%s*......\n", tmp->seq); /* print sublist, i.e. parameter list of function */ if (tmp->sublist) { fprintf (file, "SUBLIST "); LstPrintAll ((void*) tmp->sublist); } } /****** SeqInit ************************************************************** ** ** initializes the specified object. ** This is the init function set through LstManageClass ** for seq_type objects (see SeqNew). ** ** INPUT: address of an object [R] ** IMPLICIT: ** ** RETURNS: nothing */ static void SeqInit (void *obj) { SEQo *tmp = (SEQo*) obj; strcpy(tmp->name, ""); /* dummy values */ tmp->cmnt = NULL; tmp->seq = NULL; tmp->replace = NULL; tmp->len = 0; tmp->check = 0; tmp->bpos = 0; tmp->epos = 0; tmp->part_len = 0; strcpy(tmp->accno, ""); /* dummy values */ tmp->keep_f = 0; tmp->compl_f = 0; tmp->cut_f = 0; tmp->before_f = 0; tmp->after_f = 0; tmp->sublist = NULL; } /****** SeqKill ************************************************************** ** ** deletes the specified object. ** This is the delete function set through LstManageClass ** for seq_type objects (see SeqNew). ** ** INPUT: address of an object [R] ** IMPLICIT: ** ** RETURNS: nothing */ static void SeqKill (void *obj) { SEQo *tmp = (SEQo*) obj; if (tmp->seq) free(tmp->seq); if (tmp->cmnt) StrDel (tmp->cmnt); if (tmp->replace) free(tmp->replace); /* delete sublist ? */ if (tmp->sublist) LstDeleteAll((void**)&tmp->sublist); } /**API* function ************************************************************** ** ** Deletes a sequence object and resets the pointer to NULL. ** ** INPUT: address of of pointer to sequence object [R] */ void SeqDel (SEQo **seq) { SEQo *tmp = *seq; if (tmp->seq) free(tmp->seq); if (tmp->cmnt) StrDel (tmp->cmnt); if (tmp->replace) free(tmp->replace); /* delete sublist ? */ if (tmp->sublist) LstDeleteAll((void**)&tmp->sublist); free (tmp); *seq=NULL; } /**API* function ************************************************************** ** ** Sets the name of a sequence. ** ** INPUT: sequence object [W] ** new sequence name [R} */ void SeqSetName (SEQo *seq, char *name) { strcpy (seq->name, name); } /**API* function ************************************************************** ** ** Sets a comment for the sequence. ** ** INPUT: sequence object [W] ** new sequence name [R} */ void SeqSetComment (SEQo *seq, char *comment) { if (!seq->cmnt) seq->cmnt = StrNew (); StrSetS (&seq->cmnt, comment); } /****** SeqBinToAscii ********************************************************* ** ** Converts sequence of 2-bit GATC to ASCII; corresponds to ** GCG procedures BinToSeq, BinToFilter and BinToGATC; ** ** INPUT: address of sequence object */ static void SeqBinToAscii (SEQo *seq) { static char nuc[] = "CTAG", fstcall_f = TRUE; static UINT4 tbl[256]; UINT4 *seqPtr = (UINT4 *) seq->seq; unsigned char *binseq, *buff; INT4 i, k, l, m, n, x; if (fstcall_f) { /* ** make a table of translations from a byte with encoded sequence ** to an array of 4 ascii characters */ fstcall_f = FALSE; for (k=0, x=0; k < 4; k++) for (l=0; l < 4; l++) for (m=0; m < 4; m++) for (n=0; n < 4; n++) tbl[x++] = nuc[k] + 256 * nuc[l] + 65536 * nuc[m] + 16777216 * nuc[n]; } /* ** convert unsigned characters with 4 ecoded nucleotide names into ** unsigned ints (in reality an array of 4 ascii characters); start ** from the end of the sequence...then we can do the replacement ** "within" the string; ** the base address of array seq_p (=seq) must be aligned on 4 byte ** boundary!!! ** ** slightly more complicated since we have the little-big endian problem ** again...the 4 byte value in "tbl" (which is a four letter sequence) is ** LITTLE endian...it needs to be converted to platform dependent format ** which is done by the shifting; */ i = ((seq->len+3)/4)-1; binseq = (unsigned char *) seq->seq; for (; i >= 0; i--) { buff = (unsigned char *) &tbl[binseq[i]]; seqPtr[i] = ((UINT4) ((unsigned char) buff[0])) + ((UINT4) ((unsigned char) buff[1]) << 8) + ((UINT4) ((unsigned char) buff[2]) << 16) + ((UINT4) ((unsigned char) buff[3]) << 24); } seq->seq[seq->len] = '\0'; } /****** SeqRemoveStop ********************************************************* ** ** Removes trailing stop codon from sequence. ** ** INPUT: sequence object [W] ** IMPLICIT: ** ** RETURNS: */ void SeqRemoveStop (SEQo *seq) { if (seq->seq[seq->len-1] == '*') seq->seq[ --(seq->len) ] = '\0'; } /****** SeqTranslate ********************************************************* ** ** Translates a DNA sequence into protein; ** The translation is controlled by the translation table, the list ** of translation exceptions and the list of codon changes to be ** applied to the translation table. ** ** INPUT: o address dna sequence object [R] ** o start position (begin=1) [R] ** o translation table [R] ** o array of translation exception descriptions [R] or NULL ** o array of codon changes to be applied to the ** translation table [R] or NULL ** IMPLICIT: ** ** RETURNS: translated protein sequence ** NULL if there was a problem */ SEQo *SeqTranslate (SEQo *dna, INT4 start, SEQoTranslTable *tTable, SEQoTranslExcept *tExcept, SEQoTranslCodon *tCodon) { SEQoTranslExcept *tExceptNext; SEQo *prot=NULL; INT4 k, l, isFirst=1; char aa; if (dna->len - start + 1 < 3) { _ErrMsg3 (e__seqillegallength, start, dna->len); return NULL; } if (tCodon) SeqTranslTableEdit (tTable, tCodon); SeqNew (&prot); SeqAlloc (prot, (dna->len - start)/3 + 100); for (k=start-1, l=0, tExceptNext=tExcept; k < dna->len-1;) { /* deal with possible translation exception */ if (tExceptNext && k == tExceptNext->begin-1) { isFirst=0; prot->seq[l++] = tExceptNext->aa; k += tExcept->length; tExceptNext->isDone = 1; tExceptNext = (++tExceptNext)->aa ? tExceptNext : NULL; } else if (isFirst) { /* first codon */ isFirst = 0; if ((aa = SeqTranslCodon (&dna->seq[k], tTable, 1)) == 'M') { prot->seq[l++] = aa; k += 3; } else global_before_f-- ; } else { prot->seq[l++] = SeqTranslCodon (&dna->seq[k], tTable, 0); k += 3; } } prot->seq[l] = '\0'; prot->len = l; if (tCodon) /* remove edited translation table again */ SeqTranslTableRevert (tTable); SeqRemoveStop (prot); sprintf (prot->name, "%s_aa", dna->name); return prot; } /****** SeqTranslCodon ******************************************************** ** ** Translates a nucleotide triplett into an amino acid. ** The triplett may contain ambiguity codes. ** If the last nucleotide is missing an 'x' is assumed. ** ** INPUT: nucleotide triplett [R] ** the translation table [R] ** a flag if to translate the start codon [R] ** IMPLICIT: ** ** RETURNS: the translated amino acid. */ char SeqTranslCodon (char *triplett, SEQoTranslTable *transTable, INT4 isStartCodon) { static char *ntAmbigList[26]={ "A","CGT","C","AGT","","","G","ACT","", "","GT","","AC","GATC","","","","AG", "CG","T","U","ACG","AT","ACGT","CT",""}; INT4 k, l, m, *order; char b1, b2, b3, aa, aaPrev=0, *ntList[3], *aaTrans; order = SeqGetTranslNtOrder (); aaTrans = isStartCodon ? transTable->saa : transTable->aa; /* The triplett might contain ambiguity codes: assign to each base in the triplett the list of possible nucleotides Make the last nucleotide an 'x' if it is missing */ for (k=0; k<3; k++) { b1 = tolower(triplett[k]); ntList[k] = ntAmbigList[(b1 ? b1 : 'x') - 'a']; } /* get all indices into the aa transl list for all combinations */ aa = 'X'; for (k=0; (b1=ntList[0][k]); k++) for (l=0; (b2=ntList[1][l]); l++) for (m=0; (b3=ntList[2][m]); m++) { aa = aaTrans[order[b1]*16 + order[b2]*4 + order[b3]]; if (aaPrev && aa != aaPrev) { aa = 'X'; break; aaPrev = aa; } } return aa; } /****** SeqTranslTableEdit **************************************************** ** ** Translates a nucleotide triplett into an amino acid. ** The triplett may contain ambiguity codes. ** ** INPUT: nucleotide triplett [R] ** the translation table [R] ** a flag if to translate the start codon [R] ** IMPLICIT: ** ** RETURNS: the translated amino acid. */ static void SeqTranslTableEdit (SEQoTranslTable *tTable, SEQoTranslCodon *tCodon) { SEQoTranslCodon *tmp; INT4 *order; char *swap, *nt; order = SeqGetTranslNtOrder (); if (!tTable->aaAlt) tTable->aaAlt = (char *) malloc (strlen (tTable->aa) + 1); strcpy (tTable->aaAlt, tTable->aa); swap = tTable->aa; tTable->aa = tTable->aaAlt; tTable->aaAlt = swap; for (tmp = tCodon; tmp->aa; tmp++) { nt = tmp->codon; tTable->aa[ order[*nt++]*16 + order[*nt++]*4 + order[*nt] ] = tmp->aa; } } /****** SeqTranslTableRevert ************************************************** ** ** Reverts edited table to original version. ** ** INPUT: translation table [W] ** IMPLICIT: ** ** RETURNS: */ static void SeqTranslTableRevert (SEQoTranslTable *tTable) { char *swap; swap = tTable->aa; tTable->aa = tTable->aaAlt; tTable->aaAlt = swap; } /****** SeqTaxaToTranslTable ************************************************** ** ** Searches various taxa (case insensitive) to find the appropriate ** translation table; ** ** INPUT: address of buffer with organism source information ** IMPLICIT: ** ** RETURNS: the translation table */ SEQoTranslTable *SeqTaxaToTranslTable (SMoBUFF *org) { INT4 id; if (BuffSearch(org,"Protozoa") && BuffSearch(org,"Cili") && !BuffSearch(org,"Mitoch")) id = 6; else if (BuffSearch(org,"Mitochond") && BuffSearch(org,"Yeast")) id = 3; else if (BuffSearch(org,"Mitochond") && (BuffSearch(org,"Podospora") || BuffSearch(org,"Protozoa")) || BuffSearch (org, "Mycoplasma")) id = 4; else if (BuffSearch(org,"Mitochond") && (BuffSearch(org,"Vertebrata") || BuffSearch(org,"Mammalia"))) id = 2; else if (BuffSearch(org,"Mitochond") && BuffSearch(org,"Echinoderm")) id = 9; else if (BuffSearch(org,"Mitochond")) id = 5; else if (BuffSearch(org,"Bacteri") || BuffSearch(org,"Chloroplast") ) id = 11; else if (BuffSearch(org,"Platyhelminthes")) id = 14; else id = 1; /* standard */ return (SeqIdToTranslTable (id)); } /****** SeqIdToTranslTable ************************************************** ** ** Returns the translation table with specified (numeric) ID. ** ** INPUT: the id (1 to ?) [R] ** IMPLICIT: ** ** RETURNS: the translation table ** NULL if not found */ SEQoTranslTable *SeqIdToTranslTable (INT4 id) { SEQoTranslTable *tmp=translTable; for (tmp=translTable; *tmp->name; tmp++) if (tmp->id == id) return tmp; return NULL; } /****** SeqGetTranslNtOrder ************************************************** ** ** Gets the order for the nucleotides to be used to correspond a codon ** to an amino acid in the translation table ** ** INPUT: ** IMPLICIT: ** ** RETURNS: an array where the nt character addresses the order */ static INT4 *SeqGetTranslNtOrder () { static INT4 isInit=0, order[300]; if (!isInit) { order['T'] = 0; order['C'] = 1; order['A'] = 2; order['G'] = 3; isInit = 1; } return order; } /****** SeqComplement ********************************************************* ** ** reverse complements a dna sequence; ** processes also GCG ambiguity codes; ** ** INPUT: address of dna sequence object [W] ** IMPLICIT: ** ** RETURNS: 1 on success, 0 otherwise */ INT4 SeqComplement (SEQo *seq) { INT4 i,j; char c, *s=seq->seq; if (!s) return 0; /* swap flags */ i = global_before_f; global_before_f = global_after_f; global_after_f = i; for (i=0, j=seq->len-1; i < j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; } for (i=0; i < seq->len; i++) switch (s[i]) { case 'A': s[i] = 'T'; break; case 'C': s[i] = 'G'; break; case 'G': s[i] = 'C'; break; case 'T': s[i] = 'A'; break; case 'U': s[i] = 'A'; break; case 'M': s[i] = 'K'; break; case 'R': s[i] = 'Y'; break; case 'W': s[i] = 'W'; break; case 'S': s[i] = 'S'; break; case 'Y': s[i] = 'R'; break; case 'K': s[i] = 'M'; break; case 'V': s[i] = 'B'; break; case 'H': s[i] = 'D'; break; case 'D': s[i] = 'H'; break; case 'B': s[i] = 'V'; break; case 'X': s[i] = 'X'; break; case 'N': s[i] = 'N'; break; case 'a': s[i] = 't'; break; case 'c': s[i] = 'g'; break; case 'g': s[i] = 'c'; break; case 't': s[i] = 'a'; break; case 'u': s[i] = 'a'; break; case 'm': s[i] = 'k'; break; case 'r': s[i] = 'y'; break; case 'w': s[i] = 'w'; break; case 's': s[i] = 's'; break; case 'y': s[i] = 'r'; break; case 'k': s[i] = 'm'; break; case 'v': s[i] = 'b'; break; case 'h': s[i] = 'd'; break; case 'd': s[i] = 'h'; break; case 'b': s[i] = 'v'; break; case 'x': s[i] = 'x'; break; case 'n': s[i] = 'n'; break; } return 1; } /**api** SeqClr *************************************************************** ** ** deletes all sequence-descriptors ** in the list; ** ** INPUT: pointer to address of sequence object [W] ** ** IMPLICIT: ** ** RETURNS: 1 */ void SeqClr (SEQo **seq) { LstDeleteAll ((void **) seq); *seq = NULL; } /**api* SeqClean ************************************************************** ** ** removes sequences with seq->keep_f == FALSE; sets seq->keep_f ** of kept sequences to FALSE; sets list pointer to the first element ** in the set; ** ** INPUT: ** IMPLICIT: ** ** RETURNS: 1 */ void SeqClean (SEQo **seq) { LstFirst ((void **) seq); do { if (!(*seq)->keep_f) LstDelete ((void **) seq); else (*seq)->keep_f = FALSE; } while (LstNext ((void **) seq)); LstFirst ((void **) seq); } /****** SeqTest *************************************************************** ** ** reads a file, tests line for any of the tokens described for ** TestSeqFormat, and returns if something is found; ** ** INPUT: address of file-dsc. [W] ** IMPLICIT: ** ** RETURNS: token-value */ static INT4 SeqTest (FILo *file) { INT4 x, lineNoSave=0; while (!file->eof) { if (file->l[0] == '>') { file->l++; return SEQxRANGLE; } if (file->l[2] == ';') { file->l++; return SEQxSEMICOLON; } if ((x = SmLoc (file->l, "Check:")) != -1) { file->l += x + 1; return SEQxCHECK; } if ((x = SmLoc (file->l, "..")) != -1) { file->l += x + 1; return SEQxDOTDOT; } /* ** recognize EMBL format by "SQ Sequence" line followed by ** line starting with " ". */ if (SmMixLoc (file->l, "SQ Sequence", 1, 1) != -1) lineNoSave = file->n; if (SmMixLoc (file->l, " ", 1, 1) != -1) if (file->n == lineNoSave + 1) return SEQxEMBL; FilURead (file); } return e__eof; } /**api* SeqGoGcgDots ********************************************************** ** ** searches for ".." and sets file pointer to following line - if not ** found file pointer is set at begin of file ** ** INPUT: address of file-dsc. [W] ** IMPLICIT: ** ** RETURNS: 1 if dots were found ** 0 if not */ INT4 SeqGoGcgDots (FILo *file) { FILoL_S savepos; FilUSave (file, &savepos); while (!file->eof) { if (SmLoc (file->l, "..") != -1) { FilURead (file); return 1; } FilURead (file); } FilUBack (file, &savepos); file->eof = 0; return 0; } /****** SeqTestFormat ********************************************************* ** ** takes an opened file, analyzes file for sequence format: ** o GCG, if there is a line with a "Check:" followed by "..", either ** on same or following line; ** o GCG-MSF, if "Check:", ".." is followed by "//" in first column; ** o PIR, if a line with '>' in first column followed by ';' with ** a distance of 3 columns ** o PEARSON or FASTA if only the '>' is found; ** if a format could be dtermined then file pointer is set at beginning ** of sequence that is: GCG or GCG-MSF: line with ".." ** PIR, PEARSON: line with ">" ** ** INPUT: address of file-dsc [W] ** IMPLICIT: ** ** RETURNS: if format found: SEQxGCG, SEQxMSF, SEQxPIR, SEQxPEARSON ** else: 0 */ static INT4 SeqTestFormat (FILo *file) { INT4 rv, format=0, gcg_f=0, check_f=0; do { rv = SeqTest (file); if (rv == SEQxEMBL) { format = SEQxEMBL; break; } if (rv == SEQxRANGLE) format = SEQxPIR; if (rv == SEQxPIRTOKENS) format = SEQxPIR; if (rv == SEQxCHECK) { if (gcg_f) { format = SEQxMSF; FilUBack2 (file); } else check_f = TRUE; } if (rv == SEQxDOTDOT && check_f) { FilUSave2 (file); gcg_f = TRUE; check_f = FALSE; } } while (rv != e__eof && !format); if (gcg_f && !format) { format = SEQxGCG; FilUBack2 (file); } return format; } /****** SeqCopy *************************************************************** ** ** adds sequence to existing sequence ** with or without filtering (i.e. copies only alphanums and ".', \"-") ** ** INPUT: address of sequence descriptor [W] ** address of sequence string [R] ** copy option: SEQxFILTER, or 0 [R] ** IMPLICIT: ** ** RETURNS: 1 ** 0 if sequence terminator was found ('*') */ static INT4 SeqCopy (SEQo *seq, char *stream, INT4 option) { static SMoBUFF *buff=NULL; INT4 rv=1; if (!buff) buff = BuffNew (1000); if (seq->seq == NULL) /* begin of new sequence? */ BuffReset (buff); /* ** process single characters...filter nonsequence characters out */ if (option == SEQxFILTER) { for (; *stream != '\0'; stream++) { if (isalpha (*stream) || *stream == '-' || *stream == '.') BuffCopyChar (buff, *stream); else if (*stream == '*') { /* terminator */ rv = 0; break; } } BuffCopyChar (buff, '\0'); BuffShiftCurrPtr (buff, -1); /* 0 char will be overwritten by next call */ } else { /* sequence is trustworthy...copy without looking at the content */ BuffCopyString (buff, stream); } seq->len = BuffGetCurrOffset (buff); seq->seq = BuffGetPtr (buff); return rv; } /****** SeqReadPirSeq ********************************************************* ** ** assumes that file->ln contains title line >...; ** reads a sequence in PIR format from file; ** ** INPUT: pointer to address of sequence object [R] ** file object (opened for reading) [W] ** ** IMPLICIT: ** ** RETURNS: 1 if success ** 0 if either wrong format or EOF */ static INT4 SeqReadPirSeq (SEQo **seq, FILo *file) { SeqNew (seq); sscanf (&file->ln[4], "%s", (*seq)->name); FilURead (file); StrSetS (&(*seq)->cmnt, file->ln); while (FilURead (file) != e__eof) if (!SeqCopy (*seq, file->ln, SEQxFILTER)) break; SeqMakeOwn (*seq); return 1; } /****** SeqReadEMBLSeq ******************************************************** ** ** Assumes that file pointer is at begin of sequence. ** Reads a sequence in EMBL format from file; ** ** INPUT: pointer to address of sequence object [R] ** file object (opened for reading) [W] ** ** IMPLICIT: ** ** RETURNS: 1 if success ** 0 if either wrong format or EOF */ static INT4 SeqReadEMBLSeq (SEQo **seq, FILo *file) { SeqNew (seq); do { if (!SeqCopy (*seq, file->ln, SEQxFILTER)) break; } while (FilURead (file) != e__eof); SeqMakeOwn (*seq); return 1; } /****** SeqReaddGCGSeq ******************************************************** ** ** reads GCG -sequence from file; assumes that file->ln contains line ** with >..<; ** ** INPUT: pointer to address of sequence object [R] ** file object (opened for reading) [W] ** IMPLICIT: ** ** RETURNS: 1 */ static INT4 SeqReadGCGSeq (SEQo **seq, FILo *file) { SeqNew (seq); FilParse (file->nam, (*seq)->name, FILxNAME); while (FilURead (file) != e__eof) { if (!SeqCopy (*seq, file->ln, SEQxFILTER)) break; } SeqMakeOwn (*seq); return 1; } /****** SeqReadMSFSeq ********************************************************* ** ** assumes that file->ln contains line with /../; ** reads all sequences from MSF-file; ** ** INPUT: pointer to address of sequence object [R] ** file object (opened for reading) [W] ** IMPLICIT: ** ** RETURNS: number of sequences read */ static INT4 SeqReadMSFSeq (SEQo **seq, FILo *file) { char seq_nm[SEQxXNAM+1]; INT4 seq_n, max_nmz, nam_z, seq_f, seq_z; for (seq_n=0, max_nmz=0, seq_f=FALSE; FilURead (file) != e__eof;) { /* ** after the two dots all sequences occuring in the msf file are listed ** one name per row, each row starts with "Name:" */ if (!seq_f) { if (sscanf (file->ln, " Name: %s Len: %d", seq_nm, &seq_z) == 2) { SeqNew (seq); strcpy ((*seq)->name, seq_nm); SeqAlloc ((*seq), seq_n); /** allocate sequence buffer */ seq_n++; if ((nam_z = strlen (seq_nm)) > max_nmz) max_nmz = nam_z; /** size of longest name -> identation length */ } else if (SmLoc (file->ln, "//") != -1) seq_f = TRUE; /** sequences start after that */ } /* ** block with sequences is being processed */ else { /* ** read sequence name -> length is determined by longest name... ** if the string is not empty (line might be a number line ...) ** then the sequence must be copied -> get the sequence object ** by the name just read; */ strncpy (seq_nm, file->ln, max_nmz); SmEdit (seq_nm, SMxTRIM); if (seq_nm[0] != ' ') { LstFirstNamed ((void **) seq, seq_nm); /** assumes names are unique */ SeqCopy (*seq, &file->ln[max_nmz], SEQxFILTER); } } } return seq_n; } /**API* SeqReadAll ************************************************************ ** ** Opens file, tests format and reads sequence(s) if format could ** be determined. ** The following formats are understood: PIR, FASTA, EMBL, GCG, MSF. ** ** INPUT: address of pointer to sequence object [W] ** file name [R] ** IMPLICIT: ** ** RETURNS: number of sequences read; ** e__novalseqform + ** e__filnotok + */ INT4 SeqReadAll (SEQo **seq, char *fil_nm) { FILo *file; INT4 seq_n=0, rv; rv = FilUOpen2 (&file, fil_nm, SEQxXLN, FILxVAR); _ErrIf (rv) { _ErrMsg2 (rv, fil_nm); return 0; } rv = SeqTestFormat (file); switch (rv) { case SEQxGCG: seq_n = SeqReadGCGSeq (seq, file); break; case SEQxMSF: seq_n = SeqReadMSFSeq (seq, file); break; case SEQxPIR: do { SeqReadPirSeq (seq, file); seq_n++; } while (SeqTestFormat (file) == SEQxPIR); break; case SEQxPEARSON: break; case SEQxEMBL: seq_n = SeqReadEMBLSeq (seq, file); break; default: _ErrMsg3 (e__novalseqform, fil_nm, "GCG, GCG-MSF, PIR, FASTA, EMBL"); } FilUClose2 (file); return seq_n; } SEQo *SeqReadString (char *s) { SEQo *seq=NULL; SeqNew (&seq); SeqCopy (seq, s, SEQxFILTER); SeqMakeOwn (seq); return seq; } /**api* SeqReadPIR ************************************************************ ** ** reads a sequence in PIR format; ** ** INPUT: pointer to address of sequence object [W] ** file name [R] ** IMPLICIT: ** ** RETURNS: number of sequences read ** e__novalseqform + ** e__filnotok + */ INT4 SeqReadPIR (SEQo **seq, char *fil_nm) { FILo *file; INT4 k, rv; rv = FilUOpen2 (&file, fil_nm, SEQxXLN, FILxVAR); _ErrRet2(rv, fil_nm); for (k=0; SeqTestFormat (file) == SEQxPIR; k++) SeqReadPirSeq (seq, file); FilUClose2 (file); if (k==0) _ErrRet3 (e__novalseqform, fil_nm, "PIR"); return k; } /**api* SeqReadGCG ************************************************************ ** ** reads either single GCG files or GCG-MSF-file or file-of-names; ** ** INPUT: pointer to address of sequence object [W] ** name (GCG-file name) [R] ** IMPLICIT: ** ** RETURNS: 1 */ INT4 SeqReadGCG (SEQo **seq, char *name) { #ifndef dos char file_nm[FILxXNAM]; UINT4 context = 0; if (strchr (name, '{') != NULL) SeqReadMSF (seq, name); else while (FilSearch (name, file_nm, &context) != 0) SeqReadGCGFile (seq, file_nm); #endif return 1; } /**api* SeqReadGCGFile ******************************************************** ** ** opens a sequence in GCG-format and reads sequence into global seqbuff; ** sequence-info goes into sequence-descriptor; ** file-NAME is copied to sequence-name ** ** INPUT: pointer to address of sequence object [W] ** name (GCG-file name) [R] ** IMPLICIT: ** ** RETURNS: 1 if OK ** e__allocfail + ** e__novalseqform + */ INT4 SeqReadGCGFile (SEQo **seq, char *fil_nm) { FILo *file; INT4 rv; rv = FilUOpen2 (&file, fil_nm, SEQxXLN, FILxVAR); _ErrRet2 (rv, fil_nm); if (SeqTestFormat (file) != SEQxGCG) _ErrRet3 (e__novalseqform, fil_nm, "GCG"); rv = SeqReadGCGSeq (seq, file); FilUClose2 (file); return 1; } /****** SeqMSFNam ************************************************************* ** ** analyzes a name that specifies a set of sequences in MSF file ** file name must have "{*}" at the end; ** ** INPUT: o address of input string [R] ** o address that receives filename part [W] ** o address that receives seqname part [W] ** wildcard will be removed ** IMPLICIT: ** ** RETURNS: 0 if no wildcard ** 1 if yes */ static INT4 SeqMSFNam (char *name, char *file_nm, char *seq_nm) { char *off; INT4 l; for (l=0; *name != '{' && *name; name++, l++) file_nm[l] = *name; file_nm[l] = '\0'; for (l=0; *(++name) != '}' && *name; l++) seq_nm[l] = *name; seq_nm[l] = '\0'; if ((off = (char *) strchr (seq_nm, '*')) == NULL) return 0; else *off = '\0'; return 1; } /**api* SeqReadMSF ************************************************************ ** ** reads all sequences in an MSF file; ** file name must have "{*}" at the end; ** ** INPUT: pointer to address of sequence object [W] ** name of MSF file [R] ** IMPLICIT: ** ** RETURNS: number of sequences read ** e__novalseqform + ** e__filnotok + */ INT4 SeqReadMSF (SEQo **seq, char *msf_nm) { FILo *file; char fil_nm[SEQxXNAM+1], seq_nm[SEQxXNAM+1]; INT4 rv, seq_n; SeqMSFNam (msf_nm, fil_nm, seq_nm); seq_n = 0; rv = FilUOpen2 (&file, fil_nm, SEQxXLN, FILxVAR); _ErrRet2 (rv, fil_nm); if (SeqTestFormat (file) != SEQxMSF) _ErrRet3 (e__novalseqform, fil_nm, "GCG-MSF"); seq_n = SeqReadMSFSeq (seq, file); FilUClose2 (file); return seq_n; } /**api* SeqSetRecordSeparator ************************************************* ** ** GCG 7.x format on VMS has a single char separating records. ** SeqFromLib must ignore that. ** ** INPUT: length of separator [R] ** IMPLICIT: ** recordSeparatorLength (INT4) [W] ** ** RETURNS: */ void SeqSetRecordSeparator (INT4 i) { #ifdef VMS recordSeparatorLength = i; #else recordSeparatorLength = 0; #endif } /**api* SeqFromLib ************************************************************ ** ** reads sequence file from current position - assumes that the ** title line is just read in and reads comment plus sequence; ** ** INPUT: o address of sequence object [W] ** o address of file-descriptor [W] ** o optional scanf format string to extract the name [R] or ** NULL ** o string that marks the end of the sequence [R] ** o flag determines if first line after title is a comment line ** else the title line is read into comment [R] ** IMPLICIT: ** ** RETURNS: 1 ** e__eof */ INT4 SeqFromLib (SEQo **seq, FILo *file, char *findId, char *exitstr, INT4 options) { INT4 k, l, off, len, seq_z, readchar_n, rv=1, gcgascii_f = FALSE, gcgbin_f = FALSE; SeqNew (seq); /* ** edit first entry line and get entry name */ SmEdit (file->ln, SMxUPCASE); SmXLoc (file->ln, exitstr, 1, 1); if (findId) sscanf (file->ln, findId, (*seq)->name); else sscanf (file->ln, "%s", (*seq)->name); /* ** if this is a gcg sequences then it has a length field and either 2BIT ** or ASCII */ if ((off = SmLoc (file->ln, "LEN:")) != -1) { sscanf (&((file->ln)[off]), "LEN: %d", &seq_z); if (SmLoc (file->ln, "2BIT") != -1) gcgbin_f = TRUE; if (SmLoc (file->ln, "ASCII") != -1) gcgascii_f = TRUE; } /* ** read and copy second line of entry with comment to the sequence */ if (options & 1) { if (FilURead (file) == e__eof) return e__eof; } /* strcpy (seq->cmnt, file->ln); */ /* ** read the binary encoded sequence (length = sequence len * 4 ... some ** extra info is read if the last byte is not completely used; then ** convert the sequence to ascii format; seq->seq must be aligned to 4 byte ** boundary for SeqBinToAsci - SeqMalloc does this */ if (gcgbin_f || gcgascii_f) { readchar_n = gcgbin_f ? (seq_z+3)/4 : seq_z; SeqAlloc (*seq, seq_z+4+1); for (k=0, l=readchar_n; k < readchar_n; k += file->len, l -= file->len) fread ((*seq)->seq+k, 1, l > file->len ? file->len + recordSeparatorLength : l, file->fil); /* if (gcgbin_f) SeqBinToAscii ((*seq)->seq, seq_z); */ (*seq)->len = seq_z; file->l = file->ln; file->ln[0] = '\0'; /** wipe out file->ln...fread! */ } /* ** if not gcg format read the sequence until exitstr is encountered */ else { while (1) { if (FilURead (file) == e__eof) { rv = e__eof; break; } if (memcmp (file->ln, exitstr, strlen (exitstr)) == 0) break; len = strlen (file->ln); if (file->ln[len-1] == '\n') file->ln[--len] = '\0'; SeqCopy (*seq, file->ln, SEQxFILTER); } if (options & 2) (*seq)->seq = NULL; /* prevents strange behaviour of srsbuild on osf1 ... sequence is not needed anyway ..just the length */ else SeqMakeOwn (*seq); } return rv; } /****** SeqGCGCheck *********************************************************** ** ** is the equiv. to the GCG CheckSeq; calculates a check sum for the ** input sequence; ** ** INPUT: address of array holding sequence ** length of seuqence ** ** RETURNS: check sum if successful ** */ static INT4 SeqGCGCheck(char *seq, INT4 len) { static INT4 fstcall_f = 1; static char table[256]; INT4 k, check = 0, i = 0; if (fstcall_f) { for (k = 0; k <= 255; k++) table[k] = toupper(k); fstcall_f = 0; } for( i=0, check=0; i < len; i++, seq++) check += ((i % 57)+1) * table[ (INT4) *seq]; return check % 10000; } /****** SeqWrite ************************************************************** ** ** writes a sequence to file with specified characters per line and ** characters by block; ** ** INPUT: o address of file block [W] ** o address of sequence [R] ** o length of sequence [R] ** o char per line [R] ** o char per block [R] ** o format option bitmask [R] ** using SEQxNUMBER, SEQxSTAR, SMxLOWCASE, SMxUPCASE or 0 ** SEQxLMARGIN ** IMPLICIT: ** ** RETURNS: nr. of lines written */ static INT4 SeqWrite (char *seq, INT4 len, INT4 colN, INT4 blockColN, INT4 option, INT4 (*print)(char*,...)) { char line[SEQxXLN+1], *tmp; INT4 lineN = 0, k; if (!len) return 0; for (k=0; k < len && *seq != '\0'; k++) { if (k % colN == 0) { /* is end of line? */ if (k != 0) { *tmp = '\0'; if (option & SEQxEMBLNUMBER) sprintf (line, "%-70s%10d", line, k); print ("%s\n", line); } if (option & SEQxNUMBER) sprintf (line, "%8d ", k+1); else if (option & SEQxLMARGIN) sprintf (line, " "); else strcpy (line, ""); tmp = &(line[strlen (line)]); } else if (k % blockColN == 0) /* is end of block ? */ *(tmp++) = ' '; *(tmp++) = seq[k]; } if (option & SEQxSTAR) /* put star at the end of the sequence */ *tmp++ = '*'; *tmp = '\0'; /* print last line feed */ if (option & SEQxEMBLNUMBER) sprintf (line, "%-70s%10d", line, k); print ("%s\n", line); return ++lineN; } /**API* SeqWriteGCG *********************************************************** ** ** Prints a sequence in GCG format. ** ** INPUT: o address of sequence object [R] ** o sequence name [R] or NULL ** o function to be used for printing lines [R] prints to STDOUT ** if NULL ** ** RETURNS: no of lines printed */ INT4 SeqWriteGCG (SEQo *seq, char *nam, INT4 (*print)(char*,...)) { INT4 cksum; if (!print) print = (INT4 (*)(char*,...)) printf; cksum = SeqGCGCheck (seq->seq, seq->len); print ("%s Length: %d Check: %d ..\n\n", nam == NULL ? seq->name : nam, seq->len, cksum); return SeqWrite (seq->seq, seq->len, 60, 10, SEQxNUMBER, print) + 2; } /**API* SeqWriteApplet ************************************************************** ** ** Prints a sequence in GCG format. ** ** INPUT: o address of sequence object [R] ** o sequence name [R] or NULL ** o function to be used for printing lines [R] prints to STDOUT ** if NULL ** ** RETURNS: no of lines printed */ INT4 SeqWriteApplet (SEQo *seq, char *nam) { printf ("\n"); printf ("\n", seq->seq); printf (""); printf ("\n"); } /**API* SeqWritePIR *********************************************************** ** ** Prints a sequence in PIR format. ** ** INPUT: o address of sequence object [R] ** o sequence name [R] title line is omitted if NULL ** o title line [R] or NULL ** o function to be used for printing lines [R] prints to STDOUT ** if NULL ** ** RETURNS: no of lines printed */ INT4 SeqWritePIR (SEQo *seq, char *nam, char *cmnt, INT4 (*print)(char*,...)) { INT4 lncnt = 0; if (!print) print = (INT4 (*)(char*,...)) printf; if (!seq) return 0; print (">P1;%s\n", nam == NULL ? seq->name : nam); if (!seq->cmnt) print (" Length: %d\n", seq->len); else print ("%s\n", _Str (seq->cmnt)); lncnt = SeqWrite (seq->seq, seq->len, 60, 10, SEQxSTAR, print); print ("\n"); return lncnt+2; } STRv Seq2Pretty (SEQo *seq, Int4 width) { STRv s=StrNew (); char tmp[20]; Int4 i, k, len=SeqGetLength (seq); for (i=1; i <= len; i+= width) { for (k=i; k < width+i && k <= len; k+= 10) { sprintf (tmp, "%d", k); StrPrintf (&s, "%-10s", tmp); } StrAppS (&s, "\n"); StrAppN (&s, seq->seq+i-1, width); StrAppS (&s, "\n"); } return s; } /**API* SeqWriteEmbl ********************************************************** ** ** Prints a sequence in EMBL format. ** ** INPUT: o address of sequence object [R] ** o sequence name [R] title line is omitted if NULL ** o function to be used for printing lines [R] prints to STDOUT ** if NULL ** ** RETURNS: no of lines printed ** */ INT4 SeqWriteEMBL (SEQo *seq, char *nam, INT4 (*print)(char*,...)) { INT4 lncnt = 0; if (!print) print = (INT4 (*)(char*,...)) printf; if (!seq) return 0; if (nam && !ParGetBool ("printEntireEntry")) print ("SQ Sequence%6d BP;\n", seq->len); lncnt = SeqWrite (seq->seq, seq->len, 60, 10, SEQxLMARGIN | SEQxEMBLNUMBER, print); print ("//\n"); return lncnt+2; } /**Api* SeqWriteSwiss ********************************************************* ** ** writes sequence in Swissprot format to file ** ** INPUT: sequence object [R] ** sequence name ...if NULL then the title line is omitted [R] ** print line function [R] ** ** OUTPUT: ** returns: nr. of lines written to file */ INT4 SeqWriteSwiss (SEQo *seq, char *nam, INT4 (*print)(char*,...)) { INT4 lncnt = 0; if (!print) print = (INT4 (*)(char*,...)) printf; if (!seq) return 0; if (nam) if (!ParGetBool ("printEntireEntry")) print ("SQ Sequence%6d AA;\n", seq->len); lncnt = SeqWrite (seq->seq, seq->len, 60, 10, SEQxLMARGIN, print); print ("//\n"); return lncnt+2; } /**api* SeqWriteGDE *********************************************************** ** ** writes sequence in GDE format ** ** INPUT: address of sequence object [R] ** file pointer of output file [W] ** name to appear in the title line [R] or NULL ** ** RETURNS: nr. of lines written to file */ INT4 SeqWriteGDE (SEQo *seq, char *nam, INT4 (*print)(char*,...)) { INT4 ln_n=0; if (!print) print = (INT4 (*)(char*,...)) printf; if (!seq) return 0; print ("%c%s\n", '%', nam == NULL ? seq->name : nam); ln_n = SeqWrite (seq->seq, seq->len, 60, 10, 0, print); print ("\n"); return ln_n+1; } /**api* SeqWriteFasta ********************************************************* ** ** modified 3-may-95 by Peter Rice to cut out spaces ** ** writes sequence in PIR format to file ** ** INPUT: address of sequence object [R] ** file pointer of output file [W] ** name to appear in the title line [R] or NULL ** ** RETURNS: nr. of lines written to file ** */ INT4 SeqWriteFasta (SEQo *seq, char *nam, INT4 (*print)(char*,...)) { INT4 lncnt = 0; if (!print) print = (INT4 (*)(char*,...)) printf; if (!seq) return 0; print (">%s\n", nam == NULL ? seq->name : nam); lncnt = SeqWrite (seq->seq, seq->len, 60, 60, 0, print); /* block 10 to 60 */ /* print ("\n"); commented out */ return lncnt+1; /* was lncnt+2 */ } /**API* SeqWrtMSF ************************************************************* ** ** Prints a list of sequences in MSF (GCG) format. ** ** INPUT: o address of sequence object [R] ** o function to be used for printing lines [R] prints to STDOUT ** if NULL ** ** RETURNS: */ INT4 SeqWrtMSF (SEQo *seq, INT4 (*print)(char*,...)) { INT4 savepos, k, allcksum, ali_z, line_n = 60; if (!print) print = (INT4 (*)(char*,...)) printf; if (!seq) return 0; LstGetPosition (seq, &savepos); /* ** go through all sequences and find out the max length which will ** become the length of the alignment...and calculate the total check sum ** of the alignment; */ do { if (seq->len > ali_z) ali_z = seq->len; allcksum += SeqGCGCheck (seq->seq, seq->len); } while (LstNext ((void **) &seq)); allcksum = allcksum % 10000; /* ** print title of alignment and the names of the sequences occurring ** in the MSF file; */ print ("MSF: %d Type: P Check: %d ..\n\n", ali_z, allcksum); LstSetPosition ((void **) &seq, savepos); do { print (" Name: %-12s Len: %6d Check: %4d Weight: 1\n", seq->name, seq->len, SeqGCGCheck (seq->seq, seq->len)); } while (LstNext ((void **) &seq)); print ("\n//\n"); /* ** print the sequence alignment */ for (k=0; k < ali_z; k += line_n) { LstSetPosition ((void **) &seq, savepos); do { print ("%-12s ", seq->name); SeqWrite (&seq->seq[k], line_n, line_n, 10, 0, print); } while (LstNext ((void **) &seq)); print ("\n"); } return 1; } /**api** SeqAlloc ************************************************************ ** ** allocates memory for a sequence string with know length; ** ** INPUT: address of sequence object [W] ** IMPLICIT: ** ** RETURNS: 1 if OK ** 0 else */ static void SeqAlloc (SEQo *seq, INT4 len) { if (seq->seq) fprintf(stderr, "*** MEMORY LEAK in SeqAlloc ***\n"); if ((seq->seq = (char *) malloc (len + 1)) == NULL) _ErrExit2 (e__allocfail, "sequence"); } /**api** SeqMakeOwn *********************************************************** ** ** copies the sequence string from temporary to extra allocated memory; ** ** INPUT: address of sequence object [W] ** IMPLICIT: ** ** RETURNS: */ static void SeqMakeOwn (SEQo *seq) { char *tmp; if (seq->len) { if ((tmp = (char *) malloc (seq->len + 1)) == NULL) _ErrExit2 (e__allocfail, "sequence"); memcpy (tmp, seq->seq, seq->len); tmp[seq->len] = '\0'; seq->seq = tmp; } else seq->seq = NULL; } /**api** SeqSubSeq ************************************************************ ** ** Makes a subsequence from sequence as specified. Does not change the ** allocation ** ** INPUT: address of sequence object [W] ** begin of subsequence (first aa = 1) [R] ** length of subsequence [R] ** IMPLICIT: ** ** RETURNS: 1 if OK ** 0 else */ INT4 SeqSubSeq (SEQo *seq, INT4 beg, INT4 len) { if (beg <= 0 || len <= 0) return 0; if (beg > seq->len) /* begin */ return 0; if (beg + len-1 > seq->len) /* length */ len = seq->len - beg + 1; memcpy (seq->seq, &seq->seq[beg-1], len); seq->len = len; seq->seq[len] = '\0'; return 1; } /**api** SeqHead ************************************************************ ** ** makes a subsequence from start of sequence with length len ** ** INPUT: address of sequence object [W] ** length of subsequence [R] ** IMPLICIT: ** ** RETURNS: 1 if OK ** 0 else */ INT4 SeqHead(SEQo *seq, INT4 len) { /* ** SeqSubSeq does no free allocated memory, so maybe ** another implementation will be used later */ return SeqSubSeq(seq, 1, len); } /**api** SeqTail ************************************************************ ** ** makes a subsequence from end of sequence with length len ** ** INPUT: address of sequence object [W] ** length of subsequence [R] ** IMPLICIT: ** ** RETURNS: 1 if OK ** 0 else */ INT4 SeqTail(SEQo *seq, INT4 len) { /* ** SeqSubSeq does no free allocated memory, so maybe ** another implementation will be used later */ return SeqSubSeq(seq, seq->len - len + 1, len); } /**api** SeqCat ************************************************************ ** ** concatenates a subsequence (range) to another sequence (*seq) ** ** INPUT: sequence object [R] ** sequence object to be added to first [R] ** */ void SeqCat (SEQo *seq, SEQo *range) { SEQo *result = seq; char *oldseq; /* look, if there was already a sequence before */ oldseq = result->seq; /* make sure correct length is set */ if (!oldseq) { result->len = 0; oldseq = ""; } else result->len = strlen(result->seq); result->len += strlen(range->seq); result->seq = (char*) malloc(result->len + 1); strcpy(result->seq, oldseq); strcat(result->seq, range->seq); if (*oldseq) free(oldseq); } /**api* SeqSwap *************************************************************** ** ** swaps a character in all sequences; ** ** INPUT: address of sequence object [W] ** old character [R] ** new character [R] ** IMPLICIT: ** ** RETURNS: 1 */ INT4 SeqSwap (SEQo *seq, char a, char b) { INT4 savepos; LstGetPosition (seq, &savepos); LstFirst ((void **) &seq); do { SmSwap (seq->seq, a, b); } while (LstNext ((void **) &seq)); LstSetPosition ((void **) &seq, savepos); return 1; } /**api* SeqRemoveGaps ********************************************************* ** ** removes gaps (either '-' or '.') from sequence ** ** INPUT: address of sequence-dsc. [W] ** IMPLICIT: ** ** RETURNS: 1 */ INT4 SeqRemoveGaps (SEQo *seq) { SmSwapS (seq->seq, ".", ""); SmSwapS (seq->seq, "-", ""); seq->len = strlen (seq->seq); return 1; } /**api* SeqGetLength ********************************************************** ** ** Returns the sequence's length ** ** INPUT: sequence object ** ** RETURNS: sequence length */ Int4 SeqGetLength (SEQo *seq) { return seq->len; } /**api* SeqGet *************************************************************** ** ** Gets sequence in sequence buffer by name; ** ** INPUT: pointer to address of sequence object [W] ** name [R] ** IMPLICIT: ** ** RETURNS: number in list if found ** 0 if not */ INT4 SeqGet (SEQo **seq, char *seq_nm) { INT4 pos; if (!LstFirstNamed ((void **) seq, seq_nm)) return 0; LstGetPosition ((void *) *seq, &pos); return pos; } /* icarus functions */ static SEQo *seqCurr=NULL; void SeqIopGet2Bit (Int4 runTime, SEQo *seq, FILEo *file, Int4 len) { SEQo *tmp=NULL; Int4 byteN; if (runTime) IargGetArgs ("s|file|len", &seq, &file, &len); if (SeqGetLength (seq)) SeqNew (&tmp); else tmp = seq; byteN = (len+3)/4; /* sequence is stored in 4byte words */ SeqAlloc (tmp, len+4+1); fread (tmp->seq, 1, byteN, FileGetFile (file)); tmp->len = len; SeqBinToAscii (tmp); if (tmp != seq) { /* concatenate sequences */ SeqCat (seq, tmp); SeqDel (&tmp); } } void SeqIopCut (Int4 runTime, SEQo *seq, Int4 from, Int4 len) { if (runTime) IargGetArgs ("s|from|len", &seq, &from, &len); } void SeqIopNew () { SEQo *seq=NULL; STRv name; IargGetArgs ("name|list", &name, &seq); if (seqCurr) SeqClean (&seqCurr); SeqNew (&seq); if (name) { SeqSetName (seq, _Str (name)); StrDel (name); } seqCurr = seq; IcaReturn ("sequence", seq); } void SeqIopApp () { SEQo *seq; STRv s; IargGetArgs ("seq|s", &seq, &s); SeqCopy (seq, _Str(s), SEQxFILTER); StrDel (s); IcaReturn ("sequence", seq); } void SeqIopLen () { SEQo *seq; STRv s; IargGetArgs ("seq", &seq); IcaReturn ("int", seq->len); } void SeqIopMake () { SEQo *seq; IargGetArgs ("seq", &seq); SeqMakeOwn (seq); } void SeqIopTrunc (Int4 runTime, SEQo *seq, Int4 l) { Int4 len; IargGetArgs ("seq|len", &seq, &l); len = SeqGetLength (seq); if (!(len % l)) SeqSubSeq (seq, 1, len-l); } void SeqIopPrint () { STRv s; SEQo *seq, tmp; INT4 format; IargGetArgs ("format|seq|s", &format, &seq, &s); if (s) { seq = &tmp; *tmp.name = '\0'; tmp.len = StrLen (s); tmp.seq = _Str(s); } else if (!seq) seq = seqCurr; /* SeqFormatPrint (seq) */ switch (format) { case SEQxGCG: SeqWriteGCG (seq, NULL, NULL); break; case SEQxPIR: SeqWritePIR (seq, seq->name, "", NULL); break; case SEQxFASTA: SeqWriteFasta (seq, seq->name, NULL); break; case SEQxEMBL: SeqWriteEMBL (seq, seq->name, NULL); break; case SEQxSWISS: SeqWriteSwiss (seq, seq->name, NULL); break; case SEQxMSF: SeqWriteApplet (seq, seq->name); break; default: _ErrExit2 (e__unknownoption, "format in SeqIopPrint"); } if (s) StrDel (s); } SEQo* SeqGetCurrent() { SEQo* curr=seqCurr; seqCurr=NULL; return curr; } void SeqSetCurrent(SEQo* seq) { /* cancel current sequence */ if (seqCurr) SeqClr(&seqCurr); seqCurr=seq; } QxEMBL: SeqWriteEMBL (seq, seq->name, NULL); break; case SEQxSWISS: SeqWriteSwiss (seq, seq->name, NULL); break; case SEQxMSF: SeqWriteApplet (seq, seq->name); break; default: _ErrExit2 (e__unknownoption, "format in SeqIopPrint"); } if (s) StrDel (s); } SEQo* SeqGetCurrent() { SEQo* curr=seqCurr; seqCurr=NULL; return curr; } void SeqSetCurrent(SEQo* seq) { /* cancel current sequence */ if (seqCurr) SeqClr(&seqCurr); seqCurr=seqsrs/src/seq.h ** ** $RCSfile: seq.h,v $ ** $Revision: 1.3 $ ** $Date: 1997/03/03 18:20:49 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port: Lukas Rosenthaler and Reinhard Doelz ** */ #include "transl.h" #define SEQxXNAM 50 /* max size of sequence name */ #define SEQxXWIN 31 #define SEQxXCMNT 512 /* max size of sequence comment */ #define SEQxXLN 255 #define SEQxSEQBUFF 1000000 /* size of sequence buffer */ enum seqformat {SEQxGCG=1, SEQxMSF, SEQxPIR, SEQxPEARSON, SEQxFASTA, SEQxEMBL, SEQxSWISS, SEQxCLUSTAL}; enum formattoken {SEQxRANGLE=1, SEQxPIRTOKENS, SEQxCHECK, SEQxDOTDOT, SEQxSEMICOLON}; enum formatoption {SEQxFILTER=1, SEQxNUMBER=8, SEQxSTAR=16, SEQxLMARGIN=32, SEQxEMBLNUMBER=64}; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** description of a sequence */ typedef struct SEQo { char *intern; /* the first three attributes are necessary */ INT4 type_id; /* for all objects to be managed by the list */ char name[20]; STRv cmnt; /* sequence description */ char *seq; /* pointer to sequence string */ char *replace; /* string to be replaced or inserted into sequence */ INT4 len; /* length of sequence */ INT4 check; /* GCG check sum */ INT4 bpos; /* begin position of range */ INT4 epos; /* end position of range */ INT4 part_len; /* 0: complete <0: head >0: tail */ char accno[10]; char keep_f; /* flag if sequence should be kept */ char compl_f; /* flag if sequence is to be reverse complemented */ char cut_f; /* flag that replace sequence is to be inserted in range */ char before_f; /* flag that shows whether the operator BEFORE exists */ char after_f; /* flag that shows whether the operator AFTER exists */ struct SEQo *sublist; } SEQo; typedef struct SEQoTranslExcept { char aa; INT4 begin; INT4 length; INT4 isDone; } SEQoTranslExcept; typedef struct SEQoTranslCodon { char aa; char codon[4]; } SEQoTranslCodon; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of exported functions */ INT4 SeqNew (SEQo **seq); void SeqClr (SEQo **seq); void SeqClean (SEQo **seq); void SeqDel (SEQo **seq); /* input from file in various formats */ INT4 SeqReadAll (SEQo **seq, char *fil_nm); INT4 SeqReadPIR (SEQo **seq, char *fil_nm); INT4 SeqReadGCG (SEQo **seq, char *nam); INT4 SeqReadGCGFile (SEQo **seq, char *fil_nm); INT4 SeqReadMSF (SEQo **seq, char *msf_nm); INT4 SeqReadLib (SEQo **seq, FILo *file, char *exitstr); INT4 SeqFromLib (SEQo **seq, FILo *file, char *scanId, char *exitstr, INT4 comment_f); SEQo *SeqReadString (char *s); /* output to file in various formats */ INT4 SeqWriteGCG (SEQo *seq, char *nam, INT4 (*print)(char*,...)); INT4 SeqWritePIR (SEQo *seq, char *nam, char *cmnt, INT4 (*print)(char*,...)); INT4 SeqWriteFasta (SEQo *seq, char *nam, INT4 (*print)(char*,...)); INT4 SeqWriteEMBL (SEQo *seq, char *nam, INT4 (*print)(char*,...)); INT4 SeqWriteSwiss (SEQo *seq, char *nam, INT4 (*print)(char*,...)); INT4 SeqWriteMSF (SEQo *seq, INT4 (*print)(char*,...)); /* conversion of sequence into various formats */ struct STRo *Seq2Pretty (SEQo *seq, Int4 width); /* sequence manipulation */ INT4 SeqSwap (SEQo *seq, char a, char b); INT4 SeqSubSeq (SEQo *seq, INT4 beg, INT4 len); INT4 SeqRemoveGaps (SEQo *seq); INT4 SeqComplement (SEQo *seq); INT4 SeqHead (SEQo *seq, INT4 len); INT4 SeqTail (SEQo *seq, INT4 len); void SeqCat (SEQo *seq1, SEQo *seq2); /* for translating DNA to protein */ SEQoTranslTable *SeqTaxaToTranslTable (SMoBUFF *org); SEQoTranslTable *SeqIdToTranslTable (INT4 id); struct SEQo *SeqTranslate (SEQo *dna, INT4 start, SEQoTranslTable *tTable, SEQoTranslExcept *tExcept, SEQoTranslCodon *tCodon); /* others */ INT4 SeqGoGcgDots (FILo *file); INT4 SeqGet (SEQo **seq, char *seq_nm); void SeqSetRecordSeparator (INT4 i); Int4 SeqGetLength (SEQo *seq); void SeqSetName (SEQo *seq, char *name); SEQo* SeqGetCurrent(); void SeqSetCurrent(SEQo* seq); SEQoTranslTable *SeqTaxaToTranslTable (SMoBUFF *org); SEQoTranslTable *SeqIdToTranslTable (INT4 id); struct SEQo *SeqTranslate (SEQo *dna, INT4 start, SEQoTranslTable *tTable, SEQoTranslExcept *tExcept, SEQoTranslCodon *tCodon); /* others */ INT4 SeqGoGcgDots (FILo *file); INT4 SeqGet (SEQo **seq, srs/src/seqdb.c char seqdb_ID[] = "$Id: seqdb.c,v 1.7 1997/03/03 18:20:50 srs Exp $"; /* ** ** $RCSfile: seqdb.c,v $ ** $Revision: 1.7 $ ** $Date: 1997/03/03 18:20:50 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** Copyright by Thure Etzold ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include "message.h" #include "sm.h" #include "strv.h" #include "futil.h" #include "toklist.h" #include "icarus.h" #include "entry.h" #include "id.h" #include "set.h" #include "query.h" #include "library.h" #include "field.h" #include "seq.h" #include "listv.h" #define _SRS #define _SLB #include SRSINCLUDE /********************************************************* ** ENTRY stack management *********************************************************/ STRv SdbGetEntryField(STRv db, STRv acc, STRv fieldName) { SETo *set; IDoENTRY id; ENTRYv entry; int n, entryN; char query[100]; static char qname[20]="SingleEntryQuery"; STRv res; SLBoFIELD* field; SLBo* lib; STRv s; INT4 k; /* build query string */ sprintf(query,"[%s-acc:%s]",Str(db),Str(acc)); if (Query (query, qname)) { set = SetGet (qname); entryN = SetSize (qname); /* check one and only one entry */ if (entryN>0) { if (entryN!=1) { ENTRYv temp; INT4 e; /* select the one with the primary accession num */ entry=NULL; for (e=1; e<=entryN; e++) { SetGetID(set,e,&id); temp = EntryOpen (&id); lib= EntryGetLib(temp); field = LibHasFieldNamed (lib, "acc"); ASSERT(field,"NoAccession"); /* first is primary acc *HOPE* */ if (StrEqualS(acc,_Str(EntryGetField (temp, field, &k)))) { if (!entry) entry=temp; else printf("MultipleEntries: %s\n", Str(acc)); } if (temp!=entry) EntryClose (&temp); } } else { /* get id */ SetGetID (set, 1, &id); entry = EntryOpen (&id); } lib=EntryGetLib(entry); /* retrieve field */ field = LibHasFieldNamed (lib, Str(fieldName)); ASSERT(field,"NoSuchField"); /* concatenate all tokens of the field */ res=StrNew(); for (k=0; (s = (EntryGetField (entry, field, &k)));) { StrApp(&res,s); StrDel (s); } EntryClose (&entry); } else res=NULL; } else res=NULL; SetDelete(qname); return res; } /*************************************************************** ** ENTRY context ***************************************************************/ STRv currSeq=NULL; STRv currDb=NULL; BOOL exception=FALSE; /********************************************************* ** SEQUENCE CALCULATOR *********************************************************/ enum SDB_ChunkConstants { SDB_unbounded=-1, SDB_optional=1, /* chunk can be omitted */ SDB_left=2, /* chunk varies left^right to right^right */ SDB_right=3, /* chunk varies left^right to left^left */ SDB_wrong=4 /* chunk contains an error */ }; typedef struct SDBoChunk { STRv seq; int beg; int end; int uncertain; } SDBoChunk; INT4 ChunkLen(SDBoChunk* c) { INT4 len; len=c->end-c->beg; if (len<0) len=-len; return len; } BOOL ChunkUncertain(SDBoChunk* c) { int u=c->uncertain; return u==SDB_wrong || u==SDB_right || u==SDB_left; } BOOL ChunkCheck(SDBoChunk* c) { Int4 len=StrLen(c->seq); if (c->beg<=c->end) return c->beg>=0 && c->end<=len; else return c->end>=0 && c->beg<=len; } _List(SDBoChunk) calcStack[256]; _List(SDBoChunk) *calc=calcStack-1; STRv SdbEval(INT4 runTime); /*********************************************************** ** Pushes a given sequence on the calculator stack ***********************************************************/ BOOL chunkStart=TRUE; INT4 chunkFrom; void SdbPush() { *++calc=_ListNew(SDBoChunk,1); chunkStart=TRUE; } void SdbPop() { int i; for (i=0; i<_ListLen(*calc); i++) { SDBoChunk* sc=&(*calc)[i]; /* delete sequence chunk */ StrDel(sc->seq); } _ListDel(*calc); calc--; } STRv SdbRetrieve(INT4 runTime, STRv acc, STRv db) { STRv seq; if (runTime) IargGetArgs("acc|db",&acc,&db); if (acc && !StrEqualS(acc,"")) { SEQo* curr=SeqGetCurrent(); STRv res; if (!db || StrEqualS(db,"")) db=StrCpy(currDb); res=SdbGetEntryField(db,acc,StrTemp("sequence")); if (res) { SEQo* tmp=SeqGetCurrent(); seq=StrCpyS(tmp->seq); SeqSetCurrent(tmp); StrDel(res); } else { printf("!!!Entry not found:%s\n",Str(acc)); seq=StrNew(); exception=TRUE; } SeqSetCurrent(curr); } else seq=StrCpy(currSeq); StrDel(acc); StrDel(db); if (runTime) IcaReturn("strv",seq); return seq; } /************************************************************ ** Extracts a range from the current sequence ** and pushes it on the calculator stack ************************************************************/ void SdbChunk (INT4 runTime, STRv seq, INT4 to, INT4 uncertain) { SDBoChunk* sc; INT4 len; BOOL out=FALSE; if (runTime) IargGetArgs("seq|to|uncertain", &seq, &to, &uncertain); len=StrLen(seq); if (to==-2) to=len; /* apply default*/ else if (to==-3) to=chunkFrom+1; if (!chunkStart) { /* create chunk */ sc=&_ListApp(calc); sc->seq=StrCpy(seq); sc->beg=chunkFrom; sc->end=to; /* check boundaries */ if (to!=SDB_unbounded && (tolen)) { sc->uncertain=SDB_wrong; exception=TRUE; printf("Out of bounds\n"); } else sc->uncertain=uncertain; } chunkStart=FALSE; chunkFrom=to; StrDel(seq); } /************************************************************ ** Extracts a sequence calculating a feature of the current ** entry sequence, and pushes it on the calculator stack ************************************************************/ void SdbFeature(INT4 runTime,STRv feature) { if (runTime) IargGetArgs("feature", &feature); StrDel(feature); } /************************************************************ ** Replaces the given range of the (current-1) entry sequence ** with the sequence at calc top, pushes result ************************************************************/ void SdbReplace () { int from, to; STRv repl=SdbEval(FALSE); SDBoChunk *sc, *rng=*calc; /* replace range */ if (_ListLen(rng)!=1) { printf("Complex range in replace\n"); exception=TRUE; } else if (ChunkUncertain(rng)) { printf("Uncertain range in replace\n"); exception=TRUE;} if (!exception) { *calc=_ListNew(SDBoChunk,1); sc=&_ListApp(calc); sc->seq=rng->seq; from=rng->beg; to=rng->end; if (from>=0 && fromseq)) StrSubst(&sc->seq,from,to-from,repl); else { printf("Replace Out of Bonds"); exception=TRUE; } sc->beg=0; sc->end=StrLen(sc->seq); sc->uncertain=exception?SDB_wrong:0; } StrDel(repl); StrDel(rng->seq); _ListDel(rng); } /************************************************************ ** Complements the sequence on the top of the calculator stack ************************************************************/ void SdbComplement () { int i; _List(SDBoChunk) res=_ListNew(SDBoChunk,_ListLen(*calc)); for (i=_ListLen(*calc)-1; i>=0; i--) { SDBoChunk* sc=&(*calc)[i]; SDBoChunk* d=&_ListApp(&res); /* reverse beg and end to indicate complement */ d->seq=sc->seq; d->beg=sc->end; d->end=sc->beg; } _ListDel(*calc); *calc=res; } /************************************************************ ** Pops the top sequence on the calculator stack ** and appends it to the one below ************************************************************/ void SdbJoin() { int i; SDBoChunk* d=_ListAppMany(calc-1,_ListLen(*calc)); for (i=0; i<_ListLen(*calc); i++) { SDBoChunk* sc=&(*calc)[i]; d->seq=sc->seq; d->beg=sc->beg; d->end=sc->end; d->uncertain=sc->uncertain; d++; } _ListDel(*calc--); } /*********************************************************** ** Applies shifts to the top of stack sequence ***********************************************************/ INT4 jobcnt=0; enum SDBeShiftOrg { SDB_NoShift, SDB_Beg, SDB_Both, SDB_End }; BOOL moveCertain; BOOL shiftedOut; BOOL ChunkRight(_List(SDBoChunk) l, int* c, BOOL certain) { int ll=_ListLen(l); int p=*c+1; if (p>=ll) return FALSE; if (certain) { if (p==ll-1 && ChunkUncertain(l+p)) return FALSE; while (ChunkUncertain(l+p)) { moveCertain=FALSE; p++; if (p>=ll-1) return FALSE; } } *c=p; return TRUE; } BOOL ChunkLeft(_List(SDBoChunk) l, int* c, BOOL certain) { int p=*c-1; if (p<0) return FALSE; if (certain) { if (p==0 && ChunkUncertain(l)) return FALSE; while (ChunkUncertain(l+p)) { moveCertain=FALSE; p--; if (p<0) return FALSE; } } *c=p; return TRUE; } BOOL ChunkMove(_List(SDBoChunk) l, int* chunk, INT4* pos, BOOL certain) { INT4 chunkLen=0; int llen=_ListLen(l); int c=*chunk; INT4 p=*pos; if (c<=llen && p>=ChunkLen(l+c)) { if (!ChunkRight(l,chunk,certain)) return FALSE; while (c=0 && p<0) { if (!ChunkLeft(l,chunk,certain)) return FALSE; while (c>=0) { chunkLen=ChunkLen(l+c); if (p>=0) break; if (!ChunkLeft(l,&c,certain)) { *chunk=c; *pos=p; return FALSE; } p+=chunkLen; } } *chunk=c; *pos=p; return moveCertain; } BOOL ChunkFind(_List(SDBoChunk) l, BOOL fromBeg, int* chunk, INT4* pos, BOOL certain) { int llen=_ListLen(l); if (!llen) return FALSE; if (fromBeg) *chunk=0; else { *chunk=llen; if (!ChunkLeft(l,chunk,certain)) return FALSE; *pos+=ChunkLen(l+*chunk); } if (ChunkMove(l,chunk,pos,certain)) return TRUE; else return *chunk==0 || *chunk==llen-1; } void SdbShift(INT4 runTime, INT4 org, INT4 beg, INT4 end) { _List(SDBoChunk) l=*calc; SDBoChunk* c; BOOL out=FALSE; int begChunk,endChunk,i; INT4 len=0; BOOL begComplemented,endComplemented; if (runTime) IargGetArgs("org|beg|end",&org, &beg, &end); if (org==SDB_NoShift || _ListLen(l)==0) return; moveCertain=TRUE; if (!ChunkFind(l,org!=SDB_End,&begChunk,&beg, TRUE)) { shiftedOut=TRUE; return; } if (!ChunkFind(l,org==SDB_Beg,&endChunk,&end, TRUE)) { shiftedOut=TRUE; return; } if (!moveCertain) { shiftedOut=TRUE; return; } /* trim beg of list */ i=begChunk; while (--i>=0) StrDel(l[i].seq); _ListCutMany(calc,0,begChunk); l=*calc; endChunk-=begChunk; /* trim end of list */ i=endChunk; while (++i<_ListLen(l)) StrDel(l[i].seq); _ListCutMany(calc,endChunk+1,_ListLen(l)-endChunk-1); l=*calc; /* store endchunk in case begChunk==endChunk */ c=&_ListLast(l); endComplemented=c->endbeg; end-=ChunkLen(c); /* end is end-relative */ /* trim begChunk */ c=&_ListFirst(l); begComplemented=c->endbeg; if (!begComplemented) { c->beg+=beg; if (c->beg<0) { c->beg=0; out=TRUE; } else { len=StrLen(c->seq); if (c->beg>=len) c->beg=len; } } else { c->beg-=beg; len=StrLen(c->seq); if (c->beg>len) { c->beg=len; out=TRUE; } else if (c->beg<0) c->beg=0; } /* trim endChunk */ c=&_ListLast(l); if (!endComplemented) { c->end+=end; len=StrLen(c->seq); if (c->endbeg) { c->end=c->beg; out=TRUE; } else if (c->end>len) { c->end=len; out=TRUE; } } else { c->end-=end; if (c->end>c->beg) { c->end=c->beg; out=TRUE; } else if (c->end<0) { c->end=0; out=TRUE; } } if (out) { /*printf("Shifted out\n");*/ shiftedOut=TRUE; } } /********************************************************** ** Pops the calculator stack, returning the popped ** sequence **********************************************************/ void complement(char* dest, char* src, int n) { static char complBase[] = { /* a b c d e f g h i j k l m n */ 't', 0, 'g', 'h', 0, 0, 'c', 'd', 0, 0, 'm', 0, 'k', 'n', /* o p q r s t u v w x y z */ 0, 0, 0, 'y', 's', 'a', 'a', 'b', 'w', 'x', 'r', 0 }; char* s=src+n-1; while (s>=src) { char c=*s--; if (c>'z') printf("!!!Not a nucleotide in sequence source"); if (c<'a') { if (c<'A'||c>'Z') printf("!!!Not a nucleotide in sequence source: %c\n",c); *dest++=complBase[c-'A']+'A'-'a'; } else *dest++=complBase[c-'a']; } } STRv SdbEval(INT4 runTime) { /* interpret top of stack , creating actual sequence */ STRv res=NULL; char* rs; int i; INT4 len=0; BOOL certain=TRUE; BOOL wrong=FALSE; /* pre-calculate sequence lenght */ for (i=0; i<_ListLen(*calc); i++) { SDBoChunk* sc=*calc+i; if (ChunkUncertain(sc)) { certain=FALSE; if (i>0 && i<_ListLen(*calc)-1) { /* if internal uncertain block*/ wrong=TRUE; break; } continue; } else if (!ChunkCheck(sc)) { wrong=TRUE; break; } len+=ChunkLen(sc); } if (!wrong) { /* now compute sequence */ res=StrBufNew(len); res->len=len; rs=Str(res); for (i=0; i<_ListLen(*calc); i++) { SDBoChunk* sc=&(*calc)[i]; INT4 lenAdd; if (!ChunkUncertain(sc)&& ChunkCheck(sc)){ lenAdd=sc->end-sc->beg; if (lenAdd<0) { lenAdd=-lenAdd; complement(rs,Str(sc->seq)+sc->end,lenAdd); } else strncpy(rs,Str(sc->seq)+sc->beg,lenAdd); rs+=lenAdd; } /* delete sequence chunk */ StrDel(sc->seq); } *rs='\0'; _ListDel(*calc); calc--; } else { if (!certain) printf("!!!Uncertainty in the middle of the location"); else printf("!!!Wrong location definition"); SdbPop(); res=StrNew(); } if (runTime) IcaReturn("strv",res); else return res; } #ifdef XX /****** SeqTranslate ********************************************************* ** ** Translates a DNA sequence into protein; ** The translation is controlled by the translation table, the list ** of translation exceptions and the list of codon changes to be ** applied to the translation table. ** ** INPUT: * address dna sequence object [R] ** * start position (begin=1) [R] ** * translation table [R] ** * array of translation exception descriptions [R] or NULL ** * array of codon changes to be applied to the ** translation table [R] or NULL ** IMPLICIT: ** ** RETURNS: translated protein sequence ** NULL if there was a problem */ SEQo *SdbTranslate (SEQo *ntSeq, INT4 start, SEQoTranslTable *translTable, SEQoTranslExcept *translExcept, SEQoTranslCodon *translCodon) { SEQo *prot; INT4 k, l; dnaSeq = dnaseq->seq + startPos; peptlen = (dnaseq->len - startPos) / 3; if (peptlen <= 0) _ErrRet3 (e__seqillegallength, seq->len, start); /* modify translation table, if codon list is not empty */ if (tCodon) tTable = SeqTranslTableEdit (tTable, tCodon); SeqNew (protSeq); SeqAlloc (*protseq, (ntSeq->len - start)/3 + 100); for (k=start-1, l=0; k < dna->len;) { /* deal with possible translation exception */ if (tExceptNext && k == tExceptNext->start) { prot->seq[l++] = tExceptNext->aa; k += tExcept->length; tExceptNext->isDone = 1; tExceptNext = (++tExceptNext)->aa ? tExceptNext : NULL; } else if (!k) { /* first codon */ if ((aa = SeqTranslateCodon (seq, tTable, 1)) == 'M' prot->seq[l++] = aa; else { global_before_f-- ; } else prot->seq[l++] = SeqTranslateCodon (&dna->seq[k], tTable, 0); } if (codon) /* remove edited translation table again */ free (tTable); SeqRemoveStop (prot); sprintf prot->name, "%s_aa", dna->name); return prot; } SdbTranslate (char *triplett, INT4 isStartCodon, SEQoTRANSLTABLE *transTable) { static char *ntAmbigList[26]={ "A","CGT","C","AGT","","","G","ACT","", "","GT","","AC","GATC","","","","AG", "CG","T","U","ACG","AT","ACGT","CT",""}; static INT4 isInit=0, order[26]; INT4 k, l, m; char b1, b2, b3, aa, aaPrev, **ntList[3]; if (isInit) { order['T'] = 0; order['C'] = 1; order['A'] = 2; order['G'] = 3; isInit = 1; } aaTrans = isStartCodon ? transTable->saa : transTable->aa; /* The triplett might contain ambiguity codes: assign to each base in the triplett the list of possible nucleotides */ for (k=0; k<3; k++) { ntList[k] = ntAmbigList[triplett[k]]; } /* get all indices into the aa transl list for all combinations */ aa = 'X'; for (i=0,k=0; (b1=ntList[k]); k++) for (l=0; (b1=ntList[l]); l++) for (m=0; (b1=ntList[m]); m++) { aa = aaTrans[order[b1]*16 + order[b1]*4 + order[b1]]; if (aa != aaPrev) { aa = 'X'; break; aaPrev = aa; } return aa; } #endif STRv SdbGetFeatureSequence(INT4 runTime, STRv seqExpr, STRv db, INT4 shiftOrg, INT4 left, INT4 right) { STRv seq; SEQo* curr; static ICAoJOB* job=NULL; char *start; if (runTime) IargGetArgs("expr|db|shift|left|right", &seqExpr, &db, &shiftOrg, &left, &right); if (jobcnt==20808) { printf("--------------------------------------here\n"); } /* extract current sequence as STRv */ curr=SeqGetCurrent(); ASSERT (curr, "no curr sequence"); currSeq=StrCpyS(curr->seq); currDb=StrCpy(db); SeqSetCurrent(curr); /* calculate feature expression */ if (!job) { ICAoSYNTAX* syntax=(ICAoSYNTAX*)LibObjByName("syntax","ftseq"); job=IcaCreateJob(syntax); } else IcaJobNext(job); IcaJobSetString(job,Str(seqExpr)); start = SmEqs (_Str (db), "swissprot") ? "swissrange" : "sequence"; exception|=!IcaDoJob(job, start); if (calc>calcStack) exception=TRUE; if (!exception) { shiftedOut=FALSE; SdbShift(FALSE,shiftOrg,left,right); exception=shiftedOut; } if (!exception) seq=SdbEval (FALSE); else { /* clean up */ exception=FALSE; /*printf("%s", Str(seqExpr));*/ while (calc>=calcStack) SdbPop(); seq=StrNew(); } if (runTime) IcaReturn ("strv", seq); StrDel(seqExpr); StrDel(db); StrDel(currSeq); StrDel(currDb); jobcnt++; return seq; } /**API* function ************************************************************** ** ** returns the sequence of the entry as sequence object. The function ** assumes that the sequence is represented by the data-field with ** the short name "seq". ** ** INPUT: [W] the entry object ** ** RETURNS: sequence object ** NULL: entry does not have the "seq" data-field */ SEQo *SdbGetEntrySeq (ENTRYv entry) { SLBo *lib; FIELDv field; Int4 k; lib = EntryGetLib (entry); for (k=0; (field=LibNextField (lib, &k));) if (SmEqs ("seq", FieldGetShortName (field))) break; if (!field) return NULL; EntryGetField (entry, field, NULL); return SeqGetCurrent(); } INT4 SdbFunctions() { IcaSetFunction("SdbEval", (FUNC)SdbEval); IcaSetFunction("SdbPop", (FUNC)SdbPop); IcaSetFunction("SdbPush", (FUNC)SdbPush); IcaSetFunction("SdbRetrieve", (FUNC)SdbRetrieve); IcaSetFunction("SdbChunk",(FUNC) SdbChunk); IcaSetFunction("SdbFeature", (FUNC)SdbFeature); IcaSetFunction("SdbReplace", (FUNC)SdbReplace); IcaSetFunction("SdbComplement", (FUNC)SdbComplement); IcaSetFunction("SdbJoin", (FUNC)SdbJoin); IcaSetFunction("SdbGetFeatureSequence", (FUNC)SdbGetFeatureSequence); return 1; } unction("SdbEval", (FUNC)SdbEval); srs/src/seqdb.h #define _SDB_H struct SEQo *SdbGetEntrySeq (struct ENTRYo *entry); void SdbFunctions(); STRv SdbGetFeatureSequence(INT4 runTime, STRv seqExpr,STRv db,INT4 shiftOrg,INT4 left, INT4 right); #endif ", (FUNC)SdbFeature); IcaSetFunction("SdbReplace", (FUNC)SdbReplace); IcaSetFunction("SdbComplement", (FUNC)SdbComplement); IcaSetFunction("SdbJoin", (FUNC)SdbJoin); IcaSetFunction("SdbGetFeatureSequence", (FUNC)SdbGetFeatureSequence); return 1; } unction("SdbEval", (Fval); srs/src/seqlib.c char seqlib_srs_ID[] = "$Id: seqlib.c,v 1.2 1996/05/06 19:20:52 etzold Exp $"; /* ** ** $RCSfile: seqlib.c,v $ ** $Revision: 1.2 $ ** $Date: 1996/05/06 19:20:52 $ ** $Author: etzold $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.x Copyright by Thure Etzold ** ** Author: Gerald Schaefer ** EMBL, Meyerhofstrasse 1 ** D-69012 Heidelberg, Germany ** Tel: 06221 387372 ** Email: schaefer@embl-heidelberg.de ** ** ** Requires: list,expr,stack ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description sequence computation using generic list ** =========== ** ** Global Parameters: ** "printf" ** "writeFOSN" ** "shiftbeginpos" ** "shiftendpos" ** "isshiftbeginrelend" ** "isshiftendrelbegin" ** "takeuncompletefeature" ** "takeuncompleteshiftfeature" ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* #define TRACE #define DUMMY #define TRACE1 */ #include #include #include #include #include #include "message.h" #include "sm.h" #include "lst.h" #include "futil.h" #include "par.h" #include "id.h" #include "library.h" #include "entry.h" #include "seq.h" #include "query.h" #include "seqlib.h" #define _SRS #define _SLB #define _CONSTANTS #include SRSINCLUDE #define vabs(x) ((x)<0 ? -(x) : (x)) #define NAMELEN 40 enum slbfile_type {SLBxNORMAL=0, SLBxGCG7, SLBxGCG8, SLBxGCG8_1}; typedef struct STKo { void *a; }STKo; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** external, global and module wide variables */ extern FILE *protokoll; ENTRYo *global_entry; SEQo *seqCurr = NULL; /* remembers, if entry sequence was already read */ SEQo *featureSeq = NULL; SEQo *seqRangeList = NULL; static SLBoFEATURE feature = { 0, 0, 1, NULL, NULL, NULL, 0, NULL, NULL, NULL}; static FILE *file=NULL; static SMoBUFF *featureBuff=NULL; INT4 global_before_f = 0; INT4 global_after_f = 0; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** static functions */ static INT4 join(STKo *parameter_stack, STKo *eval_stack); static INT4 complement(STKo *parameter_stack, STKo *eval_stack); static INT4 replace(STKo *parameter_stack, STKo *eval_stack); static INT4 one_of(STKo *parameter_stack, STKo *eval_stack); static void SlbInitFeature (SLBoFEATURE *feature); static void SlbJoinList(); static void SlbComplementList(); static void SlbReplaceList(char *replace); static INT4 SlbInsert (INT4 bpos, INT4 epos); static INT4 SlbSetAccno(char *acc); static INT4 SlbShiftAndCheck(); static INT4 SlbEvaluate(); static void SlbWriteFosn (SEQo *seq); static SEQo *SlbRetrieveAccNo (char *accno); static char *SlbCurrEntryName (); typedef struct FUNC_DESC_ { char func_name[20]; INT4 (*func) (); } FUNC_DESC; #define MAXFUNC 4 FUNC_DESC func_table[MAXFUNC] = { { "join", join }, { "complement", complement }, { "replace", replace }, { "one-of", one_of } }; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** default function for printing lines */ static INT4 SlbPrintF (char *formatStr, ...) { va_list ap; va_start (ap, formatStr); vfprintf (file, formatStr, ap); va_end (ap); if (formatStr[strlen (formatStr) -1] != '\n') fprintf (file, "\n"); return 1; } /****** SlbGetCurrEntryName *************************************************** ** ** Prints name entry that is currently processed. ** ** INPUT: ** IMPLICIT: ** global_entry (ENTRYo *) [R] ** ** RETURNS: */ static char *SlbGetCurrEntryName () { return EntryGetFullName (global_entry); } /****** SlbEntryPrint ********************************************************* ** ** prints a single sequence entry using various options; function needs ** to know how many entries have to be printed and are currently printed ** in order to decide if the output file (if any) has to be opened or ** closed. ** ** INPUT: entry object [R] ** set Name (for constructing output file name) [R] ** number of entries to print in whole list [R] ** number of current entry [R] ** IMPLICIT: ** ** RETURNS: */ void SlbEntryPrint (ENTRYo *entry, char *setName, int entryN, int entryCurrN) { SLBoFEATURE *feature; SEQo *seq = NULL; char *fileExt; INT4 errCode, seqFormat, (*print)(char*,...); switch (tolower (ParGetStr ("seqFormat")[0])) { case 'p': seqFormat = SEQxPIR; fileExt = ".pir"; break; case 'e': seqFormat = SEQxEMBL; fileExt = ".dat"; break; case 's': seqFormat = SEQxSWISS; fileExt = ".dat"; break; case 'g': seqFormat = SEQxGCG; fileExt = ".gcg"; break; case 'f': seqFormat = SEQxFASTA; fileExt = ".fas"; break; } /* ** the next deals with the file name... part of which may be specified by ** user and open the file ...if not already open */ if (ParGetNum ("printToFile")) { char *tmp, *outFileName, outDirName[FILxXNAM+1], fileName[FILxXNAM+1]; ParDefFunction ("printf", (INT4 (*)()) SlbPrintF); outFileName = ParGetStr ("outFileName"); if ((tmp = ParGetStr ("outDirName"))) sprintf (outDirName, "%s/", tmp); else *outDirName = '\0'; if (!entryCurrN && seqFormat != SEQxGCG) { if (outFileName && *outFileName) sprintf (fileName, "%s%s", outDirName, outFileName); else sprintf (fileName, "%s%s%s", outDirName, setName, fileExt); } else if (seqFormat == SEQxGCG) { if (entryN == 1 && outFileName && *outFileName) sprintf (fileName, "%s%s", outDirName, outFileName); else sprintf (fileName, "%s%s%s", outDirName, entry->entry_nm, fileExt); } if (*fileName) { file = FilOpenW (fileName, &errCode); _ErrMsg2 (errCode, fileName); } } /* ** print text (annotation) */ print = (INT4 (*)(char*,...)) ParGetFunction ("printf"); if (ParGetNum ("printText")) EntryPrint (entry); else if (ParGetNum ("parSetFields")) { print ("entry: %s \n", entry->full_nm); EntryPrintFields (entry); } else if (seqFormat != SEQxFASTA) print ("entry: %s \n", entry->full_nm); /* ** print data (sequence) */ if (ParGetNum ("printData")) { if (IdIsSub (entry->id)) errCode = SlbGetFeature (entry, &seq, &feature); else errCode = SlbGetSequence (entry, &seq); _ErrIf (errCode) _ErrMsg2 (e__failureinslbgetx, entry->full_nm); else { switch (seqFormat) { case SEQxPIR: SeqWritePIR (seq, entry->entry_nm, 0, print); break; case SEQxEMBL: SeqWriteEMBL (seq, ParGetNum ("printText") ? NULL : EntryGetName (entry), print); break; case SEQxSWISS: SeqWriteSwiss (seq, entry->entry_nm, print); break; case SEQxGCG: SeqWriteGCG (seq, entry->entry_nm, print); break; case SEQxFASTA: SeqWriteFasta (seq, entry->entry_nm, print); break; } } } /* ** close file */ if (file && (entryCurrN == entryN - 1 || seqFormat == SEQxGCG)) { fclose (file); file = NULL; /* set back to default value /stdout/ */ } } /****** SlbGetNamedFunction *************************************************** ** ** looks for the named function in the local function table ** ** INPUT: address of function name [R] ** IMPLICIT: ** ** RETURNS: address of function descriptor, if function exists, ** otherwise NULL */ static FUNC_DESC* SlbGetNamedFunction(char* name) { INT4 i; for (i=0; i */ static INT4 one_of(STKo *parameter_stack, STKo *eval_stack) { #ifdef xxx STKoSYM op; STKoSYM first; INT4 param_count = 0; INT4 rv=1; if (ParGetNum("discardoneof")) { _ErrRet(e__foundoneof); } /* ** auf dem Stack koennen Zahlen (pos) liegen oder es kann eine ** Parameterliste mit Ranges existieren !! */ while (StkPop(parameter_stack, &op) != e__eostack) { param_count++; /* printf("Parameter: %d\n", param_count); */ if (param_count==1) first = op; } if (param_count > 0) { rv = StkPush(eval_stack, first); _ErrRet2(rv, "when evaluating one-of"); } else { /* seqRangeList with ranges */ LstFirst ((void**)&seqRangeList); if (LstNext ((void**)&seqRangeList)) LstDeleteToEndOfList((void**)&seqRangeList); } #endif return 1; } /****** SlbExe **************************************************************** ** ** this function implements the operator EXE. ** Symbols are popped from the evaluation stack until the next ** function name is popped. If there are values on the stack, ** the values are pushed into a private parameter stack. If the ** function name is popped, the corresponding function is called ** and supplied with the parameter stack. ** ** INPUT: address of evaluation stack [R] ** IMPLICIT: ** reads the content of the evaluation stack ** writes the content of the parameter stack ** ** RETURNS: 1 on success ** e__doesnotexistfunction */ INT4 SlbExe (STKo *eval_stack) { /* pop symbols from eval_stack, if operator: execute them (not possible here!) if value: put it into private parameter_stack if variable: put it's value into private parameter_stack if functionname: execute function giving it a pointer to the private parameter_stack if OP_SEQ: nothing to do */ #ifdef xxx STKo private_stack; STKoSYM sym; FUNC_DESC *func_desc_ptr; float float_val; INT4 int_flag=1, rv=1; if (!StkIniSym(&private_stack, 20)) { _ErrRet2(e__allocfail, "in initialization of private parameter stack"); } while (1) { rv = StkPop(eval_stack, &sym); if (sym.any.code == STKxFNAME) { /* get function_description pointer ... */ func_desc_ptr = SlbGetNamedFunction(sym.var_name.name); /* ??? Should there be a number that decides what parameter list to use ? */ if (func_desc_ptr) rv = (func_desc_ptr->func) (&private_stack, eval_stack); else rv = e__doesnotexistfunction; _ErrIf(rv) { StkDelSym(&private_stack); _ErrRet2(rv, sym.var_name.name); } break; } switch (sym.any.code) { case 0: break; case STKxNAME: rv = StkPush(&private_stack, sym); _ErrIf(rv) { StkDelSym(&private_stack); _ErrMsg(rv); /* because _ErrRet does not print message */ _ErrRet(rv); } break; case STKxNUMBER: /* put value into private parameter stack */ case STKxFLOAT: case STKxINUM: case STKxFNUM: int_flag = 1; ExpGetVal(&sym,&float_val,&int_flag); ExpGetSym(&sym,float_val,int_flag); rv = StkPush(&private_stack, sym); _ErrIf(rv) { StkDelSym(&private_stack); _ErrMsg(rv); /* because _ErrRet does not print message */ _ErrRet(rv); } break; } } StkDelSym(&private_stack); #endif return 1; } /****** SlbOpAfter ************************************************************ ** ** this function implements the operator AFTER ( > ). ** An integer value is popped from the evaluation stack. ** Negative positions are rejected. ** Legal positions are made negative afterwards to mark the ** existence of the 'after' operator. ** The value is pushed onto the evaluation stack again. ** ** INPUT: address of evaluation stack [R] ** IMPLICIT: ** modifies the content of the evaluation stack ** ** RETURNS: 1 */ INT4 SlbOpAfter (STKo *eval_stack) { #ifdef xxx float val, ergval; INT4 int_flag=1; INT4 rv; if (!ParGetNum("takeuncompletefeature")) _ErrRet(e__operatorafternotallowed); else global_after_f = 1; rv = ExpPopVal(eval_stack, &val, &int_flag); if (!int_flag) _ErrRet2(e__illegalvalueonstack, val); /* negative positions must not exist, parser should signal error before */ if (val<0) _ErrRet(e__illegalposition); ergval = val>0 ? val : 1; /* default */ /* ** make ergval negative to use it later as a sign ** for the existence of after_f in range */ ergval = -ergval; ExpPushVal(eval_stack, ergval, int_flag); return rv; #endif } /****** SlbOpBefore *********************************************************** ** ** this function implements the operator BEFORE ( < ). ** An integer value is popped from the evaluation stack. ** Negative positions are rejected. ** Legal positions are made negative afterwards to mark the ** existence of the 'before' operator. ** The value is pushed onto the evaluation stack again. ** ** INPUT: address of evaluation stack [R] ** IMPLICIT: ** modifies the content of the evaluation stack ** ** RETURNS: 1 */ INT4 SlbOpBefore (STKo *eval_stack) { #ifdef xxx float op1val, ergval; INT4 int_flag=1; INT4 rv; if (!ParGetNum("takeuncompletefeature")) _ErrRet(e__operatorbeforenotallowed); else global_before_f = 1; rv = ExpPopVal(eval_stack, &op1val, &int_flag); if (!int_flag) _ErrRet2(e__illegalvalueonstack, op1val); /* negative positions must not exist, parser should signal error before */ if (op1val<0) _ErrRet(e__illegalposition); ergval = op1val>1 ? op1val : 1; /* default */ /* ** make ergval negative to use it later as a sign ** for the existence of before_f in range */ ergval = -ergval; ExpPushVal(eval_stack, ergval, int_flag); return rv; #endif } /****** SlbOpRange ************************************************************ ** ** this function implements the operator RANGE ( .. ). ** Two integer values are popped from the evaluation stack. ** A new sequence object is inserted into the seqRangeList, using ** the popped value as begin and end position. The accession number ** of the new sequence object is initially an empty string. ** If a position is negative it means that an operator (before, after) ** existed. Therefore a flag (before_f, after_f) is set TRUE in SlbInsert. ** ** INPUT: address of evaluation stack [R] ** IMPLICIT: ** modifies the content of the evaluation stack ** inserts a new sequence object into seqRangeList ** ** RETURNS: 1 on success, 0 otherwise */ INT4 SlbOpRange (STKo *eval_stack) { #ifdef xxx float val1, val2; INT4 int_flag=1; INT4 rv; rv = ExpPopVals(eval_stack, &val1, &val2, &int_flag); if (!int_flag) _ErrRet3(e__illegalvaluesonstack, val1, val2); if (!val1 || !val2) _ErrRet (e__rangewithundefval); if (vabs (val1) > vabs(val2)) _ErrRet(e__illegaldirectioninrange); /* Generate new range and insert it into list */ rv = SlbInsert((INT4) val1, (INT4) val2); return rv; #endif } /****** SlbOpMakeRange ******************************************************** ** ** this function implements the operator MAKERANGE ( .. ). ** One integer value gets popped from the evaluation stack. ** A new sequence object is inserted into the seqRangeList, using ** the popped value as begin and end position. The accession number ** of the new sequence object is initially an empty string. ** ** INPUT: address of evaluation stack [R] ** IMPLICIT: ** modifies the content of the evaluation stack ** inserts a new sequence object into seqRangeList ** ** RETURNS: 1 on success, 0 otherwise */ INT4 SlbOpMakeRange (STKo *eval_stack) { float op1val; INT4 int_flag=1; INT4 rv; #ifdef xxx #ifdef TRACE1 printf("Function *SlbOpMakeRange* called\n"); #endif rv = ExpPopVal(eval_stack, &op1val, &int_flag); if (!int_flag) _ErrRet2(e__illegalvalueonstack, op1val); if (op1val<=0) _ErrRet(e__illegalposition); #ifdef TRACE printf("computing range %d .. %d \n", (INT4)op1val, (INT4)op1val); #endif /* Generate new range and insert it into list */ rv = SlbInsert((INT4)op1val, (INT4)op1val); return rv; #endif } /****** SlbOpSelect *********************************************************** ** ** this function implements the operator SELECT ( . ). ** Two integer values are popped from the evaluation stack. ** The user is asked to specify a position between that positions. ** The user-specified or default position is pushed onto stack again. ** ** INPUT: address of evaluation stack [R] ** IMPLICIT: ** modifies the content of the evaluation stack ** ** RETURNS: 1 */ INT4 SlbOpSelect (STKo *eval_stack) { #ifdef xxx char answer[20]; float op1val, op2val, ergval, userval; INT4 int_flag=1; INT4 rv; rv = ExpPopVals(eval_stack, &op1val, &op2val, &int_flag); if (!int_flag) _ErrRet3(e__illegalvaluesonstack, op1val, op2val); ergval = op1val; /* default */ if (ParGetNum("interactiveselect")) { printf("what position do you want BETWEEN %d and %d [%d]: ", (INT4)op1val, (INT4)op2val, (INT4)ergval); gets(answer); if (strlen(answer) > 0) { if (sscanf(answer, "%f", &userval) == 1) { if (userval < op1val || userval > op2val) printf("** position too low or too high: default used !!\n"); else ergval = userval; } else printf("** illegal input: default used !!\n"); } } ExpPushVal(eval_stack, ergval, int_flag); return rv; #endif } /****** SlbOpCut ************************************************************** ** ** this function implements the operator CUT ( ^ ). ** Two integer values are popped from the evaluation stack. ** A new sequence object is inserted into the seqRangeList, using ** the popped values as begin and end position. Because there should ** be only a site specified, begin and end position must be adjacent. ** At the moment the end position is set according to begin position. ** The accession number of the new sequence object is initially an ** empty string. ** ** INPUT: address of evaluation stack [R] ** IMPLICIT: ** modifies the content of the evaluation stack ** inserts a new sequence object into seqRangeList ** ** RETURNS: 1 on success, 0 otherwise */ INT4 SlbOpCut (STKo *eval_stack) { #ifdef xxx char answer[20]; float val1, val2, ergval, userval; INT4 int_flag=1; INT4 rv; rv = ExpPopVals (eval_stack, &val1, &val2, &int_flag); if (!int_flag) _ErrRet3(e__illegalvaluesonstack, val1, val2); ergval = val1; /* default */ if (val2-val1 > 1 && ParGetNum("interactivecut")) { printf("after what position do you want to CUT %d..%d [%d]: ", (INT4)val1, (INT4)val2, (INT4)ergval); gets(answer); if (strlen(answer) > 0) { if (sscanf(answer, "%f", &userval) == 1) { if (userval < val1 || userval > val2-1) printf("** position too low or too high: default used !!\n"); else ergval = userval; } else printf("** illegal input: default used !!\n"); } } val1 = ergval; val2 = val1 + 1; /* the two positions must be adjacent */ /* Generate new sequence object and insert it into list */ rv = SlbInsert ((INT4)val1, (INT4)val2); if (rv) seqRangeList->cut_f = 1; /* set flag (site_flag) */ return rv; #endif } /****** SlbOpSetAccno ********************************************************* ** ** this function implements the operator SET_ACCNO ( : ). ** The accession number is popped from the evaluation stack. ** Modifies (sets) the accession number of the sequence object, ** that was last inserted into the seqRangeList. ** ** INPUT: address of evaluation stack [R] ** IMPLICIT: ** modifies the content of the evaluation stack ** modifies last inserted sequence object in seqRangeList ** ** RETURNS: 1 on success, 0 otherwise */ INT4 SlbOpSetAccno (STKo *eval_stack) { #ifdef xxx char accno[NAMELEN]; INT4 rv; rv = ExpPopVarname(eval_stack, accno); rv = SlbSetAccno (accno); return rv; #endif } /****** SlbPrintFeature ******************************************************* ** ** this function is used to concatenate all lines belonging to ** the same feature description in a database. After concatenating ** all lines into one string, the resulting string will be parsed ** and evaluated. ** ** INPUT: address of line in feature table [R] ** IMPLICIT: ** modifies the global featureline ** ** RETURNS: */ static void SlbPrintFeature(char *ln) { INT4 len; #if defined(TRACE) printf ("%s", ln); #endif memcpy (ln, " ", 2); /* blank FT */ len = strlen (ln); if (ln[ len-1 ] == '\n') ln[len-1] = '\0'; BuffCopyString (featureBuff, ln); } /**api* SlbMakeFeature ***************************************************** ** ** accesses the feature table of an entry from the sequence library ** and returns the evaluated sequence object; also returns a pointer ** to the global feature object, wherein translation exceptions and ** special codons may be stored. ** ** INPUT: buffer with the feature description [R] ** address of entry object [R] ** pointer to address of sequence object [W] ** pointer to address of feature description object [W] ** IMPLICIT: ** featureBuff (SMoBUFF *) [W] ** ** RETURNS: 1 on success, 0 otherwise */ INT4 SlbMakeFeature (SMoBUFF *featureBuff, ENTRYo *entry, SEQo *seq, SEQo **res_seq, SLBoFEATURE **featurePtr) { #ifdef xxx static SMoBUFF *buff=NULL; #ifdef xxx EXPo *expression; INT4 rv; char *tmp; if (!buff) buff = BuffNew (100); else BuffReset (buff); #ifdef xxx if (BuffSearch (featureBuff, "join(")) return 0; #endif global_entry = entry; /* needed in SlbSeqFromAccNo to get library name */ seqCurr = seq; /* entry sequence already read */ SlbInitFeature (&feature); if (featurePtr) *featurePtr = &feature; expression = (EXPo*) LibObjByName("expression", "embl_feature"); if (!expression) _ErrRet4(e__objnotfound, 5, "seqlib.c", "embl_feature"); ExpInit(expression); SlbListReset(); /* maybe at another place ??? */ /* ** ExpEval builds only a list structure (seqRangeList), that has ** to be evaluated later. The sequence of the entry was passed ** to SlbMakeFeature via the attribute "seq". ** After ExpEval parsing is already completely done and ** feature.transl_except points to one of maybe many translation ** exception objects in a list, if there exists one. */ BuffCopyString (buff, BuffGetPtr (featureBuff)+5); /* remove line code */ while ((tmp = BuffSearch (buff,"\nFT"))) strncpy(tmp," ",3); rv = ExpEval (BuffGetPtr (buff), "location", EXPxEVALUATE); if (rv == e__parsefail) rv = e__entryparsefail; _ErrRet2(rv, entry->entry_nm); rv = SlbShiftAndCheck(); _ErrMsg2(rv, entry->entry_nm); _ErrRet(rv); rv = SlbEvaluate(); _ErrRet2(rv, entry->entry_nm); /* ** the last inserted one is the RESULT ** move it to the result sequence list */ seqCurr = NULL; /* reset to initial state */ if (featureSeq) { LstMove ((void**) res_seq, (void**)&featureSeq); return 1; } else #endif return 0; #endif } /**API* SlbGetFeature ********************************************************* ** ** Retrives for the specified subentry, or sequence feature, the sequence ** and the address of an object that contains parts of the feature ** annotation. Function accesses the feature table of the ** original flat file and evaluates the feature location expression. ** ** INPUT: address of entry object [R] ** address of pointer to sequence object [W] ** address of pointer to feature description object [W] ** IMPLICIT: ** ** RETURNS: 1 if successful ** e__entryparsefail + ** 0 otherwise */ INT4 SlbGetFeature (ENTRYo *entry, SEQo **res_seq, SLBoFEATURE **featurePtr) { #ifdef xxx EXPo *expression; INT4 rv, (*printSave)(); SlbInitFeature (&feature); if (featurePtr) *featurePtr = &feature; expression = entry->lib->form->featureExpression; ExpInit(expression); SlbListReset(); global_entry = entry; /* ** goto begin of feature in entry */ rv=EntryOpenText(entry); EntryBeginSub(entry); while ( (rv = EntryNextSub (entry)) < entry->id->subentry_n) if (_ErrIs (rv) || rv == 0) _ErrRet2 (e__entryparsefail, entry->entry_nm); /* ** print feature to the feature buffer */ if (!featureBuff) featureBuff = BuffNew (1000); else BuffReset (featureBuff); printSave = ParGetFunction ("printf"); ParDefFunction ("printf", (INT4(*)()) SlbPrintFeature); EntryPrintSub (entry); /* copy feature to featureBuff */ ParDefFunction ("printf", printSave); /* reset print function */ /* ** ExpEval builds only a list structure (seqRangeList), that has ** to be evaluated later. The sequence of the entry has not ** been read yet. After ExpEval parsing is already completely ** done and feature.transl_except points to one of maybe many ** translation exception objects in a list, if there exists one. */ rv = ExpEval(BuffGetPtr (featureBuff), "location", EXPxEVALUATE); if (rv == e__parsefail) rv = e__entryparsefail; _ErrRet2(rv, entry->entry_nm); rv = SlbShiftAndCheck(); _ErrRet(rv); if (ParGetNum ("listFOSN") && !ParGetNum ("printData")) { SlbWriteFosn (seqRangeList); } else { rv = SlbEvaluate(); _ErrRet(rv); /* ** the last inserted one is the RESULT ** move it to the result sequence list */ if (featureSeq) { LstMove ((void**) res_seq, (void**)&featureSeq); return 1; } } #endif return 0; } /**api* SlbWriteFosn ********************************************************** ** ** writes list of features as extended FOSN file with begin and end ** positions within parent sequence, complement...join ** ** INPUT: address of sequence object [R] ** IMPLICIT: ** ** RETURNS: nothing */ static void SlbWriteFosn (SEQo *seq) { SEQo *joinSeq; char hexNumStr[20], l[133]; INT4 (*print)(); IdToStr (global_entry->id, hexNumStr); print = ParGetFunction ("printf"); /* ** check first if there is a sublist (-> join) and process that */ if (seq->sublist && ParGetNum ("fosnWithPos")) { joinSeq = seq->sublist; /* ** start with the last sequence if the WHOLE join must be complemented ** in that case all individual joined sequences must be complemented */ if (seq->compl_f) LstLast ((void **) &joinSeq); else LstFirst ((void **) &joinSeq); do { if (seq->compl_f) joinSeq->compl_f = !joinSeq->compl_f; if (!*joinSeq->name) sprintf (l, "%s:%s", global_entry->lib->nam, global_entry->entry_nm); else { sprintf (l, "%s", joinSeq->name); } sprintf (l, "%s Begin: %d End: %d", l, joinSeq->bpos, joinSeq->epos); if (LibIsDataType (global_entry->lib, "dna")) sprintf (l, "%s Strand: %c", l, joinSeq->compl_f ? '-' : '+'); sprintf (l, "%s Join: %s_%d", l, global_entry->entry_nm, global_entry->id->subentry_n); sprintf (l, "%s !Id: %s\n", l, hexNumStr); print (l); } while (seq->compl_f ? LstPrev ((void **) &joinSeq) : LstNext ((void **) &joinSeq)); } /* ** normal sequence */ else { sprintf (l, "%s", EntryGetGCGName (global_entry)); if (ParGetNum ("fosnWithPos")) { if (seq->part_len > 0) seq->bpos = seq->epos - seq->part_len + 1; else if (seq->part_len < 0) seq->epos = seq->bpos + -seq->part_len - 1; sprintf (l, "%s Begin: %d End: %d", l, seq->bpos, seq->epos); if (LibIsDataType (global_entry->lib, "dna")) sprintf (l, "%s Strand: %c", l, seq->compl_f ? '-' : '+'); sprintf (l, "%s Join: %s_%d", l, EntryGetName (global_entry), global_entry->id->subentry_n); } sprintf (l, "%s !Id: %s\n", l, hexNumStr); print (l); } } /**API* SlbNextSequence ******************************************************* ** ** 'Walks' to the next sequence in the file. Use "EntryOpenStream" to open ** the flat file. ** ** INPUT: address of entry object [W] ** IMPLICIT: ** ** RETURNS: 1 on success ** 0 if at the end of the file */ INT4 SlbNextSequence (ENTRYo *entry) { #ifdef xxx SRSoFILTYP *fileType=entry->lib->form->fil_t[1]; FILo *file=entry->file[1]; INT4 k; while (1) { if (SmXLoc (file->l, fileType->fsts, fileType->fstl, fileType->fstr) != -1) break; if (FilURead (file) == e__eof) return 0; } /* ** advance lines */ for (k=1; k < fileType->adv; k++) FilURead (file); entry->isDataBegin = 1; entry->fip[1] = file->crfdd; #endif return 1; } /**API* SlbGetSequence ******************************************************** ** ** Retrieves the sequence for specified entry. ** ** INPUT: address of entry object [R] ** address of pointer to sequence object [W] ** IMPLICIT: ** ** RETURNS: 1 on success ** 0 otherwise */ INT4 SlbGetSequence (ENTRYo *entry, SEQo **seqPtr) { #ifdef xxx SEQo *seq=NULL; SRSoFILTYP *fileType; FIP fipSave; INT4 isGetSeqLenOnly = ParGetNum ("getSeqLenOnly"), splitN; char name[50], dummy[10]; #if defined(TRACE) printf("SlbGetSequence: %d\n", sequence_count++); #endif if (entry->isDataBegin) entry->isDataBegin = 0; /* stream access - file pointer is positioned */ else if (!EntryOpenData (entry)) return 0; /* ** get the file type object and assume that the first line after the ** sequence title is a comment line only if a production "find" for ** the entry name is specified */ fileType = entry->lib->form->fil_t[ENTxDATA]; SeqSetRecordSeparator (fileType->type == SLBxGCG7 ? 1 : 0); /* gcg format for vms */ SeqFromLib (seqPtr, entry->file[ENTxDATA], (*fileType->find) ? fileType->find : NULL, /* scanf gets name */ fileType->exit, (*fileType->find ? 1 : 0) | /* no title line -> no comment ... */ (isGetSeqLenOnly ? 2 : 0)); /* ** GCG 8.1 if a sequence exceeds some size it is split into overlapping ** fragments, each 110000bp long with an overlap of 10000 ** sequence which is the continuation - a file is considered to be split ** if it has exactly the split size. */ if (fileType->type == SLBxGCG8_1 && sscanf ((*seqPtr)->name, "%[A-Z0-9]_%[0]", name, dummy) == 2) { strcpy ((*seqPtr)->name, name); fipSave = entry->fip[1]; if (isGetSeqLenOnly) (*seqPtr)->len -= 10000; else SeqHead (*seqPtr, 100000); while (1) { SlbNextSequence (entry); SlbGetSequence (entry, &seq); if (seq->len == 110000) { if (isGetSeqLenOnly) seq->len -= 10000; else SeqHead (seq, 100000); } if (isGetSeqLenOnly) (*seqPtr)->len += seq->len; else SeqCat (seqPtr, seq); if (seq->len != 100000) /* the last of the split subentries */ break; } entry->fip[1] = fipSave; } /* ** if the sequence is split into two files (GCG format) then get the next ** sequence which is the continuation - a file is considered to be split ** if it has exactly the split size. */ else if ((*seqPtr)->len && (*seqPtr)->len == fileType->gcgSplitSize) { fipSave = entry->fip[1]; SlbNextSequence (entry); SlbGetSequence (entry, &seq); if (isGetSeqLenOnly) (*seqPtr)->len += seq->len; else SeqCat (seqPtr, seq); SeqClr (&seq); entry->fip[1] = fipSave; } if (!*fileType->find) /* no title line -> no name either */ strcpy ((*seqPtr)->name, entry->entry_nm); #endif return 1; } /****** SlbJoinList *********************************************************** ** ** implements the join function of a sequence expression. ** Creates a new function object as first member of a local list. ** The current parameter list is assigned to the sublist pointer ** of the new function object. As there is no parameter list any more, ** the local list can be assigned to the (new) parameter list. ** ** INPUT: ** IMPLICIT: ** seqRangeList changes ** ** RETURNS: nothing */ static void SlbJoinList() { SEQo *local_list = NULL; if (SeqNew(&local_list)) { /*sprintf (local_list->name, "%s", global_entry->entry_nm);*/ strcpy(local_list->name, "JOIN"); /* ** no hashing if LstHashSearch or LstDelete... is never used */ LstAssign((void**)&local_list->sublist, (void**)&seqRangeList); LstAssign((void**)&seqRangeList, (void**)&local_list); } else printf("ERROR: JOIN object could not be created in SlbJoinList !\n"); } /****** SlbComplementList ***************************************************** ** ** implements the complement function of a sequence expression. ** Simply inverts the complement flag of the current sequence object ** in the seqRangeList. ** ** INPUT: ** IMPLICIT: ** inverts the complement flag of the current sequence object ** ** RETURNS: nothing */ static void SlbComplementList() { seqRangeList->compl_f = !seqRangeList->compl_f; } /****** SlbReplaceList ******************************************************** ** ** implements the replace function of a sequence expression. ** Simply sets the replace string of the current sequence object ** in the seqRangeList. ** ** INPUT: ** address of replace string [R] ** IMPLICIT: ** sets the replace string of the current sequence object ** ** RETURNS: nothing */ static void SlbReplaceList(char *replace) { seqRangeList->replace = (char*) malloc(strlen(replace) + 1); strcpy(seqRangeList->replace, replace); } /****** SlbInsert ************************************************************* ** ** inserts a new (current) subsequence object (range) into the ** "seqRangeList". ** The accession number of a sequence object is up to now initially ** set to an empty string, i.e. the accession number equals the ** accession number of the current entry. ** In case of the CUT operator the cut_f flag has to be set afterwards. ** ** INPUT: start position of subsequence [R] ** end position of subsequence [R] ** IMPLICIT: ** new sequence object in seqRangeList ** ** RETURNS: 1 on success, 0 otherwise */ static INT4 SlbInsert (INT4 bpos, INT4 epos) { if (!SeqNew(&seqRangeList)) return 0; if (bpos<0) { seqRangeList->before_f = 1; seqRangeList->bpos = -bpos; } else { seqRangeList->before_f = 0; seqRangeList->bpos = bpos; } if (epos<0) { seqRangeList->after_f = 1; seqRangeList->epos = -epos; } else { seqRangeList->after_f = 0; seqRangeList->epos = epos; } return 1; } /****** SlbSetAccno *********************************************************** ** ** sets accession number of last (current) sequence object in the ** seqRangeList. The accession number of a sequence object is initially ** set to an empty string, i.e. the accession number equals the ** accession number of the current entry. ** ** INPUT: address of accession number [R] ** IMPLICIT: ** ** RETURNS: 1 on success, 0 otherwise */ static INT4 SlbSetAccno(char *acc) { if (seqRangeList) strcpy(seqRangeList->accno, acc); else { _ErrMsg(e__noseqinlist); return 0; } return 1; } /****** SlbModifyBegin ******************************************************** ** ** modifies the begin positiom of the specified sequence object. ** If an illegal position (<1) would result, an error is ** reported. ** ** INPUT: address of a sequence object [R] ** delta for shift [R] ** IMPLICIT: ** ** RETURNS: 1 on success, 0 otherwise */ static INT4 SlbModifyBegin(SEQo *range, INT4 delta) { if (range) if (range->bpos + delta > 0) range->bpos += delta; else { if (!ParGetNum("takeuncompleteshiftfeature")) { _ErrRet2 (e__shiftseqisfrag, SlbGetCurrEntryName ()); } else range->bpos = 1; } else { _ErrMsg(e__noseqinlist); return 0; } return 1; } /****** SlbModifyEnd ********************************************************** ** ** modifies the end positiom of the specified sequence object. ** If an illegal position (<1) would result, an error is ** reported. ** ** INPUT: address of a sequence object [R] ** delta for shift [R] ** IMPLICIT: ** ** RETURNS: 1 on success, 0 otherwise */ static INT4 SlbModifyEnd(SEQo *range, INT4 delta) { if (range) if (range->epos + delta > 0) range->epos += delta; else { if (!ParGetNum("takeuncompleteshiftfeature")) { _ErrRet2 (e__shiftseqisfrag, SlbGetCurrEntryName ()); } else range->epos = 1; } else { _ErrMsg(e__noseqinlist); return e__noseqinlist; } return 1; } /****** SlbSeqFromAccNo ******************************************************* ** ** gets the complete sequence string belonging to the entry with the ** specified accession number. To retrieve the sequence string the ** unique accession number is transformed into a unique id_name. ** If the sequence string is not already in the global list (seq) ** it will be retrieved by a query and the sequence object will be ** inserted into the global list. ** ** INPUT: address of accession number [R] ** IMPLICIT: ** global_entry (ENTRYo) [R] ** featureSeq (SEQo *) [W] ** ** RETURNS: address of the sequence object ** 0, in case of an error (message already printed) */ static SEQo *SlbSeqFromAccNo (char *accno) { ENTRYo *entry = global_entry; IDoENTRY *id; SEQo *seq = NULL; INT4 rv; char libEntryName[80] = "", *tmp; /* ** use external program to fetch the sequence by accession number */ if (*accno && (tmp = ParGetStr ("findAccNoCommand")) && *tmp) { if (!(seq = SlbRetrieveAccNo (accno))) return NULL; LstMove((void**)&featureSeq, (void**)&seq); } /* ** retrieve sequence if accno is specified ...no accession number means ** sequence of current entry which may not be read yet */ else { if (*accno) { #ifdef xx if (!(id = QryFindID (LibGetName (global_entry->lib, "full"), "acc", accno))) { /* _ErrMsg3(e__couldnotgetsequence,accno, global_entry->entry_nm); */ return NULL; } #endif entry = EntryOpen (id); } else if (seqCurr) return seqCurr; /* for SlbMakeFeature */ strcpy (libEntryName, EntryGetGCGName (entry)); /* ** search in the current sequence list ...to check if current entry's ** sequence is opened */ if (!LstHashSearch((void**)&featureSeq, libEntryName)) { rv = SlbGetSequence (entry, &seq); if (entry != global_entry) { EntryClose (&entry); } if (!rv) { LstDeleteAll ((void**)&seq); _ErrMsg2 (e__couldnotgetsequence, accno); return NULL; } LstMove((void**)&featureSeq, (void**)&seq); strcpy (featureSeq->name, libEntryName); } } return featureSeq; } /****** SlbRetrieveAccNo ****************************************************** ** ** Uses the command specified in "findAccNoCommand" to get entry by ** accession number. ** ** INPUT: address of accession number [R] ** IMPLICIT: ** ** RETURNS: address of the complete sequence string ** 0, in case of an error (message already printed) */ static SEQo *SlbRetrieveAccNo (char *accno) { SEQo *seq=NULL; INT4 rv; char command[256], fileName[256]; sprintf (command, ParGetStr ("findAccNoCommand"), accno, accno, accno); sprintf (fileName, ParGetStr ("inputSeqFile"), accno); system (command); rv = SeqReadAll (&seq, fileName); remove (fileName); return (rv && !_ErrIs (rv) )? seq : NULL; } /****** SeqReplace ************************************************************ ** ** ** INPUT: address of a sequence object [R] ** IMPLICIT: ** ** RETURNS: 1 on success ** e__incorrectlength */ INT4 SeqReplace (SEQo *new, SEQo *seq, char *replace, INT4 begPos, INT4 endPos, INT4 doInsert) { INT4 length; /* calculate length of output sequence */ length = strlen (seq->seq) + strlen (replace); if (!doInsert) length -= endPos - begPos + 1; new->seq = (char*) malloc (length + 1); new->len = length; if (doInsert) { strncpy (new->seq, seq->seq, begPos); new->seq[begPos] = '\0'; strcat (new->seq, replace); strcat (new->seq, &seq->seq[begPos]); /* endPos = begPos +1 */ } else { strncpy (new->seq, seq->seq, begPos - 1); new->seq[begPos - 1] = '\0'; strcat (new->seq, replace); strcat (new->seq, &seq->seq[endPos]); } if (new->len != strlen (new->seq)) _ErrRet1 (e__incorrectlength); return 1; } /****** SeqGetSubSeq ********************************************************** ** ** ** INPUT: address of a sequence object [R] ** IMPLICIT: ** ** RETURNS: 1 on success ** e__incorrectlength */ INT4 SeqGetSubSeq (SEQo *new, SEQo *seq, INT4 begPos, INT4 endPos) { INT4 length; length = endPos - begPos + 1; if (length <= 0) _ErrRet4 (e__seqwithneglen, SlbGetCurrEntryName (), begPos, endPos); new->seq = (char*) malloc (length + 1); strncpy (new->seq, &(seq->seq[ begPos-1 ]), length); new->seq[length] = '\0'; new->len = length; return 1; } /****** SlbEvalSequence ******************************************************* ** ** gets the sequence string belonging to the specified sequence object. ** If the sequence string is not already calculated the calculation ** will be done here using the complete sequence of an entry with ** an unique accession number and the begin and end of a partial ** sequence. At last the sequence string may be complemented. ** ** INPUT: address of a sequence object [R] ** IMPLICIT: ** ** RETURNS: 1 on success ** e__error, in case of an already printed error message ** e__postoohigh, position is greater than length of sequence */ static INT4 SlbEvalSequence (SEQo *new) { SEQoTranslExcept *tmp; SEQo *seq; INT4 rv; if (new->seq) return 1; /* fetch pointer (tmp) to complete sequence */ if ((seq = SlbSeqFromAccNo (new->accno)) == NULL) { _ErrMsg2 (e__couldnotgetsequence, new->accno); _ErrRet (e__error); } strcpy (new->name, seq->name); /* ** report error if begin and end positions are greater than sequence length */ /* to be fixed some time (te) */ if (feature.tExceptN > 1) { for (tmp=feature.tExcept; tmp->aa; tmp++) if (tmp->begin >= new->bpos && tmp->begin < new->bpos + new->epos) tmp->begin = tmp->begin - new->bpos + 1; } if (new->bpos > seq->len) { if (!ParGetNum ("takeuncompletefeature")) _ErrRet1 (e__postoohigh); else new->bpos = seq->len; } if (new->epos > seq->len) { if (!ParGetNum ("takeuncompletefeature")) _ErrRet1 (e__postoohigh); else new->epos = seq->len; } if (new->replace) rv = SeqReplace (new, seq, new->replace, new->epos, new->bpos, new->cut_f); else rv = SeqGetSubSeq (new, seq, new->bpos, new->epos); _ErrRet (rv); if (new->compl_f) SeqComplement (new); return 1; } /****** SlbShiftAndCheck ***************************************************** ** ** looks for the current values of the modification parameters (shift) and ** checks the global seqRangeList. In the seqRangeList there could be ** one sequence object generated by an expression like "135 .. 177" or ** one function object that has a sublist of sequence objects generated ** by an expression like "join(135 .. 177, complement(23 .. 97))". ** ** INPUT: ** IMPLICIT: ** ** RETURNS: 1 on success ** e__nothingtoevaluate ** e__invalidshift ** e__relbegandend ** */ static INT4 SlbShiftAndCheck() { SEQo *range; INT4 begPos=0, endPos=0, isBegRelEnd=0, isEndRelBeg=0; INT4 head_len=0, tail_len=0; INT4 rv; if (!seqRangeList) { _ErrRet2 (e__nothingtoevaluate, SlbGetCurrEntryName ()); } begPos = ParGetNum ("shiftbeginpos"); endPos = ParGetNum ("shiftendpos"); isBegRelEnd = ParGetNum ("isshiftbeginrelend"); isEndRelBeg = ParGetNum ("isshiftendrelbegin"); /* ** return error message for all combinations of ** modification parameters that should not occur */ if (isBegRelEnd && isEndRelBeg) _ErrRet2 (e__relbegandend, SlbGetCurrEntryName ()); else if (isBegRelEnd && begPos > endPos) _ErrRet5 (e__invalidshift, SlbGetCurrEntryName (), begPos, endPos, "end"); else if (isEndRelBeg && begPos > endPos) _ErrRet5 (e__invalidshift, SlbGetCurrEntryName (), begPos, endPos, "beg"); /* ** compute length of head or tail subsequence */ if (isEndRelBeg) head_len = endPos - begPos + 1; if (isBegRelEnd) tail_len = endPos - begPos + 1; seqRangeList->part_len = 0; /* whole sequence */ if (head_len > 0) seqRangeList->part_len = -head_len; if (tail_len > 0) seqRangeList->part_len = tail_len; range = seqRangeList->sublist; /* for shorter source code */ if (!range) { if (begPos && !isBegRelEnd) rv = SlbModifyBegin (seqRangeList, begPos); else if (begPos && isBegRelEnd) rv = SlbModifyBegin (seqRangeList, endPos - begPos); else if (endPos && !isEndRelBeg) rv = SlbModifyEnd (seqRangeList, endPos); _ErrRet (rv); /* already printed */ rv = SlbEvalSequence(seqRangeList); _ErrRet (rv); /* already printed */ } else { /* ** range is the sublist of a (Join-) function */ if (begPos && !isBegRelEnd) if (LstFirst((void**)&range)) rv = SlbModifyBegin (range, begPos); if (endPos && !isEndRelBeg) if (LstLast((void**)&range)) rv = SlbModifyEnd (range, endPos); if (LstFirst((void**)&range)) { do { rv = SlbEvalSequence(range); _ErrRet (rv); /* already printed */ } while (LstNext((void**)&range)); } else { _ErrRet(e__noparamlist); } } return 1; } /****** SlbEvaluate *********************************************************** ** ** evaluates the global seqRangeList. In the seqRangeList there could be ** one sequence object generated by an expression like "135 .. 177" or ** one function object that has a sublist of sequence objects generated ** by an expression like "join(135 .. 177, complement(23 .. 97))". ** ** INPUT: ** IMPLICIT: ** featureSeq (SEQo *) [W] ** ** RETURNS: 1 on success, 0 otherwise ** */ static INT4 SlbEvaluate() { SEQo *range; if (!seqRangeList) { _ErrMsg(e__nothingtoevaluate); return 0; } range = seqRangeList->sublist; /* for shorter source code */ if (!range) { /* the single range (seqRangeList) has been evaluated already */ SeqJoin (&featureSeq, seqRangeList); } else { /* ** range is the sublist of a (Join-) function. ** Make sure that all ranges in this list ** are already evaluated (SlbEvalSequence) ** before joining them (see SlbShiftAndCheck) */ if (LstFirst((void**)&range)) { SeqJoin (&featureSeq, range); } else { _ErrMsg(e__noparamlist); return 0; } } /* ** give sequence a name, and complement it if necessary */ if (seqRangeList->compl_f && seqRangeList->sublist) SeqComplement (featureSeq); strcpy (featureSeq->name, "RESULT"); strcpy (featureSeq->accno, "RESULT"); if (seqRangeList->part_len < 0) SeqHead(featureSeq, -seqRangeList->part_len); if (seqRangeList->part_len > 0) SeqTail (featureSeq, seqRangeList->part_len); return 1; } /**api* SlbListReset ********************************************************** ** ** deletes all local lists (seq, seqRangeList) created during evaluation ** ** INPUT: ** IMPLICIT: ** featureSeq (SEQo *) [W] ** ** RETURNS: 1 */ INT4 SlbListReset() { LstDeleteAll ((void**) &seqRangeList); if (featureSeq) LstDeleteAll ((void**) &featureSeq); return 1; } /****** SlbCitationDump **************************************** ** ** dumps all information belonging to the specified object. ** This is the print function set through LstManageClass ** for citationtype objects (see SlbCitationNew). ** ** INPUT: address of an object [R] ** file pointer [W] or NULL ** IMPLICIT: ** ** RETURNS: nothing */ static void SlbCitationDump (FILE *file, void *obj) { CITATION *tmp = (CITATION*)obj; if (!file) file = stderr; fprintf (file, "*** /CITATION %d\n", tmp->citationNum); } /**api* SlbCitationNew ************************************************* ** ** gets a new initialized citation object. ** The citationtype_id tells, if the class CITATION is already ** registered by the list module (LstManageClass). ** ** INPUT: pointer to address of citation object [W] ** IMPLICIT: ** ** RETURNS: */ INT4 SlbCitationNew (CITATION **citation) { static INT4 citationtype_id=0; if (!citationtype_id) LstManageClass (&citationtype_id, sizeof (CITATION), NULL, NULL, SlbCitationDump); return LstNew ((void **) citation, citationtype_id); } /****** SlbInitFeature ******************************************************** ** ** initializes global feature object ...functions that modify it can ** be called directly form the parser. ** For managing translation exceptions the list module has been used. ** Therefore, when resetting the feature object, an already existing ** list has to be destroyed. ** ** INPUT: feature object [W] ** IMPLICIT: ** ** RETURNS: */ static void SlbInitFeature (SLBoFEATURE *feature) { feature->tTableId = 0; /* id of translation table to be used */ feature->codonStartShifted = 0; /* normally there should be no shifting */ feature->codonStart = 1; /* default start position */ feature->isPseudo = 0; /* ** if lists of special treated codons, translation exceptions or ** citations exist, free the lists */ if (!feature->tCodon) { _addObj (feature->tCodon, feature->tCodonN, feature->tCodonAllocN, SEQoTranslCodon); } else if (feature->tCodonN > 1) feature->tCodonN = 1; feature->tCodon->aa = 0; if (!feature->tExcept) { _addObj (feature->tExcept, feature->tExceptN, feature->tExceptAllocN, SEQoTranslExcept); } else if (feature->tExceptN > 1) feature->tExceptN = 1; feature->tExcept->aa = 0; if (feature->citation) LstDeleteAll((void**)&feature->citation); feature->citation = NULL; /* no list */ if (!feature->gene) { feature->gene = BuffNew (20); feature->product = BuffNew (20); feature->note = BuffNew (20); } else { BuffReset (feature->gene); BuffReset (feature->product); BuffReset (feature->note); } } /**api* SlbSetCodonStart ***************************************************** ** ** ** ** INPUT: ** IMPLICIT: ** feature (SLBoFEATURE *) [W] ** ** RETURNS: 1 */ INT4 SlbSetCodonStart (PRSoST *tokList, FILo *file) { #ifdef xxx UINT4 tokval; char tokstr[20]; PrsUnSym (tokList, tokstr, &tokval); feature.codonStart = atoi (tokstr); #endif return 1; } /**api* SlbSetCodon ********************************************************** ** ** ** ** INPUT: ** IMPLICIT: ** feature (SLBoFEATURE *) [W] ** ** RETURNS: 1 */ INT4 SlbSetCodon (PRSoST *tokList, FILo *file) { #ifdef xxx SEQoTranslCodon *tCodon=&feature.tCodon[feature.tCodonN-1]; UINT4 tokval; char tokstr[20]; PrsUnSym (tokList, tokstr, &tokval); PrsUnSym (tokList, tokstr, &tokval); tCodon->aa = *tokstr; PrsUnSym (tokList, tCodon->codon, &tokval); _addObj (feature.tCodon, feature.tCodonN, feature.tCodonAllocN, SEQoTranslCodon); (++tCodon)->aa = 0; #endif return 1; } /**api* SlbSetTranslTable *************************************************** ** ** ** ** INPUT: ** IMPLICIT: ** feature (SLBoFEATURE *) [W] ** ** RETURNS: 1 */ INT4 SlbSetTranslTable(PRSoST *tokList, FILo *file) { #ifdef xxx UINT4 tokval; char tokstr[20]; PrsUnSym (tokList, tokstr, &tokval); feature.tTableId = atoi (tokstr); #endif return 1; } /**api* SlbSetTranslExcept **************************************************** ** ** ** ** INPUT: ** IMPLICIT: ** feature (SLBoFEATURE *) [W] ** ** RETURNS: 1 */ INT4 SlbSetTranslExcept (PRSoST *tokList, FILo *file) { #ifdef xxx SEQoTranslExcept *tExcept; UINT4 tokval; char tokstr[20], end[20]; tExcept = &feature.tExcept[feature.tExceptN-1]; PrsUnSym (tokList, tokstr, &tokval); /* ) */ PrsUnSym (tokList, tokstr, &tokval); /* aa */ tExcept->aa = *tokstr; PrsUnSym (tokList, end, &tokval); /* posend */ PrsUnSym (tokList, tokstr, &tokval); /* posbegin */ tExcept->begin = atoi (tokstr); tExcept->length = atoi (end) - tExcept->begin + 1; /* add new terminator */ _addObj (feature.tExcept, feature.tExceptN, feature.tExceptAllocN, SEQoTranslExcept); (++tExcept)->aa = 0; #endif return 1; } /**api* SlbSetCitation ***************************************************** ** ** ** ** INPUT: ** IMPLICIT: ** feature (SLBoFEATURE *) [W] ** ** RETURNS: 1 */ INT4 SlbSetCitation (PRSoST *tokList, FILo *file) { #ifdef xxx UINT4 tokval; char tokstr[20]; SlbCitationNew (&feature.citation); /* get new object */ PrsUnSym (tokList, tokstr, &tokval); feature.citation->citationNum = atoi (tokstr); #endif return 1; } /**api* SlbSetPseudo ********************************************************** ** ** Called during feature parsing. Sets the "pseudo gene" flag. ** ** INPUT: ** IMPLICIT: ** feature (SLBoFEATURE *) [W] ** ** RETURNS: 1 */ INT4 SlbSetPseudo (PRSoST *tokList, FILo *file) { feature.isPseudo = 1; return 1; } /**api* SlbSaveQualText ******************************************************* ** ** Called during feature parsing. Saves the text for certain qualifiers. ** ** INPUT: ** IMPLICIT: ** feature (SLBoFEATURE *) [W] ** ** RETURNS: 1 */ INT4 SlbSaveQualText (PRSoST *tokList, FILo *file) { #ifdef xxx UINT4 tokval; char text[500], qualName[30]; PrsUnSym (tokList, text, &tokval); PrsUnSym (tokList, qualName, &tokval); switch (tolower (qualName[0])) { case 'g': /* gene */ BuffCopyString (feature.gene, text); break; case 'p': /* product */ BuffCopyString (feature.product, text); break; case 'n': /* note */ BuffCopyString (feature.note, text); break; default: _ErrExit2 (e__unknownoption, qualName); } #endif return 1; } ist, FILo *file) { #ifdef xxx UINT4 tokval; char text[500], qualName[30]; PrsUnSym (tokList, text, &tokval); PrsUnSym (tokList, qualName, &tokval); switch (tolower (qualName[0])) { case 'g': /* gene */ BuffCopyString (feature.gene, text); break; case 'p': /* product */ BuffCopyString (feature.product, text); break; case 'n': /* note */ srs/src/seqlib.h ** ** $RCSfile: seqlib.h,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:17:19 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** */ typedef struct { char *manager; /* the first two attributes are necessary */ INT4 type_id; /* for all objects to be managed by the list module */ INT4 citationNum; } CITATION; typedef struct SLBoFEATURE { INT4 tTableId; INT4 codonStartShifted; /* set during translation */ INT4 codonStart; /* from the databank */ struct SEQoTranslCodon *tCodon; /* List of special codon translations */ INT4 tCodonN; INT4 tCodonAllocN; struct SEQoTranslExcept *tExcept; /* List of transl_except */ INT4 tExceptN; INT4 tExceptAllocN; CITATION *citation; /* List of citations (numbers) */ INT4 isPseudo; /* only for CDS features */ SMoBUFF *gene; SMoBUFF *product; SMoBUFF *note; } SLBoFEATURE; #ifndef _SEQo typedef struct SEQo *dummytointroducestructtagSEQoinseqlib; typedef struct ENTRYo *dummytointroducestructtagENTRYoinseqlib; #endif INT4 SlbMakeFeature (SMoBUFF *featureBuff, struct ENTRYo *entry, struct SEQo *entry_seq, struct SEQo **res_seq, SLBoFEATURE **featurePtr); INT4 SlbGetFeature (struct ENTRYo *entry, struct SEQo **res_seq, SLBoFEATURE **featurePtr); INT4 SlbGetSequence(struct ENTRYo *entry, struct SEQo **res_seq); INT4 SlbListReset(); INT4 SlbNextSequence (struct ENTRYo *entry); ruct SEQo *dummytointroducestructtagSEQoinseqlib; typedef struct ENTRYo *dummytointroducestructtagENTRYoinseqlib; #endif INT4 SlbMakeFeature (SMoBUFF *featureBuff, struct ENTRYo *entry, struct SEQo *entry_seq, struct SEQo **res_seq, SLBoFEATURE **featurePtr); INT4 SlbGetFeature (struct ENTRYo *entry, struct SEsrs/src/set.c char set_ID[] = "$Id: set.c,v 1.8 1997/03/03 18:20:51 srs Exp $"; /* ** ** $RCSfile: set.c,v $ ** $Revision: 1.8 $ ** $Date: 1997/03/03 18:20:51 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.0 Copyright by Thure Etzold ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** 69012 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** Requires: file, sm, message ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** functions for manipulating sets of IDs ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include "message.h" #include "lst.h" #include "sm.h" #include "strv.h" #include "futil.h" #include "id.h" #include "entry.h" #include "set.h" #include "library.h" #define _SRS #define _SLB #include SRSINCLUDE #define SETxNOCPY 0 #define SETxNULL 4294967295U /* long with all bits turned ON */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** macro for comparing entry ID's - IDs are BIG-endian on all operating ** systems! ie, last byte of IDs are compared first, then second last... */ #define CMP(a,b,cmp,len) {\ register INT4 _i;\ for (_i = (len)-1; _i >= 0; _i--) {\ if (((cmp) = (a)[_i] - (b)[_i]) != 0) break;\ }} /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** macro to copy sets */ #define _SetCopyIds(b, a1, a2, len)\ len = (unsigned long) a2 - (unsigned long) a1;\ _BuffCopyNChars (b, a1, len) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** macro inits string buffer */ #define _SetInitBuff(b)\ if (!buff) \ buff = BuffNew (2000);\ else\ BuffReset (buff) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of static functions */ static void SetInit (void *obj); static void SetKill (void *obj); static void SetDump (FILE *file, void *obj); static IDPTR SetOr (IDPTR a, IDPTR b, INT4 an, INT4 bn, INT4 *cn, INT4 id_z); static IDPTR SetNot (IDPTR a, IDPTR b, INT4 an, INT4 bn, INT4 *cn, INT4 id_z); static IDPTR SetAnd (IDPTR a, IDPTR b, INT4 an, INT4 bn, INT4 *cn, INT4 id_z); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** declaration of global or module wide variables */ static SMoBUFF *buff=NULL; static SETo *set=NULL; /**api* SetDump ************************************************************** ** ** dumps all information belonging to the specified object. ** This is the print function set through LstManageClass ** for set_type objects (see SetNew). ** ** INPUT: address of an object [R] ** file pointer [W] or NULL ** IMPLICIT: ** ** RETURNS: nothing */ static void SetDump (FILE *file, void *obj) { SETo *tmp = (SETo*)obj; if (!file) file = stderr; fprintf (file, "set *%s* with %d entries\n", tmp->nam, tmp->n); } /****** SetInit ************************************************************** ** ** initializes the specified object. ** This is the init function set through LstManageClass ** for set_type objects (see SetNew). ** ** INPUT: address of an object [R] ** IMPLICIT: ** ** RETURNS: nothing */ static void SetInit (void *obj) { SETo *tmp = (SETo*)obj; tmp->id_p = NULL; /* dummy values */ tmp->queryStr = NULL; tmp->tmp_f = FALSE; tmp->anal_f = 0; tmp->n = 0; tmp->idType = NULL; tmp->allocN = 0; tmp->isDb = 0; } /****** SetKill ************************************************************** ** ** deletes the specified object. ** This is the delete function set through LstManageClass ** for set_type objects (see SetNew). ** ** INPUT: address of an object [R] ** IMPLICIT: ** ** RETURNS: nothing */ static void SetKill (void *obj) { SETo *tmp = (SETo*)obj; if (tmp->id_p) free (tmp->id_p); if (tmp->queryStr) StrDel (tmp->queryStr); } /**api* SetNew **************************************************************** ** ** Creates a new set with a unique name used as identifier. ** If called with option "temp" then a unique name is created and ** in case the address of set name is not NULL copied there. ** Issues a message if set with specified name exists already. **

    ** A set can be deleted with SetDelete. SetClean deletes all ** sets created with "temp". ** Use SetGet to obtain an existing set by name. ** ** INPUT: set name [W] or NULL ** option: "temp" (or NULL) [R] ** IMPLICIT: ** set (SETo *) [W] ** ** RETURNS: address of new set ** NULL: specified set name is alredy in use */ SETo *SetNew (char *setName, char *opt) { static INT4 setclass_id=0; static INT4 setN=0; char tmpName[SETxXNAM]; if (!setclass_id) { LstManageClass (&setclass_id, sizeof (SETo), SetInit, SetKill, SetDump); } if (opt && opt[0] == 't') { /* "temp" */ sprintf (tmpName, "tmpset_%d", ++setN); if (setName) strcpy (setName, tmpName); } else if (setName) { strcpy (tmpName, setName); SmEdit (tmpName, SMxLOWCASE); } if (!SetTestName (tmpName)) { _ErrMsg2 (e__setnotuniqname, tmpName); return NULL; } LstNewNamed ((void **) &set, setclass_id, tmpName); set->tmp_f = (opt && opt[0] == 't') ? TRUE : FALSE; return set; } /**api* SetTestName *********************************************************** ** ** checks if set-name has not been previously defined or if name is ** reserved - issues a message if the case; ** ** INPUT: address of name [R] ** IMPLICIT: ** set (SETo *) [R] ** ** RETURNS: 1 if new ** 0 if not */ INT4 SetTestName (char *setName) { LINKo *link; INT4 context; char tmpName[80]; strcpy (tmpName, setName); SmEdit (tmpName, SMxLOWCASE); if (LstHashSearch ((void **) &set, tmpName)) return 0; /* for (context=0; (link = LibNextLink (&context)); ) if (SmEqs (tmpName, link->nam1) || SmEqs (tmpName, link->nam2)) return 0; */ return 1; } /**api* SetSetIsDb *********************************************************** ** ** Sets a flag in the set objects that it now represents an entire data ** bank. ** ** INPUT: set object [W] ** flag: TRUE or FALSE [R] ** IMPLICIT: ** set (SETo *) [R] ** ** RETURNS: */ void SetSetIsDB (SETo *set, Int4 flag) { set->isDb = flag; } /**api* SetIsDb *********************************************************** ** ** Returns 'true' if the set represents an entire databank. ** bank. ** ** INPUT: set object [W] ** IMPLICIT: ** ** RETURNS: 1 or 0 */ INT4 SetIsDB (SETo *set) { return set->isDb; } /**api* SetGetName ************************************************************ ** ** Returns the name of the set. ** ** INPUT: set object [W] ** IMPLICIT: ** ** RETURNS: set name */ char *SetGetName (SETo *set) { return set->nam; } /**API* SetGet ************************************************************* ** ** Searches for a set with specified name and returns its address ** (case insensitive). ** ** INPUT: set name [R] ** IMPLICIT: ** set (SETo *) [R] ** ** RETURNS: address of set object ** NULL if not found */ SETo *SetGet (char *setName) { char tmpName[80]; strcpy (tmpName, setName); SmEdit (tmpName, SMxLOWCASE); if (!LstHashSearch ((void **) &set, tmpName)) return NULL; if (set->anal_f && set->idType != NULL) /* list libraries */ SetLibStat (set); return set; } /**API* SetSize ************************************************************* ** ** Returns the size of the set (number of IDs) with the specified name. ** ** INPUT: set name [R] ** IMPLICIT: ** ** RETURNS: number of entries in the set */ INT4 SetSize (char *nam) { SETo *set; if (!(set = SetGet (nam))) return 0; else return set->n; } /**API* SetGetSize ************************************************************ ** ** Returns the size of the set (number of IDs). ** ** INPUT: set object [R] ** IMPLICIT: ** ** RETURNS: number of entries in the set */ INT4 SetGetSize (SETo *set) { return set->n; } /**API* SetIsSubEntry ********************************************************* ** ** Returns 1 if the set contains subentry IDs. ** ** INPUT: set name [R] ** IMPLICIT: ** ** RETURNS: 1 ** 0 if not */ INT4 SetIsSubEntry (char *nam) { SETo *set; if (!(set = SetGet (nam)) || !set->idType) return 0; else return set->idType->siz > 4 ? 1 : 0; } /**API* SetRename ************************************************************* ** ** Renames a set. ** ** INPUT: set object [W] ** new name for the set [R] ** IMPLICIT: ** set (SETo *) [W] ** ** RETURNS: 1: success ** 0: set name is already in use */ Int4 SetRename (SETo *set, char *newSetName) { SmEdit(newSetName,SMxLOWCASE); if (!SetTestName(newSetName)) { _ErrMsg2 (e__setnotuniqname, newSetName); return 0; } if (!LstChangeObjectName(set, newSetName)) { return 0; } return 1; } /**API* SetDelete ************************************************************* ** ** Deletes a Set with specified name. ** ** INPUT: set name [R] ** IMPLICIT: ** set (SETo *) [W] ** ** RETURNS: 1 if success ** set name does not exist: e__novalnam */ INT4 SetDelete (char *setName) { char tmpName[80]; strcpy (tmpName, setName); SmEdit (tmpName, SMxLOWCASE); if (!LstHashSearch ((void **) &set, tmpName)) _ErrRet(e__novalnam); LstDelete ((void **) &set); return 1; } INT4 SetDel (SETo *setPtr) { if (!LstHashSearch ((void **) &set, setPtr->nam)) _ErrRet(e__novalnam); LstDelete ((void **) &set); } /**api* SetClean ************************************************************** ** ** Deletes all temporary sets; ** ** INPUT: ** IMPLICIT: ** set (SETo *) [W] ** ** RETURNS: number of sets deleted */ INT4 SetClean () { INT4 setDeletedN=0; if (!set) return 0; LstFirst ((void **) &set); do { if (set->tmp_f) { LstDelete ((void **) &set); setDeletedN++; } } while (LstNext ((void **) &set)); return setDeletedN;; } /**api* SetPrintAll ********************************************************* ** ** Prints information on all sets in global list; ** ** INPUT: ** IMPLICIT: ** ** RETURNS: nothing */ void SetPrintAll() { LstPrintAll((void*)set); } /**api* SetAlloc ************************************************************** ** ** allocates memory for a set of pointers; ** ** INPUT: address of set descriptor [W] ** number of IDs [R] ** id-Type object [R] or NULL ** ** RETURNS: 1 ** e__allocfail + */ INT4 SetAlloc (SETo *set, INT4 n, IDoTYPE *idType) { if (idType) set->idType = idType; if ((set->id_p = (IDPTR) malloc (n * set->idType->siz)) == 0) _ErrRet2(e__allocfail, "set->ids by SetAlloc"); set->allocN = n; return 1; } /**api* SetGetIdBuff ************************************************************** ** ** Returns the pointer to an ID buffer with the specified size. In case ** the set's existing ID buffer is not large enough it will be increased. ** ** INPUT: set object [W] ** number of bytes [R] ** ** RETURNS: address of ID-buffer */ IDPTR SetGetIdBuff (SETo *set, INT4 n) { if (n > set->allocBytesN) { if (!set->allocBytesN) { if (!(set->id_p = (IDPTR) malloc (n))) _ErrExit2 (e__allocfail, "set ID buffer"); } else { if (!(set->id_p = (IDPTR) realloc ((void*) set->id_p, n))) _ErrExit2 (e__allocfail, "set ID buffer"); } set->allocBytesN = n; } return set->id_p; } /**api* SetAlloc ************************************************************** ** ** Reallocates memory for a set of pointers; ** ** INPUT: address of set descriptor [W] ** number of IDs [R] ** id-Type object [R] or NULL ** IMPLICIT: ** ** RETURNS: 1 ** e__allocfail + */ INT4 SetRealloc (SETo *set, INT4 n, IDoTYPE *idType) { if (idType) set->idType = idType; if ((set->id_p = (IDPTR) realloc ((void*) set->id_p, n*set->idType->siz)) == 0) _ErrRet2(e__allocfail, "set->ids by SetRealloc"); set->allocN = n; return 1; } /**api* SetSetEntryN ************************************************************** ** ** Sets the number of the entries in the set. ** ** INPUT: set object [W] ** entry number [R] */ void SetSetEntryN (SETo *set, INT4 n) { set->n = n; } /**api* SetSetEntryN ************************************************************** ** ** Sets the number of the entries in the set. ** ** INPUT: set object [W] ** ID-type object [R] */ void SetSetIdType (SETo *set, IDoTYPE *idType) { set->idType = idType; } /**API* SetGetNextLibStat ***************************************************** ** ** Returns next pair of library name and number of entries of set. ** This is useful information if a set is composed of IDs from ** different libraries. ** ** INPUT: name of set [R] ** pointer to address of library name [W] ** iteration context (must be initially set to 0) [W] ** IMPLICIT: ** ** RETURNS: number of entries from library ** 0 if no more value pairs exist */ INT4 SetGetNextLibStat (char *setName, char **libName, INT4 *context) { SETo *set; if (!(set = SetGet (setName))) return 0; if (!set->anal_f) SetLibStat (set); if (*context < 0 || *context >= set->lib_n) { *context = 0; return 0; } *libName = set->lib_nm[*context]; return set->lib_z[(*context)++]; } /**api* SetLibStat ************************************************************ ** ** forms an array of number of ID's per library in a set + library name ** and connects array to set-descrptor; note that all ID's of a certain ** library are always clustered since ID-block is sorted. ** ** INPUT: address of set-descriptor [W] ** IMPLICIT: ** ** RETURNS: nr of different sets found */ INT4 SetLibStat (SETo *set) { SLBo *lib; unsigned char idPtrSave = 255; IDoENTRY *id;{ IDPTR idPtr; INT4 k, n=0, siz, libN = 0; if (!set->n || set->anal_f) return 0; siz = set->idType->siz; for (k=0, idPtr=set->id_p+set->idType->lbxbeg; k < set->n; k++, idPtr += siz) if ((unsigned char ) *idPtr != idPtrSave) { idPtrSave = *idPtr; /* if ID is subentry-ID find subentry lib */ id = IdMakeFromBuff (idPtr, set->idType); lib = (SLBo *) LibObjById ("library", *idPtr); if (IdIsSub (id)) lib = LibGetSubEntryLib (lib, IdGetSubN (id)); set->lib_nm[libN] = LibName (lib); if (libN > 0) { set->lib_z[libN-1] = k-n; n = k; } n = k; libN++; } set->lib_z[libN-1] = k-n; set->lib_n = libN; set->anal_f = 1; return 1; } } /**api* SetMakeOwn ************************************************************ ** ** allocates storage for a set that is parked in global storage or some ** other storage and copies it there. ** ** INPUT: address of set-descriptor [W] ** address of id-descr. set will receive [R] or NULL ** IMPLICIT: ** ** RETURNS: 1 ** e__allocfail + */ INT4 SetMakeOwn (SETo *set, IDoTYPE *idType) { IDPTR id_p; INT4 siz; if (idType) set->idType = idType; if (!set->idType) _ErrRet (e__error); siz = set->n * set->idType->siz; /*PURIFY*/ if (siz) { if ((id_p = (IDPTR) malloc (siz)) == 0) _ErrRet2(e__allocfail, "ids-block by SetMakeOwn"); memcpy (id_p, set->id_p, set->n * set->idType->siz); } else id_p = NULL; set->id_p = id_p; return 1; } /**api* SetSort *************************************************************** ** ** heapsort the IDs in a set ** ** INPUT: set object [W] ** IMPLICIT: ** ** RETURNS: 1 ** e__allocfail + */ INT4 SetSort (SETo *set) { SetHeapSort (set->id_p, set->n, set->idType->siz, 0, set->idType->siz); SetRemoveDouble (set->id_p, set->n, set->idType->siz, &set->n); return 1; } /**api* SetOp ***************************************************************** ** ** Performs logical operations AND, OR, NOT with sets of same type; ** if addres of resultant set is NULL then set a is replaced by resultant ** set "a" and memory held previously by set a is freed. ** ** INPUT: address of set a [W] ** address of set b [R] ** address of result set [W] (or NULL) ** operator: SETxAND, SETxOR, SETxNOT [R] ** IMPLICIT: ** ** RETURNS: 1 if success ** 0 i both sets empty ** invalid set types: e__novalsettyp + ** invalid set operator: e__novalopt + */ INT4 SetOp (SETo *a, SETo *b, SETo *resultSet, INT4 op) { IDPTR idPtr; INT4 n; /* ** both sets are empty ...might not even have ** ID descriptors since, if from unsuccessful index search, were never set. */ if (a->n == 0 && b->n == 0) return 0; /* ** get the id descriptor from either of the two sets - it might not be ** defined for either; */ if (!b->idType) b->idType = a->idType; if (!a->idType) a->idType = b->idType; if (a->idType != b->idType) _ErrRet3 (e__novalsettyp, a->idType->nam, b->idType->nam); switch (op) { case SETxOR: idPtr = SetOr (a->id_p, b->id_p, a->n, b->n, &n, a->idType->siz); break; case SETxAND: idPtr = SetAnd (a->id_p, b->id_p, a->n, b->n, &n, a->idType->siz); break; case SETxNOT: idPtr = SetNot (a->id_p, b->id_p, a->n, b->n, &n, a->idType->siz); break; default: _ErrRet3(e__novalopt, op, "logical operator"); } if (!resultSet) { if (a->id_p && (a->id_p != b->id_p)) free (a->id_p); resultSet = a; } resultSet->n = n; resultSet->id_p = idPtr; SetMakeOwn (resultSet, a->idType); return 1; } /**API* SetGetID ************************************************************** ** ** Retrieves the ID with the specified number from the specified set. ** The first ID in set has the number 1. See also SetNextId. ** ** INPUT: address of set object [R] ** ID number within set [R] ** address of output id-object [W] ** IMPLICIT: ** ** RETURNS: 1 ** 0 if the ID number is out of range */ INT4 SetGetID (SETo *set, INT4 n, IDoENTRY *id) { if (n < 1 || n > set->n) return 0; id->idType = set->idType; id->siz = set->idType->siz; memcpy (id->id, set->id_p + --n * id->siz, id->siz); IdSplit (id); return 1; } /**API* SetNextId ************************************************************** ** ** Iterates over all IDs in the set. ** See also SetGetID. ** ** INPUT: address of set [R] ** address of output ID object [W] ** address of iterator (must be set to 0 to start) [W] ** ** RETURNS: the ID object ** NULL: set exhausted */ IDoENTRY *SetNextId (SETo *set, IDoENTRY *id, INT4 *i) { if (*i < set->n) { id->idType = set->idType; id->siz = set->idType->siz; memcpy (id->id, set->id_p + *i * id->siz, id->siz); IdSplit (id); (*i)++; return id; } else { *i = 0; return NULL; } } ENTRYv SetGetEntry (SETo *set, Int4 i) { IDoENTRY id; ENTRYv entry; SetGetID (set, i, &id); entry = EntryOpen (&id); return entry; } /**API* SetAddID ************************************************************** ** ** Adds an entry ID to an existing set. ** ** INPUT: address of set object [W] ** address of id-object describing the ID to be added [R] ** IMPLICIT: ** ** RETURNS: 1 ** allocation error: e__allocfail + */ INT4 SetAddID (SETo *set, IDoENTRY *id) { IDoTYPE *idType; /* ** get the ID-descriptor and copy it to the set if it doesn't have one */ if (set->idType) idType = set->idType; else if (id->idType) { idType = id->idType; set->idType = idType; } else return 0; /* ** allocate more space if needed */ if (set->allocN == set->n) if (set->n == 0) _ErrStop (SetAlloc (set, 1, set->idType)); else { set->allocN = set->allocN * 2; set->id_p = (IDPTR) realloc (set->id_p, (set->allocN) * idType->siz); } memcpy (set->id_p + (set->n++ * idType->siz), id->id, idType->siz); return 1; } /**API* SetGetQueryStr ******************************************************** ** ** Returns the query string that is associated to the specified set. ** ** INPUT: set name [R] ** IMPLICIT: ** ** RETURNS: query string ** NULL if the set could not be found */ char *SetGetQueryStr (char *setName) { SETo *set; char *tmp; if (!(set = SetGet (setName))) return NULL; return _Str(set->queryStr); } /**API* SetGetQuery *********************************************************** ** ** Returns the query string that is associated to the specified set. ** ** INPUT: set name [R] ** IMPLICIT: ** ** RETURNS: query string ** NULL if the set could not be found */ char *SetGetQuery (SETo *set) { return "does not work yet"; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /***** SetOr ***************************************************************** ** ** does logical OR operation between to sets and writes a third set; ** ** INPUT: address of first element of first set [R] ** address of first element of second set [R] ** number of elements in a [R] ** number of elements in b [R] ** location that will receive number of elements in c [W] ** element size in bytes [R] ** IMPLICIT: ** buff (SMoBUFF *) [W] ** ** RETURNS: */ static IDPTR SetOr (IDPTR a, IDPTR b, INT4 an, INT4 bn, INT4 *resultN, INT4 idSize) { IDPTR a_p=a, b_p=b, a_low=a, b_low=b; IDPTR a_end=a_p + an * idSize, b_end=b_p + bn * idSize; INT4 len, cmp, k, inc = idSize-1; _SetInitBuff (buff); while (a_p < a_end && b_p < b_end) { for (k = inc; k >= 0; k--) { if ((cmp = a_p[k] - b_p[k]) != 0) break; } if (cmp == 0) { /* equal */ if (b_low != SETxNOCPY) { _SetCopyIds (buff, b_low, b_p, len) b_low = SETxNOCPY; a_low = a_p; } a_p += idSize; b_p += idSize; } else if (cmp < 1) { /* smaller */ if (b_low != SETxNOCPY) { _SetCopyIds (buff, b_low, b_p, len) b_low = SETxNOCPY; a_low = a_p; } a_p += idSize; } else { /* bigger */ if (a_low != SETxNOCPY) { _SetCopyIds (buff, a_low, a_p, len) a_low = SETxNOCPY; b_low = b_p; } b_p += idSize; } } if (a_low != SETxNOCPY) { /* collect the rest */ _SetCopyIds (buff, a_low, a_end, len) if (b_p != b_end) { _SetCopyIds (buff, b_p, b_end, len) } } else { _SetCopyIds (buff, b_low, b_end, len) if (a_p != a_end) { _SetCopyIds (buff, a_p, a_end, len) } } *resultN = BuffGetCurrOffset (buff) / idSize; return (IDPTR) BuffGetPtr (buff); } /****** SetNot **************************************************************** ** ** does logical AND NOT operation between to sets and writes a third set; ** ** INPUT: address of first element of first set [R] ** address of first element of second set [R] ** number of elements in a [R] ** number of elements in b [R] ** location that will receive number of elements in c [W] ** element size in bytes [R] ** IMPLICIT: ** buff (SMoBUFF *) [W] ** ** RETURNS: 1 */ static IDPTR SetNot (IDPTR a, IDPTR b, INT4 an, INT4 bn, INT4 *resultN, INT4 idSize) { IDPTR a_p= a, b_p=b, a_low=a, b_low=b; IDPTR a_end=a_p + an * idSize, b_end=b_p + bn * idSize; INT4 len, cmp, k, inc=idSize-1; _SetInitBuff (buff); while (a_p < a_end && b_p < b_end) { for (k = inc; k >= 0; k--) { if ((cmp = a_p[k] - b_p[k]) != 0) break; } if (cmp == 0) { /* equal */ if (a_low != SETxNOCPY) { _SetCopyIds (buff, a_low, a_p, len) a_low = SETxNOCPY; b_low = b_p; } a_p += idSize; b_p += idSize; } else if (cmp < 1) { /* smaller */ if (b_low != SETxNOCPY) { b_low = SETxNOCPY; a_low = a_p; } a_p += idSize; } else { /* bigger */ if (b_low != SETxNOCPY) { b_low = SETxNOCPY; a_low = a_p; } b_p += idSize; } } if (a_low != SETxNOCPY) { /* collect rest */ _SetCopyIds (buff, a_low, a_end, len) } else { _SetCopyIds (buff, a_p, a_end, len) } *resultN = BuffGetCurrOffset (buff) / idSize; return (IDPTR) BuffGetPtr (buff); } /****** SetAnd **************************************************************** ** ** Does logical AND operation between to sets and writes into third set. ** ** INPUT: address of first element of first set [R] ** address of first element of second set [R] ** number of elements in a [R] ** number of elements in b [R] ** location that will receive number of elements in c [W] ** element size in bytes [R] ** IMPLICIT: ** buff (SMoBUFF *) [W] ** ** RETURNS: */ static IDPTR SetAnd (IDPTR a, IDPTR b, INT4 an, INT4 bn, INT4 *resultN, INT4 idSize) { IDPTR a_p=a, b_p=b, a_low=a, b_low=b; IDPTR a_end=a_p+an*idSize, b_end=b_p+bn*idSize; INT4 len, cmp, k, inc=idSize-1; _SetInitBuff (buff); while (a_p < a_end && b_p < b_end) { for (k = inc; k >= 0; k--) { if ((cmp = a_p[k] - b_p[k]) != 0) break; } if (cmp == 0) { /* equal */ if (b_low != SETxNOCPY) { b_low = SETxNOCPY; a_low = a_p; } a_p += idSize; b_p += idSize; } else if (cmp < 1) { /* less */ if (a_low != SETxNOCPY) { _SetCopyIds (buff, a_low, a_p, len) a_low = SETxNOCPY; b_low = a_p; } a_p += idSize; } else { /* bigger */ if (a_low != SETxNOCPY) { _SetCopyIds (buff, a_low, a_p, len) a_low = SETxNOCPY; b_low = b_p; } b_p += idSize; } } if (a_low != SETxNOCPY) { /* get rest */ _SetCopyIds (buff, a_low, a_p, len) } *resultN = BuffGetCurrOffset (buff) / idSize; return (IDPTR) BuffGetPtr (buff); } /**api* SetMapIds ************************************************************* ** ** similar to SetAnd but more general -> ** copies all elements from set "a" that have a map-region owned ** by at least one element in set "b"; resultant set "c" will ** therefore contain a subset of set "a" ** though part of ID used for mapping is variable it defaults to 4 bytes ** here -> modify the "cmp =..." line so that the compared values ** are shifted by (4-mlen)*8 bits to the right -> 4 byte would then ** be the largest map-length, ** ** INPUT: address of first element of first set [R] ** address of first element of second set [R] ** number of elements in a [R] ** number of elements in b [R] ** location that will receive number of elements in c [W] ** ID-size in bytes of first set [R] ** ID-size in bytes of second set [R] ** offset of join region in first set's ID [R] ** offset of join region in second set's ID [R] ** length of join region [R] ** IMPLICIT: ** buff (SMoBUFF *) [W] ** ** RETURNS: */ IDPTR SetMapIds (IDPTR a, IDPTR b, INT4 an, INT4 bn, INT4 *resultN, INT4 aidSize, INT4 bidSize, INT4 amoff, INT4 bmoff, INT4 mlen) { IDPTR a_p=a, b_p=b; IDPTR a_end=a_p+an*aidSize, b_end=b_p+bn*bidSize; INT4 cmp; _SetInitBuff (buff); while (a_p < a_end && b_p < b_end) { CMP (a_p + amoff, b_p + bmoff, cmp, 4) if (cmp == 0) { /* equal */ _BuffCopyNChars (buff, a_p, aidSize) a_p += aidSize; } else if (cmp < 1) /* less */ a_p += aidSize; else /* bigger */ b_p += bidSize; } *resultN = BuffGetCurrOffset (buff) / aidSize; return (IDPTR) BuffGetPtr (buff); } /**api* SetMapToParent ******************************************************** ** ** Takes a set of subentry IDs, removes the subentry-no and removes ** redundant elements; ** length of PARENT-ID should be variable but is here always 4 byte! ** ** INPUT: address of ID-block [R] ** nr of IDs [R] ** adress of nr of IDs in resultant set [W] ** size of CHILD-ID [R] ** offset of PARENT-ID [R] ** length of PARENT-ID [R] ** IMPLICIT: ** buff (SMoBUFF *) [W] ** ** RETURNS: 1 */ IDPTR SetMapToParent (IDPTR a, INT4 a_n, INT4 *resultN, INT4 siz, INT4 off, INT4 len) { UINT4 id_s, id; IDPTR id_p; INT4 k, cmp; _SetInitBuff (buff); id_s = SETxNULL; for (k=0, id_p=a; k < a_n; k++, id_p = id_p + siz) { memcpy (&id, (id_p + off), sizeof (UINT4)); if (k > 0) { CMP ((IDPTR) &id, (IDPTR) &id_s, cmp, 4); } else { cmp = -1; } if (cmp != 0) { id_s = id; _BuffCopyNChars (buff, &id, sizeof (UINT4)) } } *resultN = BuffGetCurrOffset (buff) / sizeof (UINT4); return (IDPTR) BuffGetPtr (buff); } /**api* SetLink *************************************************************** ** ** similar to SetMapIds but more specialized -> ** compares entry-ID with link ID and creates a sorted set of ** linked ID's (the part of the link ID that was not used for ** comparison); ** ** INPUT: address of first element of first set [R] ** address of first element of second set [R] ** address of buffer reserved for third set [W] ** number of elements in a [R] ** number of elements in b [R] ** location that will receive number of elements in c [W] ** 1 or 2 copare ** IMPLICIT: ** buff (SMoBUFF *) [W] ** ** RETURNS: 1 */ IDPTR SetLink (IDPTR a, INT4 a_n, IDPTR b, INT4 b_n, INT4 *resultN, INT4 rev_f) { IDPTR aPtr=a, bPtr, aEnd, bEnd; INT4 cmp, shift; _SetInitBuff (buff); bPtr = b + (rev_f ? 4 : 0); aEnd = a + a_n*4; bEnd = b + (b_n * 2)*4; shift = rev_f ? -4 : 4; while (aPtr < aEnd && bPtr < bEnd) { CMP (aPtr, bPtr, cmp, 4); if (cmp == 0) { /* equal */ _BuffCopyNChars (buff, (bPtr + shift), 4) bPtr += 2*4; } else if (cmp < 1) /* less */ aPtr += 4; else /* bigger */ bPtr += 2*4; } *resultN = BuffGetCurrOffset (buff) / 4; SetHeapSort ((IDPTR) BuffGetPtr (buff), *resultN, 4, 0, 4); return (IDPTR) BuffGetPtr (buff); } /**api* SetCutLink ************************************************************ ** ** Cuts either first or second ID from each link ID and writes it ** into result set. Set is always sorted. ** Function assumes that entry ID's within link-ID's are always 4 byte ** long (will have to be changed as soon as subentry-IDs will be involved ** in links!!) ** ** INPUT: address of set with link-IDs [R] ** number of ID's in set [R] ** address of number of IDs in result set [W] ** reverse flag [R] ** IMPLICIT: ** buff (SMoBUFF *) [W] ** ** RETURNS: 1 */ IDPTR SetCutLink (IDPTR a, INT4 a_n, INT4 *resultN, INT4 rev_f) { IDPTR aPtr, aEnd; _SetInitBuff (buff); aPtr = a + (rev_f ? 0 : 4); aEnd = 8 * a_n + a; for (; aPtr < aEnd; aPtr+=8) _BuffCopyNChars (buff, aPtr, 4) *resultN = BuffGetCurrOffset (buff) / 4; return (IDPTR) BuffGetPtr (buff); } /**api* SetRemoveDouble ******************************************************* ** ** removes duplicates from a set of IDs; ** ** INPUT: address of input set [R/W] ** address of output set [W] may be the same as input set ** size of input set [R] ** address to place size of output set [W] ** ID-size [R] ** IMPLICIT: ** ** RETURNS: 1 **/ INT4 SetRemoveDouble (IDPTR idPtr, INT4 idN, INT4 idSize, INT4 *resultN) { IDPTR off, last, out; if (idN == 0) { *resultN = 0; return 0; } off = idPtr + idSize; last = idPtr + idN * idSize; out = idPtr + idSize; for (; off < last; off += idSize) if (memcmp (off, out-idSize, idSize) != 0) { memcpy (out, off, idSize); out += idSize; } *resultN = (out - idPtr) / idSize; return 1; } /**api* SetCountKey ********************************************************** ** ** counts the number of unique keys within ID ...assumes that the set ** is sorted after the key to be counted; ** ** INPUT: address of input set [R] ** size of input set [R] ** size of ID [R] ** size of key [R] ** offset of key within set [R] ** IMPLICIT: ** ** RETURNS: 1 **/ INT4 SetCountKey (IDPTR idPtr, INT4 idN, INT4 idSize, INT4 keyOff, INT4 keySize) { INT4 keyN=0; char *tmp, *tmpSave=NULL; for (tmp = (char*)(idPtr + idSize * (idN-1) + keyOff); tmp >= (char*) idPtr; tmp -= idSize) if (!keyN || memcmp (tmp, tmpSave, keySize) != 0) { keyN++; tmpSave = tmp; } return keyN; } /**api* SetHeapSort *********************************************************** ** ** uses "sort" from Numerical Recipies in C, p 247; ** sorts an array of ID's using a key-number within the ID with specified ** begin and length; ** Note that the base of array is shifted by one element to make the ** first element the element with index=1; ** ** INPUT: base address of array [W] ** number of elements [R] ** size of ID [R] ** offset of sorting key in ID [R] ** length of sorting key [R] ** IMPLICIT: ** ** RETURNS: 1 */ INT4 SetHeapSort (IDPTR ra, INT4 n, INT4 siz, INT4 beg, INT4 len) { INT4 k, l, j, ir, i, cmp; unsigned char rra[SETxXID]; IDPTR a_p, b_p; if (n <= 1) return 0; /* nothing to sort */ ra = ra - siz; /* num recipies start with "1" as first index in array */ l = (n >> 1) + 1; ir = n; for (;;) { if (l > 1) memcpy (rra, ra + --l * siz, siz); else { memcpy (rra, ra + ir * siz, siz); memcpy (ra + ir * siz, ra + 1 * siz, siz); if (--ir == 1) { memcpy (ra + 1 * siz, rra, siz); return 1; } } i = l; j = l << 1; while (j <= ir) { for (k=beg+len-1, a_p = ra + j*siz, b_p = ra + (j+1)*siz; k >= beg; k--) { if ((cmp = a_p[k] - b_p[k]) != 0) break; } if (j < ir && cmp < 0) ++j; for (k=beg+len-1, a_p = rra, b_p = ra + j*siz; k >= beg; k--) { if ((cmp = a_p[k] - b_p[k]) != 0) break; } if (cmp < 0) { memcpy (ra + i*siz, ra+j*siz, siz); j += (i = j); } else j = ir + 1; } memcpy (ra + i * siz, rra, siz); } } j = l << 1; while (j <= ir) { for (k=beg+len-1, a_p = ra + j*siz, b_p = ra + (j+1)*siz; k >= beg; k--) { if ((cmp = a_p[k] - b_p[k]) != 0) break; } if (j < ir && cmp < 0) ++j; for (k=beg+len-1, a_p = rra, b_p = ra + j*siz; k >= beg; k--) { if ((cmp = a_p[k] - b_p[k]) != 0) break; } if (cmp < 0) { memcpy (ra + i*siz, ra+j*siz, siz); j += (i = j); } else j = ir + 1; } memcpy (ra + i * siz, rrasrs/src/set.h ** ** $RCSfile: set.h,v $ ** $Revision: 1.7 $ ** $Date: 1997/03/03 18:20:52 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port: Lukas Rosenthaler and Reinhard Doelz ** */ #define SETxXKEY 80 /* max key size */ #define SETxXNAM 20 /* max size of set name */ #define SETxXCMNT 132 /* max size of set description */ #define SETxXID 12 /* max len of ID */ #define SETxXLIBS 64 /* max no of source libraries of a set */ enum set_op {SETxOR=40, SETxAND, SETxNOT}; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Description of a set. */ typedef struct SETo { char *list; /* for usage of module "list" only! should be (void *) but the gdb... */ INT4 class_id; /* for "list" module */ char nam[SETxXNAM]; /* (API) name of set */ char cmnt[SETxXCMNT]; /* set description */ struct STRo *queryStr; /* query string used to generate set*/ char time[SETxXNAM]; /* (API) creation time */ INT4 n; /* number of IDs */ struct IDoTYPE *idType; /* pointer to ID descriptor */ IDPTR id_p; /* array of IDs */ INT4 lib_n; /* no of different source libraries */ char *lib_nm[SETxXLIBS]; /* names of these libraries */ INT4 lib_z[SETxXLIBS]; /* how many IDs of each library? */ INT4 anal_f; /* flag if libraries were counted */ INT4 tmp_f; /* flag if set is for temporary use */ INT4 allocN; /* allocated space for n Ids */ INT4 isDb; /* flag if set represents a databank */ Int4 allocBytesN; /* number of allocated bytes */ } SETo; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of exported functions */ /* operations on sets */ SETo *SetNew (char *nam, char *opt); SETo *SetGet (char *nam); INT4 SetDelete (char *nam); INT4 SetSort (SETo *set); Int4 SetRename (SETo *set, char *newSetName); INT4 SetClean (); void SetPrintAll (); INT4 SetOp (SETo *a, SETo *b, SETo *c, INT4 op); /* info about set */ INT4 SetSize (char *setName); INT4 SetIsSubEntry (char *setName); INT4 SetGetNextLibStat (char *setName, char **libName, INT4 *context); char *SetGetQueryStr (char *setName); char *SetGetQuery (SETo *set); char *SetGetName (SETo *set); INT4 SetGetSize (SETo *set); struct ENTRYo *SetGetEntry (SETo *set, Int4 i); /* modify set */ void SetSetIdType (SETo *set, struct IDoTYPE *idType); void SetSetEntryN (SETo *set, INT4 n); IDPTR SetGetIdBuff (SETo *set, INT4 n); /* allocation */ INT4 SetAlloc (SETo *set, INT4 n, struct IDoTYPE *idType); INT4 SetRealloc (SETo *set, INT4 n, struct IDoTYPE *idType); INT4 SetMakeOwn (SETo *set, struct IDoTYPE *idType); /* handling IDs in sets */ INT4 SetGetID (SETo *set, INT4 n, struct IDoENTRY *id); struct IDoENTRY *SetNextId (SETo *set, struct IDoENTRY *id, INT4 *i); INT4 SetAddID (SETo *set, struct IDoENTRY *id); /* others ... */ void SetSetIsDB (SETo*, Int4); INT4 SetIsDB (SETo *set); INT4 SetLibStat (SETo *set); INT4 SetTestName (char *nam); IDPTR SetMapIds (IDPTR a, IDPTR b, INT4 an, INT4 bn, INT4 *cn, INT4 aid_z, INT4 bid_z, INT4 amoff, INT4 bmoff, INT4 mlen); IDPTR SetMapToParent (IDPTR a, INT4 a_n, INT4 *c_n, INT4 siz, INT4 off, INT4 len); IDPTR SetLink (IDPTR a, INT4 a_n, IDPTR b, INT4 b_n, INT4 *resultN,INT4 rev_f); IDPTR SetCutLink (IDPTR a, INT4 a_n, INT4 *resultN, INT4 rev_f); INT4 SetRemoveDouble (IDPTR a, INT4 a_n, INT4 id_z, INT4 *b_n); INT4 SetHeapSort (IDPTR ra, INT4 n, INT4 siz, INT4 beg, INT4 len); INT4 SetCountKey (IDPTR idPtr, INT4 idN, INT4 idSize, INT4 keyOff, INT4 keySize); 4 aid_z, INT4 bid_z, INT4 amoff, INT4 bmoff, INT4 mlen); IDPTR SetMapToParent (IDPTR a, INT4 a_nsrs/src/sm.c char sm__ID[] = "$Id: sm.c,v 1.5 1996/11/27 19:45:26 weare Exp $"; /* ** ** $RCSfile: sm.c,v $ ** $Revision: 1.5 $ ** $Date: 1996/11/27 19:45:26 $ ** $Author: weare $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port: Lukas Rosenthaler and Reinhard Doelz ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** D-69012 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** Requires: file, sm, message ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** contains functions for string manipulation ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #define DEBUGNOT #include #include #include #include /*#include */ #include #include "message.h" #include "sm.h" #include "lst.h" #include "regexp.h" #define _BuffIncWrite(buff,len) (buff)->writePtr += (len) #define _BuffIncRead(buff,len) (buff)->readPtr += (len) void SmMemMove (char *to, char *from, int len); /****** SmCharSet ************************************************************* ** ** decodes strings used to describe character set; ** "A-Da-d" -> "ABCDabcd" ** "\-" -> "-" ** ** INPUT: address of string [W] ** IMPLICIT: ** ** RETURNS: address of expanded charset string ** */ char *SmCharSet (char *s) { char *loc, tmpa[512+1], tmpb[512+1]; INT4 k; for (loc=s; (loc = strchr (loc, '-')) != NULL; loc++) { if (*(loc-1) == '\\') continue; if (loc == s || *(loc+1) == '\0' || *(loc-1) >= *(loc+1)) _ErrExit (e__novalterm); memcpy (tmpa, loc-1, 3); tmpa[3] = '\0'; for (k=1, tmpb[0] = *(loc-1); tmpb[k-1] < *(loc+1); k++) tmpb[k] = tmpb[k-1] + 1; tmpb[k] = '\0'; SmSwapS (s, tmpa, tmpb); } while (SmSwapS (s, "\\-", "-")) ; return s; } /**api* SmFill **************************************************************** ** ** ** writes the specified number specified character into string address ** ** INPUT: address of string [W] ** number of characters to write [R] ** character to write [R] ** ** RETURNS: 1 */ char *SmFill (char *str, INT4 n, char c) { INT4 k; for (k = 0; k < n; str[k++] = c) ; str[k] = '\0'; return str; } /**api* SmLoc ***************************************************************** ** ** return index of string t in string s, -1 if none; ** ** INPUT: address of string1 [R] ** address of string2 that is searched in string1 [R] ** ** RETURNS: index of string2 in string1 ** -1 if not there */ INT4 SmLoc(char *str1, char *str2) { INT4 i, j, k; for (i = 0; str1[i] != '\0'; i++) { for (j = i, k = 0; str2[k] != '\0' && str1[j] == str2[k]; j++, k++) ; if (k > 0 && (str2[k] == '\0' || *str2 == '\0')) return i; } return -1; } /****** SmXLoc **************************************************************** ** ** searches string1 for occ. of string2 starting from first index ** until the second; if found then string2 is replaced by blanks in ** string1; ** ** INPUT: address of string1 ** address of string2 that is searched in string1 ** index where to start (first in string is 1) ** index where to stop (first in string is 1) ** ** RETURNS: index of string2 in string1 ** -1 if not there */ INT4 SmXLoc(char *str1, char *str2, INT4 l, INT4 r) { INT4 i, j, k; for (i = --l; str1[i] != '\0' && i < r; i++) { for (j = i, k = 0; str2[k] != '\0' && str1[j] == str2[k]; j++, k++) ; if (k > 0 && (!str2[k] || !*str2)) { while (j > i) str1[--j] = ' '; return i; } } return -1; } /****** SmMixLoc ************************************************************** ** ** same as SmXLoc but case insensitive; does no blotting out ** ** INPUT: address of string1 ** address of string2 that is searched in string1 ** index where to start (first in string is 1) ** index where to stop (first in string is 1) ** ** RETURNS: index of string2 in string1 ** -1 if not there */ INT4 SmMixLoc(char *str1, char *str2, INT4 l, INT4 r) { INT4 i, j, k; for (i = --l; str1[i] != '\0' && i < r; i++) { for (j = i, k = 0; str2[k] != '\0' && (isalpha (str1[j]) ? toupper (str1[j]) : str1[j]) == (isalpha (str2[k]) ? toupper (str2[k]) : str2[k]); j++, k++) ; if (k > 0 && (str2[k] == '\0' || *str2 == '\0')) return i; } return -1; } /**api* SmStrCmp ************************************************************** ** ** same as strcmp - but case insensitive ** ** ** INPUT: string 1 [R] ** string 2 [R] ** IMPLICIT: ** ** RETURNS: difference of first characters that differ ** 0 if equal ** */ INT4 SmStrCmp (char *a, char *b) { for (; *a && *b; a++, b++) if (tolower (*a) != tolower (*b)) break; return (tolower (*a) - tolower (*b)); } /**api* SmStrCmpLen *********************************************************** ** ** same as SmStrCmp but continues comparison until specified length ** is reached; ** ** INPUT: string 1 [R] ** string 2 [R] ** comparison length [R] ** IMPLICIT: ** ** RETURNS: difference of first characters that differ ** 0 if equal */ INT4 SmStrCmpLen (char *a, char *b, INT4 len) { for (; *a && *b && len; a++, b++, len--) if (tolower (*a) != tolower (*b)) break; return !len ? 0 : (tolower (*a) - tolower (*b)); } /**api* SmRStrCmp ************************************************************* ** ** same as strcmp - but case insensitive (strings are converted to ** uppercase first) ** once above replacement is done then SmRStrCmp may be called SmStrCmp ** ** INPUT: string 1 [R] ** string 2 [R] ** IMPLICIT: ** ** RETURNS: positive no if string 1 is greater (alphab.) ** negative if string 2 is less ** 0 if both strings are equal */ INT4 SmRStrCmp (char *a, char *b) { INT4 cmp; while (1) { if ((cmp = toupper (*a) - toupper (*b)) != 0) return cmp; if (!*a && !*b) return 0; a++, b++; } } /**api* SmRStrCmpLen ********************************************************** ** ** same as SmRStrCmpLen - but a length can be set where string comparison ** should stop; if the two strings are identical until length the ** 0 is returned; ** ** INPUT: string 1 [R] ** string 2 [R] ** length - comparison stops after length is reached [R] ** IMPLICIT: ** ** RETURNS: positive no if string 1 is greater (alphab.) ** negative if string 2 is less ** 0 if both strings are equal */ INT4 SmRStrCmpLen (char *a, char *b, INT4 len) { INT4 cmp; while (len--) { if ((cmp = toupper (*a) - toupper (*b)) != 0) return cmp; if (!*a && !*b) return 0; a++, b++; } return 0; } /****** SmBinLoc ************************************************************** ** ** return index of string t in string s, -1 if none; ** as Smloc except that it searches any bytes (not only ascii) ** ** INPUT: address of string1 ** address of string2 that is searched in string1 ** length of string 1 ** length of string 2 ** ** RETURNS: index of string2 in string1 ** -1 if not there */ INT4 SmBinLoc(char *str1, char *str2, INT4 len1, INT4 len2) { INT4 i, j, k; for (i = 0; i < len1; i++) { for (j = i, k = 0; k < len2 && str1[j] == str2[k]; j++, k++) ; if (k == len2) return i; } return -1; } /*#define _SmUpper(c) (c >= 'a' & c <= 'z') ? (223 & c) : c */ #define _SmUpper(c) charTbl [(int) c] /**api* SmEdit **************************************************************** ** ** mofifies a string: ** SMxTRIM: cuts of leading and trailing " \n\t" ** SMxTRIM2: cuts of leading and trailing " \n\t" ** SMxLEAD: only leader is trimmed ** SMxTRAIL: only trailer is trimmed ** SMxUPCASE: converts to upper case ** SMxLOWCASE: converts to lower case ** SMxDECODE: replaces \n, \b by proper character values ** SMxDETAB: replaces \t by ' ' ** ** modified: 9-OCT-1992 strcmp->strcpy (remc...) ** ** INPUT: address of string [W] ** bit mask containing constants (see above) [R] ** ** RETURNS: address of modified string */ char *SmEdit (char *s, UINT4 bm) { static char charTbl[255]; static INT4 isInit; char remc[10], remc2[10], *remc_p; INT4 code, k, l, slen; if (!isInit) { for (k=0; k < 255; k++) charTbl[k] = toupper (k); isInit = 1; } strcpy (remc, " \n\t\""); strcpy (remc2, " \n\t"); slen = strlen(s); if (bm & SMxTRIM || bm & SMxTRIM2) { remc_p = bm & SMxTRIM ? &(remc[0]) : &(remc2[0]); if (!(bm & SMxTRAIL)) { /* trim beginning */ for (k = 0; s[k] != 0 && (strchr(remc_p, s[k]) != 0); k++) ; if (bm & SMxTRIM2 && s[k] == '\"') /* " */ k++; slen -= k; if (k > 0) memcpy(s, &s[k], slen+1); } if (!(bm & SMxLEAD)) { /* trim end */ for (k = slen - 1; k >= 0 && (strchr(remc_p, s[k]) != 0); k--) ; if (bm & SMxTRIM2 && s[k] == '\"') /* " ..emacs colors */ k--; if (s[++k]) /* modify only if necess..string might be protected */ s[k] = '\0'; slen = k; } } if (bm & SMxDECODE) { for (k = 0, l = 0; k < slen; k++) if (s[k] != '\\') s[l++] = s[k]; else switch (s[++k]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': code = s[k] - '0'; while (isdigit (s[k+1])) { k++; code = code*10 + (s[k] - '0'); } s[l++] = code; break; case 'n': s[l++] = 10; break; case 'a': s[l++] = 7; break; case 't': s[l++] = 9; break; case 'b': s[l++] = 7; break; case 'r': s[l++] = 13; break; case '\"': /* " ...emacs colors */ s[l++] = 34; break; case '\\': s[l++] = 92; break; case '-': s[l++] = '\\'; /* see PrsDecode */ s[l++] = '-'; break; default: s[l++] = s[k]; break; } s[l] = '\0'; } if (bm & SMxUPCASE) for (k = slen-1; k>=0; k--) s[k] = _SmUpper (s[k]); /* s[k] = toupper(s[k]); */ if (bm & SMxLOWCASE) for (k = 0; k < slen; k++) s[k] = tolower(s[k]); if (bm & SMxDETAB) for (k = 0; k < slen; k++) if (s[k] == '\t') s[k] = ' '; return s; } /**api* SmTime **************************************************************** ** ** should become OBSOLETE ** writes current date and time in the input string address in the format: ** " 9-OCT-1989 9:12\0"; ** ** INPUT: time value (seconds) [R] or 0 ** ** RETURNS: pointer to time string */ char *SmTime (unsigned long usertime_val) { time_t time_val = usertime_val; struct tm *t_s; char min[3]; static char timstr[30]; static char *month[12] = {"JAN","FEB","MAR","APR","MAY","JUN","JUL", "AUG","SEP","OCT","NOV","DEC"}; if (time_val == 0) time (&time_val); t_s = localtime (&time_val); sprintf(min, "%2d", t_s->tm_min); /* min may need leading '0' */ if (t_s->tm_min < 10) min[0] = 48; sprintf (timstr, "%2d-%s-19%d %2d:%s", t_s->tm_mday, month[t_s->tm_mon], t_s->tm_year, t_s->tm_hour, min); return &timstr[0]; } /**api* SmSwap **************************************************************** ** ** replaces all occurances of a character in a string by another character ** ** INPUT: address of string [W] ** character to be replaced [R] ** replacement character [R] ** ** returns: 1 */ INT4 SmSwap (char *s, char a, char b) { char *loc; while ((loc = strchr (s, a)) != NULL) *loc = b; return 1; } /**api* SmSwapFirst *********************************************************** ** ** swaps only first occurrence of string; ** ** INPUT: string to be searched and modified [W] ** string to be searched [R] ** replacement string [R] ** ** RETURNS: 1 if swap ** 0 if no swap */ INT4 SmSwapFirst (char *str, char *search, char *replace) { char *tmp, *loc; INT4 sLen, rLen, diff; if (!(loc = strstr (str, search))) return 0; sLen = strlen (search); rLen = strlen (replace); if (sLen > rLen) { /* move chars AFTER searchstring from left to right */ diff = sLen - rLen; for (tmp=loc+sLen; *tmp; tmp++) *(tmp - diff) = *tmp; } else if (sLen < rLen) { /* move chars AFTER searchstring from right */ diff = rLen - sLen; for (tmp=str+strlen(str); tmp >= loc + sLen; tmp--) *(tmp + diff) = *tmp; } memcpy (loc, replace, rLen); return 1; } /****** SmReplace ************************************************************* ** ** ** INPUT: address of string [W] ** pointer inside the buff to the substring to be replaced [W] ** length of string to be replaced [R] ** replacement string [R] ** length of that substring [R] ** IMPLICIT: ** ** RETURNS: ** pointer to the beginning of the replaced string */ char *SmReplace (char *buff, char *target, INT4 targetLen, char *s, INT4 lenS) { char *endPtr; INT4 off, shift; off = (Int4)(target - buff) + targetLen; shift = lenS - targetLen; if (shift != 0) { endPtr = buff + off; SmMemMove (endPtr + shift, endPtr, strlen(buff) - off + 1); memcpy (endPtr - targetLen, s, lenS); } return endPtr-targetLen; } /**api* SmSwapS *************************************************************** ** ** swap all occurrances of old string against new string; goes from left ** to right; ** ** INPUT: address of input string [W] ** address of old string (to be searched in string) [R] ** address of new string [R] ** ** RETURNS: 1 if swap ** 0 if no swap */ INT4 SmSwapS (char *str, char *a, char *b) { INT4 off=0, strLen, a_z, b_z, swap_f, rv; #ifdef sun char *tmp; #endif swap_f = FALSE; strLen = strlen (str); a_z = strlen (a); b_z = strlen (b); while ((rv = SmLoc (str+off, a)) != -1) { off += rv; swap_f = TRUE; #ifdef sun tmp = (char *) malloc (strLen - a_z - off + 1); memcpy (tmp, &str[off+a_z], strLen - a_z - off + 1); memcpy (&str[off+b_z], tmp, strLen - a_z - off + 1); free (tmp); #else memmove (&str[off+b_z], &str[off+a_z], strLen-a_z-off+1); #endif memcpy (&str[off], b, b_z); strLen += b_z - a_z; /* string size changes */ off += b_z; } return swap_f; } void SmMemMove (char *to, char *from, int len) { #ifdef sun char *tmp; tmp = (char *) malloc (len); memcpy (tmp, from, len); memcpy (to, tmp, len); free (tmp); #else memmove (to, from, len); #endif } /****** SmFLen **************************************************************** ** ** replaces in format-string for printf '#' against width (neg. or pos) ** ** INPUT: address of format-string [W] ** any number of width numbers [R] ** IMPLICIT: ** ** RETURNS: address of modified string */ char *SmFLen (char *s,...) { static char tmps[SMxXTMP]; va_list ap; char tmp[5]; INT4 wid; strcpy (tmps, s); va_start (ap, s); while (strchr (tmps, '#') != NULL) { wid = va_arg (ap, INT4); sprintf (tmp, "%d", wid); SmSwapS (tmps, "#", tmp); } va_end (ap); return tmps; } /**api* SmElement ************************************************************* ** ** extracts string element with specified number bordered by begin, or end ** of string or specified character; first element has number 1; ** ** INPUT: address of input string [R] ** address of output string [W] ** delimiter character [R] ** element number [R] ** option SMxSKIP or SMxNOSKIP [R] ** IMPLICIT: ** ** RETURNS: 1 if success ** 0 if specified element not found */ INT4 SmElement (char *a, char *b, char tok, INT4 n, INT4 skip_o) { INT4 k, l, beg, len; for (k=0, l=0; k < n -1; k++) { /* goto element begin */ while (a[l] != tok && a[l] != '\0') l++; if (a[l++] == '\0') return 0; } beg = l; if (skip_o == SMxNOSKIP && beg != 0) beg--; while (a[l] != tok && a[l] != '\0') /* goto element's end */ l++; if (beg == l) return 0; len = l-beg; memcpy (b, &(a[beg]), len); b[len] = '\0'; return 1; } /**api* SmStrTok ************************************************************** ** ** inspired from strtok, ...tok is a separator STRING with one or more ** characters; function returns next substring bordered by tok; the ** context is reset when called with a different string ...or when ** an iteration is complete and there are no more substrings ...this ** means that it must be always iterated until the function returns NULL; ** function put '\0's into the input string; ** ** INPUT: string [W] ** string token [R] ** IMPLICIT: ** ** RETURNS: pointer to next substring ** NULL if there are no more */ char *SmStrTok (char *str, char *tok) { static char *strSave, *strPtr=NULL, *tokPtr, *tmpPtr; if (strSave != str || !strPtr) strSave = str, strPtr = str; if (!*strPtr) { /* at end of string */ strPtr = NULL; return NULL; } if ((tokPtr = strstr (strPtr, tok))) { *tokPtr = '\0'; tmpPtr = strPtr; strPtr = tokPtr + strlen (tok); return tmpPtr; } else { /* no token found */ tmpPtr = strPtr; strPtr = str + strlen (str); return tmpPtr; } } /**api* SmEqs **************************************************************** ** ** compares to strings case insensitive; ** ** INPUT: string a [R] ** string b [R] ** IMPLICIT: ** ** RETURNS: 1 if equal ** 0 if not */ INT4 SmEqs (char *a, char *b) { for (; *a && *b; a++, b++) if (toupper (*a) != toupper (*b)) break; return (!*a && !*b) ? 1 : 0; } static Int4 buffAllocN, buffAllocByte, buffFreedN, buffFreedByte; /**api* BuffNew *************************************************************** ** ** Creates a new buffer object with the specified initial size which ** will double as needed; ** ** INPUT: initial size in bytes [R] ** ** RETURNS: buffer object */ SMoBUFF *BuffNew (INT4 size) { SMoBUFF *buff; if (size < 10) /* minimum size of buffer */ size = 10; if ((buff = (SMoBUFF *) malloc (sizeof (SMoBUFF))) == NULL) _ErrExit2 (e__allocfail, "buff object"); if ((buff->buff = (char *) malloc (size)) == NULL) _ErrExit2 (e__allocfail, "buff string"); buff->writePtr = buff->buff; buff->readPtr = buff->buff; buff->size = size; *buff->buff = '\0'; #ifdef DEBUG buffAllocN++; if (!(buffAllocN%1000)) fprintf (stderr, "BUFFERS: allocN: %d, freedN, %d\n", buffAllocN, buffFreedN); #endif return buff; } /**api* BuffInit ************************************************************** ** ** Creates a new buffer object if the buffer object's address is NULL ** otherwise just resets the buffer. ** ** INPUT: address of buffer object [R] (initially NULL) ** initial size in bytes [R] ** IMPLICIT: ** ** RETURNS: buffer object */ SMoBUFF *BuffInit (SMoBUFF *buff, INT4 size) { if (!buff) buff = BuffNew (size); else BuffReset (buff); return buff; } /**api* BuffReset ************************************************************* ** ** Resets a buffer object, ie, resets the "current" pointer to the buffer ** begin. ** ** INPUT: address of buffer object [R] ** IMPLICIT: ** ** RETURNS: */ void BuffReset (SMoBUFF *buff) { buff->writePtr = buff->buff; buff->readPtr = buff->buff; *buff->buff = '\0'; } /**api* BuffResetRead ********************************************************* ** ** Resets a the read pointer of a buffer object, ** ** INPUT: address of buffer object [R] ** IMPLICIT: ** ** RETURNS: */ void BuffResetRead (SMoBUFF *buff) { buff->readPtr = buff->buff; } /**api* BuffGetCurrOffset ***************************************************** ** ** Returns the offset of the current pointer from the buffer begin. ** ** INPUT: address of buffer object [R] ** IMPLICIT: ** ** RETURNS: offset */ INT4 BuffGetCurrOffset (SMoBUFF *buff) { return (INT4) (buff->writePtr - buff->buff); } /**api* BuffLength ************************************************************ ** ** Returns the offset of the current pointer from the buffer begin. ** ** INPUT: address of buffer object [R] ** IMPLICIT: ** ** RETURNS: offset */ INT4 BuffLength (SMoBUFF *buff) { return (INT4) (buff->writePtr - buff->buff); } /**api* BuffGetCurrPtr ******************************************************** ** ** Returns the current pointer, pointing to the current location in ** the buffer. ** ** INPUT: address of buffer object [R] ** IMPLICIT: ** ** RETURNS: current pointer */ char *BuffGetCurrPtr (SMoBUFF *buff) { return buff->writePtr; } /**api* BuffGetPtr ************************************************************ ** ** Returns the pointer to the buffer begin - this may change during buffer ** growth. ** ** INPUT: address of buffer object [R] ** IMPLICIT: ** ** RETURNS: current pointer */ char *BuffGetPtr (SMoBUFF *buff) { return buff->buff; } /**api* BuffCopyChar ********************************************************** ** ** Copies a single character to the buffer and advances current pointer. ** Doubles the buffer if the end of buffer is reached. Does NOT put ** a NULL character at the end! ** ** INPUT: address of buffer object [W] ** character value [R] ** IMPLICIT: ** ** RETURNS: */ void BuffCopyChar (SMoBUFF *buff, char c) { if ((INT4) (buff->writePtr - buff->buff) == buff->size) BuffGrow (buff, 1); *(buff->writePtr++) = c; } /**API* BuffCopyNChar ******************************************************* ** ** Copies exactly n characters to the buffer and advances current ** pointer. Doubles the buffer if the end of buffer is reached. ** Does NOT put a NULL character at the end. All the string will be ** copied if the length of s is n or more. ** ** INPUT: address of buffer object [W] ** string to be copied [R] ** IMPLICIT: ** ** RETURNS: */ void BuffCopyNChar (SMoBUFF *buff, char *s, INT4 n) { if(n > 0) { if ((INT4) (buff->writePtr - buff->buff + n) >= buff->size) BuffGrow (buff, n+1); strncpy (buff->writePtr, s, n); buff->writePtr += n; } } /**api* BuffCopyString ******************************************************** ** ** Copies a string to the buffer and advances current pointer. ** Doubles the buffer if the end of buffer is reached. ** ** INPUT: address of buffer object [W] ** string to be copied [R] ** IMPLICIT: ** ** RETURNS: */ void BuffCopyString (SMoBUFF *buff, char *s) { INT4 len; len = strlen (s); if ((INT4) (buff->writePtr - buff->buff + len) >= buff->size) BuffGrow (buff, len+1); strcpy (buff->writePtr, s); buff->writePtr += len; } /**api* BuffCat *************************************************************** ** ** Copies contents of second buffer to first buffer ** (analogous to 'strcat'). If the 'read pointer' is not at the ** buffer begin then that is used as begin of the buffer to ** be copied from. ** ** INPUT: address of buffer [W] ** address of buffer [R] ** IMPLICIT: ** ** RETURNS: */ void BuffCat (SMoBUFF *a, SMoBUFF *b) { INT4 len; len = b->writePtr - b->readPtr; _BuffCopyNChars (a, b->readPtr, len); *(a->writePtr) = '\0'; /* add NULL terminator */ } /**api* BuffPrintF ************************************************************ ** ** Copies a string to the buffer that is previously formatted (in a ** printf fashion. ** Doubles the buffer if the end of buffer is reached. ** ** INPUT: address of buffer object [W] ** string to be copied [R] ** IMPLICIT: ** ** RETURNS: */ void BuffPrintF (SMoBUFF *buff, char *formatStr, ...) { va_list ap; char s[2000]; va_start (ap, formatStr); vsprintf (s, formatStr, ap); va_end (ap); BuffCopyString (buff, s); } /**api* BuffVPrintF *********************************************************** ** ** Copies a string to the buffer that is previously formatted (in a ** printf fashion. ** Doubles the buffer if the end of buffer is reached. ** ** INPUT: address of buffer object [W] ** string to be copied [R] ** IMPLICIT: ** ** RETURNS: */ void BuffVPrintF (SMoBUFF *buff, char *formatStr, va_list ap) { char s[50000]; vsprintf (s, formatStr, ap); BuffCopyString (buff, s); } /****** BuffGrow ************************************************************** ** ** 'Grows' the buffer to double size or if this is not sufficient, ** by the specified size. ** ** INPUT: address of buffer object [W] ** minimum size by which to grow [W] ** IMPLICIT: ** ** RETURNS: */ void BuffGrow (SMoBUFF *buff, INT4 size) { INT4 off1, off2; if (buff->size < size) /* check if doubling is not enough */ buff->size += size; else buff->size = buff->size * 2; off1 = (INT4) (buff->writePtr - buff->buff); off2 = (INT4) (buff->readPtr - buff->buff); if ((buff->buff = (char *) realloc (buff->buff, buff->size)) == NULL) _ErrExit2 (e__allocfail, "buff string"); buff->writePtr = buff->buff + off1; buff->readPtr = buff->buff + off2; } /**api* BuffShiftCurrPtr ****************************************************** ** ** Shifts the current pointer by requested amont back (negative) or ** forward. ** ** INPUT: address of buffer object [W] ** IMPLICIT: ** ** RETURNS: */ void BuffShiftCurrPtr (SMoBUFF *buff, INT4 n) { buff->writePtr += n; /* should do some checking */ } /**api* BuffFill ************************************************************** ** ** Writes the specified number of times specified character into buffer. ** ** INPUT: address of buffer object [W] ** number of characters to write [R] ** character to write [R] ** ** RETURNS: 1 */ void BuffFill (SMoBUFF *buff, INT4 n, char c) { INT4 k; for (k=0; k < n; k++) { if ((INT4) (buff->writePtr - buff->buff + 1) >= buff->size) /* the 1 for the NULL char */ BuffGrow (buff, 1); *(buff->writePtr++) = c; } *(buff->writePtr) = '\0'; /* add NULL terminator - safer! */ } /**api* BuffTrim ************************************************************** ** ** Trims the buffer from begin and/or end ** ** INPUT: address of buffer object [W] ** option: "lf" trims line feed from end ** option: "continue" trims line feed from end ** ** RETURNS: 1 */ void BuffTrim (SMoBUFF *buff, char *option) { char *tmp; switch (tolower (option[0])) { case 'l': /* lf */ tmp = buff->writePtr; while (*(--tmp) == '\n') { *tmp = '\0'; buff->writePtr = tmp; } break; case 'c': /* continue */ tmp = buff->writePtr - 2; if (*tmp == '\\') { *tmp = '\0'; buff->writePtr -= 2; } break; default: _ErrExit2 (e__unknownoption, option); } } /**api* BuffToUpper *********************************************************** ** ** ** INPUT: address of buffer object [W] ** ** RETURNS: address of string */ char *BuffToUpper (SMoBUFF *buff) { SmEdit (buff->buff, SMxUPCASE); return buff->buff; } /**api* BuffToLower *********************************************************** ** ** ** INPUT: address of buffer object [W] ** ** RETURNS: address of string */ char *BuffToLower (SMoBUFF *buff) { SmEdit (buff->buff, SMxLOWCASE); return buff->buff; } /**api* BuffSearchSensitive ********************************************* ** ** Searches a string and returns pointer to string if found. ** Search is case sensitive. ** ** INPUT: buffer object [R] ** address of string [R] ** ** RETURNS: pointer to location if found ** NULL if not */ char *BuffSearchSensitive (SMoBUFF *buff, char *s) { BuffCopyChar (buff, '\0'); /* make sure there is a NULL terminator */ BuffShiftCurrPtr (buff, -1); return strstr (buff->buff, s); } /**api* BuffSearch ************************************************************ ** ** Searches a string and returns pointer to string if found. ** Search is case insensitive. ** ** INPUT: buffer object [R] ** address of string [R] ** ** RETURNS: pointer to location if found ** NULL if not */ char *BuffSearch (SMoBUFF *buff, char *s) { char *buf; INT4 len = strlen(s); BuffCopyChar (buff, '\0'); /* make sure there is a NULL terminator */ BuffShiftCurrPtr (buff, -1); for (buf = buff->buff; *buf; buf++) if (!SmStrCmpLen(buf, s, len)) { return buf; } return NULL; } /**api* BuffDuplicate **************************************************** ** ** Creates a new buffer object with the necessary initial size ** and copies the existing buffer to it. ** ** INPUT: address of buffer object [R] ** IMPLICIT: ** ** RETURNS: buffer object */ SMoBUFF *BuffDuplicate(SMoBUFF *oldBuff) { SMoBUFF *buff; INT4 size; size = strlen(oldBuff->buff) + 1; if ((buff = (SMoBUFF *) malloc (sizeof (SMoBUFF))) == NULL) _ErrExit2 (e__allocfail, "buff object"); if ((buff->buff = (char *) malloc (size)) == NULL) _ErrExit2 (e__allocfail, "buff string"); strcpy(buff->buff, oldBuff->buff); /* copy content of buffer */ buff->writePtr = buff->buff+size-1; buff->size = size; return buff; } /**api* BuffIsEmpty ***************************************************** ** ** Returns TRUE if buffer object is empty, FALSE otherwise ** ** INPUT: address of buffer object [R] ** IMPLICIT: ** ** RETURNS: 1 if buffer object empty ** 0 otherwise */ INT4 BuffIsEmpty(SMoBUFF *buff) { if (buff->writePtr == buff->buff) return 1; else return 0; } /**api* BuffDelete ******************************************************* ** ** Deletes a buffer object and frees the allocated memory. ** ** INPUT: address of buffer object [R] ** IMPLICIT: ** ** RETURNS: nothing */ void BuffDelete(SMoBUFF **buff) { #ifdef DEBUG buffFreedN++; #endif free((*buff)->buff); free(*buff); *buff = NULL; } /**api* BuffPrint ******************************************************* ** ** Prints the string contained in a buffer object. ** ** INPUT: address of buffer object [R] ** IMPLICIT: ** ** RETURNS: nothing */ void BuffPrint (FILE *file, SMoBUFF *buff) { if (file) fprintf (file, "%s", buff->buff); else printf ("%s", buff->buff); } /**api* BuffReadFile ********************************************************** ** ** Prints the string contained in a buffer object. ** ** INPUT: address of buffer object [R] ** IMPLICIT: ** ** RETURNS: nothing */ void BuffReadFile (SMoBUFF *buff, FILE *file, INT4 size) { _BuffReserve (buff, size); fread (buff->writePtr, 1, size, file); _BuffIncWrite (buff, size); } /**api* BuffReadLine ********************************************************** ** ** Reads a line from file into the buffer; ** ** INPUT: address of buffer object [R] ** IMPLICIT: ** ** RETURNS: nothing */ int BuffReadLine (SMoBUFF *buff, FILE *file, int maxLen) { char *tmp; int len; _BuffReserve (buff, maxLen); if (!(tmp = fgets (buff->writePtr, maxLen, file))) return 0; else { len = strlen (tmp); _BuffIncWrite (buff, len); return 1; } } /**api* BuffCollapse ********************************************************** ** ** Replaces a stretch of whitespace chars by single blankl ** ** INPUT: address of buffer object [R] ** IMPLICIT: ** ** RETURNS: pointer to string */ char *BuffCollapse (SMoBUFF *buff) { char *w, *r; *buff->writePtr = '\0'; for (w=r=buff->buff; *r != '\0'; r++) { if (*r == ' ') { *w++ = ' '; while (*r == ' ') r++; r--; } else *w++ = *r; } *w = *r; buff->writePtr = buff->buff + strlen (buff->buff); return buff->buff; } /**api* BuffFormat *********************************************************** ** ** Returns the formatted string; string returned 'owned' by the function ** so make sure you do something with it before calling the function ** again. ** ** INPUT: address of buffer object [W] ** maximum length of the output line [R] ** identation of first line [R] or 0 ** identation of all/following line [R] ** text to be printed in front of each line [R] or NULL ** IMPLICIT: ** ** RETURNS: current pointer */ char *BuffFormat (SMoBUFF *buff, INT4 lineSize, INT4 firstIdent, INT4 allIdent, char *leftText) { static SMoBUFF *tmp=NULL; char *p, *pSave; INT4 k, lineLen; if (leftText) allIdent = strlen (leftText); if (!tmp) tmp = BuffNew (lineSize); else BuffReset (tmp); /* text or ident to the left of first line */ if (leftText) BuffCopyString (tmp, leftText); else if (firstIdent) BuffFill (tmp, firstIdent, ' '); lineLen = BuffGetCurrOffset(tmp); p = buff->buff; k = lineLen + (buff->writePtr - p); while (k >= lineSize) { pSave = p; p += lineSize - lineLen; while (*p != ' ' && p > pSave) /* find the next ' ' backwards */ p--; if (p == pSave) /* if no space was found break at line end */ p += lineSize - lineLen; *(p++) = '\0'; BuffCopyString (tmp, pSave); BuffCopyChar (tmp, '\n'); /* text or ident to the left of following lines */ if (leftText) BuffCopyString (tmp, leftText); else BuffFill (tmp, allIdent, ' '); lineLen = allIdent; k = lineLen + (buff->writePtr - p); } BuffCopyString (tmp, p); return tmp->buff; } char *SmScanNumber (char *s, INT4 *num) { *num = 0; while (isdigit (*s)) *num = *num * 10 + (*s++ - '0'); return s; /* points to first character after number */ } char *BuffExpandTemplate (char *template) { static char newTemplate[100]; char *tmp; INT4 k, l; for (k=0, tmp=template; *tmp;) { if (!isdigit (*tmp)) newTemplate[k++] = *tmp++; else { if (strchr ("aA", *(tmp-1)) == NULL) { tmp = SmScanNumber (tmp, &l); while (--l) { newTemplate[k] = newTemplate[k-1]; k++; } } else while (isdigit (*tmp)) newTemplate[k++] = *tmp++; } } newTemplate[k] = '\0'; return newTemplate; } #define BYTE1 0xFFUL #define BYTE2 0xFF00UL #define BYTE3 0xFF0000UL #define BYTE4 0xFF000000UL /**api* BuffPack ************************************************************** ** ** Returns the formatted string; string returned 'owned' by the function ** so make sure you do something with it before calling the function ** again. ** ** INPUT: address of buffer object [W] ** maximum length of the output line [R] ** identation of first line [R] or 0 ** identation of all/following line [R] ** text to be printed in front of each line [R] or NULL ** IMPLICIT: ** ** RETURNS: current pointer */ void BuffPack (SMoBUFF *buff, char *template, ...) { va_list ap; char *s, *tmp; INT4 n, len; va_start (ap, template); for (tmp=template; *tmp; tmp++) { switch (*tmp) { case 'a': /* ASCII string */ s = va_arg (ap, char *); if (isdigit (tmp[1])) tmp = SmScanNumber (tmp+1, &len) - 1; else len = strlen (s) + 1; _BuffReserve (buff, len); strncpy (buff->writePtr, s, len); _BuffIncWrite (buff, len); break; case 'i': /* signed integer */ n = va_arg (ap, INT4); _BuffReserve (buff, 4); buff->writePtr[0] = n & BYTE1; buff->writePtr[1] = (n & BYTE2) >> 8; buff->writePtr[2] = (n & BYTE3) >> 16; buff->writePtr[3] = (n & BYTE4) >> 24; _BuffIncWrite (buff, 4); break; default: /* digit ...or whitespace */ if (isdigit (*tmp)) { int diff; diff = tmp - template; tmp = BuffExpandTemplate (template); tmp += diff -1; } } } va_end (ap); } /**api* BuffUnPack ************************************************************ ** ** Unpacks items from buffer, a number after the item means ** repetition, except after 'a' or 'z' where it means length. ** ** a: copy of ASCII string ** z: pointer to ASCII string ** i: 4 byte signed integer ** ** INPUT: address of buffer object [W] ** template string [R] ** list of pointers to receive unpacked values ** IMPLICIT: ** ** RETURNS: 1 if successful ** 0 if not all items could be read */ INT4 BuffUnpack (SMoBUFF *buff, char *template, ...) { va_list ap; char *s, **sPtr, *tmp; INT4 *n, len; va_start (ap, template); for (tmp=template; *tmp; tmp++) { if (buff->readPtr >= buff->writePtr) return 0; switch (*tmp) { case 'a': /* ASCII string */ s = va_arg (ap, char *); if (isdigit (tmp[1])) { tmp = SmScanNumber (tmp+1, &len) - 1; strncpy (s, buff->readPtr, len); s[len] = '\0'; } else { strcpy (s, buff->readPtr); len = strlen (s) + 1; } _BuffIncRead (buff, len); break; case 'z': /* pointer to ASCII string */ sPtr = va_arg (ap, char **); *sPtr = buff->readPtr; if (isdigit (tmp[1])) tmp = SmScanNumber (tmp+1, &len) - 1; else len = strlen (*sPtr) + 1; _BuffIncRead (buff, len); break; case 'i': /* signed integer */ n = va_arg (ap, INT4 *); *n = ((UINT4) ((unsigned char) buff->readPtr[0])) + ((UINT4) ((unsigned char) buff->readPtr[1]) << 8) + ((UINT4) ((unsigned char) buff->readPtr[2]) << 16) + ((UINT4) ((unsigned char) buff->readPtr[3]) << 24); _BuffIncRead (buff, 4); break; default: /* digit ...or whitespace */ if (isdigit (*tmp)) { int diff; diff = tmp - template; tmp = BuffExpandTemplate (template); tmp += diff -1; } } } va_end (ap); return 1; } static regexp *regCurr=NULL; /****** BuffMatch ************************************************************* ** ** Matches a string against a regular expression. ** Use RegGetField to extract fields denoted by parentheses or the ** entire match. ** ** INPUT: buffer object to be searched [R] ** string with regular expression [R] ** IMPLICIT: ** ** RETURNS: 1 if string matches ** 0 if not */ int BuffMatch (SMoBUFF *buff, char *reStr) { static int classId = 0; static struct SMoRE { char *list; /* for usage of module "list" only! */ INT4 class_id; /* for "list" module */ char nam[100]; regexp *re; } *re=NULL; if (!classId) LstManageClass (&classId, sizeof (struct SMoRE), NULL, NULL, NULL); if (!LstHashSearch ((void **) &re, reStr)) { LstNewNamed ((void **) &re, classId, reStr); re->re = RegComp (reStr); } regCurr = re->re; return RegExec (re->re, buff->buff) ? 1 : 0; } /****** RegGetMatch *********************************************************** ** ** Extracts entire match (field number 0) or subfield from previous ** regular expression match by RegMatch. ** ** INPUT: number of match to be returned [R] ** IMPLICIT: ** regCurr (regexp *) ** ** RETURNS: string ** NULL if invalid number specified */ char *BuffGetMatch (int n) { static SMoBUFF *b[10]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; static INT4 cnt=0; SMoBUFF *buff=b[cnt++%10]; char *endp, *startp; int len; if (!buff) buff = BuffNew(100); else BuffReset (buff); if (n >= 0 && n <= 9 && regCurr) { startp = regCurr->startp[n]; endp = regCurr->endp[n]; len = endp - startp; _BuffCopyNChars (buff, startp, len); BuffCopyChar (buff, '\0'); return buff->buff; } return NULL; } /****** BuffSubstMatch ************************************************************** ** ** Replaces match by previous regular expression with specified number ** by specified string. ** ** INPUT: address of buffer object [W] ** number of match to be replaced [R] ** replacement string [R] ** IMPLICIT: ** regCurr (regexp *) ** ** RETURNS: */ char *BuffSubstMatch (SMoBUFF *buff, int n, char *s) { char *endp, *startp; int lenMatch, lenS, shift; if (n >= 0 && n <= 9 && regCurr) { startp = regCurr->startp[n]; endp = regCurr->endp[n]; lenMatch = endp - startp; lenS = strlen (s); shift = lenS - lenMatch; if (shift > 0) _BuffReserve (buff, shift); if (shift != 0) SmMemMove (endp+shift, endp, buff->writePtr - endp+1); memcpy (startp, s, lenS); } _BuffIncWrite (buff, shift); return buff->buff; } /****** BuffReplace *********************************************************** ** ** ** INPUT: address of buffer object [W] ** pointer inside the buff to the substring to be replaced [W] ** length of string to be replaced [R] ** replacement string [R] ** length of that substring [R] ** IMPLICIT: ** ** RETURNS: ** pointer to the beginning of the target into the buffer */ char *BuffReplace (SMoBUFF *buff, char *target, INT4 targetLen, char *s, INT4 lenS) { char *endPtr; INT4 off, shift; off = (INT4)(target - buff->buff) + targetLen; shift = lenS - targetLen; if (shift > 0) _BuffReserve (buff, shift); if (shift != 0) { endPtr = buff->buff + off; SmMemMove (endPtr + shift, endPtr, buff->writePtr - endPtr + 1); memcpy (endPtr - targetLen, s, lenS); } _BuffIncWrite (buff, shift); return endPtr-targetLen; } #ifdef MAIN INT4 SDL_fnct(){} main() { SMoBUFF *test; char *ptr; test = BuffInit(NULL, 1000); BuffCopyString(test, "1234567890abcdefghi"); ptr = BuffGetPtr(test) + 5; ptr = BuffReplace(test, ptr, 3, "XXXXX", 5); printf("%s %s\n", BuffGetPtr(test), ptr); ptr = BuffReplace(test, BuffGetPtr(test), 5, "YYxxx", 2); printf("%s %s\n", BuffGetPtr(test), ptr); } #endif /**api* SmIsSeparator ******************************************************* ** ** Determines whether the input contains trivial character or not ** ** INPUT: address of input string ** separator character ** ** RETURNS: true if all the chars of input string are same ** false otherwise */ INT4 SmIsSeperator(char *s, char c) { while(*s) if( *s++ != c) return -1; return 1; } est, BuffGetPtr(test), 5, "YYxxx", 2); printf("%s %s\n", BuffGetPtr(test), ptr); } #endif /**api* SmIsSeparator ******************************************************* ** ** Determines whether the input contains trivial character or not ** ** INPUT: address of input string ** separator character ** ** RETURNS: true if all the chars of input string are same ** falsrs/src/sm.h ** ** $RCSfile: sm.h,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:17:22 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port: Lukas Rosenthaler and Reinhard Doelz ** */ #include #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #ifndef MAX #define MAX(a,b) ((a)<(b) ? (b) : (a)) #endif #ifndef MIN #define MIN(a,b) ((a)<(b) ? (a) : (b)) #endif #define SMxXTMP 512 #define SMxXITEML 80 #define SMxSKIP 0 #define SMxNOSKIP 1 #define SMxMIXCASE 0 #define SMxTRIM 1 #define SMxUPCASE 2 #define SMxLOWCASE 4 #define SMxDECODE 8 #define SMxDETAB 16 #define SMxLEAD 32 #define SMxTRAIL 64 #define SMxTRIM2 128 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** buffer object; */ typedef struct SMoBUFF { char *buff; char *writePtr; char *readPtr; INT4 size; } SMoBUFF, *SMpBUFF; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of functions to be exported */ char *SmFLen (char *s,...); char *SmFill (char *str, INT4 n, char c); char *SmEdit (char *s, UINT4 bm); char *SmTime (unsigned long time_val); INT4 SmSwap (char *s, char a, char b); INT4 SmSwapS (char *s, char *a, char *b); INT4 SmElement (char *a, char *b, char tok, INT4 n, INT4 skip_o); char *SmCharSet (char *s); char *SmStrTok (char *str, char *tok); INT4 SmSwapFirst (char *str, char *search, char *replace); /* string comparison */ INT4 SmEqs (char *a, char *b); INT4 SmMixLoc(char *str1, char *str2, INT4 l, INT4 r); INT4 SmXLoc(char *str1, char *str2, INT4 l, INT4 r); INT4 SmLoc(char *str1, char *str2); INT4 SmStrCmp (char *a, char *b); INT4 SmStrCmpLen (char *a, char *b, INT4 len); INT4 SmRStrCmp (char *a, char *b); INT4 SmRStrCmpLen (char *a, char *b, INT4 len); INT4 SmBinLoc(char *str1, char *str2, INT4 len1, INT4 len2); /* buffer Management */ struct SMoBUFF *BuffNew (INT4 initSize); void BuffReset (struct SMoBUFF *buff); struct SMoBUFF *BuffInit (struct SMoBUFF *buff, INT4 initSize); void BuffResetRead (SMoBUFF *buff); void BuffGrow (SMoBUFF *buff, INT4 size); INT4 BuffLength (struct SMoBUFF *buff); INT4 BuffGetCurrOffset (struct SMoBUFF *buff); char *BuffGetCurrPtr (struct SMoBUFF *buff); char *BuffGetPtr (struct SMoBUFF *buff); void BuffCopyChar (struct SMoBUFF *buff, char c); void BuffCopyString (struct SMoBUFF *buff, char *s); void BuffPrintF (SMoBUFF *buff, char *formatStr, ...); void BuffVPrintF (SMoBUFF *buff, char *formatStr, va_list ap); void BuffShiftCurrPtr (SMoBUFF *buff, INT4 n); void BuffFill (SMoBUFF *buff, INT4 n, char c); /* buffer editing */ void BuffCat (SMoBUFF *a, SMoBUFF *b); void BuffTrim (SMoBUFF *buff, char *option); char *BuffToUpper (SMoBUFF *buff); char *BuffToLower (SMoBUFF *buff); char *BuffSearchSensitive (SMoBUFF *buff, char *s); char *BuffSearch (SMoBUFF *buff, char *s); SMoBUFF *BuffDuplicate(SMoBUFF *oldBuff); INT4 BuffIsEmpty(SMoBUFF *buff); void BuffDelete(SMoBUFF **buff); void BuffPrint (FILE *file, SMoBUFF *buff); void BuffReadFile (SMoBUFF *buff, FILE *file, int size); int BuffReadLine (SMoBUFF *buff, FILE *file, int maxLen); char *BuffCollapse (SMoBUFF *buff); char *BuffReplace (SMoBUFF *buff, char *target, INT4 targetLen, char *s, INT4 lenS); char *BuffFormat (SMoBUFF *buff, INT4 lineSize, INT4 firstIdent, INT4 allIdent, char *leftText); void BuffPack (SMoBUFF *buff, char *template, ...); INT4 BuffUnpack (SMoBUFF *buff, char *template, ...); /* regular expressions */ int BuffMatch (SMoBUFF *buff, char *reStr); char *BuffGetMatch (int n); char *BuffSubstMatch (SMoBUFF *buff, int n, char *s); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** BuffCopyNChar as macro */ #define _BuffCopyNChars(b, s, len) \ {\ if ((INT4) ((b)->writePtr - (b)->buff + (len)) >= (b)->size) \ BuffGrow ((b), (len));\ memcpy ((b)->writePtr, (s), (len));\ (b)->writePtr += (len);\ } #define _BuffReserve(buffer,len) \ if ((INT4) ((buffer)->writePtr - (buffer)->buff + (len)) >= (buffer)->size) \ BuffGrow ((buffer), len+1) int n); char *BuffSubstMatch (SMoBUFF *buff, int n, char *s); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** BuffCopyNChar as macro */ #define _BuffCopyNChars(b, s, len) \ {\ if ((INT4) ((b)->writePtr - (b)->buff + (len)) >= (b)->size) \ BuffGrow ((b), (len));\ memcpy ((b)->writePtr, (s), (len));\ (b)->writePtr += (lesrs/src/srs.h ** ** $RCSfile: srs.h,v $ ** $Revision: 1.6 $ ** $Date: 1997/03/12 16:17:46 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** This file must be included by applications that bind to the SRS library ** */ #include "def.h" #include "message.h" #include "futil.h" #include "sm.h" #include "tm.h" #include "strv.h" #include "dict.h" #include "idx.h" #include "seq.h" #include "par.h" #include "variable.h" #include "arglist.h" #include "id.h" #include "set.h" #include "entry.h" #include "seqdb.h" #include "library.h" #include "seqlib.h" #include "query.h" #include "queryass.h" #include "templ.h" #include "link.h" #include "toklist.h" #include "cursor.h" #include "icarus.h" #include "icabnf.h" #include "view.h" #include "appl.h" # define _CONSTANTS # define _SRS # define _SLB # define _SYNTAX #ifndef DECLARE_ONLY # define _FUNCTION # define QUERY_M # define XQUERY_M # define SEQLIB_M #endif #include "srs5.h" #ifndef DECLARE_ONLY # ifndef NO_ENVIRONMENT # ifndef VMS # include "srsenv.h" # endif # endif # include "odd.h" # define _INITOBJS # define _CONSTANTS # define _SDL # define _ODD # define _FUNCTION # include "oddclass.h" #endif .h" #include "icarus.h" #include "icabnf.h" #include "view.h" #include "appl.h" # define _CONSTANTS # define _SRS # define _SLB # define _SYNTAX #ifndef DECLARE_ONLY # define _FUNCTION # define QUERY_M # define XQUERY_M # define SEQLIB_M #endif #isrs/src/srs5.h ** ** $RCSfile: srs5.h,v $ ** $Revision: 1.20 $ ** $Date: 1997/03/13 19:40:06 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** from ODD file: "srsica:srs.i" ** date of ODD compilation: 13-MAR-1997 19:09 ** */ #define O_SRSDB 12 #define LIBxFILE 1 #define LIBxNAME 2 #define LIBxPATH 3 #if defined(_SRS) && !defined(_ICAoSYNTAX) #define _ICAoSYNTAX typedef struct ICAoSYNTAX { char *name; /* Name of the syntax. */ char *fileName; /* Name of the Icarus file with the production list. */ char *rules; /* Pointer to the production list. */ struct SMoBUFF_ *buff; /* Name of the file with ICA rules */ struct ICAoSYNTAX *commandSyntax; /* The syntax of for the commands */ struct ICAoNAMELIST *prodList; /* List of productions */ struct ICAoCOMMAND *userCommand; struct taskList *taskList; char *ign; /* String containing characters to be ignored or skipped during parsing (white space). */ char *lf; /* A regular expression to skip comments. */ unsigned char linkFlag; struct VARo *prod; struct VARoSCOPE *scope; struct regexp *cmntRe; char *ignAlt; } ICAoSYNTAX; #endif #ifndef _PARo #define _PARo typedef struct PARo { char *intern; /* for internal use for the list manager */ INT4 classId; /* for internal use for the list manager */ char *name; /* name of associated global parameter */ char *str; /* Value of 'string' parameter. */ INT4 num; /* Value of 'number' parameter. */ float real; /* Value of 'real' parameter. */ INT4 (*function) (); /* Value of 'function' parameter. */ void *object; /* Value of 'object' parameter. */ unsigned char isVolatile; unsigned char type; /* Parameter type. */ char *comment; /* Short description of parameter. */ char *helpTopic; /* help topic associated to parameter */ char *key; /* keystroke associated to parameter or value */ struct PARoTYPE *parType; /* Object 'partype' for validating the parameter value. */ struct PARoTYPE *check; /* Object 'partype' for validating the parameter value. */ INT4 isLocked; /* internal use... */ char *set; /* Icarus command to set the current value. */ char *get; /* Icarus command to get the current value. */ } PARo; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Describes further a parameter type by specifying constraints or a function for checking the parameter value. */ #ifndef _PARoTYPE #define _PARoTYPE typedef struct PARoTYPE { char *intern; /* for internal use for the list manager */ INT4 classId; /* for internal use for the list manager */ char *name; /* Name of associated global parameter. */ INT4 (*check) (); /* Function that checks parameter value. */ INT4 max; /* Max value, or max length. */ INT4 min; /* Mmin value, or min length. */ float maxReal; /* Max real value. */ float minReal; /* Min real value. */ char *charSet; /* Permissible set of chars for parameter value string. */ } PARoTYPE; #endif #ifndef _PARoLIST #define _PARoLIST typedef struct PARoLIST { struct PARo *par; /* List of all predefined parameters. */ INT4 parN; /* Number of predefined parameters. */ struct PARoTYPE *parType; /* List of all predefined parameter types. */ INT4 parTypeN; /* Number of predefined parameter types. */ } PARoLIST; #endif #ifndef _arg_t #define _arg_t typedef struct arg_t { char *name; INT4 type; char *parameter; char *comment; INT4 (*check) (); INT4 defaultNum; char *defaultStr; float defaultReal; } arg_t; #endif #ifndef _ARGoLIST #define _ARGoLIST typedef struct ARGoLIST { char *name; char *usage; struct arg_t *arg; INT4 argN; } ARGoLIST; #endif #if defined(_SRS) && !defined(_SLBoFIL) #define _SLBoFIL typedef struct SLBoFIL { char *nam; /* File name without extension and directory name. */ char *lnam; /* Logical name (meaningful only for GCG programs)/ */ INT4 isBad; /* This flag will be set upon failure to open this file */ } SLBoFIL; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Top level object of the databank (library) description. */ #if defined(_SRS) && !defined(_SLBo) #define _SLBo typedef struct SLBo { char *nam; /*API Name of library. */ char *shortName; /*API Short name for library - needed for DOS file names. */ char *lnam[3]; /* Logical name(s) for the library (GCG). */ struct SRSoGROUP *group; /* Library group this library belongs to. */ struct SLBo *parent; /* Library can be a virtual library of subentries. In that case this attribute must point to the library of parent entries. */ struct SLBoFORM *form; /* Pointer to the format description. */ char *dirName[3]; /* Address of Name of directory with all flat files. */ char *cmnt; /* One line comment on library. */ char *ifiles; /* Name of the Icarus file(s) with the databank description. */ INT4 idNum; INT4 maxNameLen; /* max length of unique entry name - important for ID-index */ INT4 maxIndexSizeKb; INT4 csiz; struct SLBoFIL *fil; /* list of pointers to file descriptions */ INT4 nfil; /* number of file descriptions */ unsigned char skey; unsigned char isFromUser; unsigned char dataType; char *indexDirName; /* Address of the name of the directory with the SRS indices. */ INT4 pargroup; unsigned char upd_f; unsigned char updlink_f; unsigned char isActive; /* Flag if library is active. */ unsigned char isInit; /* Flag if library is initiated. */ struct FILo *file[4]; INT4 allEntryCnt; INT4 newEntryCnt; INT4 updEntryCnt; char *entryNam; struct IDoENTRY *idCurr; struct TOKoLIST *tokList; struct ICAoJOB *job; unsigned char partFiles; /* Single flat files are to be indexed as separate parts for later merging. */ struct SLBo *subEntries[10]; /* List of all $library objects that represent subentry types. */ INT4 partSize; /* Size of the databank part in number of entries to be indexed separately for later merging. */ } SLBo; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Associates a number between 1 and 255 (library-ID) and a library (databank). */ #if defined(_SRS) && !defined(_LIBoID) #define _LIBoID typedef struct LIBoID { struct SLBo *library; /* Library object. */ INT4 n; /* Library-ID to be associated to the library */ } LIBoID; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** List of active libraries together with their directory names. A particular environment can be selected by defining the parameter 'environment' */ #if defined(_SRS) && !defined(_LIBoENV) #define _LIBoENV typedef struct LIBoENV { char *name; /* Name of the environment. */ struct LIBoLIBENV *libenv; /* List of active libraries. */ INT4 libenvN; /* Number of libraries in that list. */ } LIBoENV; #endif #if defined(_SRS) && !defined(_LIBoLIBENV) #define _LIBoLIBENV typedef struct LIBoLIBENV { struct SLBo *lib; /* Library object. */ char *dirName[3]; /* List of directory names with the library's flat files. The files will be searched in the directories in the same order as of the list. */ char *indexDirName; /* Name of the directory with the SRS indices. */ } LIBoLIBENV; #endif #if defined(_SRS) && !defined(_SRSoDB) #define _SRSoDB typedef struct SRSoDB { struct LIBoID *libId; INT4 libIdN; struct LIBoENV *environment; /* List of defined library environments. */ INT4 environmentN; /* Number of defined library environments. */ struct SLBo *slb; INT4 nslb; struct SRSoGROUP *group; INT4 ngroup; struct SRSoFLD *fld; INT4 nfld; struct IDoTYPE *iddsc; INT4 niddsc; struct SRSoFILTYP *filtyp; INT4 nfiltyp; struct LINKo *lnk; INT4 nlnk; struct ICAoSYNTAX *syntax; INT4 syntaxN; struct ARGoLIST *command; INT4 commandN; struct APPLo *application; INT4 applicationN; struct PARoLIST *parTable; /* table of predefined global parameters */ struct VIEWo *view; INT4 viewN; struct LIBoHREF *href; INT4 hrefN; INT4 xcopy_n; INT4 xlist_n; INT4 copy_fst; INT4 list_fst; struct SLBo **libTable; } SRSoDB; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Description of a library (databank) group. */ #if defined(_SRS) && !defined(_SRSoGROUP) #define _SRSoGROUP typedef struct SRSoGROUP { char *key; char *com; /*API Name of library group. */ char *short_nm; /*API Short name (abbreviation) of library group. */ char *cmnt; /* A single line of text describing the group. */ char *help; unsigned char single_f; /* This flag determines if all libraries in the group can be searched simultaneously or one at a time (this is advisable if the libraries differ greatly in their data-fields. */ struct SLBo *library[50]; /* Pointers to the libraries in the group */ INT4 libraryN; struct SLBoFIELD *field[500]; INT4 fieldN; char *fieldCount; unsigned char upd_f; } SRSoGROUP; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Description of a data-field within a library. */ #ifndef _SLBoFIELD #define _SLBoFIELD typedef struct SLBoFIELD { unsigned char index; /* Index type - 'show' means that the field can be displayed only; 'group' points to a group of indices. */ char *name; char *code; /* Code of the token in the 'fields' token list that contains the data-field. */ INT4 fieldTokCode; char *token; /* If the data-field is not contained in the 'fields' token list the full name 'tokenList|code' must be specified here. */ struct IDoTYPE *indexId; /* The ID-type description for the IDs that will be put into the index. */ char *indexToken[5]; /* The name of the token list that supplies the values for indexing. The list name may be followed by a token code separated by ':'. */ INT4 indexTokCode[5]; unsigned char isSystem; /* A 'system' data field is only for internal use and should be ignored by a user interface. */ unsigned char keyConvert; /* Directs conversion of index strings. */ struct SRSoFLD *type; /*API Object that describes the data-field type. */ struct SRSoFLD *replace; /*API Field type of corresponding field object from parent entry in case it is not the same. */ struct SLBoFIELD *parent; /* Indicates if the field definition of the parent entry library should be taken instead. */ struct IDXo *idx; struct INXo *inx; struct BTRo *btree; struct IDSoFILE *idFile; unsigned char do_f; INT4 *on_fp; INT4 pargroup; unsigned char done_f; unsigned char noerrmsg_f; /* Supresses printing of parsing error messages. */ char *format; /* Name of default format of the contents of a field (see $srsfield). */ char *tableToken; /* Name of the table and the token code. */ INT4 tableTokCode; unsigned char tableFormat; /* The format of the default as displayed inside a 'table view'. If left unspecified then the same attribute of the 'format' object is read. */ } SLBoFIELD; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Specifies the parser to be used for parsing all data-fields of a library, its flat file format and has a list of all data-field descriptions. */ #if defined(_SLB) && !defined(_SLBoFORM) #define _SLBoFORM typedef struct SLBoFORM { struct SLBoFIELD *f; INT4 nf; unsigned char access_f; struct ICAoSYNTAX *syntax; /* The syntax of the flat file entry. */ struct SRSoFILTYP *fil_t[4]; /* List of flat file types. There can be more than (eg, the sequence and annotation are stored in two different files). */ unsigned char tableFormat; unsigned char printFormat; struct DICTo *tokenDict; INT4 isInit; struct LIBoDataType *contains[5]; /* List of types of data contained in the databank described. */ } SLBoFORM; #endif #ifndef _LIBoFieldFormat #define _LIBoFieldFormat typedef struct LIBoFieldFormat { char *name; char *eval; INT4 isSelected; } LIBoFieldFormat; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Description of a data-field Type (eg, 'Authors'). */ #if defined(_SRS) && !defined(_SRSoFLD) #define _SRSoFLD typedef struct SRSoFLD { char *shortn; /*API Short name (abbreviation) of data-field type */ char *nam; /*API Short name of data-field type */ char *cmnt; INT4 pargroup; unsigned char ityp; /* The type of the field type. At the moment only 'header' is used. The other types should be used to enforce a certain type on all the library fields referencing them. */ unsigned char isGroup; /* field type: single or group (of other field types) */ struct SRSoFLD *group; /* pointer to the field type group */ struct LIBoFieldFormat *format; INT4 formatN; } SRSoFLD; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Every entry of every databank indexed in SRS is represented by an entry-ID which uniquely identifies it. Several ID types are defined (eg, entry-ID, seq-ID, 3D-ID). Only the subentry-ID is structurally different from the others. */ #if defined(_SRS) && !defined(_IDoTYPE) #define _IDoTYPE typedef struct IDoTYPE { char *nam; /* Name of Id-type. */ INT4 siz; /* Size of ID in number of bytes. */ INT4 fddbeg; /* Offset of fadd (file address within IDX file) within ID. */ INT4 fddlen; /* Size of fadd in bytes. */ INT4 lbxbeg; /* Offset of databank-ID within ID. */ INT4 lbxlen; /* Size of databank-ID in bytes. */ INT4 lxbeg; /* Offset of subentry number within ID. */ INT4 lxlen; /* Size of subentry number in bytes. */ INT4 (*cpy) (); /* Function for printing an individual entry represented by ID. */ } IDoTYPE; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Describes a flat file type. Databanks may have more than one flat file type, eg, databanks in PIR or GCG with 'ref'-files containing the sequence annotation and 'seq'-files with the sequence. */ #if defined(_SRS) && !defined(_SRSoFILTYP) #define _SRSoFILTYP typedef struct SRSoFILTYP { char *name; /* Symbolic name of the file. */ char *typ_nm; /* File extension name. */ char *searchName; /* A search string used for finding all files in the specified directory (only for file per entry databanks). Any number of wildcards ('*' - matches all, '?' matches all single character) may be used. */ INT4 ln_z; UINT4 context; char *fipVar; /* Name of the Icarus variable containing the file address of the entry begin. */ struct SRSoFILTYP *shareWith; /* The file type can be only logical and the actual file object shared with another file type. It is to pretend that input comes from two different files where in fact it doesn't. */ char *fieldTokens; /* Name of the token table that has one token for each data-field of the entry. */ INT4 saveName; /* For databanks where each entry resides in a separate file where the file name cannot be inferred from the entry name. Option to request the whole or part of the file name to be saved in the IDX index. */ INT4 saveNameLength; /* Max. length of the name saved according to 'saveName'. */ unsigned char sngl_f; /* Selects a file has only one single entry. */ char *pipe; /* Format string (printf style) to create a command for processing the entry file before reading (eg, 'uncompress %%s'). */ } SRSoFILTYP; #endif #ifndef _LIBoSUBENTRY #define _LIBoSUBENTRY typedef struct LIBoSUBENTRY { char *name; struct IDoTYPE *idType; struct SRSoFLD *first; struct SLBoFIELD *fields; /* The Definition of the fields of the subentry. Each field must correspond to a field in the parent entry. Part of the definition (such as 'token' can 'shadow' the definition of the parent). */ INT4 fieldsN; } LIBoSUBENTRY; #endif #ifndef _LIBoHREF #define _LIBoHREF typedef struct LIBoHREF { char *name; char *link; } LIBoHREF; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Specifies a link between two libraries. A link can be built by using two indices built from one data-field of each library ('type=index') or by reading one library and processing cross-reference data ('type=read'). */ #if defined(_SRS) && !defined(_LINKo) #define _LINKo typedef struct LINKo { INT4 val; /* The weight attached to a link can be used to eliminate ambiguities during path resolution, or to force a certain path. */ char *token; INT4 tokCode; INT4 codeNum; char *nam1; /* Name of the first library - in case not the library name itself. */ char *nam2; /* Name of the first library - in case not the library name itself. */ struct IDoTYPE *id1_d; /* Object describing the first library's ID's to be linked. */ struct IDoTYPE *id2_d; /* Object describing the second library's ID's to be linked. */ struct SLBo *lib1; /* Object desribing the first library. */ struct SLBo *lib2; /* Object desribing the second library. */ struct SRSoFLD *fromField; /* Object describing the data-field of first library providing link information (only for index links). */ struct SRSoFLD *toField; /* Object describing the data-field of second library providing link information (for both index- and read-links). */ unsigned char rev_f; unsigned char init_f; unsigned char isActive; unsigned char do_f; INT4 goodRefN; INT4 badRefN; /* count of unsuccessful links */ INT4 lib1EntryN; /* number of entries from library 1 linked */ INT4 lib2EntryN; /* number of entries from library 2 linked */ INT4 linkIdN; IDPTR id_p; char *idWrtOff; struct FILEo *toFile; struct FILEo *fromFile; struct BTRo *btree1; struct BTRo *btree2; struct IDSoFILE *ids1; struct IDSoFILE *ids2; struct LINKo *use; /* Reference to the link object to be used to resolve the link. */ INT4 isOpen; unsigned char typ; /* Type of the link. 'read': first library must be read to find cross-references to second library; 'index': two indices, one from each library will be used to build the link; 'parent': link between entry and subentry. */ } LINKo; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Description of individual data-fields of both root and leaf databanks of a view. */ #ifndef _VIEWoFIELD #define _VIEWoFIELD typedef struct VIEWoFIELD { struct SRSoFLD *type; /* Reference the object describing the field type. */ char *format; /* If the field type has additional format options a format can be specified for the field, otherwise the default will be taken. */ } VIEWoFIELD; #endif #ifndef _VIEWoLIB #define _VIEWoLIB typedef struct VIEWoLIB { struct SLBo *lib; struct VIEWoFIELD *fields; INT4 fieldsN; INT4 fieldsAllocN; char *query; char *viewName; unsigned char printOnlyEntryN; } VIEWoLIB; #endif #ifndef _VIEWo #define _VIEWo typedef struct VIEWo { char *name; INT4 format; unsigned char isEntryNamePrinting; unsigned char useShortFieldNames; struct VIEWoLIB *root; INT4 rootN; INT4 rootAllocN; struct VIEWoFIELD *rootFields; INT4 rootFieldsN; INT4 rootFieldsAllocN; struct VIEWoLIB *leaves; INT4 leavesN; INT4 leavesAllocN; INT4 n; INT4 isNascent; INT4 isDeleted; char *templateFile; struct TEMPLo *templ; void (*entryNamePrint)(); void (*entryNPrint)(); } VIEWo; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Description of a data type which can be linked to applications. */ #ifndef _LIBoDataType #define _LIBoDataType typedef struct LIBoDataType { char *name; /* Symbolic name of the data-type, eg, "DNASequence" */ struct APPLo *applications[20]; /* List of applications that can be called with data of this type. */ } LIBoDataType; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Description of an application to be called on data of a certain type. */ #ifndef _APPLo #define _APPLo typedef struct APPLo { char *name; /* Symbolic name of the application. */ char *title; /* Short description of the program that can be used in a title line. */ INT4 type[5]; /* Type of the application. */ INT4 inSeqFormat; /* Format of the input sequence(s) */ struct APPLoOpt *options; /* List of command line options. */ INT4 optionsN; char *command; /* Icarus script used to defined the command line to call the application program. */ char *launch; /* Icarus script used to launch the program. The script relies on $opt.command being defined */ struct ICAoJOB *interp; struct STRo *com; } APPLo; #endif #ifndef _APPLoOpt #define _APPLoOpt typedef struct APPLoOpt { char *name; struct APPLoOptGroup *group; char *prompt; INT4 type; INT4 guiType; struct APPLoOptVal *values; /* List of option values. */ INT4 valuesN; char *defStr; INT4 defInt; float defReal; } APPLoOpt; #endif #ifndef _APPLoOptVal #define _APPLoOptVal typedef struct APPLoOptVal { char *name; char *prompt; char *valStr; INT4 valInt; float valReal; INT4 on; } APPLoOptVal; #endif #ifndef _APPLoOptGroup #define _APPLoOptGroup typedef struct APPLoOptGroup { char *name; } APPLoOptGroup; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Value in an enumeration */ #ifndef _ODDoVALUE #define _ODDoVALUE typedef struct ODDoVALUE { char *name; /* Name of value. */ INT4 n; /* Number value. */ char *rem; /* Comment field. */ } ODDoVALUE; #endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Argument of Icarus command. */ #ifndef _IARGoVALUE #define _IARGoVALUE typedef struct IARGoVALUE { char *name; /* Name of the argument in an Icarus program. */ char *rem; /* Comment field. */ unsigned char isUnnamed; /* Defines if parameter may be unnamed. */ unsigned char isRequired; /* Defines if parameter is required. */ unsigned char type; /* Type of the argument */ char *className; INT4 defInt; /* Default value of type 'int' arguments. */ char *defaultStr; /* Default value of type 'string' arguments. */ struct ODDoVALUE *vals; INT4 valsN; unsigned char isSet; struct VARo *val; } IARGoVALUE; #endif #ifndef _IARGoCOM #define _IARGoCOM typedef struct IARGoCOM { char *name; /* Name of command in Icarus programs. */ char *functionName; /* C function that implements the command. */ INT4 isShow; /* Determines whether the command should appear in the Icarus functions reference list. */ char *rem; /* Comment field. */ unsigned char returnType; /* Type of value to be returned (if any). */ INT4 time; /* Execution time of command. */ char *returnClass; unsigned char isDirectCall; /* Call function directly or via C-interface. */ char *methodOf; /* The class of which this function is a method otherwise treated as normal function. */ struct IARGoVALUE *args; INT4 argsN; INT4 (*function)(); /* Function to be executed for command. */ INT4 orderN; /* Number of arguments ordered from C function (via 'IargGetArgs'). */ INT4 orderAllocN; /* Number of orders currently allocated. */ struct IARGoVALUE **order; /* Array with a list of argument orders. */ } IARGoCOM; #endif #ifdef _FUNCTION #undef _FUNCTION INT4 LibParSetFields (char *); #define LibParSetFields_F (INT4(*)()) LibParSetFields INT4 LibParSetLibs (char *); #define LibParSetLibs_F (INT4(*)()) LibParSetLibs INT4 LibParSetLinkLibs (char *); #define LibParSetLinkLibs_F (INT4(*)()) LibParSetLinkLibs INT4 LibSetEnvironment (char *); #define LibSetEnvironment_F (INT4(*)()) LibSetEnvironment INT4 LibParSetLibsViewRoot (char *); #define LibParSetLibsViewRoot_F (INT4(*)()) LibParSetLibsViewRoot INT4 LibParSetLibsViewLeaf (char *); #define LibParSetLibsViewLeaf_F (INT4(*)()) LibParSetLibsViewLeaf typedef INT4 (*SDLoFNCTx)(); SDLoFNCTx SDL_fnctx[] = { LibParSetFields_F, LibParSetLibs_F, LibParSetLinkLibs_F, LibSetEnvironment_F, LibParSetLibsViewRoot_F, LibParSetLibsViewLeaf_F }; #endif tLinkLibs INT4 LibSetEnvironment (char *); #define LibSetEnvironment_F (INT4(*)()) LibSetEnvironment INT4 LibParSetLibsViewRoot (char *); #define LibParSetLibsViewRoot_F (INT4(*)()) LibParSetLibsViewRoot INT4 LibParSetLibsViewLeaf (char *);srs/src/srsbuild.c char srsbuild_srs_ID[] = "$Id: srsbuild.c,v 1.18 1997/03/13 19:40:08 srs Exp $"; /* ** ** $RCSfile: srsbuild.c,v $ ** $Revision: 1.18 $ ** $Date: 1997/03/13 19:40:08 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port: Lukas Rosenthaler and Reinhard Doelz ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** Requires: ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include "srs.h" #include "merge.h" #include "btree.h" #include "index.h" #include "ids.h" #define BLDxMAXTMPSETSIZE 10000 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of static functions */ static void BldLibIndex (char *libName); static void BldLibRelocate (char *libName); static void BldCompress (char *libName); static void BldSetReleaseName (char *libName); static void BldIndexTouch (char *libName); static void BldIndexLink (char *lib1Name, char *lib2Name); static void BldReadLink (char *libName); static void BldIndicesOpen (ENTRYv entry); static void BldIndicesClose (SLBo *lib); static void BldEntryFinish (ENTRYv entry); static void BldShowWords (ENTRYv entry, SLBoFIELD *field); static int BldIndexOpen (SLBo *lib, SLBoFIELD *field, Int4 partNo); static INT4 BldEntryId (ENTRYv entry); static LINKo *BldLinkFind (INT4 code); static void BldMakeLinkDict (SLBo *lib); static void BldIndexMerge (char *libName); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** function used by module "message" for printing error messages */ static int PrintMessage (MSGo *msg) { if (!ParGetNum ("showWarnings")) { switch (msg->msg_code) { case e__parsefail: case e__novalreference: case e__namnotuniq: case e__bldparsefail: case e__parsererror1: case e__parsererror2: case e__parsererror3: return 0; } } IcaPrintMessage (msg); return 1; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** main section... */ int main (int argc, char **argv) { ARGoLIST *arglist; char *tmpStr; LibOpen ("srs5"); arglist = (ARGoLIST *) LibObjByName ("arglist", "srsbuild"); argc = ArgGet (arglist, argc, argv); MsgSetFnct ((FUNC)IcaPrintMessage); IcaInitSyntax (LibObjByName ("syntax", "icarus")); if (ParGetNum ("indexLink") && argc == 3) { MsgSetFnct ((Func)PrintMessage); BldIndexLink (argv[1], argv[2]); } else if (ParGetNum ("compress") && argc == 2) BldCompress (argv[1]); else if (ParGetNum ("touchIndex") && argc == 2) BldIndexTouch (argv[1]); else if ((tmpStr = ParGetStr ("releaseName")) && *tmpStr && argc == 2) BldSetReleaseName (argv[1]); else if (ParGetNum ("printLibInfo") && argc == 2) LibPrintInfo (argv[1]); else if (ParGetNum ("relocateLib") && argc == 2) BldLibRelocate (argv[1]); else if (ParGetNum ("readLink") && argc == 2) BldReadLink (argv[1]); else if (ParGetNum ("mergeIndex") && argc == 2) BldIndexMerge (argv[1]); else if (ParGetNum ("buildIndex") && argc == 2) BldLibIndex (argv[1]); else ArgUsage (arglist); exit (0); } /****** BldLibIndex *********************************************************** ** ** do the indexing of a library; ** ** INPUT: name of library ** IMPLICIT: ** convert (int) [W] ** global parameter "fieldList" [R] ** global parameter "newId" [W] ** ** RETURNS: */ static void BldLibIndex (char *libName) { SLBo *lib; char *fieldList, *fieldName; ENTRYv entry; Int4 k; if (!(lib = (SLBo *) LibObjByName ("library", libName))) _ErrExit3 (e__objectunknown, "library", libName); _ErrMsg2 (i__processing, lib->nam); /* select data-fields for processing */ LibSetField (libName, 0, "xinit"); if ((fieldList = ParGetStr ("fieldList")) && *fieldList) while ((fieldName = strtok (fieldList, " "))) { fieldList = NULL; LibSetField (libName, fieldName, "set"); /* if an ID field is among the selected the "newId" flag must be set */ if (LibIsIdField (libName, fieldName)) ParDefNum ("newId", 1); /* new ID index must be build */ } else { LibSetField (libName, 0, "allindex"); ParDefNum ("newId", 1); /* new ID index must be build */ } entry = EntryOpenStream (lib); MsgSetFnct ((Func)PrintMessage); for (k=0; EntryNext (entry); k++) { if (EntryIsPartBegin (entry)) { if (k) BldIndicesClose (lib); BldIndicesOpen (entry); } BldEntryFinish (entry); } BldIndicesClose (lib); } static void BldActivateFields (char *libName, char *option) { char *fieldList, *fieldName; /* set the fields (indices to be processed */ LibSetField (libName, 0, "init"); if ((fieldList = ParGetStr ("fieldList")) && *fieldList) { ParDefNum ("parSetFields", 1); while ((fieldName = strtok (fieldList, " "))) { fieldList = NULL; LibSetField (libName, fieldName, "set"); } } else LibSetField (libName, 0, "compress"); /*compress is the same as allIndex*/ } /****** BldCompress *********************************************************** ** ** ** INPUT: name of library ** IMPLICIT: ** convert (int) [W] ** global parameter "fieldList" [R] ** global parameter "newId" [W] ** ** RETURNS: */ static void BldCompress (char *libName) { SLBo *lib; SLBoFIELD *field; char fileName[FILxXNAM+1]; int c, partNo; if (!(lib = (SLBo *) LibObjByName ("library", libName))) _ErrExit3 (e__objectunknown, "library", libName); BldActivateFields (libName, "compress"); /* iterate over active fields (indices) */ for (partNo=0; MergeNextPartNo (lib, &partNo); ) { for (c=0; (field = (LibNextField (lib, &c))); ) if (FieldIs (field, "active")) { if (FieldIs (field, "index")) { if (partNo != -1) MergeGetIndexPartName (lib, field, partNo, "write", fileName); else LibGetIndexName (lib, field, fileName, "write"); BtrCompress (fileName); } else _ErrMsg2 (e__inxnotcompress, field->type->nam); } } } /****** BldIndexMerge ********************************************************* ** ** Merges all index partitions to single index. ** ** INPUT: name of library ** */ static void BldIndexMerge (char *libName) { SLBo *lib; SLBoFIELD *field; MERGEvSet merge; char fileName[FILxXNAM+1]; Int4 c; if (!(lib = (SLBo *) LibObjByName ("library", libName))) _ErrExit3 (e__objectunknown, "library", libName); if (!LibIs (lib, "partitioned")) _ErrExit2 (e__bldLibNotMerge, libName); BldActivateFields (libName, "compress"); merge = MergeInit (lib); ParDefNum ("buildIndex", 1); /* for BldIndexOpen */ for (c=0; (field = (LibNextField (lib, &c))); ) if (FieldIs (field, "active")) { MergeIndex (merge, field); } BldIndicesClose (lib); } /****** BldIndexTouch ********************************************************* ** ** sets internal index date to current date ...this is necessary if ** the original flat files are moved after index building; ** ** INPUT: name of library ** IMPLICIT: ** convert (int) [W] ** global parameter "fieldList" [R] ** global parameter "newId" [W] ** ** RETURNS: */ static void BldIndexTouch (char *libName) { SLBo *lib; SLBoFIELD *field; char *fieldList, *fieldName, fileName[FILxXNAM+1]; int c; if (!(lib = (SLBo *) LibObjByName ("library", libName))) _ErrExit3 (e__objectunknown, "library", libName); BldActivateFields (libName, "touch"); for (c=0; (field = LibNextField (lib, &c)); ) if (FieldIs (field, "active")) { LibGetIndexName (lib, field, fileName, "read"); BtrTouch (fileName); if (FieldIs (field, "id")) IdxTouch (fileName); } } /****** BldLibRelocate ******************************************************** ** ** processes a file of a sequence library; ** ** INPUT: library object [W] ** IMPLICIT: ** ** OUTPUT: ** returns: */ static void BldLibRelocate (char *libName) { SLBo *lib; SLBoFIELD *field; ENTRYv entry; if (!(lib = (SLBo *) LibObjByName ("library", libName))) _ErrExit3 (e__objectunknown, "library", libName); LibSetField (libName, 0, "xinit"); /* activate ID-index */ BldIndexOpen (lib, LibGetIdField (lib), 0); entry = EntryOpenStream (lib); MsgSetFnct ((Func)PrintMessage); while (EntryNext (entry)) { BldEntryId (entry); } BldIndicesClose (lib); } /****** BldSetReleaseName ***************************************************** ** ** associates a release name to the library's indices ** ** INPUT: library name [W] ** IMPLICIT: ** ** OUTPUT: ** returns: */ static void BldSetReleaseName (char *libName) { SLBo *lib; SLBoFIELD *field; struct IDXo *idx; char indexName[133]; INT4 errCode; lib = (SLBo *) LibObjByName ("library", libName); if (!lib) _ErrExit3 (e__objectunknown, "library", libName); field = LibGetIdField (lib); LibGetIndexName (lib, field, indexName, "read"); idx = IdxOpen (indexName, "update", 0, &errCode); _ErrExit2 (errCode, indexName); IdxSetReleaseName (idx, ParGetStr ("releaseName")); IdxClose (idx); } /****** BldIndicesOpen ******************************************************* ** ** Opens all indices for index building ** ** INPUT: library object [W] ** */ static void BldIndicesOpen (ENTRYv entry) { SLBo *lib=EntryGetLib (entry); SLBoFIELD *field; Int4 c, partNo; if (LibIs (lib, "partitioned")) partNo = EntryGetPartNo (entry); else partNo = 0; if (!ParGetNum ("parseTest")) { for (c=0; (field = LibNextField (lib, &c));) if (FieldIs (field, "active")) BldIndexOpen (lib, field, partNo); } } /****** BldIndicesClose ******************************************************* ** ** prepares a library for indexing ** ** INPUT: library object [W] ** IMPLICIT: ** ** RETURNS: 1 */ static void BldIndicesClose (SLBo *lib) { LINKo *link; SLBoFIELD *field; int context; for (context=0; (field = LibNextField (lib, &context)); ) { if (!field->do_f) continue; if (field->idx) IdxClose (field->idx); if (field->inx) InxClose (field->inx); if (field->btree) BtrClose (field->btree); } } /****** BldIndexLink ********************************************************** ** ** links two libraries using two selected indices ** ** INPUT: name of one library [R] ** name of other library [R] ** IMPLICIT: ** ** RETURNS: 1 */ static void BldIndexLink (char *lib1Name, char *lib2Name) { LINKo *link; BTRoREC *record1, *record2; SETo *set1, *set2; FIP idFip1, idFip2; int opt; if (!(link = LibGetLink (lib1Name, lib2Name))) _ErrExit3 (e__novallink, lib1Name, lib2Name); if (!(link = LinkOpen (link, "writeindex"))) exit (0); set1 = SetNew (NULL, "temp"); set2 = SetNew (NULL, "temp"); SetAlloc (set1, BLDxMAXTMPSETSIZE, link->id1_d); SetAlloc (set2, BLDxMAXTMPSETSIZE, link->id2_d); for (idFip1=1, opt=BTRxFIRST; (record1 = BtrRecordGet (link->btree1, opt)); idFip1++, opt=BTRxNEXT) { if ((record2 = BtrSearch (link->btree2, record1->str, &idFip2, 0))) { LinkCollectSet (set1, record1, link->ids1); LinkCollectSet (set2, record2, link->ids2); LinkSets (link, set1, set2); link->goodRefN++; } else { _ErrMsg4 (e__novalreference, link->lib1->nam, link->lib2->nam, record1->str); link->badRefN++; } } if (link->linkIdN) LinkClose (link); } void BldPrintProgress (ENTRYv entry) { SLBo *lib=EntryGetLib (entry); if (lib->allEntryCnt % 300 == 0) _ErrMsg3 (i__processingentry, lib->allEntryCnt, EntryGetName (entry)); } /**api* BldReadLink ***************************************************************** ** ** Processes all 'read links' for specified databank. Opens the flat file, ** reads entries one by one and builds link indices. ** ** INPUT: library name [R] */ static void BldReadLink (char *libName) { SLBo *lib; SLBoFIELD *field; ENTRYv entry; LINKo *link; TOKoLIST *tokList; TOKoTOKEN *tok; char *tokListName, *tokStr; Int4 i, j, k, code, isTest=ParGetBool ("parseTest"); if (!(lib = (SLBo *) LibObjByName ("library", libName))) _ErrExit3 (e__objectunknown, "library", libName); if (!isTest) BldIndexOpen (lib, LibGetIdField (lib), 0); for (i=0, k=0; (link = LinkNext (lib, "read", &i)); k++) { _ErrMsg2 (i__bldReadLink, LibGetLinkToName (link)); if (!isTest) link = LinkOpen (link, "writeread"); } if (!k) { _ErrMsg2 (e__bldNoReadLinks, libName); return; } entry = EntryOpenStream (lib); MsgSetFnct ((Func)PrintMessage); while (EntryNext (entry)) { BldEntryId (entry); for (i=0; (link = LinkNext (lib, "read", &i));) { for (k=0; (tokListName = LinkNextToken (link, &code, &k));) { tokList = IcaGetTokenList (EntryGetJob (entry), tokListName); for (j=0; (tok = TokNextWithCode (tokList, code, &j));) { tokStr = TokGetStringCopy (tokList, tok); if (isTest) printf (" code: %d, %s -> %s\n", code, tokStr, LibGetLinkToName (link)); else if (!LinkIdWithString (link, EntryGetId (entry), tokStr)) _ErrMsg4 (e__novalreference, LibGetLinkFromName (link), LibGetLinkToName (link), tokStr); } } } } if (!isTest) for (i=0; (link = LinkNext (lib, "read", &i));) LinkClose (link); } /****** BldIndexOpen ********************************************************** ** ** opens an index and links it to the data-field; ** ** INPUT: library object [R] ** data-field object [R] ** number of library part [R] or 0 ** IMPLICIT: ** global parameter "newId" [R] ** global parameter "buildIndex" [R] ** ** RETURNS: 1 */ static int BldIndexOpen (SLBo *lib, SLBoFIELD *field, Int4 partNo) { INXo *index=NULL; char readIndexName[133], writeIndexName[133]; Int4 errCode; /* ** two different file names...input directory is not necessarily ** the output directory */ if (partNo) { MergeGetIndexPartName (lib, field, partNo, "read", readIndexName); MergeGetIndexPartName (lib, field, partNo, "write", writeIndexName); } else { LibGetIndexName (lib, field, readIndexName, "read"); LibGetIndexName (lib, field, writeIndexName, "write"); } /* ** open index for writing */ if (ParGetNum ("relocateLib")) { field->idx = IdxOpen (writeIndexName, "write", LibGetIdRecordSize (lib), &errCode); _ErrExit2 (errCode, writeIndexName); } else if (ParGetNum ("buildIndex")) { if (FieldIs (field, "id") && !ParGetNum ("newId")) { field->btree = BtrOpen (readIndexName, "read", &errCode); _ErrExit2 (errCode, FileGetName (field->btree->file, "path")); if (!(field->idFile = IdsOpen (readIndexName, "read", 0, NULL,&errCode))) _ErrExit (e__error); } else { if (FieldIs (field, "index")) { index = InxOpen (writeIndexName, "new"); if (FieldIs (field, "num")) InxSetType (index, "num"); else if (FieldIs (field, "real")) InxSetType (index, "real"); else InxSetType (index, "string"); InxSetCache (index, lib->csiz); if (FieldIs (field, "id")) { field->idx = IdxOpen (writeIndexName, "write", LibGetIdRecordSize (lib), &errCode); _ErrExit2 (errCode, writeIndexName); if (LibHasNoFiles (lib) && !LibIsFilePerEntry (lib)) LibSetLibFlatFiles (lib, field->idx); } } else _ErrExit2 (e__fieldnotindex, field->type->nam); } } field->inx = index; return 1; } /****** BldEntryId ************************************************************ ** ** Gets the entry-ID and places it into the ID index if appropriate. ** ** INPUT: entry object [w] ** ** RETURNS: 1: normal completion ** 0: no valid entry-id token could be obtained */ static INT4 BldEntryId (ENTRYv entry) { SLBoFIELD *field; TOKoLIST *tokList; TOKoTOKEN *tok; SLBo *lib=EntryGetLib (entry); char *tokStr, *buff; EntryParse (entry); field = LibGetIdField (EntryGetLib (entry)); tokList = EntryGetTokList (entry, field->indexToken[0]); if (!(tok = TokGetFirst (tokList))) return 0; tokStr = TokGetStringCopy (tokList, tok); strcpy (EntryGetName (entry), tokStr); /* get entry ID and insert into index */ if ((ParGetBool ("newId") || ParGetBool ("relocateLib")) && !ParGetBool ("parseTest")) { if (FieldIsKeyConvert (field)) SmEdit (tokStr, SMxLOWCASE); EntryIdRecordPack (entry, IdxRecordNew (field->idx)); if (ParGetNum ("newId")) { SmEdit (tokStr, SMxLOWCASE); IdBuild (EntryGetId (entry), LibToId (lib), lib->allEntryCnt, 0); InxInsertStr (field->inx, tokStr, EntryGetId (entry)); } } else IdBuild (EntryGetId (entry), LibToId (lib), lib->allEntryCnt, 0); BldPrintProgress (entry); return 1; } /****** BldEntryFinish ******************************************************** ** ** INPUT: entry object [R] ** IMPLICIT: ** ** RETURNS: */ static void BldEntryFinish (ENTRYv entry) { SLBoFIELD *field; INT4 c; if (BldEntryId (entry)) { for (c=0; (field = LibNextField (EntryGetLib (entry), &c)); ) { if (FieldIs (field, "active")) { if (ParGetNum ("parseTest")) BldShowWords (entry, field); else if (FieldIs (field, "index") && !FieldIs (field, "id")) BldSaveKey (entry, field); } } } } /****** BldSaveKey ************************************************************ ** ** ** INPUT: entry object [R] ** field object [R] ** IMPLICIT ** toklist (PRSoST *) */ INT4 BldSaveKey (ENTRYv entry, SLBoFIELD *field) { TOKoLIST *tokList; TOKoTOKEN *tok; IDoENTRY id, *idPtr; char *tokStr; INT4 c, isSubEntry, code, wantedCode; idPtr = (isSubEntry=FieldIs (field, "subEntry")) ? &id : EntryGetId (entry); tokList = IcaGetTokenList (EntryGetJob (entry), field->indexToken[0]); for (c=0; (tok = TokNext (tokList, &c));) { tokStr = TokGetStringCopy (tokList, tok); code = TokGetCode (tok); wantedCode = field->indexTokCode[0]; if (isSubEntry) IdBuildSub (&id, EntryGetId (entry), TokGetCode (tok)); else if (wantedCode != ICAxUNDEFCODE && code != wantedCode) continue; InxInsertStr (field->inx, SmEdit (tokStr, SMxLOWCASE|SMxTRIM), idPtr); } return 1; } /****** BldShowWords ********************************************************** ** ** Displays for specified data-field all words that could be extracted ** from the current entry. ** ** INPUT: entry object[R] ** data-field object [R] ** IMPLICIT: ** ** RETURNS: */ static void BldShowWords (ENTRYv entry, SLBoFIELD *field) { TOKoLIST *tokList; TOKoTOKEN *tok; INT4 c, code, wantedCode; if (FieldIs (field, "id")) { printf ("---------------------------------------\n"); printf ("Entry no: %d, fip1: %d fip2: %d\n", (EntryGetLib (entry))->allEntryCnt, EntryGetFip (entry, 0), EntryGetFip (entry, 1)); } printf (" %s:\n", LibGetFieldName (field)); tokList = IcaGetTokenList (EntryGetJob (entry), field->indexToken[0]); for (c=0; (tok = TokNext (tokList, &c));) { code = TokGetCode (tok); wantedCode = field->indexTokCode[0]; if (wantedCode == ICAxUNDEFCODE || code == wantedCode) printf (" code: %d, %s\n", TokGetCode (tok), TokGetStringCopy (tokList, tok)); } } (EntryGetLib (entry))->alsrs/src/srscheck.c char srscheck_ID[] = "$Id: srscheck.c,v 1.14 1997/03/15 14:15:10 srs Exp $"; /* ** ** $RCSfile: srscheck.c,v $ ** $Revision: 1.14 $ ** $Date: 1997/03/15 14:15:10 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** checks if all indexes are up to date and writes ** out a DCL file to keep system up to date ** ** still to be done: ** o do "srsbuild -r" if the IDX index is not of the correct version ** o compress index if date is ok but index is not compressed ** o check ALL indices for the dates ...not just the Id index ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #define NO_ENVIRONMENT 1 #include "srs.h" typedef struct CHECKoInfo { SLBo *lib; UINT4 libCreTime; } CHECKoInfo; static DICTv compressFieldsDict=NULL; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** static functions */ static int CheckLink (LINKo *link); int CheckIsBigLib (SLBo *lib); static void CheckBuildLinks (); static void CheckPrintSrsEnvHeader (char **envPtr); static void CheckSingleIndices (CHECKoInfo *ci); static int CheckOperateIndices (SLBo *lib); static void CheckBuildAllIndices (SLBo *lib); static int CheckIsNewLibrary (CHECKoInfo *ci); static CHECKoInfo *CheckInfoNew (SLBo *lib); static void CheckInfoDel (CHECKoInfo **ci); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** main section */ int main(int argc, char *argv[], char *envp[]) { CHECKoInfo *ci; ARGoLIST *arglist; SRSoGROUP *group; SLBo *lib; TEMPLv templ; char *tok, *tokList, etcDirName[FILxXNAM+1]; int rv, context1, context2, isLibSelect=0, isLibUnSelect=0; char *tmp; #ifndef VMS char *scriptName = "SRSETC:srsupdate"; #else char *scriptName = "SRSETC:srsupdate.com"; #endif strcpy (etcDirName, ""); /* ** open the resource file and get pointer to all library objects */ LibOpen ("srs5"); IcaInitSyntax (LibObjByName ("syntax", "icarus")); arglist = (ARGoLIST *) LibObjByName ("arglist", "srscheck"); argc = ArgGet (arglist, argc, argv); if (argc > 2) { ArgUsage (arglist); _ErrorExit (); } if (ParGetNum ("srsEnvHeader")) { CheckPrintSrsEnvHeader (envp); exit (0); } else if (ParGetNum ("printLibInfo") && argc == 2) { /* print only info ? */ LibPrintInfo (argv[1]); exit (0); } if (!((tmp = ParGetStr ("updateScriptName")) && *tmp)) tmp = scriptName; templ = TemplOpen ("SRSICA:srscheck.i", tmp); FileSetMode (TemplGetOutFile (templ), "rwxr-xr-x"); TemplWith (templ, "$srscheck"); strcpy (etcDirName, getenv ("SRSETC")); if (!*etcDirName) strcpy (etcDirName, ParGetStr ("etcDir")); TemplPrint ("head.unix", etcDirName); /* ** process list of libraries to be checked...if specified */ if (*(tokList = ParGetStr ("checkLibList"))) isLibSelect = 1; else if (*(tokList = ParGetStr ("notCheckLibList"))) isLibUnSelect = 1; for (context1=0; (group = LibNextLibGroup (&context1)); ) /* set all libs */ for (context2=0; (lib = LibNextLib (group, &context2)); ) ParDefNum (lib->nam, isLibSelect ? 0 : 1); if (isLibSelect || isLibUnSelect) /* set libs specified in list */ while ((tok = strtok (tokList, " "))) { /** set the databases of "SQ" */ tokList = NULL; if (!(lib = (SLBo *) LibObjByName ("library", tok))) _ErrExit3 (e__objectunknown, "library", tok); ParDefNum (lib->nam, isLibUnSelect ? 0 : 1); } /* ** now iterate over all selected libs that are not user defined libraries */ for (context1=0; (group = LibNextLibGroup (&context1)); ) { for (context2=0; (lib = LibNextLib (group, &context2)); ) { if (LibIs (lib, "user") || !LibIs (lib, "selected") || LibIs (lib, "subentries")) continue; _ErrMsg2 (i__checkinglib, lib->nam); ci = CheckInfoNew (lib); rv = CheckIsNewLibrary (ci); _ErrIf (rv) { /* if there is something wrong with library */ _ErrMsg2 (i__givinguplib, lib->nam); ParDefNum (lib->nam, 0); /* turn lib OFF ...nothing can be done */ continue; } if (!rv) { CheckBuildAllIndices (lib); lib->upd_f = TRUE; } else { lib->upd_f = FALSE; CheckSingleIndices (ci); } CheckOperateIndices (lib); CheckInfoDel (&ci); } } CheckBuildLinks (); TemplEndWith (templ); TemplClose (templ); exit (0); } static CHECKoInfo *CheckInfoNew (SLBo *lib) { CHECKoInfo *ci; ci = calloc (sizeof (CHECKoInfo), 1); ci->lib = lib; return ci; } static void CheckInfoDel (CHECKoInfo **ci) { if (*ci) free (*ci); *ci = NULL; } /******************************************************************************* ** ** Set of functions to set flags of different types for the field object. ** Utilizes flags in the field objects that are normally used in other contexts. ** */ static void CheckSetFieldIsDone (SLBoFIELD *field) { field->done_f =1; } static void CheckSetFieldDoBuild (SLBoFIELD *field) { field->do_f =1; } static void CheckSetFieldDoCompress (SLBoFIELD *field) { if (!compressFieldsDict) compressFieldsDict = DictCreate(DictCreateClassSelfPtrKey (FALSE)); DictSet (&compressFieldsDict, field, SLBoFIELD*) = field; } static INT4 CheckGetFieldIsDone (SLBoFIELD *field) { return field->done_f; } static INT4 CheckGetFieldDoBuild (SLBoFIELD *field) { return field->do_f; } static INT4 CheckGetFieldDoCompress (SLBoFIELD *field) { if (compressFieldsDict && DictWith (compressFieldsDict, field)) return 1; else return 0; } /****** CheckIdIndex ********************************************************** ** ** Creates "checkindex" objects for all indexable fields and sets ** both create and compress flags. ** ** INPUT: address of library object [W] ** IMPLICIT: ** ** RETURNS: 1 */ static void CheckBuildAllIndices (SLBo *lib) { SLBoFIELD *field; INT4 c; for (c=0; (field = LibNextField (lib, &c)); ) { if (FieldIs (field, "index")) { CheckSetFieldDoBuild (field); CheckSetFieldDoCompress (field); } } _ErrMsg2 (i__mustbuildinx, lib->nam); } /****** CheckSingleIndices **************************************************** ** ** Checks every individual index if up to date. The index will be ** rebuilt if it is: ** o older than the idx file ** o does not exist ** o is busy (which should mean it was never completed because of a ** crash) ** It will be just compressed if it is not compressed and fine otherwise. ** ** ** INPUT: address of library object [W] ** IMPLICIT: ** ** RETURNS: 1 */ static void CheckSingleIndices (CHECKoInfo *ci) { SLBo *lib=ci->lib; LIBoINDEX *libInx; SLBoFIELD *field; int c; UINT4 idInxCreTime; /* creation date of ID index */ if ((libInx = LibIndexOpen (lib, LibGetIdField (lib), 0))) idInxCreTime = IdxGetTimeCreated (libInx->idx); for (c=0; (field = LibNextField (lib, &c)); ) { if (FieldIs (field, "index")) { /* index not found */ if (!(libInx = LibIndexOpen (lib, field, 1))) { CheckSetFieldDoBuild (field); CheckSetFieldDoCompress (field); _ErrMsg3 (i__indexnotexist, LibGetFieldName (field), LibGetName (lib, "full")); } /* index not completed - rebuild! */ else if (BtrIsBusy (libInx->btree)) { CheckSetFieldDoBuild (field); CheckSetFieldDoCompress (field); _ErrMsg3 (i__indexnotcompleted, LibGetFieldName (field), LibGetName (lib, "full")); } /* library more recent as index */ else if (ci->libCreTime > BtrGetTimeCreated (libInx->btree)) { CheckSetFieldDoBuild (field); CheckSetFieldDoCompress (field); _ErrMsg3 (i__indexnotuptodate, LibGetFieldName (field), LibGetName (lib, "full")); } /* index not compressed */ else if (!IdsIsCompressed (libInx->idsFile)) { CheckSetFieldDoCompress (field); _ErrMsg3 (i__indexnotcompressed, LibGetFieldName (field), LibGetName (lib, "full")); } } } } /****** CheckOperateIndices ************************************************* ** ** Write the commands to build and compress all indices ** of the library. ** ** INPUT: address of library object [W] ** address of template object [W] ** IMPLICIT: ** ** RETURNS: 1 */ static int CheckOperateIndices (SLBo *lib) { SLBoFIELD *field; int context, procIndexSize, procSize, indexSize; char *indexDirName, *outDirName, fieldList[512]; indexDirName = ParGetStr ("indexDirName"); outDirName = ParGetStr ("outDirName"); TemplPrint ("build.head", LibName (lib)); /* ** commands for index compression: if ids files are regarded as ** being large then the files are built and compressed by ** independent srsbuild calls; */ procIndexSize = ParGetNum ("procIndexSize"); while (1) { for (context=0, procSize=0, fieldList[0]='\0'; (field = LibNextField (lib, &context)); ) { if (FieldIs (field, "index") && !CheckGetFieldIsDone (field) && CheckGetFieldDoBuild (field)) { indexSize = 1 /*field->relIndexSize*/ * lib->maxIndexSizeKb; /* ** add index to list if ..list is still empty ...or if there ** is still space in "process memory" ...set the "on" flag of ** the field object */ if (!procSize || procSize + indexSize <= procIndexSize) { sprintf (fieldList, "%s %s", fieldList, field->type->shortn); procSize += indexSize; CheckSetFieldIsDone (field); } } } if (!procSize && indexSize) break; TemplPrint ("build.indexList", LibName (lib), fieldList, indexDirName, outDirName, ParGetStr ("env")); if (!indexSize) /* index sizes were not specified */ break; } /* compress indices one by one */ for (context=0; (field = LibNextField (lib, &context)); ) if (FieldIs (field, "index") && CheckGetFieldDoCompress (field)) { TemplPrint ("compress.index", LibName (lib), field->type->shortn, indexDirName, outDirName, ParGetStr ("env")); if (LibIs (lib, "partitioned")) { static FILEo *file=NULL; if (!file) file = FileNew (NULL); FileSetName (file, "full", LibGetIndexName (lib, field, NULL, "read")); TemplPrint ("merge.index", LibName (lib), field->type->shortn, indexDirName, outDirName, ParGetStr ("env")); if (!FieldIs (field, "id")) TemplPrint ("merge.deleteIndex", FileGetName (file, "path")); } } /*TemplPrint ("tail");*/ return 1; } /****** CheckBuildLinks ******************************************************* ** ** processes all "index" and "read" links ** ** INPUT: ** IMPLICIT: ** ** RETURNS: 1 */ static void CheckBuildLinks () { SRSoGROUP *group; SLBo *lib; LINKo *link; char *indexDirName, *outDirName; int i, j, isFirstReadLink=1, isFirstIndexLink=1; indexDirName = ParGetStr ("indexDirName"); outDirName = ParGetStr ("outDirName"); /* ** analyze all pairwise links ...first "index" links */ for (i=0; (link = LibNextLink (&i)); ) { if (LinkIs (link, "using")) continue; if (!CheckLink (link)) { _ErrMsg3 (i__mustbuildlink, LibGetLinkFromName (link), LibGetLinkToName (link)); if (LinkIs (link, "index")) { if (isFirstIndexLink) { TemplPrint ("link.indexLink.head"); isFirstIndexLink = 0; } TemplPrint ("link.indexLink.do", LibGetLinkFromName (link), LibGetLinkToName (link), indexDirName, outDirName, ParGetStr ("env")); } } } /* ** then "read" links */ for (i=0; (group = LibNextLibGroup (&i)); ) { for (j=0; (lib = LibNextLib (group, &j)); ) { if (!lib->updlink_f) continue; if (isFirstReadLink) { TemplPrint ("link.readLink.head"); isFirstReadLink = 0; } TemplPrint ("link.readLink.do", LibName (lib), indexDirName, outDirName, ParGetStr ("env")); } } } /****** CheckIsNewLibrary ***************************************************** ** ** checks if libaries indices are OK and puts the library's ** creation time into the info object. ** ** INPUT: address of info object [W] ** ** RETURNS: TRUE: indices are up to date ** FALSE: must be built */ static int CheckIsNewLibrary (CHECKoInfo *ci) { SLBo *lib=ci->lib; LIBoINDEX *libInx; FILEo *file; int k, rv; UINT4 creTime, context; char searchName[132], fileName[FILxXNAM+1]; libInx = LibIndexOpen (lib, LibGetIdField (lib), 1); /* open ID index */ if (!LibIsFilePerEntry (lib)) { for (k=0, ci->libCreTime=0; k < lib->nfil; k++) { if (!(file = LibOpenFlatFile (lib, k, LibGetFileType (lib, NULL, NULL), &rv))){ _ErrMsg2 (e__checkInvalidLibInfo, LibGetIcarusFileName (lib, "structure")); return 0; } creTime = FileGetTime (file, "create"); if (ci->libCreTime < creTime) ci->libCreTime = creTime; } if (!libInx || ci->libCreTime > BtrGetTimeCreated (libInx->btree)) return 0; } /* ** each entry resides in a separate file, count all these files and ** compare the number of files with the number of keys in the ID index - ** for that the ID index must be opened - but first check if the index ** exists; */ else { if (*lib->form->fil_t[0]->searchName) sprintf (searchName, "%s%s", lib->dirName[0], lib->form->fil_t[0]->searchName); else sprintf (searchName, "%s*.%s", lib->dirName[0], lib->form->fil_t[0]->typ_nm); for (k=0, context=0; FilSearch (_FilTempLN (searchName), fileName, &context); k++) ; /* flag lib to be reindexed but allow 2 entries tolerance (fssp, hssp)*/ if (!libInx || (k < BtrGetRecordN (libInx->btree)-2) || (k > BtrGetRecordN (libInx->btree) + 2)) { if (libInx) _ErrMsg4 (i__diffentrynum, lib->nam, BtrGetRecordN (libInx->btree), k); return 0; } } return 1; /* indices are OK */ } /****** CheckLink ************************************************************* ** ** checks if link index is up to date; ** ** INPUT: address of link descriptor [R] ** IMPLICIT: ** ** RETURNS: 1 if link OK ** 0 if update needed */ static int CheckLink (LINKo *link) { FILE *file; SLBo *lib1 = link->lib1, *lib2 = link->lib2; LIBoINDEX *libInx; UINT4 indexTime1, indexTime2, linkTime; char fileName[FILxXNAM+1]; if (!LinkIs (link, "libs")) return 1; if (LinkIs (link, "user")) return 1; /* links to user libs have not to be updated */ if (!LibIs (lib1, "selected") || !LibIs (lib2, "selected")) return 1; /* one of the 2 libs is not selected for updating */ if (!lib1->upd_f && !lib2->upd_f) { libInx = LibIndexOpen (lib1, LibGetIdField (lib1), 1); indexTime1 = libInx ? BtrGetTimeCreated (libInx->btree) : 0; libInx = LibIndexOpen (lib2, LibGetIdField (lib2), 1); indexTime2 = libInx ? BtrGetTimeCreated (libInx->btree) : 0; /* time = LinkGetCreTime (link); !!!te */ LibGetLinkName (link, 0, fileName, "read"); file = fopen (_FilTempLN (fileName), "r"); linkTime = file ? TimeFileCreate (file) : 0; fclose (file); if (!(linkTime <= indexTime1 || linkTime <= indexTime2)) return 1; } /* ** if link is of type INDEX then it is build by reading the library's ** flatfile (-> extract the crossreferences) */ if (!LinkIs (link, "index")) lib1->updlink_f = TRUE; return 0; } /****** CheckIsBigLib ********************************************************* ** ** checks if library is big ** ** INPUT: address of library object[R] ** IMPLICIT: ** ** RETURNS: 1 if big ** 0 if not */ int CheckIsBigLib (SLBo *lib) { SLBoFIELD *field; int context, totalIndexSize; if (!lib->maxIndexSizeKb) return 0; for (context=0, totalIndexSize=0; (field = LibNextField (lib, &context)); ) if (FieldIs (field, "index")) { totalIndexSize += lib->maxIndexSizeKb * /*field->relIndexSize*/ 1; } return (totalIndexSize > ParGetNum ("procIndexSize")) ? 1 : 0; } /****** CheckPrintSrsEnvHeader ************************************************ ** ** prints a C-language header file that defines all SRS environment ** variables as they are currently defined; ** ** INPUT: ** IMPLICIT: ** envp (char **) [R] ** ** RETURNS: */ static void CheckPrintSrsEnvHeader (char **envPtr) { TEMPLv templ; char var[800], val[3000]; templ = TemplOpen ("SRSICA:srsenv.i", "SRSEXE:srsenv.h"); TemplWith (templ, "srsenv.unix"); TemplPrint ("head"); for (; *envPtr; envPtr++) { val[0] = '\0'; /* there might be no defined value */ sscanf (*envPtr, "%[^=]=%[^:]", var, val); if ((SmStrCmpLen (var, "SRS", 3) == 0) && *val) TemplPrint ("name", var, var, val); } TemplPrint ("tail"); TemplEndWith (templ); TemplClose (templ); } ckPrintSrsEnvHeader (char **envPtr) { TEMPLv templ; char var[800], val[3000]; templ = TemplOpen ("SRSICA:srsenv.i", "SRSEXE:srsenv.h"); TemplWith (templ, "srsenv.unix"); TemplPrint ("head"); for (; *envPtr; envPtr++) { val[0] = '\0'; /* there might be no defined value */ sscanf (*envPtr, "%[^=]=%[^:]"srs/src/srspict.c char srsnet_ID[] = "$Id: srspict.c,v 1.1 1996/05/06 15:17:26 srs Exp $"; /* ** ** $RCSfile: srspict.c,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:17:26 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** Copyright by Thure Etzold ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** 69012 Heidelberg, Germany ** Tel: 06221 387372 ** Email: etzold@embl-heidelberg.de ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** program takes a list of coordinates (databank nodes in a graph) ** of the form: 'coord:' databankName x y and produces a GIF file ** and a image map file for the WWW server ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include "gd.h" #include "srs.h" #define brown 165, 42, 42 #define darkorange 255, 140, 0 #define rosybrown 188, 143, 143 #define seagreen 46, 139, 87 #define darkred 152, 20, 0 #define olivegreen 76, 39, 0 #define steelblue 57, 127, 145 #define maize 220, 185, 22 #define mediumaquamarine 102, 205, 170 #define cornflowerblue 100, 149, 237 #define mediumvioletred 199, 21, 133 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** structure describing a databank node in the image; */ typedef struct PICToNODE { char name[20]; int x; int y; int fg, bg; int isOnGraph; } PICToNODE; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** external, global and module wide variables */ static SCRIPTo *script; static gdImagePtr bullet=NULL; static int light, shade, red, grey, white, black, transparent, fg[10], bg[10]; ; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** static functions */ static void PictClose (gdImagePtr im, char *fileName); static void PictPrintDB (gdImagePtr im, char *name, int color1, int color2, int x, int y); static void PictPrintLegend (gdImagePtr im, int left, int upper); static void PictNetwork (gdImagePtr im); static void PictInit (gdImagePtr im); static void PictPrintLinkBox (gdImagePtr im, int x, int y, int linkN); static void PictRelocateNodes (PICToNODE *node, float width, float height); void PictLinkInfo (char *s1, char *s2, int x1, int y1, int x2, int y2) { ScriptWriteFrom (script, "PIC-LINKINFO", _s(s1), _s(s2), _d(x1), _d(y1), _d(x2), _d(y2)); } void PictLibInfo (char *s, int x1, int y1, int x2, int y2) { ScriptWriteFrom (script, "PIC-LIBINFO", _s(s), _d(x1), _d(y1), _d(x2), _d(y2)); } /****** PictPrintNetwork ***************************************************** ** ** Initialises colors and other things that other functions need; ** works on global variables ...not nice ...pragmatic solution! ** ** INPUT: ** IMPLICIT: ** all variables are global ** ** RETURNS: */ static void PictPrintNetwork () { SRSoGROUP *group; SLBo *lib; LINKo *link; INT4 k, l, i, c1, c2, c, rv, x, y; PICToNODE dbNode[100], *node, *tmp; gdImagePtr im; im = gdImageCreate (750, 600); PictInit (im); script = ScriptOpen ("SRSWWW:wgetz.script", "SRSWWW:srsnet.map"); fg[0] = gdImageColorAllocate (im, black); fg[1] = gdImageColorAllocate (im, black); fg[2] = gdImageColorAllocate (im, black); fg[3] = gdImageColorAllocate (im, black); fg[4] = gdImageColorAllocate (im, black); fg[5] = gdImageColorAllocate (im, black); fg[6] = gdImageColorAllocate (im, black); bg[0] = white; bg[1] = white; bg[2] = white; bg[3] = white; bg[4] = white; bg[5] = white; bg[6] = white; /* ** assign databank names and background and foreground colors to ** the nodes */ for (k=0, l=0, c1=0; (group = LibNextLibGroup (&c1));) { for (c2=0, i=0; (lib = LibNextLib (group, &c2)); k++, i++) { node = &dbNode[k]; strcpy (node->name, LibGetName (lib, "full")); node->fg = fg[l]; node->bg = bg[l]; node->isOnGraph = 0; } if (i) /* if group is not empty */ l++; } dbNode[k].name[0] = '\0'; /* terminating node */ /* ** read the file with the coordinates and assign x and y coordinates ** to the nodes */ { FILo file; char libName[80]; rv = FilUOpen (&file, "SRSWWW:srsnet.dat", 512, 0); _ErrExit2 (rv, "SRSWWW:srsnet.dat"); do { if (sscanf (file.ln, "coord: %s %d %d", libName, &x, &y) == 3) { for (k=0; *dbNode[k].name; k++) { node = &dbNode[k]; if (SmEqs (libName, node->name)) { node->x = x; node->y = y; node->isOnGraph = 1; } } } FilURead (&file); } while (!FilEof (&file)); } /* ** find default positions for databanks not listed in the coordinate ** file */ for (tmp=dbNode, y=0; *(tmp->name); tmp++) if (!tmp->isOnGraph) { tmp->x = 0; tmp->y = y; tmp->isOnGraph = 1; y += 50; } PictRelocateNodes (dbNode, 750, 530); /* ** paint the all links between nodes */ for (c=0; (link = LibNextLink (&c)); ) if (link->lib1 && link->lib2) PictLinkDBs (im, black, dbNode, LibGetName (link->lib1, "full"), LibGetName (link->lib2, "full")); /* ** paint the nodes */ for (k=0; *dbNode[k].name; k++) { PictPrintDB (im, dbNode[k].name, dbNode[k].fg, dbNode[k].bg, dbNode[k].x, dbNode[k].y); } /* figure lengend */ /* PictPrintLegend (im, 40, 540);*/ /* default action for the clickable WWW map */ ScriptWriteFrom (script, "PIC-LIBINFO", _s("points_to_nothing"), _d(0), _d(0), _d(im->sx), _d(im->sy)); ScriptClose (script); PictClose (im, "SRSWWW:srsnet.gif"); } /****** PictRelocateNodes ***************************************************** ** ** ** INPUT: ** IMPLICIT: ** ** RETURNS: */ static void PictRelocateNodes (PICToNODE *node, float width, float height) { PICToNODE *tmp; INT4 k, hrim=40, vrim=30; float minx=1000, maxx=0, miny=1000, maxy=0; float relx, rely; width -= 2*hrim; height -= 2*vrim; for (k=0; *node[k].name; k++) { tmp = &node[k]; if (tmp->x < minx) minx = tmp->x; if (tmp->x > maxx) maxx = tmp->x; if (tmp->y < miny) miny = tmp->y; if (tmp->y > maxy) maxy = tmp->y; } maxx -= minx; maxy -= miny; relx = width / maxx; rely = height / maxy; for (k=0; *node[k].name; k++) { tmp = &node[k]; tmp->x = (tmp->x - minx) * relx + hrim ; tmp->y = (tmp->y - miny) * rely + vrim ; } } /****** PictPrintGraphTable *************************************************** ** ** Prints a picture that represents the databank network in a tabular ** form. ** ** INPUT: ** IMPLICIT: ** script (SCRIPTo *) [W] ** ** RETURNS: */ static void PictPrintGraphTable () { gdImagePtr im; im = gdImageCreate (560, 620); script = ScriptOpen ("SRSWWW:wgetz.script", "SRSWWW:srslink.map"); PictInit (im); fg[0] = gdImageColorAllocate (im, 210, 210, 250); fg[1] = gdImageColorAllocate (im, 190, 190, 230); fg[2] = gdImageColorAllocate (im, 170, 170, 210); fg[3] = gdImageColorAllocate (im, 140, 140, 190); fg[4] = gdImageColorAllocate (im, 110, 110, 170); fg[5] = gdImageColorAllocate (im, 80, 80, 150); fg[6] = gdImageColorAllocate (im, 50, 50, 130); bg[0] = black; bg[1] = black; bg[2] = black; bg[3] = white; bg[4] = white; bg[5] = white; bg[6] = white; PictNetwork (im); PictPrintLegend (im, 20, 560); PictClose (im, "SRSWWW:srslink.gif"); ScriptClose (script); } #define HRIM 4 #define VRIM 0 #define BOXLEN (12+2*VRIM) #define BOXHEIGHT (12+2*VRIM) static void PictNetwork (gdImagePtr im) { SRSoGROUP *group, *group2; SLBo *lib, *lib2; struct LINKoNOD *path; INT4 maxLen, len, textLen; INT4 c1, c2, c3, c4, i, k, x, y; char *libName, *lib2Name; /* find maximum length of databank names */ maxLen = 0; for (c1=0; (group = LibNextLibGroup (&c1)); ) for (c2=0; (lib = LibNextLib (group, &c2)); ) { len = strlen (LibGetName (lib, "full")); if (maxLen < len) maxLen = len; } textLen = maxLen*6; /* print databank names horizontally */ x=10; y=10; for (k=0, c1=0; (group = LibNextLibGroup (&c1));) { for (c2=0, i=0; (lib = LibNextLib (group, &c2)); i++) { gdImageFilledRectangle (im, x, y, x+textLen+2*HRIM, y+12+2*VRIM, fg[k]); gdImageString (im, gdFontSmall, x+HRIM, y+VRIM, LibGetName (lib, "full"), bg[k]); PictLibInfo (LibGetName (lib, "full"), x, y, x+textLen+2*HRIM, y+12+2*VRIM); y += 12 + 2 * VRIM + 1; } if (i) k++; } /* print databank names vertically */ x += textLen + 2* HRIM ; for (k=0, c1=0; (group = LibNextLibGroup (&c1));) { for (c2=0, i=0; (lib = LibNextLib (group, &c2)); i++) { gdImageFilledRectangle (im, x, y, x+12+2*VRIM, y+textLen+2*HRIM, fg[k]); gdImageStringUp (im, gdFontSmall, x+VRIM, y+HRIM+textLen, LibGetName (lib, "full"), bg[k]); PictLibInfo (LibGetName (lib, "full"), x, y, x+12+2*VRIM, y+textLen+2*HRIM); x += 12 + 2 * VRIM + 1; } if (i) k++; } y = 10; for (c1=0; (group = LibNextLibGroup (&c1)); ) for (c2=0; (lib = LibNextLib (group, &c2)); ) { x = 10+textLen+2*HRIM+1; libName = (LibGetName (lib, "full")); for (c3=0; (group2 = LibNextLibGroup (&c3)); ) for (c4=0; (lib2 = LibNextLib (group2, &c4)); ) { lib2Name = LibGetName (lib2, "full"); if (lib == lib2) goto endofline; /* proceed until diagonal is reached */ if ((LibGetLink (libName, lib2Name))){ /* direct link */ PictPrintLinkBox (im, x, y, 1); PictLinkInfo (libName, lib2Name, x, y, x+BOXLEN, y+BOXHEIGHT); } else { if ((path = LinkSearchPath (libName, lib2Name))) { PictPrintLinkBox (im, x, y, LinkGetPathLength (path)); PictLinkInfo (libName, lib2Name, x, y, x+BOXLEN, y+BOXHEIGHT); } } x += BOXLEN+1; } endofline: y += BOXHEIGHT+1; } } static void PictPrintLinkBox (gdImagePtr im, int x, int y, int linkN) { static int grey[4]; char tmp[5]; if (!grey[0] && ! grey[1]) { grey[0] = white; grey[1] = gdImageColorAllocate (im, 255, 240, 240); grey[2] = gdImageColorAllocate (im, 255, 220, 220); grey[3] = gdImageColorAllocate (im, 255, 200, 200); } gdImageFilledRectangle (im, x, y, x+BOXLEN, y+BOXHEIGHT, grey[linkN-1]); sprintf (tmp, "%d", linkN); gdImageString (im, gdFontSmall, x+HRIM, y+VRIM, tmp, linkN == 1 ? red : black); } static void PictClose (gdImagePtr im, char *fileName) { FILE *file; int rv; /* Make output image interlaced (allows "fade in" in some viewers, and in the latest web browsers) */ gdImageInterlace (im, 1); /* set transparent color */ transparent = gdImageColorExact (im, 190, 190, 190); gdImageColorTransparent(im, transparent); file = FilOpenW (fileName, &rv); _ErrExit2 (rv, fileName); gdImageGif (im, file); fclose (file); gdImageDestroy (im); } /****** PictInit *************************************************************** ** ** Initialises colors and other things that other functions need; ** works on global variables ...not nice ...pragmatic solution! ** ** INPUT: pointer to image [W] ** IMPLICIT: ** all variables are global ** ** RETURNS: */ static void PictInit (gdImagePtr im) { FILE *file; int rv; /* First color allocated is background. */ white = gdImageColorAllocate (im, 255, 255, 255); grey = gdImageColorAllocate(im, 190, 190, 190); light = gdImageColorAllocate (im, 255, 240, 255); shade = gdImageColorAllocate (im, 80, 80, 100); black = gdImageColorAllocate (im, 0, 0, 0); red = gdImageColorAllocate (im, 255, 0, 0); file = FilOpenR ("SRSWWW:bullet.gif", &rv); _ErrExit2 (rv, "SRSWWW:bullet.gif"); bullet = gdImageCreateFromGif(file); } /****** PictLinkDBs ************************************************************ ** ** ** ** ** INPUT: pointer to image [W] ** IMPLICIT: ** ** RETURNS: 1 if success ** 0 if name could not be found or if no coordinates exist */ int PictLinkDBs (gdImagePtr im, int color, PICToNODE *node, char *libName1, char *libName2) { FILE *in; PICToNODE *node1, *node2; int x, y, h, l; /* ** Search both databank names and exchange for a "node" object ** and connect them by a line */ for (node1=node; *(node1->name); node1++) if (SmEqs (node1->name, libName1)) break; for (node2=node; *(node2->name); node2++) if (SmEqs (node2->name, libName2)) break; if (!node1->isOnGraph || !node2->isOnGraph || !*node1->name || !*node2->name) return 0; gdImageLine (im, node1->x, node1->y, node2->x, node2->y, color); /* ** find the center of that line for drawing a bullet (for clicking) */ if (node1->y < node2->y) h = node2->y, l = node1->y; else l = node2->y, h = node1->y; y = l + (h - l) /2; if (node1->x < node2->x) h = node2->x, l = node1->x; else l = node2->x, h = node1->x; x = l + (h - l) /2; /* ** paste the bullet and print its coordinates into the WWW image map file */ x -= bullet->sx/2; y -= bullet->sy/2; gdImageCopy (im, bullet, x, y, 0, 0, bullet->sx, bullet->sy); ScriptWriteFrom (script, "PIC-LINKINFO", _s(node1->name), _s(node2->name), _d(x), _d(y), _d(x+bullet->sx), _d(y+bullet->sy)); return 1; } /****** PictPrintDB ************************************************************ ** ** Initialises colors and other things that other functions need; ** works on global variables ...not nice ...pragmatic solution! ** ** INPUT: pointer to image [W] ** IMPLICIT: ** ** RETURNS: */ static void PictPrintDB (gdImagePtr im, char *name, int color1, int color2, int x, int y) { /* Points for polygon */ gdPoint points[10]; int x1, y1, x2, y2, len, xrel, yrel, margin=4, outRim=2, diff; /* ** calculate size of text, and of the whole box in points */ len = strlen (name); x1 = 1; y1 = 1; x2 = x1 + len*8 + margin*2; /* font is 8*16 */ y2 = y1 + 16 + margin*2; /* ** calculate positions of that box on the image */ xrel = (x2 - x1) / 2; yrel = (y2 - y1) / 2; x1 = x-xrel; y1 = y-yrel; x2 = x+xrel; y2 = y+yrel; /* ** paste an even bigger box in "light" ...for the 3d aspect */ /* gdImageFilledRectangle (im, x1-outRim, y1-outRim, x2+outRim, y2+outRim, light); */ /* ** now paste over the "light" box a "shade" polygon ...together they will ** be ligth and shadow ...node that the polygon drawing is a bit buggy */ diff = (y2-y1)/2; points[0].x = x2 + outRim; points[0].y = y2 + outRim; points[1].x = x2 + outRim; points[1].y = y1 - outRim; points[2].x = x2 - diff - 1; points[2].y = y1 + diff - 1; /* the +1 prevents some bug ...a white line */ points[3].x = x1 + diff; points[3].y = y1 + diff; points[4].x = x1 - outRim; points[4].y = y2 + outRim; /* gdImageFilledPolygon(im, points, 5, shade); */ /* ** now print the rectangle with the databank name and write a ** "rect" statement into the WWW image map file */ gdImageFilledRectangle (im, x1, y1, x2, y2, color1); gdImageString(im, gdFontLarge, x1+margin, y1+margin, name, color2); ScriptWriteFrom (script, "PIC-LIBINFO", _s(name), _d(x1), _d(y1), _d(x2), _d(y2)); } /****** PictPrintLegend ******************************************************** ** ** Prints the legend with the color codes for the databank groups. ** ** INPUT: pointer to image [W] ** IMPLICIT: ** bullet ** fg ** black ** ** RETURNS: */ static void PictPrintLegend (gdImagePtr im, int left, int upper) { SRSoGROUP *group; int x,y, probeSize=12, space=5, bigSpace=10; int k, i, c1, c2; char tmp[132]; /* ** print the creation time and explain the bullet */ x = left; y = upper; sprintf (tmp, "Creation Date: %s\n", TimeToString (0, "date")); gdImageString(im, gdFontSmall, x, y, tmp, black); x+= 180; if (ParGetNum ("doNetworkPict")) { gdImageCopy (im, bullet, x, y, 0, 0, bullet->sx, bullet->sy); x += bullet->sy + space; } else if (ParGetNum ("doGraphTablePict")) { PictPrintLinkBox (im, x, y, 1); x+= BOXLEN; PictPrintLinkBox (im, x, y, 2); x+= BOXLEN; PictPrintLinkBox (im, x, y, 3); x+= BOXLEN; PictPrintLinkBox (im, x, y, 4); x+= BOXLEN + space; } gdImageString (im, gdFontSmall, x, y, "Press to get link information", black); /* ** print on next line a color probe and the databank group name */ x = left; y = upper+20; for (k=0, c1=0; (group = LibNextLibGroup (&c1));) { for (c2=0, i=0; (LibNextLib (group, &c2)); i++) ; if (i) { /* if group is not empty */ gdImageFilledRectangle (im, x, y, x+probeSize, y+probeSize, fg[k++]); x += probeSize + space; gdImageString(im, gdFontSmall, x, y, group->com, black); x += strlen (group->com) * 6 + bigSpace; } } gdImageRectangle (im, left-bigSpace, upper-bigSpace, x+bigSpace, upper+30+bigSpace, black); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** The main thing */ INT4 main (INT4 argc, char *argv[], char *envp[]) { ARGoLIST *arglist; gdImagePtr im_out; SrsEnv (); LibOpen ("srswin"); arglist = (ARGoLIST *) LibObjByName ("arglist", "srspict"); argc = ArgGet (arglist, argc, argv); if (ParGetNum ("doNetworkPict")) PictPrintNetwork (); if (ParGetNum ("doGraphTablePict")) PictPrintGraphTable (); return 0; } x+bigSpace, upper+30+bigSpace, black); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** The main thing */ INT4 msrs/src/srswww.c char srswww_ID[] = "$Id: srswww.c,v 1.26 1997/03/15 14:14:22 srs Exp $"; /* ** ** $Source: /homes/srs/cvsroot/srs/src/srswww.c,v $ ** $Revision: 1.26 $ ** $Date: 1997/03/15 14:14:22 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.0 Copyright by Thure Etzold ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** 69012 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** Modified to fit the new SRS WWW interface ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include /* #include #include */ #include "message.h" #include "sm.h" #include "tm.h" #include "strv.h" #include "lst.h" #include "futil.h" #include "templ.h" #include "par.h" #include "id.h" #include "set.h" #include "library.h" #include "appl.h" #include "btree.h" #include "idx.h" #include "entry.h" #include "link.h" #include "seq.h" #include "query.h" #include "queryass.h" #include "seqdb.h" #include "icarus.h" #include "icaarg.h" #include "variable.h" #include "view.h" #include "srswww.h" #define _SRS #define _SLB #define _WWW #include "srs5.h" #define WWWxMAXLINESIZE 500000 typedef struct SCRIPTo{ void *x; }SCRIPTo; INT4 SmRemoveChar(char remoteAddr[],char c); INT4 LibShufflebuff(char s[]); void LibRevStr(char s[]); INT4 LibPower(int base, int n); extern char *ScriptFile; extern char *RParGetStr(char *strfmt, ...); /* * * * * * * * stuff from HTTP server's "util.c" * * * * * * * * * */ #define LF 10 #define CR 13 static char *makeword(char *line, char stop) { int x = 0,y; char *word = (char *) malloc(sizeof(char) * (strlen(line) + 1)); for(x=0;((line[x]) && (line[x] != stop));x++) word[x] = line[x]; word[x] = '\0'; if(line[x]) ++x; y=0; while ((line[y++] = line[x++])); return word; } static char *fmakeword(char **buffPtr, char *buffEnd, char stop, int *cl) { int wsize; char *word; int ll; wsize = 132; ll=0; word = (char *) malloc(sizeof(char) * (wsize + 1)); while(1) { word[ll] = *(*buffPtr)++; if(ll==wsize) { word[ll+1] = '\0'; wsize+=102400; word = (char *)realloc(word,sizeof(char)*(wsize+1)); } --(*cl); if((word[ll] == stop) || (*buffPtr >= buffEnd) || (!(*cl))) { if(word[ll] != stop) ll++; word[ll] = '\0'; return word; } ++ll; } } static char x2c(char *what) { register char digit; digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0')); digit *= 16; digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0')); return(digit); } static void unescape_url(char *url) { register int x,y; for(x=0,y=0;url[y];++x,++y) { if((url[x] = url[y]) == '%') { url[x] = x2c(&url[y+1]); y+=2; } } url[x] = '\0'; } static void plustospace(char *str) { register int x; for(x=0;str[x];x++) if(str[x] == '+') str[x] = ' '; } /* * * * * * * * end stuff from HTTP server's "util.c" * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** external, global and module wide variables */ VIEWo *wwwView=NULL; char buff[WWWxMAXLINESIZE+1]; ENTRYv entryCurr; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of static functions */ static INT4 WwwViewEntryInTable (TEMPLv templ, ENTRYv entry, VIEWoLIB *vlib, Int4 entryNum, Int4 isRoot, Int4 rowN); static void WwwViewEntryInList (TEMPLv templ, ENTRYv entry, VIEWoLIB *vlib, Int4 entryNum, Int4 isRoot); static void WwwPrintTableEmptyEntry (VIEWoLIB *vlib, Int4 rowN); static void WwwPresentSkipChunkSet (TEMPLv templ, INT4 setSize, INT4 queryN); static void WwwDeleteQuery (); static void WwwViewTableHeader (TEMPLv templ, VIEWo *view); static Int4 WwwIsViewForQuery (VIEWo *view, char *setName); static void WwwViewPrintEntryN (VIEWo *view, VIEWoLEAFSET *leaf, ENTRYv entry, Int4 rowN); static void WwwViewSave (VIEWo *view, char *option); static void WwwApplOptPrint (APPLo *appl, APPLoOpt *opt); char *WwwReadInput (int byteN, char *fileName) { static char buff[10000]; FILE *file; fread (buff, 1, byteN, stdin); if (ParGetBool ("debugSRSWWW")) { /* file with form input for debugging */ file = fopen (fileName, "w"); fwrite (buff, 1, byteN, file); fclose (file); chmod (fileName, 00777); } return buff; } Int4 WwwPrintContentType (char *s) { static Int4 isPrinted=0; char *tmp; if (*(tmp = ParGetStr ("mimeType"))) s = tmp; if (!isPrinted) { isPrinted=1; if (s && SmEqs (s, "none")) ; else if (s) { /*printf ("Pragma: no-cache\r\n");*/ printf ("%s\r\n", s); /*printf ("Expires: Thu, 01 Dec 1994 16:00:00 GMT\r\n");*/ /* date see internet RFC-1945! */ printf ("\r\n"); } else { /*printf ("Pragma: no-cache\r\n");*/ printf ("Content-type: text/html\r\n"); /*printf ("Expires: Thu, 01 Dec 1994 16:00:00 GMT\r\n");*/ printf ("\r\n"); } return 1; } return 0; } INT4 WwwPrintMessage (MSGo *msg) { static TEMPLv templ=NULL; MsgSetFnct ((Func)IcaPrintMessage); /* avoid recursion in error printing! */ if (!(templ = TemplGet ())) { templ = TemplOpen ("SRSICA:srswww.i", NULL); } TemplWith (templ, "$messages"); WwwSetColorScheme (templ); if (WwwPrintContentType (NULL)) { TemplPrint ("head"); } switch (msg->msg_code) { case i__wroteset: break; case e__parsererror3: TemplPrint ("parseError", msg->primsg, msg->secmsg); break; default: if (msg->msg_t == MSGxINFO) TemplPrint ("info", msg->primsg, msg->secmsg); else TemplPrint ("error", msg->primsg, msg->secmsg); break; } TemplEndWith (); MsgSetFnct (WwwPrintMessage); } int WwwParInput (int byteN, char *buff) { struct { char *name; char *val; } entry[1000]; int k, len, entryN=0, isDebug=ParGetBool ("isDebug"); char *name, *val; if (isDebug) printf ("Content-type: text/html\n\n"); /* ** the for loop contains code from the "post-query.c" shipped with Mosaic ** collect all pairs entry name and value from stdin */ for (k=0; byteN && (buff < buff+byteN); k++) { entry[k].val = fmakeword (&buff, buff+byteN, '&',&byteN); plustospace (entry[k].val); unescape_url (entry[k].val); entry[k].name = makeword (entry[k].val,'='); } entryN = k; /* ** now process these pairs into pairs of parameter name and value */ for (k=0; k < entryN; k++) { name = entry[k].name; val = entry[k].val; SmEdit (val, SMxTRIM); /* macintotsh client */ if (isDebug) printf ("#par /name=%s /str=%s
    \n", name, val); ParIsVolatileName (name); ParDefStr (name, val); } if (isDebug) printf("


    \n"); return entryN; } INT4 WwwPrintF (char *formatStr, ...) { static char *ln = NULL; va_list ap; if (!ln) if (!(ln = (char *) malloc (WWWxMAXLINESIZE+1))) _ErrExit2 (e__allocfail, "WWW output line"); /*[WWWxMAXLINESIZE+1]*/; va_start (ap, formatStr); vsprintf (ln, formatStr, ap); va_end (ap); printf ("%s", ln); if (ln[strlen (ln) -1] != '\n') printf ("\n"); return 1; } char *WwwChecked (Int4 flag) { return flag ? "CHECKED" : ""; } char *WwwSelected (Int4 flag) { return flag ? "SELECTED" : ""; } /****** WwwStringEncode ******************************************************* ** ** Replaces special characters by HTML codes; ** ** INPUT: string [W] ** IMPLICIT: ** ** RETURNS: modified string */ char *WwwStringEncode (char *str) { static STRv s=NULL; if (!s) s = StrNew (); else StrClear (&s); StrAppS (&s, str); StrReplace (&s, "&", "&"); StrReplace (&s, "|", "|"); StrReplace (&s, "<", "<"); StrReplace (&s, ">", ">"); return _Str (s); } INT4 WwwIndexValueLink (char *formatStr, ...) { static char *libName, *fieldName; va_list ap; char *value, tmp[80], queryStr[132]; INT4 entryN; if (!formatStr) { /* init */ libName = ParGetStr ("libName"); fieldName = ParGetStr ("listIndex"); return 1; } va_start (ap, formatStr); value = va_arg (ap, char *); entryN = va_arg (ap, INT4); va_end (ap); sprintf (tmp, "%s", value); sprintf (queryStr, "[%s-%s:%s]", libName, fieldName, value); printf ("%-55s %6d entries\n", WwwTransform ("encode", queryStr), fieldName, tmp, entryN); return 1; } /**api* WwwViewFeature ******************************************************** ** ** views a sequence feature ** ** INPUT: name of set [R] ** IMPLICIT: ** ** RETURNS: */ void WwwViewFeature (char *queryStr, INT4 subEntryN) { #ifdef script SETo *set, *setSub; IDoENTRY id, idSub; SCRIPTo *script; script = ScriptOpen (ScriptFile, NULL); if (QryDo (queryStr, "Q")) { set = SetGet ("Q"); SetGetID (set, 1, &id); setSub = SetNew ("QSUB", NULL); idSub.id_d = (IDoTYPE *) LibObjByName ("idtype", "seq-ft-id"); IdBuildSub (&idSub, &id, subEntryN); SetAddID (setSub, &idSub); ParDefBool ("parSetFields", 1); ParDefBool ("Features", 1); ParDefBool ("Definition", 1); ParDefBool ("ID", 1); ParDefBool ("takeuncompletefeature", 1); WwwPrintSet ("QSUB", 1, 1, script); } #endif } /**api* WwwPresentLaunchAppls ************************************************* ** ** In case they are available list all applications that can be launched ** for the specified query. ** ** INPUT: query number */ void WwwPresentLaunchAppls (Int4 queryNo, ENTRYv entry) { WWWoQUERY *query; SLBo *lib; LIBoDataType *dataType; APPLo **appl=NULL, *tmp; Int4 applN=0, applAllocN=0, k, i, c1, c2; if (!entry) query=WwwGetQuery (queryNo); else lib = EntryGetLib (entry); for (k=0; entry || query->lib[k].entryN; k++) { if (!entry) lib = (SLBo*) LibObjByName ("library", query->lib[k].name); for (c1=0; (dataType = LibNextDataType (lib, &c1));) for (c2=0; (tmp = ApplNextInDataType (dataType, &c2));) { for (i=0; i < applN; i++) if (tmp == appl[i]) break; if (i == applN && (!entry || ApplIs (tmp, "single"))) { *_addObj (appl, applN, applAllocN, APPLo*) = tmp; } } if (entry) break; } if (applN) { TemplPrint ("launch.head"); for (k=0; k < applN; k++) TemplPrint ("launch.appl", ApplGetName (appl[k])); TemplPrint ("launch.tail"); } free (appl); if (!entry) WwwDelQuery (query); } /**api* function *********************************************************** ** ** Presents all view where all libraries in the group ** are contained as root libraries. ** ** INPUT: library group object (or NULL) [R] */ void WwwPresentActiveViews (SRSoGROUP *group, SLBo *lib, WWWoQUERY *query, TEMPLv templ, Int4 isOptional) { VIEWo *view; VIEWoLIB *vlib; Int4 currViewNo=0, j, i, c, k, isPrinted=0; WwwInitViews (templ); if (ViewGetViewsN () > 0) { currViewNo = ParGetNum ("viewNumber"); if (!isOptional) TemplPrint ("selectView.head"); for (c=0,j=1; (view = ViewNext (&c));j++) { if (ViewIs (view, "forAll") && !isOptional) TemplPrint ("selectView.name", j, WwwSelected (j == currViewNo), ViewGetName (view)); else for (k=0; (vlib=ViewGetNextRootLib (view, &k));) { for (i=0; lib || (group && (lib = LibNextLib (group, &i))) || (query && (lib = (SLBo*) LibObjByName ("library", query->lib[i++].name)));){ if (vlib->lib == lib) { if (!isPrinted && isOptional) { TemplPrint ("selectView.head"); isPrinted = 1; } TemplPrint ("selectView.name", j, WwwSelected (j == currViewNo), ViewGetName (view)); } if (!group) break; else lib=NULL; } } } if (!isOptional || isPrinted) TemplPrint ("selectView.tail"); } } /**api* WwwPresentViewsForLeaf *********************************************** ** ** As WwwPresentViewForLibs but for a single leaf library. ** ** INPUT: view object [R] ** leaf object [R] */ void WwwPresentViewsForLeaf (VIEWo *view, VIEWoLIB *vlib, TEMPLv templ) { VIEWoLIB *rootVlib; Int4 c, j, k; char *tmp, *viewName; WwwInitViews (templ); viewName = ViewGetLeafView (vlib); if (ViewGetViewsN () > 0) { TemplPrint ("selectView.head", view->n, LibName (vlib->lib), WwwSelected (!*viewName)); for (c=0,j=1; (view = ViewNext (&c));j++) { tmp = ViewGetName (view); if (ViewIs (view, "forAll")) TemplPrint ("selectView.name", WwwSelected (SmEqs (viewName, tmp)), tmp); else for (k=0; (rootVlib=ViewGetNextRootLib (view, &k));) if (vlib->lib == rootVlib->lib) TemplPrint ("selectView.name", WwwSelected (SmEqs (viewName, tmp)), tmp); } TemplPrint("selectView.tail"); } } /****** WwwPresentViewList **************************************************** ** ** Print a menu with list all the views for selection. ** Requires that the template context is already set to a list ** with the "view labels" by TemplWith. ** ** INPUT: option: "reset", "current" [R] ** */ void WwwPresentViewList (char *option, TEMPLv templ) { VIEWo *view; char *tmp; Int4 k, i, currentViewNumber = ParGetNum("viewNumber"); WwwInitViews (templ); if (option[0] == 'r') /* reset */ currentViewNumber = 0; /*Int4 WwwIsViewForQuery (VIEWo *view, char *setName)*/ TemplPrint("head"); for (k=0, i=1; (view = ViewNext (&k)); i++) TemplPrint ("name", i, WwwSelected (k==currentViewNumber), ViewGetName (view)); TemplPrint("tail"); } /**api* WwwViewPartI ********************************************************** ** ** Lets user create or edit a view, part I, which is the selection of ** the leaf and root libraries. ** ** INPUT: view number [R] ** flag whether to edit an existing view [R] ** */ void WwwViewPartI (INT4 viewNo,INT4 isEdit, TEMPLv templ) { VIEWo *view; VIEWoLIB *vlib; SLBo *lib; SLBoFIELD *field; SRSoGROUP *group; INT4 i,c1,c2,c3, isFound; char *libName, *viewName; if(!isEdit) TemplPrint("create.logo"); else ParDefNum("nascentViewN", viewNo); view = WwwViewGet (viewNo, templ); if (view && WwwIsViewInternal (view)) WwwViewSave (view, ""); TemplPrint("create.head",viewNo,viewNo,viewNo,viewNo); TemplPrint("rootHeader", viewNo, view ? ViewGetName (view) : "", viewNo, WwwChecked (!view || ViewIsTable (view)), viewNo, viewNo, WwwChecked (view && ViewIsShortNames (view)), viewNo); if (!view) TemplPrint ("nascentName", viewNo); for(c1=0; (group = LibNextLibGroup(&c1)); ) { if( ! LibNofGroups(group) ) continue; TemplPrint("separator"); for(c2=0; (lib= LibNextLib(group,&c2)); ) { libName = LibGetName(lib,"full"); isFound=0; if (view) for (c3=0; (vlib=ViewGetNextRootLib (view, &c3));) if (vlib->lib == lib) { isFound = 1; break; } TemplPrint("rootLibsSelect",viewNo,libName, WwwSelected (isFound), libName); } } TemplPrint("rootTrailer"); TemplPrint("leafHeader"); for(c1=0; (group = LibNextLibGroup(&c1)); ) { if( !LibNofGroups(group) ) continue; TemplPrint("separator"); for(c2=0; (lib= LibNextLib(group,&c2)); ) { libName = LibName (lib); isFound=0; if (view) for (c3=0; (vlib=ViewGetNextLeafLib (view, &c3));) if (vlib->lib == lib) { isFound = 1; break; } TemplPrint("leafLibsSelect", viewNo, libName, WwwSelected (isFound), libName); } } TemplPrint("leafTrailer"); } char *WwwEntryQuery (ENTRYv entry, char *entryName, char *libName) { static STRv s=NULL; SLBo *lib; if (!s) s=StrNew (); else StrClear (&s); if (entry) { entryName = EntryGetName (entry); libName = LibName (EntryGetLib (entry)); lib = EntryGetLib (entry); } else lib = (SLBo*) LibObjByName ("library", libName); StrPrintf (&s, "[%s-%s:'%s']", libName, FieldGetName (LibGetIdField (lib)), entryName); return WwwTransform ("encode", _Str (s)); } /**api* WwwEntryPrint ********************************************************* ** ** Prints a single entry in various forms. ** ** INPUT: entry object [R] ** script object [W] ** IMPLICIT: ** ** RETURNS: */ void WwwEntryPrint (TEMPLv templ, ENTRYv entry) { static int entryNum=0; SEQo *seq=NULL, *protseq=NULL; char *entryName, *libName; TemplWith (templ, "$entry.inList"); if (ParGetBool ("printEntireEntry")){ /* print the complete entry */ /* print a few buttons */ TemplWith (templ, "envelope.head"); TemplPrint ("head", LibName (EntryGetLib (entry)), EntryGetName (entry), EntryGetFullName (entry)); WwwPresentLaunchAppls (0, entry); WwwPresentActiveViews (NULL, EntryGetLib (entry), NULL, templ, 1); TemplPrint ("tail"); TemplEndWith (); EntryViewPrintEnvelope (entry, "head"); EntryPrint (entry, NULL); EntryViewPrintEnvelope (entry, "tail"); } else if (ParGetBool ("downloadEntireEntry")){ /* download complete entry */ EntryPrint (entry, NULL); } else { /* entry within entry list */ entryName = EntryGetName (entry); libName = LibName (EntryGetLib (entry)); if (*ParGetStr ("userIdOpt")) { TemplPrint ("entry.rootName", ++entryNum, EntryGetFullName (entry), WwwEntryQuery (entry, NULL, NULL), EntryGetFullName (entry)); } else TemplPrint ("entry.inListNoId", WwwEntryQuery (entry, NULL, NULL), libName, entryName); if (LibIsAnyFieldActive (libName)) { EntryViewPrintEnvelope (entry, "head"); ParDefBool ("isHTMLFormat", 1); EntryPrintFields (entry, NULL); EntryViewPrintEnvelope (entry, "tail"); } } TemplEndWith (); } /**api* WwwPrintHelpTopic ***************************************************** ** ** prints help topic ** ** INPUT: name of help topic [R] ** IMPLICIT: ** ** RETURNS: */ void WwwPrintHelpTopic (char *helpTopic) { TEMPLv templ; templ = TemplOpen ("SRSDB:general.it", NULL); TemplWith (templ, "$main.fields"); WwwPrintContentType (NULL); TemplPrint(helpTopic); TemplEndWith(); } /****** WwwLinkStat *********************************************************** ** ** ** */ INT4 WwwLinkStat (char *setName) { TEMPLv templ; SLBo *lib; SRSoGROUP *group; char queryStr[512], *libName; INT4 k=0, context1, context2, context3, doSkipLib, isSelected=0; Int4 entryN =0,linkLibsN =0; templ = TemplOpen ("SRSICA:srswww.i", NULL); WwwPrintContentType(NULL); WwwQueryRepeat (ParGetNum ("linkSetNumber")); TemplWith(templ,"$linkSet"); TemplPrint("head"); WwwPrintButtons (templ); TemplPrint("tableHead", setName); for (context1=0; (group = LibNextLibGroup (&context1));) for (context2=0; (lib = LibNextLib (group, &context2));) if (LibIs (lib, "linkTarget")) { TemplPrint("newRow"); doSkipLib=0; for (context3=0; (SetGetNextLibStat (setName, &libName, &context3));) if (SmEqs (lib->nam, libName)) doSkipLib = 1; /* don't link to libs contained in the set */ if (!doSkipLib) { isSelected = 1; linkLibsN++; TemplPrint("libName",linkLibsN,lib->nam,lib->nam); sprintf (queryStr, "%s > %s", setName, lib->nam); WwwQueryLinkDo(queryStr); sprintf (queryStr, "%s < %s", setName, lib->nam); WwwQueryLinkDo(queryStr); sprintf (queryStr, "%s ! (%s < %s)", setName, setName, lib->nam); WwwQueryLinkDo(queryStr); TemplPrint("endRow"); } } if (!isSelected) _ErrMsg2 (e__nolinklibselected, "LINK"); TemplPrint("tail",linkLibsN); TemplEndWith(); return k; } /****** WwwQueryLinkDo *************************************************** ** ** ** ** ** ** ** */ WwwQueryLinkDo(char *queryStr) { WWWoQUERY *query; Int4 entryN, k; k = WwwQueryDo (queryStr, "link"); if( k ) { query = WwwGetQuery(k); TemplPrint("libEntriesH",ParGetStr("userId"),k,query->entryN); WwwDelQuery(query); } else { TemplPrint("libEntries",0); } } /****** WwwWriteFile *************************************************** ** */ INT4 WwwWriteFile (char *formatStr, ...) { FILE *file; va_list ap; va_start (ap, formatStr); vfprintf (file, formatStr, ap); va_end (ap); if (formatStr[strlen (formatStr) -1] != '\n') fprintf (file, "\n"); return 1; } /****** WwwGrowQuery ********************************************************** ** ** new query string is constructed from the selected ** entry names from result page ** ** INPUT: query string [W] ** Entry name [R] ** */ void WwwGrowQuery(char *queryString, char *fullEntry) { static char oldLibName[30] =""; char entryName[30],libName[30]; if(!*fullEntry) _ErrMsg2 (i__invalidentry, fullEntry); sscanf(fullEntry,"%[^:]:%[^@]",libName,entryName); if(!*queryString) { /* head part */ sprintf(queryString,"[%s-id:%s",libName,entryName); } else { /* tail parts */ if( SmEqs(oldLibName,libName)) sprintf(queryString,"%s | %s",queryString,entryName); else { sprintf(queryString,"%s] | [%s-id:%s",queryString,libName,entryName); } } strcpy(oldLibName,libName); } /****** WwwNextSelectedQuery ************************************************** ** ** Returns the number of the next query selected in the query manager. ** ** INPUT: the address of iterator (set to 0 to get the first) [W] ** address of pointer to the query name (or NULL) [W] ** ** RETURNS: the number of the next selected query. ** 0: no query was selected ** */ Int4 WwwNextSelectedQuery (Int4 *c, char **name) { static Int4 queryN=0; char *tmp; if (!*c) { *c = 1; queryN = ParGetNum ("numberOfQueries"); } else (*c)++; while (!*(tmp = ParGetStrF ("qmstr%d", *c)) && *c <= queryN) (*c)++; if (*c > queryN) return (*c = 0); if (name) *name = tmp; return (*c); } /****** WwwQuerySelectedEntries *********************************************** ** ** Make a set with selected entries from the query result page and ** do the query. ** ** RETURNS: the number of the resulting query/set ** 0: no entry was selected ** */ Int4 WwwQuerySelectedEntries () { char *entryName,queryString[5000]; Int4 i, entryN, queryN=0, last=ParGetNum ("viewEntriesChunkSize"); queryString[0] ='\0'; for(i=1, entryN=0; i <= last; i++){ entryName = ParGetStrF("EntryNum_%d",i); if(*entryName) { WwwGrowQuery(queryString,entryName); entryN++; } } if (entryN) { sprintf(queryString,"%s]",queryString); queryN = WwwQueryDo(queryString,"select"); } return queryN; } /**api* WwwQueryPrint ******************************************************** ** ** Prints the page with the results of a query. The entry list can ** be printed either as a normal list or as a table. ** ** INPUT: the query number in the "query history" [R] ** */ void WwwQueryPrint (INT4 queryN) { WWWoQUERY *query; TEMPLv templ; Int4 startN=ParGetNum ("viewEntriesStartN"), chunkSize=ParGetNum ("viewEntriesChunkSize"); templ = WwwInit (); WwwInitViews (templ); TemplWith (templ, "$queryResult"); TemplPrint ("head"); WwwPrintButtons (templ); /* get the query and print the header of result list*/ query = WwwGetQuery (queryN); TemplPrint ("title", WwwStringEncode (query->queryStr), query->entryN,query->entryN); TemplPrint ("options.head", queryN, chunkSize, queryN); TemplWith (templ, "options"); WwwPresentLaunchAppls (queryN, NULL); TemplEndWith (); TemplPrint ("options.download"); TemplWith (templ, "options"); WwwPresentActiveViews (NULL, NULL, query, templ, 0); TemplEndWith (); TemplPrint ("options.tail"); TemplPrint ("entriesStart"); /* print entry list */ if (ParGetNum ("viewNumber") > 1) WwwPrintSetView (templ, query->name, startN, chunkSize); else WwwPrintSet (templ, query->name, startN, chunkSize); WwwDelQuery (query); WwwPresentSkipChunkSet (templ, query->entryN, queryN); TemplPrint ("tail"); TemplEndWith (); } char *WwwRootLibNames (VIEWo *view) { static char s[500]; VIEWoLIB *vlib; Int4 k; for (k=0, s[0]='\0'; (vlib = ViewGetNextRootLib (view, &k));) sprintf (s, "%s%s ", s, LibName (vlib->lib)); s[strlen(s)-1] = '\0'; return s; } /****** WwwPrintSelectField *************************************************** ** ** Prints a field name in the list fields to be selected for view. ** ** INPUT: view object [R] ** number of view [R] ** field object [R] ** view library object [R] or NULL if field from root library ** number of columns per row [R] ** address of count of fields in the current row [R] ** */ void WwwPrintSelectField (VIEWo *view, Int4 viewNum, SLBoFIELD *field, VIEWoLIB *vlib, Int4 numCol, Int4 *count) { LIBoFieldFormat *format; char *fieldName,*tmp, *libNames; Int4 c; fieldName = LibGetFieldName (field); if (!vlib) libNames = WwwRootLibNames (view); else libNames = LibName (vlib->lib); if (FieldIs (field, "header")) { if (*count>0) TemplPrint ("newRow"); TemplPrint ("fieldHeader", numCol, fieldName); *count = 0; } else { if (!((*count)++ % numCol)) TemplPrint ("newRow"); if (vlib) /* field of leaf library */ TemplPrint ("field", viewNum, LibName (vlib->lib), fieldName, WwwChecked (ViewIsLeafField (view, vlib, field)), fieldName, libNames, fieldName, ""); else TemplPrint ("field", viewNum, fieldName, WwwChecked (ViewIsRootField (view, field)), fieldName, libNames, fieldName, ""); /* if field has format option print the menu with all options */ if (field->type->formatN) { if (vlib) { TemplPrint ("format.head", viewNum, LibName (vlib->lib), fieldName); for (c=0; (format=LibNextFieldFormat (field->type, &c));){ tmp = ParGetStrF("v%d_LF_%s_%s_format", viewNum, LibName (vlib->lib), fieldName); TemplPrint ("format.name",SmEqs(tmp,format->name) ? "SELECTED" : "", format->name); } } else { TemplPrint ("format.head", viewNum, fieldName); for (c=0; (format=LibNextFieldFormat (field->type, &c));){ tmp = ParGetStrF("v%d_RF_%s_format",viewNum,fieldName); TemplPrint ("format.name",SmEqs(tmp,format->name) ? "SELECTED" : "", format->name); } } TemplPrint ("format.tail"); } TemplPrint ("fieldTail"); } } /**api* WwwPrintSetView ******************************************************* ** ** Equivalent to WwwPrintSet (calls WwwPrintSet) but prints the list of ** entries using a view. ** ** INPUT: the template object [W] ** the query name [R] ** the start entry number [R] ** the chunk size [R] ** IMPLICIT: ** wwwView (VIEWo *) ** */ void WwwPrintSetView (TEMPLv templ, char *queryName, Int4 startN, Int4 chunkSize) { Int4 viewNo = 0; ParDefBool ("isHTMLFormat", 1); if (!(viewNo = ParGetNum("viewNumber"))) viewNo = ViewGetViewsN (); wwwView = ViewGetWithNo (viewNo); if (!WwwIsViewForQuery (wwwView, queryName)) { _ErrMsg3 (e__wwwnomatchingview, queryName, ViewGetName (wwwView)); WwwPrintSet (templ, queryName, startN, chunkSize); } else { ParDefBool ("isView", 1); ParSetVolatile ("isView"); if (ViewIsTable (wwwView)) { TemplWith (templ, "$entry.inTable"); WwwViewTableHeader (templ, wwwView); ParDefBool("isTable", 1); ParSetVolatile ("isTable"); } WwwPrintSet (templ, queryName, startN, chunkSize); if (ViewIsTable (wwwView)) { TemplPrint ("tail"); TemplEndWith (); } } ViewDelete (wwwView); } /****** WwwViewTableHeader **************************************************** ** ** Prints the header of the table containing a view of one or more ** entries. ** ** INPUT: template object [W] ** */ static void WwwViewTableHeader (TEMPLv templ, VIEWo *view) { SLBoFIELD *field; VIEWoLIB *tmp, *vlib; char *libName; Int4 k, l, m; TemplPrint ("head"); for (k=0, l=0; (tmp=ViewGetNextRootLib (view, &k)); l++) vlib = tmp; libName = l>1 ? "RootLibs" : LibName (vlib->lib); TemplPrint ("title.library", libName); for (m=0; (field=ViewGetNextField (vlib, &m));) TemplPrint ("title.field", LibName (vlib->lib), LibGetFieldName (field), ViewIsShortNames (view) ? LibGetFieldShortName (field) : LibGetFieldName (field)); /* ... and view leaf fields names */ for (k=0; (vlib=ViewGetNextLeafLib (view, &k));) { TemplPrint ("title.library", LibName (vlib->lib)); if (!ViewLeafIsOnlyEntryN (vlib)) for(m=0; (field=ViewGetNextField (vlib, &m));) TemplPrint ("title.field", LibName (vlib->lib), LibGetFieldName (field), ViewIsShortNames (view) ? LibGetFieldShortName (field) : LibGetFieldName (field)); } TemplPrint ("title.tail"); } /****** WwwViewPrintEntryN *************************************************** ** ** Prints an entry view inside a table. ** ** INPUT: leaf object [R] ** the root entry object [R] ** number of rows to extend [R] ** ** RETURNS: number of fields printed for the entry */ static void WwwViewPrintEntryN (VIEWo *view, VIEWoLEAFSET *leaf, ENTRYv entry, Int4 rowN) { char *viewName, *queryStr; Int4 viewN; viewName = ViewGetLeafView (leaf->vlib); viewN = *viewName ? ViewGetViewNumber (viewName) : 0; if (*viewName); queryStr = ViewGetLeafQuery (leaf->vlib, entry); TemplPrint ("onlyEntryN", rowN, viewN, WwwTransform ("encode", queryStr), leaf->entryN); } /**api* WwwPrintSet *********************************************************** ** ** Prints a list of entries in various formats. ** ** INPUT: o template object [W] ** o name of set/query [R] ** o number of first entry to be printed, first is 1...if 0 ** then is set to 1 [R] ** o number of entries to print, if 0 then size of set is ** assumed [R] ** IMPLICIT: ** ** RETURNS: */ void WwwPrintSet (TEMPLv templ, char *setName, int firstN, int printN) { ENTRYv entry; SETo *set; IDoENTRY id; char *tmp; INT4 setEntryN, k, lastN, moreN; if (!firstN) firstN = 1; set = SetGet (setName); setEntryN = SetSize (setName); if (!printN) printN = setEntryN; lastN = firstN + printN - 1; for (k=firstN; k <= lastN && k <= setEntryN; k++) { SetGetID (set, k, &id); entry = EntryOpen (&id); if (entry) { if (LibIs (EntryGetLib (entry), "user")) chdir (_FilTempLN (ParGetStrF ("%sDirName", LibName (EntryGetLib (entry))))); if(ParGetBool("isView")) EntryView (entry, wwwView); else WwwEntryPrint (templ, entry); EntryClose (&entry); } } } void WwwViewEntryNamePrint (VIEWo *view, ENTRYv entry, Int4 entryNo, Int4 rowN, Int4 isRoot) { if (ViewIsTable (view)) { if (isRoot) TemplPrint ("rootNameManyLibs", rowN, entryNo, EntryGetFullName (entry), WwwEntryQuery (entry, NULL, NULL), LibName (EntryGetLib (entry)), EntryGetName(entry)); else TemplPrint ("leafName", rowN, WwwEntryQuery (entry, NULL, NULL), EntryGetName (entry)); } else { if (isRoot) TemplPrint ("rootName", entryNo, EntryGetFullName (entry), WwwEntryQuery (entry, NULL, NULL), EntryGetFullName(entry)); else TemplPrint ("leafName", WwwEntryQuery (entry, NULL, NULL), EntryGetFullName (entry)); } } /**api* WwwViewGet ************************************************************** ** ** Retrieves a view object from user context. The view number can ** be obtained by ViewGetViewNumber. Delete the object with ViewDelete. ** A view can also be logically deleted by user ** - check with ViewIsDeleted. ** ** INPUT: view number [R] * the template used for printing entries [R] ** ** RETURNS: view object ** ** */ VIEWo *WwwViewGet (INT4 viewN, TEMPLv templ) { VIEWo *view; VIEWoLIB *vlib; VIEWoFIELD *vfield; SLBo *lib, *rootLib; SLBoFIELD *field; SRSoGROUP *group; char *libName, *fieldName, *viewName; INT4 c1,c2,c3; if (!*(viewName = ParGetStrF ("view%d_Name", viewN))) return ViewGetWithNo (viewN); /* might be internally known */ view = ViewNew (viewN, viewName); ViewSetTemplate (view, templ); ViewSetEntryNamePrint (view, WwwViewEntryNamePrint); ViewSetEntryNamePrinting (view, 1); ViewSetEntryNPrint (view, (Func) WwwViewPrintEntryN); if (ParGetNumF("view%d_isTable", viewN)) ViewSetFormat (view, "table"); ViewSetUseShortNames (view, ParGetNumF ("view%d_isShortNames", viewN)); if (ParGetNumF ("ViewDeleted_%d", viewN)) ViewMarkDeleted (view); /* process root databanks */ for (c1=0; (group = LibNextLibGroup(&c1));) { for (c2=0; (lib = LibNextLib (group, &c2));) { if (ParGetNumF ("v%d_R_%s", viewN, LibName (lib))) { rootLib = lib; vlib = ViewAddRootLib (view, lib); } } } for (c3=0; (field = LibNextField (rootLib, &c3));) { fieldName = LibGetFieldName (field); if (ParGetNumF ("v%d_RF_%s", viewN, fieldName)) { vfield = ViewAddRootField (view, LibFieldType (field)); ViewSetFieldFormat (vfield, ParGetStrF ("v%d_RF_%s_format", viewN, fieldName)); } } /* process leaf databanks */ for (c1=0; (group = LibNextLibGroup (&c1));) { for (c2=0; (lib = LibNextLib (group, &c2));) { libName = LibGetName (lib, "full"); if (ParGetNumF ("v%d_L_%s", viewN, libName)) { vlib = ViewAddLeafLib (view, lib); ViewSetLeafQuery (vlib, ParGetStrF ("v%d_Lextra_%s_query", viewN, libName)); ViewSetLeafPrintN (vlib, ParGetNumF ("v%d_Lextra_%s_onlyEntryN", viewN, libName)); ViewSetLeafView (vlib, ParGetStrF ("v%d_Lextra_%s_view", viewN, libName)); for(c3=0; (field = LibNextField (lib, &c3));) { fieldName = LibGetFieldName (field); if(ParGetNumF("v%d_LF_%s_%s", viewN, libName, fieldName)) { vfield = ViewAddField (vlib, LibFieldType (field)); ViewSetFieldFormat (vfield, ParGetStrF ("v%d_LF_%s_%s_format", viewN, libName,fieldName)); } } } } } return view; } Int4 WwwIsViewInternal (VIEWo *view) { return *ParGetStrF ("view%d_Name", ViewGetNo (view)) ? 0 : 1; } static void WwwViewSave (VIEWo *view, char *option) { VIEWoLIB *vlib; SLBoFIELD *field; Int4 n=ViewGetNo (view), k, c, c2; ParDefStrF (ViewGetName (view), "view%d_Name", n); if (ViewIsShortNames (view)) ParDefStrF ("1", "view%d_isShortNames", n); if (ViewIsTable (view)) ParDefStrF ("1", "view%d_isTable", n); for(c=0, k=0; (vlib = ViewGetNextRootLib (view, &c)); k++) { ParDefStrF ("1", "v%d_R_%s", n, LibName (vlib->lib)); if (!k) for(c2=0; (field = ViewGetNextField (vlib, &c2));) { ParDefStrF ("1", "v%d_RF_%s", n, FieldGetName (field)); } } for(c=0, k=0; (vlib = ViewGetNextLeafLib (view, &c)); k++) { ParDefStrF ("1", "v%d_L_%s", n, LibName (vlib->lib)); for(c2=0; (field = ViewGetNextField (vlib, &c2));) { ParDefStrF ("1", "v%d_LF_%s_%s", n, LibName (vlib->lib), FieldGetName (field)); } } } void WwwInitViews (TEMPLv templ) { static int isInit=0; VIEWo *view; Int4 c, viewNo; if (isInit) return; for (c=0; (view = ViewNext (&c));) { /* get modified version if exists */ viewNo = ViewGetNo (view); if (!ViewIs (view, "forAll") && *ParGetStrF ("view%d_Name", viewNo)) { view = WwwViewGet (viewNo, templ); ViewSetWithNo (view, viewNo); } else { ViewSetTemplate (view, templ); ViewSetEntryNamePrint (view, WwwViewEntryNamePrint); ViewSetEntryNPrint (view, (Func) WwwViewPrintEntryN); ViewSetEntryNamePrinting (view, 1); } } ViewSetUserList (WwwViewGet, templ); isInit=1; } /**api* WwwQueryGetSet ******************************************************** ** ** This is SRSWWW's version of 'QueryGetSet' of the query module. ** The difference is that queries represented with names inside ** the query are evaluated by submitting the query associated to ** a set name. ** Evaluation of the overall query is a recursive process. ** */ INT4 WwwQuerySetGet () { WWWoQUERY *query; SLBo *lib; SETo *set; char name[132]; IargGetArgs ("name", name); if (!(set = SetGet (name))) { if ((lib = (SLBo *) LibObjByName ("library", name)) || SmEqs (name, "parent")) { set = SetNew (name, NULL); SetSetIsDB (set, 1); } else if ((query = WwwGetQueryName (name))) { set = QueryRecursive (query->queryStr, name); } else _ErrExit2 (e__nosetorlib, name); } IcaReturn ("set", set); } /**api* WwwQueryDo ************************************************************ ** ** evaluates a query in a recursive way ...whenever a set name is ** encountered that set is reconstructed by repeating the ** associated query (if not already done). ** ** INPUT: query expression string [R] ** query type: "link", "query" [R] ** IMPLICIT: ** ** RETURNS: number of query in history if success ** 0 if not */ INT4 WwwQueryDo (char *queryStr, char *queryType) { static INT4 isInit=0; char queryName[80]; INT4 queryN=ParGetNum ("numberOfQueries"); if (!isInit) /* set SRSWWW's own function */ IcaSetFunction ("QuerySetGet", WwwQuerySetGet); sprintf (queryName, "Q%d", queryN + 1); if (Query (queryStr, queryName)) { WwwRegisterQuery (queryName, SetGetQueryStr (queryName), queryType); return queryN + 1; } return 0; } /**api* WwwQueryRepeat ******************************************************** ** ** Repeats a query already recorded in history which is identified ** by the query number. ** ** INPUT: ** IMPLICIT: ** ** RETURNS: */ INT4 WwwQueryRepeat (INT4 queryN) { static INT4 isInit=0; WWWoQUERY *query=NULL; if (!isInit) /* set SRSWWW's own function */ IcaSetFunction ("QuerySetGet", WwwQuerySetGet); query = WwwGetQuery (queryN); Query (query->queryStr, query->name); WwwDelQuery (query); return 1; } /**api* WwwQueryExpression **************************************************** ** ** Evaluates a query expression and prints the result; ** ** INPUT: o the type of the result set: "expression", "query", ... [R] ** o the query string [R] ** IMPLICIT: ** ** RETURNS: */ void WwwQueryExpression (char *queryType, char *queryStr) { char *s; s= WwwTransform ("decode", queryStr); if (WwwQueryDo (s, queryType)) WwwQueryPrint (ParGetNum ("numberOfQueries")); else _ErrMsg2 (i__querynegative, queryStr); } /**api* WwwLinkSet ************************************************************ ** ** links a set from history to selected libraries using various options; ** ** INPUT: number of query to be linked [R] ** IMPLICIT: ** ** RETURNS: number of result query in history ** 0: no library was selected for linking */ Int4 WwwLinkSet (Int4 queryN) { QASvQUERY qas; WWWoQUERY *query; SLBo *lib; SRSoGROUP *group; Int4 k, c1, c2; qas = QasNew (); QasInitLink (qas); query = WwwGetQuery (queryN); QasSetQueryToLink (qas, query->queryStr); WwwDelQuery (query); QasSetLinkType (qas, ParGetStr ("linkSetType")); QasSetTmpSetNum (qas, queryN); for (k=0, c1=0; (group = LibNextLibGroup (&c1));) for (c2=0; (lib = LibNextLib (group, &c2));) if (LibIs (lib, "linkTarget")) { QasSetLinkWith (qas, LibName (lib)); k++; } if (!k) { _ErrRet2 (e__nolinklibselected, "[S+L]"); return 0; } else queryN = WwwQueryDo (QasGetQueryString (qas), "link"); QasDelete (qas); return queryN; } Int4 WwwLinkEntry (char *libName, char *entryName) { QASvQUERY qas; SLBo *lib; SRSoGROUP *group; Int4 k, c1, c2, queryN; qas = QasNew (); QasInitLink (qas); QasSetQueryToLink (qas, WwwEntryQuery (NULL, entryName, libName)); QasSetLinkType (qas, "toLibs"); QasSetTmpSetNum (qas, 555); for (k=0, c1=0; (group = LibNextLibGroup (&c1));) for (c2=0; (lib = LibNextLib (group, &c2));) if (LibIs (lib, "linkTarget")) { QasSetLinkWith (qas, LibName (lib)); k++; } if (!k) { _ErrRet2 (e__nolinklibselected, "[S+L]"); return 0; } else queryN = WwwQueryDo (QasGetQueryString (qas), "link"); QasDelete (qas); return queryN; } /**api* WwwTransform ********************************************************* ** ** if a query string is put as parameter value in html script then ** <> chars are recognized as syntactic elements; ** ** INPUT: option "decode" and "encode" [R] ** string to be transformed [R] ** IMPLICIT: ** ** RETURNS: */ char *WwwTransform (char *option, char *s) { static char tmp[1000]; strcpy (tmp, s); if (option[0] == 'e') { SmSwapS (tmp, ">", ">"); SmSwapS (tmp, "<", "<"); SmSwapS (tmp, "+", "_PL_"); SmSwapS (tmp, " ", "_SP_"); } else { SmSwapS (tmp, ">", ">"); SmSwapS (tmp, "<", "<"); SmSwapS (tmp, "_PL_", "+"); SmSwapS (tmp, "_SP_", " "); } return tmp; } /**api* WwwRegisterQuery ****************************************************** ** ** records a query description as a list of parameters; ** these parameter's will be saved in the user file; ** ** INPUT: name of successful query [R] ** query expression [R] ** query type: "query", "link" ** IMPLICIT: ** ** RETURNS: */ void WwwRegisterQuery (char *queryName, char *queryStr, char *queryType) { char *libName, parName[80]; INT4 c, k, libN, queryN, entryN; entryN = SetSize (queryName); if ((SmEqs (queryType, "expression") || SmEqs (queryType, "query") || SmEqs(queryType,"link") || SmEqs (queryType, "select")) && entryN) { queryN = ParGetNum ("numberOfQueries"); ParDefNum ("numberOfQueries", ++queryN); sprintf (parName, "QueryStr%d", queryN); ParDefStr (parName, queryStr); sprintf (parName, "QuerySize%d", queryN); ParDefNum (parName, entryN); sprintf (parName, "QueryType%d", queryN); ParDefStr (parName, queryType); sprintf (parName, "isSubEntry%d", queryN); ParDefNum (parName, SetIsSubEntry (queryName)); sprintf(parName,"QueryDeleted_%d",queryN); /* added: Ramu */ ParDefNum(parName,ParGetNum(parName)); /* for query manager function */ sprintf(parName,"QueryComm%d",queryN); ParDefStr(parName,ParGetStr(parName)); for (c=0, k=1; (libN=SetGetNextLibStat (queryName, &libName, &c)); k++) { sprintf (parName, "QueryLibrary%d_%d", queryN, k); ParDefStr (parName, libName); sprintf (parName, "QueryLibraryN%d_%d", queryN, k); ParDefNum (parName, libN); } } } /**api* WwwDeleteQuery ****************************************************** ** ** deletes last query in history; ** ** INPUT: ** IMPLICIT: ** ** RETURNS: */ static void WwwDeleteQuery () { char parName[80]; INT4 queryN, k; queryN = ParGetNum ("numberOfQueries"); sprintf (parName, "QueryStr%d", queryN); ParDelete (parName); sprintf (parName, "QuerySize%d", queryN); ParDelete (parName); sprintf (parName, "QueryType%d", queryN); ParDelete (parName); sprintf (parName, "isSubEntry%d", queryN); ParDelete (parName); for (k=0; ; k++) { sprintf (parName, "QueryLibrary%d_%d", queryN, k); if (!ParDelete (parName)) break; /* no more items */ sprintf (parName, "QueryLibraryN%d_%d", queryN, k); ParDelete (parName); } ParDefNum ("numberOfQueries", --queryN); } /**api* WwwGetQueryName ********************************************************* ** ** Returns descriptor of query with specified name. ** ** INPUT: query name [R] ** IMPLICIT: ** ** RETURNS: query descriptor object */ WWWoQUERY *WwwGetQueryName (char *name) { INT4 queryN; if (!(sscanf (name, "Q%d", &queryN) || sscanf (name, "q%d", &queryN))) _ErrExit3 (e__objectunknown, "set", name); return WwwGetQuery (queryN); } /**api* WwwGetQuery *********************************************************** ** ** Creates a query object with all information about it from the user ** file - this object must be deleted with WwwDelQuery after use. ** ** INPUT: address of query object [W] ** IMPLICIT: ** ** RETURNS: */ WWWoQUERY *WwwGetQuery(int queryN) { WWWoQUERY *query; char parName[132]; int k; if (queryN > ParGetNum ("numberOfQueries")) { _ErrExit3 (e__objectunknown, "query" , "number?"); } query = malloc (sizeof (WWWoQUERY)); query->queryN = queryN; sprintf (query->name, "Q%d", queryN); sprintf (parName, "QueryStr%d", queryN); /* better copy query string since it will have to be encoded for printing on HTML and therefore needs some extraspace */ strcpy (query->queryStr, ParGetStr (parName)); sprintf(parName,"QueryComm%d",queryN); strcpy(query->comment,ParGetStr(parName)); sprintf (parName, "QuerySize%d", queryN); query->entryN = ParGetNum (parName); sprintf (parName, "QueryType%d", queryN); query->type = ParGetStr (parName); sprintf (parName, "isSubEntry%d", queryN); query->isSubEntry = ParGetBool (parName); sprintf(parName, "QueryDeleted_%d",queryN); query->isDeleted = ParGetNum(parName); for (k=0;; k++) { sprintf (parName, "QueryLibrary%d_%d", queryN, k+1); if (!*(query->lib[k].name = ParGetStr (parName))) break; sprintf (parName, "QueryLibraryN%d_%d", queryN, k+1); query->lib[k].entryN = ParGetNum (parName); } query->lib[k].entryN = 0; /* end marker ..."name" is also NULL! */ return query; } /**api* WwwDelQuery ********************************************************* ** ** Deletes a query object created with WwwGetQuery or WwwGetQueryName. ** ** INPUT: address of query object [W] ** */ void WwwDelQuery (WWWoQUERY *query) { if (query) free (query); } void WwwPrintValue (char *libName, char *fieldName, char *value, Int4 n, Int4 entryN) { TemplPrint ("value", n, libName, fieldName, value, fieldName, libName, fieldName, WwwTransform ("encode", value), value, entryN); } /**api* WwwParRead *********************************************************** ** ** reads parameters from user-context file ** ** INPUT: userID [R] ** true if failure to read parameter file is fatal; ** IMPLICIT: ** ** RETURNS: */ void WwwParRead (char *userId, INT4 doInsist) { INT4 rv; if (!userId || !*userId) { if (doInsist) _ErrExit (e__filnotok); else return; } rv = ParRead (WwwGetName (userId, "context")); if (_ErrIs (rv) && doInsist) _ErrExit2 (rv, userId); } /**api* WwwParWrite *********************************************************** ** ** reads parameters from user-context file ** ** INPUT: userID [R] ** IMPLICIT: ** ** RETURNS: */ void WwwParWrite (char *userId) { ParSave (WwwGetName (userId, "context")); } /**api* WwwNewUserId *********************************************************** ** ** reads parameters from user-context file ** ** INPUT: userID [R] ** IMPLICIT: ** ** RETURNS: */ char *WwwNewUserId () { static char userId[80]; char tmp1[30]; char tmp2[30]; char *remoteAddr = getenv ("REMOTE_ADDR"), *dirName, command[255]; int k; if (!remoteAddr) remoteAddr = "local"; ParDefStr("remoteAddress",remoteAddr); SmRemoveChar(remoteAddr,'.'); /* trim to 8 characters */ for (k=strlen (remoteAddr) - 8; k > 0; k--) remoteAddr[k-1] = ' '; LibBaseConv(atoi(remoteAddr),60,tmp1); LibBaseConv(TimeGet(),60,tmp2); sprintf (userId, "%s%s",tmp1, tmp2 ); dirName = WwwGetName (userId, "directory"); if (mkdir (dirName, 00777) != 0) _ErrExit2 (e__filnotok, dirName); sprintf (command, "chmod 777 %s", dirName); system (command); ParDefStr ("userId", userId); return userId; } /**api* WwwFileName ********************************************************** ** ** returns a file or directory name ** ** INPUT: userID [R] ** option: "context", "directory" [R] ** IMPLICIT: ** ** RETURNS: file name */ char *WwwGetName (char *userId, char *option) { static char name[255], rootDirName[80]="SRSWWWTMP"; switch (tolower (option[0])) { case 'c': /* context */ sprintf (name, "%s/%s/user.par", rootDirName, userId); break; case 'd': /* directory */ sprintf (name, "%s/%s", rootDirName, userId); break; case 's': /* status */ sprintf (name, "%s/%s/busy", rootDirName, userId); break; default: _ErrExit2 (e__unknownoption, option); } return _FilLN (name); } /**api* WwwGetIdParam ********************************************************* ** ** builds the Id parameter for calling wgetz via command line ** ** INPUT: ** IMPLICIT: ** ** RETURNS: parameter for command line */ char *WwwGetIdParam () { static char parStr[80]; char *userId; userId = ParGetStr ("userId"); if (!userId || !*userId) { parStr[0] = '\0'; return parStr; } else { sprintf (parStr, "-id+%s+", userId); return parStr; } } /**api* WwwGetODDFile ********************************************************* ** ** Gets, if available, the ODD file for the library; ** ** INPUT: ** IMPLICIT: ** ** RETURNS: */ void WwwGetODDFile (char *libName) { #ifdef xxx SLBo *lib; FILEo file; INT4 rv; char fileName[132]; if (SmEqs (libName, "hyperlink")) strcpy (fileName, "SRSICA:hyperlink.sdl"); else { if (!(lib = (SLBo*) LibObjByName ("library", libName))) _ErrExit3 (e__objectunknown, "library", libName); if (*lib->oddfile) sprintf (fileName, "SRSICA:%s", lib->oddfile); else return; } rv = FilUOpen (&file, fileName, 255, 0); _ErrExit2 (rv, fileName); printf ("
    ");
      do {
        fputs (WwwStringEncode (file.ln), stdout);
        rv = FilURead (&file);
      }
      while (rv != e__eof);
      printf ("
    "); FilUClose (&file); #endif } /***LibBaseConv************************************************************* ** Author: Chenna Ramu ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387372 ** Email: chenna@embl-heidelberg.de ** ** Base Conversion to any base less than the number of characters ** available in symbol table. ** ** ** INPUT: num : Decimal number to be converted ** base : ** temp : converted number as string ** */ int LibBaseConv( int num, int base, char *temp) { char abuf[]= {"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvxyz" }; Int4 i = 0, r = 0, iret = 0; temp[0] = '\0'; /* LibShuffleBuff(abuf); */ if (base > strlen(abuf) ) { _ErrMsg2 (e__illegalbaseconv,strlen(abuf)+1); base = strlen(abuf); /* assume the maximum possible base */ } for(i=0; num >= base; i++) { r = num%base; iret = iret + LibPower(10,i) * r; num = (num-r)/base ; temp[i] = abuf[r]; } iret = iret + LibPower(10,i) * num; temp[i] = abuf[num]; temp[i+1] = '\0'; LibRevStr(temp); return (iret); } /** LibPower ************************************************* ** ** ** ** raise base to the power n and return the result ** ** **/ INT4 LibPower(int base, int n) { int i = 0; for( i = 1; n > 0; --n) i = i * base; return i; } /** LibRevStr ******************************************************************* ** ** ** ** Reverse given string ** ** ** **/ void LibRevStr(char s[]) { int c,i,j; for(i=0, j = strlen(s)-1; i = setSize) return; /* do not show skip set when there is only one result page */ if( !startN) startN = 1; TemplWith (templ, "$chunkSet"); TemplPrint ("head", WwwGetIdParam(),queryN, chunkSize,ParGetNum("viewNumber")); if( ParGetNum("viewEntriesStartN") > windowSize * chunkSize) chunkStart = startN/chunkSize; if( chunkStart-5 > 0) /* slide window size */ chunkStart = chunkStart - 5 ; for( k=chunkStart; k < windowSize+chunkStart+5 ; k++) { if( (k*chunkSize+1) > setSize) break; if (startN == (k*chunkSize+1)) TemplPrint ("current",WwwGetIdParam(),queryN,k*chunkSize+1, (setSize < chunkSize) ? setSize:chunkSize, ParGetNum("viewNumber"),k+1); else TemplPrint ("other", WwwGetIdParam(), queryN,k*chunkSize+1, (setSize < chunkSize) ? setSize:chunkSize, ParGetNum("viewNumber"),k+1); } if( chunkEnd < 1 ) chunkEnd = 1; TemplPrint ("tail", WwwGetIdParam(),queryN,chunkEnd, (setSize < chunkSize) ? setSize:chunkSize,ParGetNum("viewNumber")); TemplEndWith (); } /**api* WwwIsViewForQuery **************************************************** ** ** Determines if the view is really suitable for a particular query. ** If the query has elements from more than one databank then all of ** these must be root libraries in the view. ** ** INPUT: the view object [R] ** the query object [R} ** IMPLICIT: ** ** RETURNS: 1: view is suitable ** 0: not */ static Int4 WwwIsViewForQuery (VIEWo *view, char *setName) { VIEWoLIB *vlib; char *libName; Int4 isFound, c, h, n; if (ViewIs (view, "forAll")) return 1; for (c=0; (n = SetGetNextLibStat (setName, &libName, &c));) { for (h=0, isFound=0; (vlib = ViewGetNextRootLib (view, &h));) if (SmEqs (libName, LibName (vlib->lib))) isFound++; if (!isFound) return 0; } return 1; } /**api* WwwPresentChunkSizes ************************************************** ** ** Prints the chunk sizes for listing and viewing entries; ** ** INPUT: script object [R] ** IMPLICIT: ** ** RETURNS: */ Int4 WwwPresentChunkSizes (TEMPLv templ) { INT4 viewChunk[20] = {5, 10, 20, 30, 40, 50, 100, 200, 500, 1000, 2000, 5000, 10000}, viewChunkCurr = ParGetNum ("viewEntriesChunkSize"), k; TemplPrint("head"); for (k=0; viewChunk[k]; k++) { TemplPrint ("size", viewChunk[k] == viewChunkCurr ? "SELECTED" : "", viewChunk[k]); } TemplPrint("tail"); } /**api* WwwPresentChunkSizesMime ********************************************** ** ** prints the chunk sizes for exporting entries; ** ** INPUT: script object [R] ** IMPLICIT: ** ** RETURNS: */ void WwwPresentChunkSizesMime (TEMPLv templ, Int4 queryN) { WWWoQUERY *query = WwwGetQuery (queryN); INT4 entryN=query->entryN, k, l, chunkSize = ParGetNum ("viewEntriesChunkSize"); TemplWith (templ,"mime"); TemplPrint ("head"); for (k=entryN, l=0; k > 0 && l < 50 /*max menu size*/; k -= chunkSize, l++) TemplPrint ("size", WwwSelected (!l), l*chunkSize+1, k < chunkSize ? entryN : (l+1)*chunkSize ); TemplPrint ("tail"); TemplEndWith (); WwwDelQuery (query); } /**api* WwwSetColorScheme ***************************************************** ** ** Sets the color scheme for the current page. The color is specified ** by the parameter "wwwColorScheme" ** */ void WwwSetColorScheme (TEMPLv templ) { char *color, tmp[200]; color = ParGetStr ("wwwColorScheme"); if (color && *color && !(SmEqs (color, "plain"))) { TemplWith (templ, "$colorScheme"); TemplWith (templ, color); ParDefStr ("pageColor", TemplSPrint (tmp, "page")); ParDefStr ("cellColor", TemplSPrint (tmp, "cell")); ParSetVolatile ("pageColor"); ParSetVolatile ("cellColor"); TemplEndWith (); TemplEndWith (); } } /* ought to disappear soon */ void WwwPresentColorMenu () { char *color, *colorSelected; struct VARo *any, *tmp; Int4 i; colorSelected = ParGetStr ("wwwColorScheme"); if (!*colorSelected) colorSelected = "plain"; TemplPrint ("head"); any = TemplExists (NULL, "$colorScheme"); for (i=0; (tmp = AnyNextInList (any, &i));) { color = VarGetName (tmp); TemplPrint ("color", SmEqs (colorSelected, color) ?"SELECTED" :"", color); } TemplPrint ("tail"); } TEMPLv WwwInit () { TEMPLv templ; templ = TemplOpen ("SRSICA:srswww.i", NULL); WwwSetColorScheme (templ); WwwPrintContentType(NULL); return templ; } void WwwApplOpt (APPLo *appl) { TEMPLv templ; APPLoOpt *opt; APPLoOptGroup *group, *groupPrev; WWWoQUERY *query; SETo *set; SEQo *seq; STRv s; ENTRYv entry; IDoENTRY id; char *applName; Int4 queryNo, i; applName = ApplGetName (appl); templ = WwwInit (); TemplWith (templ, "applOpt"); TemplPrint ("head", applName, applName); WwwPrintButtons (templ); TemplPrint ("title", applName, applName, ApplGetTitle (appl)); if (ApplIs (appl, "search") && (opt = ApplOptNamed (appl, "search"))) WwwApplOptPrint (appl, opt); /* display input sequence(s) */ TemplPrint ("sequence.head"); if ((queryNo=WwwQuerySelectedEntries ())) { query = WwwGetQuery (queryNo); set = SetGet (query->name); for (i=1; i <= set->n; i++) { SetGetID (set, i, &id); entry = EntryOpen (&id); seq=SdbGetEntrySeq (entry); s = Seq2Pretty (seq, 60); if (ApplIs (appl, "multi")) TemplPrint ("sequence.multi", WwwEntryQuery (entry, NULL, NULL), EntryGetFullName (entry), i, _Str (s), seq->len, i, EntryGetName (entry), i, EntryGetFullName (entry), seq->len); else TemplPrint ("sequence.single", _Str (s)); EntryClose (&entry); StrDel (s); if (!ApplIs (appl, "multi")) break; } WwwDelQuery (query); } /* submit button */ TemplPrint ("submit"); if (opt = ApplOptNamed (appl, "output")) WwwApplOptPrint (appl, opt); /* list of options */ TemplPrint ("options.head"); for (groupPrev=NULL, i=0; (opt=ApplNextOpt (appl, &i));) { group = ApplOptGetGroup (opt); if (!group) continue; if (group != groupPrev) { TemplPrint ("options.group.head", ApplOptGroupGetSize (appl, group), ApplOptGroupGetName (group)); groupPrev = group; } else TemplPrint ("options.group.next"); WwwApplOptPrint (appl, opt); } TemplPrint ("options.tail"); TemplPrint ("tail"); } static void WwwApplOptPrint (APPLo *appl, APPLoOpt *opt) { APPLoOptVal *val; char *applName; Int4 l; applName = ApplGetName (appl); TemplPrint ("options.group.option.head"); TemplPrint ("options.group.option.prompt", ApplOptGetPrompt (opt)); if (ApplOptIs (opt, "menu")) { TemplPrint ("options.group.option.menu.head", applName, ApplOptGetName (opt)); for (l=0; (val=ApplOptNextVal (opt, &l)); ) { if (ApplOptValIs (val, "named")) TemplPrint ("options.group.option.menu.valNamed", ApplOptValGetValue (opt, val), WwwSelected (ApplOptValIs (val, "on")), ApplOptValGetName (val)); else TemplPrint ("options.group.option.menu.val", WwwSelected (ApplOptValIs (val, "on")), ApplOptValGetValue (opt, val)); } TemplPrint ("options.group.option.menu.tail"); } else if (ApplOptIs (opt, "radio")) for (l=0; (val=ApplOptNextVal (opt, &l)); ) TemplPrint ("options.group.option.radio.val", applName, ApplOptGetName (opt), ApplOptValGetValue (opt, val), WwwChecked (ApplOptValIs (val, "on")), ApplOptValGetPrompt (val)); else if (ApplOptIs (opt, "multi")) for (l=0; (val=ApplOptNextVal (opt, &l)); ) TemplPrint ("options.group.option.multi.val", applName, ApplOptGetName (opt), WwwChecked (ApplOptValGetInt (opt, val)), ApplOptValGetPrompt (val)); else if (ApplOptIs (opt, "real")) TemplPrint ("options.group.option.real", ApplOptGetDefValue (opt), applName, ApplOptGetName (opt)); else if (ApplOptIs (opt, "int")) TemplPrint ("options.group.option.int", ApplOptGetDefValue (opt), applName, ApplOptGetName (opt)); else if (ApplOptIs (opt, "bool")) TemplPrint ("options.group.option.bool", WwwChecked (ApplOptGetDefInt (opt)), applName, ApplOptGetName (opt)); else if (ApplOptIs (opt, "string")) TemplPrint ("options.group.option.string", ApplOptGetDefValue (opt), applName, ApplOptGetName (opt)); TemplPrint ("options.group.option.tail"); } (opt));srs/src/srswww.h typedef struct WWWoQUERY { char name[80]; char queryStr[5000]; char comment[300]; char *type; INT4 entryN; INT4 queryN; INT4 isSubEntry; struct { char *name; int entryN; } lib[20]; char linkLib[30]; char linkType[30]; int isDeleted; } WWWoQUERY; typedef struct ENTRYo *dummytointroducestructtagENTRYo; /* parameters, userId, messages */ INT4 WwwPrintMessage (MSGo *msg); char *WwwReadInput (int byteN, char *fileName); INT4 WwwParInput (int byteN, char *buff); void WwwParWrite (char *userId); void WwwParRead (char *userId, INT4 doInsist); char *WwwNewUserId (); char *WwwGetName (char *userId, char *option); INT4 WwwPrintF (char *formatStr, ...); INT4 WwwLinkSet (Int4 queryN); /*void WwwLinkToLibs (char *queryStr);*/ void WwwLibInfo (char *libName, char *userId); void WwwLinkInfo (TEMPLv templ, char *libName1, char *libName2); void WwwPrintHelpTopic (char *helpTopic); void WwwDoBlastSearch (); void WwwQueryExpression (char *queryType, char *queryStr); void WwwListIndex (char *userId); void WwwGetMessage (); void WwwSendMessage (); void WwwPrintLinkOptions (char *query); void WwwPrintLibNetwork (); void WwwGetODDFile (char *libName); /* retrieval, query */ void WwwInitRetrieve (); INT4 WwwQueryDo (char *expr, char *queryType); char *WwwRetrieve (); INT4 WwwQueryDoRecursive (INT4 queryN, char *queryStr); void WwwRegisterQuery (char *queryName, char *queryStr, char *queryType); struct WWWoQUERY *WwwGetQuery (int queryN); struct WWWoQUERY *WwwGetQueryName (char *name); void WwwDelQuery (struct WWWoQUERY *query); char *WwwTransformQuery (char *option, char *queryStr); /* others */ void WwwEntryPrint (struct TEMPLo *templ, struct ENTRYo *entry); char *WwwGetIdParam (); void WwwViewFeature (char *queryStr, INT4 subEntryN); char *WwwStringEncode (char *); char *WwwTransform (char *option, char *str); /* helpers for printing HTML pages */ TEMPLv WwwInit (); INT4 WwwPresentChunkSizes (struct TEMPLo *templ); void WwwPresentChunkSizesMime (struct TEMPLo *templ, Int4 entryN); void WwwPrintButtons (struct TEMPLo *templ); char *WwwChecked (Int4 flag); char *WwwSelected (Int4 flag); /* printing entries */ void WwwPrintSet (struct TEMPLo *templ, char *setName, int firstN, int printN); void WwwPrintSetView (struct TEMPLo *templ, char *setName, int firstN, int printN); void WwwQueryPrint (INT4 queryN); void WwwPrintValue (char *libName, char *fieldName, char *value, Int4 n, Int4 entryN); /* dealing with views */ void WwwInitViews (TEMPLv templ); struct VIEWo *WwwViewGet (INT4 viewN, struct TEMPLo *templ); void WwwPrintSelectField (struct VIEWo *view, Int4 viewNum, struct SLBoFIELD *field, struct VIEWoLIB *vlib, Int4 numCol, Int4 *count); void WwwPresentViewList (char *option, TEMPLv templ); void WwwPresentActiveViews (struct SRSoGROUP*, struct SLBo*, struct WWWoQUERY*, TEMPLv, Int4); void WwwPresentViewsForLeaf (struct VIEWo *view, struct VIEWoLIB *vlib, TEMPLv templ); void WwwViewPartI (INT4 viewNumber,INT4 isEdit, TEMPLv templ); void WwwSetColorScheme (struct TEMPLo *templ); struct VIEWo *view, Int4 viewNum, struct SLBoFIELD *field, struct VIEWoLIB *vlib, Int4 numCol, Int4 *count); void WwwPresentViewList (char *option, TEMPLv templ); void WwwPresentActiveViews (struct SRSoGROUP*, struct SLBo*, struct WWWoQUERY*, TEMPLv, Int4); void WwwPresentViewsForLeaf (struct VIEWo *view, struct VIEWoLIB *vlib, TEMPLv templ); void WwwViewPartIsrs/src/strv.c ** ** MODULE for management of virtually-copied strings ** ** Authors: Giorgio Verde ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387451 ** Email: verde@embl-heidelberg.de ** *************************************************************************/ #include #include #include #include #include #include "def.h" #include "message.h" #include "strv.h" #define DEBUGnot static Int4 strAllocN, strAllocByte, strFreedN, strFreedByte; /****** StrBufNew ********************************************************* ** ** Creates a STRv buffer with space for a string of lenght dim ** The string length must be manually set by the user ** ** INPUT: the maximum lenght of the contained string ** RETURNS: a new STRv with the uninitialized buffer */ STRv StrBufNew(int dim) { STRv s=(STRv)malloc(sizeof(STRo)+dim); #ifdef DEBUG strAllocByte += dim; strAllocN++; if (!(strAllocN%10000)) fprintf (stderr, "allocN: %d, allocByte: %d, freedN, %d, freedByte: %d\n", strAllocN, strAllocByte, strFreedN, strFreedByte); #endif s->usage=1; s->dim=dim; return s; } /****** StrBufChange ********************************************************* ** ** Vanilla function for string modification ** Moves all characters of the string after position beg ("cut" position) ** to position end ("paste" position) **
    if end>beg this results in the creation of space for end-beg ** characters in position beg **
    if end a new STRv buffer is created only if: **
    - the STRv buffer has usage>1 (2 or more STRv's share a virtual copy) **
    - the STRv buffer needs to be grown ** ** INPUT: the pointer to the STRv to be modified ** the cut position ** the paste position */ void StrBufChange(STRv* val, int beg, int end) { STRv s=*val; int len=s->len; int dlen=end-beg; if (s->dimusage>1) { STRv old=s; s=StrBufNew(len+dlen); memcpy(s->arr+end, old->arr+beg, len-beg+1); if (dlen>0) memcpy(s->arr, old->arr, beg); else memcpy(s->arr, old->arr, end); StrDel (old); } else MemMove(s->arr+end, s->arr+beg, len-beg+1); s->len=len+dlen; *val=s; } #define STRTEMP_NUM 10 STRo StrNULLObj = { 1+STRTEMP_NUM, 0, 1, '\0' }; STRv StrNULL=&StrNULLObj; STRv StrTemporary[STRTEMP_NUM]= { &StrNULLObj, &StrNULLObj, &StrNULLObj, &StrNULLObj, &StrNULLObj, &StrNULLObj, &StrNULLObj, &StrNULLObj, &StrNULLObj, &StrNULLObj }; /**API* StrNew ********************************************************* ** ** Creates a new STRv containing the empty string (virtually copied) **
    See STRv creators: StrNew, StrCpy, StrCpyS, StrTemp ** ** RETURNS: a new STRv */ STRv StrNew() { return StrCpy(StrNULL); } /**API* StrCpy ********************************************************* ** ** creates a new STRv containing a ** virtual copy of the given STRv **
    See STRv creators: StrNew, StrCpy, StrCpyS, StrTemp ** ** INPUT: a STRv (can be NULL) ** RETURNS: a copy of input ** NULL if input is NULL */ STRv StrCpy(STRv val) { if (val) val->usage++; return val; } /**API* StrDel ********************************************************* ** ** Deletes a STRv (a virtual copy of the value). ** If the given STRv was the only instance of the value in ** use, the value buffer is freed. ** Must be used whenever an assigned STRv goes out of scope ** ** INPUT: a STRv (can be NULL) */ void StrDel(STRv val) { if (val && !--(val->usage)) { #ifdef DEBUG { if (val->len!=strlen(val->arr)) { printf("SuspectSTRv\n"); } strFreedByte += val->dim; strFreedN++; } #endif free(val); } } /**API* StrGrow ********************************************************* ** ** Reserves space so that following operations on the STRv ** can modify it's value to a longer string. This is just ** an optimization, as STRv's grow automatically if the ** value lenght exceeds the allocated buffer **
    See STRv optimizers: StrGrow, StrShrink ** ** INPUT: o [W] pointer to the STRv to be grown ** o the number of characters to be reserved for growth */ void StrGrow(STRv* val, int dlen) { STRv s=*val; int len=s->len; if (s->dimusage>1) { STRv old=s; s=StrBufNew(len+dlen); s->len=len; memcpy(s->arr, old->arr, len+1); if (!--(old->usage)) { #ifdef DEBUG strFreedByte += old->dim; strFreedN++; #endif free(old); } *val=s; } } /**API* StrShrink ********************************************************* ** ** Optimizes the value buffer to have exactly the lenght ** needed to contain the string value ** See STRv optimizers: StrGrow, StrShrink ** ** INPUT: [W] pointer to the STRv to be trimmed */ void StrShrink(STRv* val) { STRv s=*val; int len=s->len; if (s->dim>len) { STRv old=s; s=StrBufNew(len); s->len=len; memcpy(s->arr, old->arr, len+1); #ifdef DEBUG strFreedByte += old->dim; strFreedN++; #endif free(old); *val=s; } } /**API* StrClear ********************************************************* ** ** if the STRv buffer is unique, resets the content of the STRv to ** "" without freeing the buffer ** ** INPUT: [W] the STRv to be cleard */ void StrClear(STRv* sp) { STRv s=*sp; if (s->usage==1) { s->len=0; s->arr[0]='\0'; } else StrSet(sp, StrNULL); } /* operations */ /**API* StrSet ********************************************************* ** ** Assignes to one STRv the value of another STRv (virtual copy) ** The old value of the STRv is released **
    See STRv modifiers: StrSet, StrIns, StrApp, StrAdd, StrCut **
    To assign instead a char* value, see StrSetS ** ** INPUT: o [W] pointer to the STRv to be modified ** o STRv value to be assigned */ void StrSet(STRv* dest, STRv src) { if (*dest!=src) { StrDel(*dest); *dest=StrCpy(src); } } /**API* StrIns ********************************************************* ** ** Inserts in one STRv the value of another STRv at the beginning ** of the string. The destination STRv buffer is grown if needed. ** The old value of the STRv is released **
    See STRv modifiers: StrSet, StrIns, StrApp, StrAdd, StrCut **
    To insert instead a char* value, see StrInsS ** ** INPUT: o [W] pointer to the STRv to be modified ** o STRv value to be inserted */ void StrIns(STRv* dest, STRv src) { int len=src->len; StrBufChange(dest, 0, len); memcpy((*dest)->arr, src->arr, len); } /**API* StrApp ********************************************************* ** ** Appends to one STRv the value of another STRv. ** The destination STRv buffer is grown if needed. ** The old value of the STRv is released **
    See STRv modifiers: StrSet, StrIns, StrApp, StrAdd, StrCut **
    To append instead a char* value, see StrAppS ** ** INPUT: o [W] pointer to the STRv to be modified ** o STRv value to be appended */ void StrApp(STRv* dest, STRv src) { int dlen=(*dest)->len; int len=src->len; StrBufChange(dest, dlen, dlen+len); memcpy((*dest)->arr+dlen, src->arr, len); } /**API* StrAdd ********************************************************* ** ** Inserts in one STRv the value of another STRv at a certain ** position. The position must be between 0 (works like StrIns) ** and the lenght of the string (works like StrApp). If outside ** this range, a PosOutOfBounds exception is thrown. ** The destination STRv buffer is grown if needed. ** The old value of the STRv is released **
    See STRv modifiers: StrSet, StrIns, StrApp, StrAdd, StrCut **
    To append instead a char* value, see StrAddS ** ** INPUT: o [W] pointer to the STRv to be modified ** o the position of insertion. ** o STRv value to be added */ void StrAdd(STRv* dest, int pos, STRv src) { int dlen=(*dest)->len; int len=src->len; ASSERT(pos<=dlen, "PosOutOfBounds"); StrBufChange(dest, pos, pos+len); memcpy((*dest)->arr+pos, src->arr, len); } /**API* StrCut ********************************************************* ** ** Cuts in one STRv the characters starting at a certain ** position and for a given lenght. ** The position must be between 0 and the length of the string. ** If outside this range, a PosOutOfBounds exception is thrown. ** The given length can be longer then the length of the string; ** in that case it is adjusted to the string length ** The destination STRv buffer keeps its lenght, and must be ** explicitly trimmed with StrShrink if needed. ** The old value of the STRv is released **
    See STRv modifiers: StrSet, StrIns, StrApp, StrAdd, StrCut ** ** INPUT: o [W] pointer to the STRv to be modified ** o the cutting position ** o the cutting length */ void StrCut(STRv* dest, int pos, int len) { int dlen=(*dest)->len; ASSERT(pos<=dlen, "PosOutOfBounds"); if (len>dlen-pos) len=dlen-pos; StrBufChange(dest, pos+len, pos); } /**API* StrSub ********************************************************* ** ** creates a new STRv containing a ** substring of the given STRv **
    See STRv creators: StrNew, StrCpy, StrCpyS, StrTemp ** ** INPUT: a STRv ** the postition of the substring ** the length of the substring ** RETURNS: the substring */ STRv StrSub(STRv s, int pos, int len) { if (pos>s->len) pos=s->len; if (pos+len>s->len) len=s->len-pos; return StrNCpyS(s->arr+pos, len); } /**API* StrRight ********************************************************* ** ** creates a new STRv containing the characters of the given STRv ** on the right of the given position (including the one at the position) **
    See STRv creators: StrNew, StrCpy, StrCpyS, StrTemp ** ** INPUT: a STRv ** the cut position ** RETURNS: the substring */ STRv StrRight(STRv s, int pos) { if (pos>s->len) pos=s->len; return StrNCpyS(s->arr+pos, s->len-pos); } /**API* StrLeft ********************************************************* ** ** creates a new STRv containing the characters of the given STRv ** on the left of the given position (excluding the one at the position) **
    See STRv creators: StrNew, StrCpy, StrCpyS, StrTemp ** ** INPUT: a STRv ** the cut position ** RETURNS: the substring */ STRv StrLeft(STRv s, int pos) { if (pos>s->len) pos=s->len; return StrNCpyS(s->arr, pos); } /**API* StrSubst ********************************************************* ** ** Substitutes a range of characters in one STRv in a given ** position and of a certain lenght with the value of a given STRv. ** ** ** INPUT: o [W] pointer to the STRv to be modified ** o position of replacement (0<=pos<=len) ** o num char to replace in the original string ** if bigger, it's adjusted to string lenght ** o value to replace */ void StrSubst(STRv* dest, int pos, int len, STRv subst) { int dlen=(*dest)->len; int slen=subst->len; ASSERT (pos<=dlen, "PosOutOfBounds"); if (len>dlen-pos) len=dlen-pos; StrBufChange(dest, pos+len, pos+slen); memcpy((*dest)->arr+pos, subst->arr, slen); } /**API* StrDebug ********************************************************* ** ** Debug function to print the status of a STRv on stdout ** ** INPUT: the STRv to be displayed */ void StrDebug(STRv s) { printf("STRv:%p ", s); if (s) { char *p=s->arr, *stop; if (s->usage!=1) printf("usage:%d ", s->usage); printf("len:%d ", s->len); if (s->dim!=s->len) printf("grow:%d ",s->dim-s->len); /* check if the string is printable stop=p+s->len; while (parr; char c; if (s->usage==1) { while (c=*p) *p++=_ToUpper(c); } else { STRv d=StrBufNew(s->len); char* dp=d->arr; d->len=s->len; while (c=*p++) *dp++=_ToUpper(c); s->usage--; *sp=d; } } /**API* StrLower ********************************************************* ** ** Converts a STRv into lower case ** ** INPUT: a ponter to STRv */ void StrLower(STRv* sp) { STRv s=*sp; char* p=s->arr; char c; if (s->usage==1) { while (c=*p) *p++=_ToLower(c); } else { STRv d=StrBufNew(s->len); char* dp=d->arr; d->len=s->len; while (c=*p++) *dp++=_ToLower(c); s->usage--; *sp=d; } } /**API* StrTrim *************************************************************** ** ** Removes leading and trailing spaces or, if specified, other ** characters. ** ** INPUT: a pointer to STRv [W] ** a set of characters to be removed [R] or NULL */ void StrTrim (STRv* str, char *skipSet) { static char ws[10]=" \n\t"; STRv tStr; char *s; Int4 k, l, len; len = StrLen (*str); if (!skipSet) skipSet = ws; s = _Str (*str); for (k=0; k < len && strchr (skipSet, s[k]); k++) ; for (l=len-1; l>0 && strchr (skipSet, s[l]); l--) ; len = l-k+1; tStr = StrSub (*str, k, len < 0 ? 0 : len); StrSet (str, tStr); } /* queries */ /**API* StrEmpty ********************************************************* ** ** returns if the string is empty ** ** ** INPUT: the STRv (must be not NULL) ** RETURNS: TRUE if the STRv is the empty string */ BOOL StrEmpty(STRv str) { return !str->len; } /**API* StrLen ********************************************************* ** ** returns the length of the string value ** ** ** INPUT: the STRv (must be not NULL) ** RETURNS: length in chars */ int StrLen(STRv str) { return str->len; } /**API* StrEqual ********************************************************* ** ** compares 2 STRv's for equal values ** ** ** INPUT: o STRv (must be not NULL) ** o STRv (must be not NULL) ** RETURNS: TRUE if equal */ BOOL StrEqual(STRv s1, STRv s2) { if (s1==s2) return TRUE; else if (s1->len==s2->len) return strcmp(s1->arr, s2->arr)==0; else return FALSE; } /**API* StrCmp ********************************************************* ** ** compares 2 STRv's for lexicographic ordering ** ** ** INPUT: o s1:STRv (must be not NULL) ** o s2:STRv (must be not NULL) ** RETURNS: o <0 if s10 if s1>s2 */ int StrCmp(STRv s1, STRv s2) { if (s1==s2) return 0; else return strcmp(s1->arr, s2->arr); } /**API* StrHash ********************************************************* ** ** calculates a hash value for a STRv. ** ** ** INPUT: o STRv (must be not NULL) ** o upper bound for the result ** RETURNS: an integer 0<= i < max */ int StrHash(STRv val, int max) { return StrHashS(val->arr, max); } /* user */ /**API* StrConst ********************************************************* ** ** Defines a STRv value to become a constant to be never released. ** The returned char* cannot be used for modifying the string, ** and it is guaranteed to be stable. ** ** INPUT: STRv (must be not NULL) ** RETURNS: the STRv value as char* */ char* StrConst(STRv val) { val->usage++; return val->arr; } /**API* StrVal ********************************************************* ** ** Returns a C string containing a (real) copy of the STRv value ** The user can do everything with it and has the reponsability ** of freeing it. ** ** INPUT: STRv (must be not NULL) ** RETURNS: the STRv value as char* */ char* StrVal(STRv val) { int len=val->len+1; char* s=malloc(len); memcpy(s, val->arr, len); return s; } /**API* StrGet ********************************************************* ** ** Writes the STRv value into an allocated C char buffer of a ** given size. If there is enough space in the buffer, string ** will be NULL-terminated, else only the portion which fits ** is copied. ** ** INPUT: o [W] the pointer to the buffer ** o the length of the buffer ** o the STRv to be copied (must be not NULL) ** RETURNS: o a pointer to the first unused char in the buffer ** if the value fitted ** o NULL otherwhise */ char* StrGet(char* dest, int sz, STRv src) { int len=src->len+1; if (len<=sz) { memcpy(dest, src->arr, len); return dest+len; } else { memcpy(dest, src->arr, sz); return NULL; } } /**API* StrShared ********************************************************* ** ** Returns the number of virtual copies of the given STRv ** (not counting the given copy) ** ** INPUT: a STRv ** RETURNS: o 0 if this is the only instance of the value ** o >0 if the buffer is shared by other STRv's */ int StrShared(STRv s) { return s->usage-1; } /* c string operations */ /**API* StrTemp ********************************************************* ** ** Creates a temporary STRv from a C string. This STRv does'nt ** need to be deleted with StrDel, but the user is not entitled ** to perform modifying operations on this string ** (for example StrAppS(&StrTemp("bla"),"alb") is unlegal) ** Basically, the only legal operation is to use StrTemp where ** the STRv is not modified. ** The maximum number of active temporary STRv is defined by ** the macro STRTEMP_NUM ** ** INPUT: a pointer to a C string ** RETURNS: a temporary STRv */ STRv StrTemp(char* src) { static int currTemp=0; STRv* s=&StrTemporary[currTemp]; StrSetS(s, src); currTemp=(currTemp+1)%STRTEMP_NUM; return *s; } /**API* StrCpyS ********************************************************* ** ** Creates a new STRv from a C string (char*) ** ** INPUT: the C string ** RETURNS: a STRv */ STRv StrCpyS(char* src) { int len=strlen(src); STRv s=StrBufNew(len); s->len=len; memcpy(s->arr, src, len+1); return s; } /**API* StrSetS ********************************************************* ** ** Assignes to a STRv the value of a C string (char*) ** The old value of the STRv is released ** ** INPUT: [W] pointer to the STRv to be assigned ** the C string */ void StrSetS(STRv* dest, char* src) { int len=strlen(src); int dlen=(*dest)->len; StrBufChange(dest, dlen, len); memcpy((*dest)->arr, src, len+1); } /**API* StrInsS ********************************************************* ** ** Inserts at the beginning of a STRv the value of a C string (char*) ** The old value of the STRv is released ** ** INPUT: [W] pointer to the STRv to be assigned ** the C string */ void StrInsS(STRv* dest, char* src) { int len=strlen(src); StrBufChange(dest, 0, len); memcpy((*dest)->arr, src, len); } /**API* StrAppS ********************************************************* ** ** Appends to a STRv the value of a C string (char*) ** The old value of the STRv is released ** ** INPUT: [W] pointer to the STRv to be assigned ** the C string */ void StrAppS(STRv* dest, char* src) { int dlen=(*dest)->len; int len=strlen(src); StrBufChange(dest, dlen, dlen+len); memcpy((*dest)->arr+dlen, src, len); } /**API* StrFill ********************************************************** ** ** Appends a certain number of fill characters to a STRv. ** ** INPUT: [W] pointer to the STRv to be assigned ** the fill character [R] ** number of characters to be added [R] */ void StrFill(STRv* dest, char c, Int4 len) { int dlen=(*dest)->len, k; StrBufChange(dest, dlen, dlen+len); for (k=0; karr[dlen+k] = c; (*dest)->arr[dlen+k] = '\0'; } /**api* StrReplace ********************************************************* ** ** Replaces all occurrences of the "from" substring with the "to" ** string. ** ** INPUT: [W] pointer to the STRv to be assigned ** "from" substring to be searched [R} ** "to" string to be inserted [R] */ STRv StrReplace (STRv* dest, char *from, char *to) { char *p; int len=(*dest)->len, pos, fromLen=strlen(from), toLen=strlen(to); p=_Str (*dest); while ((p=strstr (p, from))) { pos = p - _Str(*dest); StrBufChange (dest, pos+fromLen, pos+toLen); p = _Str (*dest) + pos; memcpy (p, to, toLen); p += toLen; } } /**API* StrAppN ********************************************************* ** ** Appends to a STRv a given number of chars of a C string (char*) ** if the string is shorter, then the number of chars is the length ** of the source string ** The old value of the STRv is released ** ** INPUT: [W] pointer to the STRv to be assigned ** the C string ** the number of chars */ void StrAppN(STRv* dest, char* src, int len) { int dlen=(*dest)->len; /* copy until \0 is found */ char* p=src; while (parr+dlen, src, len); } /**API* StrNSetS ********************************************************* ** ** returns a STRv containing the first 'len' characters ** of a C string (char*) ** ** INPUT: the C string ** len=the number of chars ** RETURNS: the STRv */ STRv StrNCpyS(char* src, int len) { STRv s=StrBufNew(len); s->len=len; memcpy(s->arr, src, len); s->arr[len]='\0'; return s; } /**API* StrNSetS ********************************************************* ** ** Assignes to a STRv the first 'len' characters of a C string (char*) ** The old value of the STRv is released ** ** INPUT: [W] pointer to the STRv to be assigned ** the C string ** len=the number of chars */ void StrNSetS(STRv* dest, char* src, int len) { int dlen=(*dest)->len; StrBufChange(dest, dlen, len); memcpy((*dest)->arr, src, len); (*dest)->arr[len]='\0'; } /**API* StrAddS ********************************************************* ** ** Inserts in a STRv the value of a C string (char*) at ** a given position ** The old value of the STRv is released ** ** INPUT: [W] pointer to the STRv to be assigned ** the position of insertion (see StrAdd) ** the C string */ void StrAddS(STRv* dest, int pos, char* src) { int dlen=(*dest)->len; int len=strlen(src); ASSERT(pos<=dlen, "OutOfBounds"); StrBufChange(dest, pos, pos+len); memcpy((*dest)->arr+pos, src, len); } /**API* StrEqualS ********************************************************* ** ** Compares the value of a STRv with the value of a C string (char*) ** ** INPUT: the STRv to be compared ** the C string ** RETURNS: TRUE if they are equal */ BOOL StrEqualS(STRv s1, char* s2) { return strcmp(s1->arr, s2)==0; } /**API* StrCmpS ********************************************************* ** ** Compares the value of a STRv with the value of a C string (char*) ** for lexicographic ordering ** ** INPUT: s1:the STRv to be compared ** s2:the C string ** RETURNS: <0 if s10 if s1>s2 */ int StrCmpS(STRv s1, char* s2) { return strcmp(s1->arr, s2); } /**API* StrHashS ********************************************************* ** ** calculates a hash value for a C string ** ** ** INPUT: the C string (char*) ** RETURNS: an integer 0<= i < max */ int StrHashS (char* s, int max) { WORD h=0, g; while (*s) { h=(h << 4 | (h&0xf0000000L)>>28) ^ *s++; } return h%max; } /* for string initialization */ void StrInitStatic(STRv s,int sz, int num) { while (num--) { s->usage=1; s->len=strlen(s->arr); s->dim=s->len+1; s=offset(s,sz,STRv); } } /* conversions */ /**API* StrFromInt ********************************************************* ** ** Creates a STRv from an int value ** ** INPUT: the integer ** RETURNS: a new STRv with the value of the integer */ STRv StrFromInt(int i) { char buf[20]; sprintf(buf, "%d", i); return StrCpyS(buf); } /**API* StrToInt ********************************************************* ** ** Converts a STRv to an integer ** The function uses atoi for the conversion ** ** INPUT: the STRv ** RETURNS: a new STRv with the value of the integer */ int StrToInt(STRv s) { return atoi(s->arr); } STRv StrFromPtr(void* p) {return NULL;} void* StrToPtr(STRv s) {return NULL;} /* functions needed for use in icarus */ /**API* StrPrintf ********************************************************* ** ** formatted print into a STRv ** ** INPUT: o [W] pointer to the STRv to be assigned (if NULL, the ** function returns the result string) ** the format string ** the print items ** RETURNS: o the result string (if the str pointer was assigned, the ** return value is just a pointer to the result, not a copy) */ STRv StrPrintf (STRv* str, char *format, ...) { va_list ap; char s[2000]; STRv res; va_start (ap, format); vsprintf (s, format, ap); va_end (ap); if (str) { StrAppS (str, s); res=*str; } /* returns just a pointer!! don't delete! */ else res=StrCpyS(s); return res; } /**API* StrEncode ********************************************************* ** ** Changes all non-printable characters into printable ** excape expressions, in C format (like \n -> "\n") ** **
    See also: StrDecode, StrTranslate ** ** INPUT: [W] pointer to the STRv to be converted */ STRv StrEncode (STRv *str) { char codeStr[10], *code, *s; INT4 k; for (k = 0; k < StrLen (*str);) { s = _Str (*str); switch (s[k]) { case '\n': code = "\\n"; break; case 7: code = "\\b"; break; case '\t': code = "\\t"; break; case '\r': code = "\\r"; break; case '"': code = "\\\""; /* " ...emacs colors;-( */ break; case '\\': code = "\\\\"; break; default: if (s[k] < 8) { sprintf (codeStr, "\\%d", s[k]); code = codeStr; } else { code = NULL; k++; } break; } if (code) { StrSubst (str, k, 1, StrTemp (code)); k += strlen (code); } } return *str; } /**API* StrDecode ********************************************************* ** ** Converts C format escape expressions into ASCII codes (like "\n"->\n) ** **
    See also: StrEncode, StrTranslate ** ** INPUT: [W] pointer to the STRv to be converted */ void StrDecode (STRv* str) { char *s; INT4 k,l, slen, code; StrBufChange(str,0,0); s = _Str (*str); slen = StrLen (*str); for (k = 0, l = 0; k < slen; k++) if (s[k] != '\\') s[l++] = s[k]; else switch (s[++k]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': code = s[k] - '0'; while (isdigit (s[k+1])) { k++; code = code*10 + (s[k] - '0'); } s[l++] = code; break; case 'n': s[l++] = 10; break; case 'a': s[l++] = 7; break; case 't': s[l++] = 9; break; case 'b': s[l++] = 7; break; case 'r': s[l++] = 13; break; case '\"': /* " ...emacs colors;-( */ s[l++] = 34; break; case '\\': s[l++] = 92; break; case '-': s[l++] = '\\'; /* see PrsDecode */ s[l++] = '-'; break; default: s[l++] = s[k]; break; } s[l] = '\0'; (*str)->len = l; } /**api* function ************************************************************** ** ** Formats a string so that it fits on a device with fixed line size. ** Additional arguments control identation and prefix. ** ** INPUT: address of STRv [W] ** maximum length of the output line [R] ** identation of first line [R] or 0 ** identation of all/following lines [R] or 0 ** text to be printed in front of each line [R] or NULL ** ** RETURNS: o A new STRv with the input string reformatted. Deletion is ** client responsability ** */ STRv StrFormat (STRv str, INT4 lineSize, INT4 firstIdent, INT4 allIdent, char *leftText) { STRv tmp=NULL; char *p, *pSave, cSave; INT4 k, lineLen; if (leftText) allIdent = strlen (leftText); tmp = StrNew (); /* text or ident to the left of first line */ if (leftText) StrAppS (&tmp, leftText); else if (firstIdent) StrFill (&tmp, ' ', firstIdent); for (lineLen=StrLen (tmp), k=lineLen + StrLen (str), p=_Str(str); k >= lineSize; lineLen=allIdent, k=lineLen + StrLen (str) - (p - _Str(str))) { pSave = p; p += lineSize - lineLen; while (*p != ' ' && p > pSave) /* find the next ' ' backwards */ p--; if (p == pSave) /* if no space was found break at line end */ p += lineSize - lineLen; cSave = *p; *p = '\0'; StrPrintf (&tmp, "%s\n", pSave); *(p++) = cSave; /* text or ident to the left of following lines */ if (leftText) StrAppS (&tmp, leftText); else StrFill (&tmp, ' ', allIdent); } StrAppS (&tmp, p); return tmp; } /**api* function ************************************************************** ** ** Removes a line feed at the end of the string. ** ** INPUT: [W] pointer to the STRv to be modified ** */ void StrCutLF (STRv *s) { Int4 l=StrLen (*s); char *tmp=_Str (*s); if (tmp[l-1] == '\n') StrCut (s, l-1, 1); } /**API* StrTranslate ********************************************************* ** ** Changes all characters of the string which are contained ** in the 'from' character set into ** the corresponding character in the 'to' charcter set. ** The 2 character sets must have the same lenght ** **
    See also: StrEncode, StrDecode ** ** INPUT: [W] pointer to the STRv to be converted */ void StrTranslate(STRv* s, char* from, char* to) { char* p; StrBufChange(s,0,0); p=Str(*s); p+=strcspn(p,from); /* substitute to end string */ while (*p) { *p++=to[strchr(from,*p)-from]; p+=strcspn(p,from); } } 'from' character set into ** the corresponding character in the 'to' charcter set. ** The 2 character sets must have the same lenght ** **
    See also: StrEncode, StrDecode ** ** INPUT: [W] pointer to the STRv to be converted */ void StrTranslate(STRvsrs/src/strv.h #define _STRV_H typedef struct STRo { int usage; int len; int dim; char arr[1]; } STRo; typedef STRo* STRv; extern STRv StrNULL; /* allocation */ STRv StrNew(); STRv StrCpy(STRv src); void StrDel(STRv val); void StrGrow(STRv* val, int dlen); void StrShrink(STRv* val); void StrClear(STRv* s); STRv StrSub(STRv s, int pos, int len); STRv StrLeft(STRv s, int pos); STRv StrRight(STRv s, int pos); /* operations */ void StrSet(STRv* dest, STRv src); void StrIns(STRv* dest, STRv src); void StrApp(STRv* dest, STRv src); void StrAdd(STRv* dest, int pos, STRv src); void StrCut(STRv* dest, int pos, int len); void StrSubst(STRv* dest, int pos, int len, STRv subst); void StrDebug(STRv s); void StrUpper(STRv* s); void StrLower(STRv* s); /* queries */ BOOL StrEmpty(STRv str); int StrLen(STRv str); BOOL StrEqual(STRv s1, STRv s2); int StrCmp(STRv s1, STRv s2); int StrHash(STRv val, int max); /* user */ char* StrConst(STRv val); char* StrVal(STRv val); char* StrGet(char* dest, int sz, STRv src); #define Str(val) ((val)->arr) #define _Str(val) ((val)->arr) int StrShared(STRv s); /* c string operations */ STRv StrTemp(char* src); STRv StrCpyS(char* src); void StrSetS(STRv* dest, char* src); void StrInsS(STRv* dest, char* src); void StrAppS(STRv* dest, char* src); void StrAppN(STRv* dest, char* src, int len); void StrAddS(STRv* dest, int pos, char* src); BOOL StrEqualS(STRv s1, char* s2); int StrCmpS(STRv s1, char* s2); int StrHashS (char* val, int dim); STRv StrNCpyS(char* s, int len); void StrNSetS(STRv* dest, char* s, int len); /* low-level */ STRv StrBufNew(int dim); void StrBufChange(STRv* val, int beg, int end); /* conversions */ STRv StrFromInt(int i); int StrToInt(STRv s); STRv StrPtr(void* p); void* PtrStr(STRv s); /* functions similar to Buff... */ void StrCutLF (STRv *s); STRv StrPrintf (STRv* str, char *format, ...); STRv StrEncode (STRv *str); void StrDecode (STRv* str); void StrTranslate(STRv* s, char* from, char* to); void StrFill(STRv* dest, char c, Int4 len); void StrTrim (STRv *s, char *skipSet); STRv StrFormat (STRv str, INT4 lineSize, INT4 firstIdent, INT4 allIdent, char *leftText); /* for string initialization */ typedef struct { struct { int u; int l; int d; } DontInitalize; char arr[20]; } STRoStatic_20; typedef struct { struct { int u; int l; int d; } DontInitalize; char arr[100]; } STRoStatic_100; typedef struct { struct { int u; int l; int d; } DontInitalize; char arr[1000]; } STRoStatic_1000; void StrInitStatic(STRv list, int size, int num); #define _StrInitStatic(list,num) StrInitStatic((STRv)(list),sizeof((list)[0]),num) #endif char *leftText); /* for string initialization */ typedef struct { struct { int u; int l; int d; } DontInitalize; char arr[20]; } STRoStatic_20; typedef struct { struct { int u; int l; int d; } DontInitalize; char arr[100]; } STRoStatic_100; typedef struct { struct { int u; int l; int d; } DontInitalize; char arr[1000]; } STRoStatic_1000; void StrInitStatic(STRv lisrs/src/templ.c char template_ID[] = "$Id: templ.c,v 1.22 1997/03/18 22:52:33 srs Exp $"; /* ** ** $Source: /homes/srs/cvsroot/srs/src/templ.c,v $ ** $Revision: 1.22 $ ** $Date: 1997/03/18 22:52:33 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.0 Copyright by Thure Etzold ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** facility for writing any type of command procedure within a program ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include "def.h" #include "message.h" #include "sm.h" #include "futil.h" #include "library.h" #include "strv.h" #include "lst.h" #include "par.h" #include "dict.h" #include "variable.h" #include "templ.h" #include "icarus.h" #include "icaarg.h" #define TEMPLxMaxContextN 20 typedef struct TEMPLo { FILEo *inFile; FILEo *outFile; STRv outString; VARo *varList; ICAoJOB *job; struct TEMPLoLABEL *label; DICTv labelDict; INT4 labelN; INT4 labelAllocN; } TEMPLo; typedef struct TEMPLoCONTEXT { TEMPLo *templ; STRv name; VARo *var; Int4 isRoot; } TEMPLoCONTEXT; typedef struct TEMPLoLABEL { char *name; FIP fip; } TEMPLoLABEL; static TEMPLo *templCurr=NULL; static ICAoJOB *templJob=NULL; static TEMPLoCONTEXT *templContext=NULL; void TemplIcaAddLabel (); static void TemplIcaAddTemplate (); static void TemplInit (); static char *TemplContext (char *option, TEMPLo *templ, VARo *var, Int4 isRoot); static struct VARo *TemplGetTemplate (TEMPLv templ, char *name); static Int4 TemplWithImpl (TEMPLo *templ, char *label); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** for the variable dictionary */ static void* TemplToKey (DictElem* e) { return offset(templContext->templ->label, (WORD)*e - 555, TEMPLoLABEL*)->name; } static CLASSoDICT dictClass = { (ValComparer)strequal, (ValHasher)strhash, (KeyAccessor)TemplToKey, NULL, 0 }; void TemplIcaAddLabel (Int4 runTime, STRv name, Int4 fip) { TEMPLo *templ = templContext->templ; TEMPLoLABEL *tmp; if (runTime) IargGetArgs ("name|fip", &name, &fip); tmp = _addObj (templ->label, templ->labelN, templ->labelAllocN, TEMPLoLABEL); tmp->name = (char *) malloc (StrLen(name)+1); strcpy (tmp->name, _Str (name)); tmp->fip = fip; DictSet (&templ->labelDict, tmp->name, TEMPLoLABEL*) = (void *) (displ(tmp,templ->label) + 555); /* add 555 since NULL not allowed */ } static void TemplIcaAddTemplate () { VARo *var; IargGetArgs ("var", &var); } static void TemplInit () { ICAoSYNTAX *syntax; if (!templJob) { syntax = (ICAoSYNTAX*)LibObjByName ("syntax", "icarus"); templJob = IcaCreateJob (syntax); IcaSetFunction("TemplIcaAddLabel", (FUNC) TemplIcaAddLabel); IcaSetFunction("TemplIcaAddTemplate", (FUNC) TemplIcaAddTemplate); } } /**API* TemplOpen ************************************************************* ** ** Opens the template file and the output stream. ** TemplWith must be used before the first call of TemplPrint. ** ** INPUT: name of template file [R] ** name of output file (opens 'stdout' if NULL) [R] ** IMPLICIT: ** templJob (JOBo*) ** ** RETURNS: ** the new template object ** NULL if read file could not open */ TEMPLo *TemplOpen (char *inFileName, char *outFileName) { TEMPLo *templ; TemplInit (); /* new templ object */ if (!(templ = (TEMPLo *) calloc (1, sizeof (TEMPLo)))) _ErrExit2 (e__allocfail, "templ object"); /* open files, init label dictionary and variable list*/ templ->inFile = FileNew (inFileName); if (!FileOpen (templ->inFile)) return(NULL); templ->outFile = FileNew (outFileName); if (!FileOpen (FileSetWrite(templ->outFile))) _ErrExit2 (e__filnotok, FileGetName (templ->outFile, "full")); templ->labelDict = DictCreate (&dictClass); /*DictCreateClassStrKey (NULL, mPtr(TEMPLoLABEL, name), 0));*/ templ->varList = VarNew (); /* scan the templ input file for variable names and insert in dictionary */ TemplWith (templ, NULL); IcaJobSetFile (templJob, templ->inFile); IcaDoJob (templJob, "scan"); if (templJob->prog) VarExec (templJob->prog); TemplEndWith (); return templ; } static VARo *TemplGetTemplate (TEMPLo *templ, char *name) { TEMPLoLABEL *label; VARo *var; Iter i; TemplContext ("push", templ, NULL, 0); var = AnyGetListAssoc (templ->varList, name); if (!VarType (var)) { if ((i = DictWith (templ->labelDict, name))) label = (TEMPLoLABEL*) ((char *)templ->label + ((Word) DictIn (i, TEMPLoLABEL*) - 555)); else _ErrExit3 (e__labelnotfound, name, FileGetName (templ->inFile, "full")); FileSeek (templ->inFile, label->fip); IcaJobNext (templJob); IcaJobSetFile (templJob, templ->inFile); IcaDoJob (templJob, "template"); IcaExecProg (templJob); AnySetList (var, VarGet (&templJob->scope, name)); } TemplContext ("pop", NULL, NULL, 0); return var; } /**API* TemplGet ************************************************************** ** ** Returns the template object set by the last TemplWith call. ** ** RETURNS: the template object ** NULL: no template open ** */ TEMPLv TemplGet () { return templContext ? templContext->templ : NULL; } FILEo *TemplGetOutFile (TEMPLv templ) { return templ->outFile; } /**API* TemplPrint ************************************************************ ** ** Prints the text contained by specified label. Additional arguments ** are required if the text contains '%' metacharacters. ** ** INPUT: o label name starting from current template context ** (see TemplWith). Instead of the name the position of ** the label within the list can be used by specifying the ** number in square brackets (eg, [2]). The first label ** in the list has number 1. [R] ** o additional arguments to be inserted into text [R] ** IMPLICIT: ** templJob (JOBo*) ** */ void TemplPrint (char *name, ...) { TEMPLo *templ=templContext->templ; STRv str; char s[90000]; va_list ap; TemplWith (templ, name); va_start (ap, name); str = VarGetStrv (templContext->var); vsprintf (s, _Str(str), ap); StrDel (str); va_end (ap); fprintf (templ->outFile->file, "%s", s); TemplEndWith (); } /**API* TemplPrintAll ********************************************************* ** ** Prints all elements of the list specified by the name argument. ** ** INPUT: o label name starting from current template context ** (see TemplWith). Instead of the name the position of ** the label within the list can be used by specifying the ** number in square brackets (eg, [2]). The first label ** in the list has number 1. [R] ** IMPLICIT: ** templJob (JOBo*) ** */ ANYv TemplPrintAll (char *name) { TEMPLo *templ=templContext->templ; ANYv any, anyList; INT4 errCode, k, i; anyList = TemplExists (templ, "command"); TemplWith (templ, "command"); for (i=0, k=1; (any=AnyNextInList (anyList, &i)); k++) TemplPrint (TemplN (k, NULL)); TemplEndWith (); } ANYv TemplSPrintAll (STRv *str, char *name) { TEMPLo *templ=templContext->templ; ANYv any, anyList; INT4 errCode, k, i; char tmp[1000]; anyList = TemplExists (templ, "command"); TemplWith (templ, "command"); for (i=0, k=1; (any=AnyNextInList (anyList, &i)); k++) { TemplSPrint (tmp, TemplN (k, NULL)); StrAppS (str, tmp); } TemplEndWith (); } /**API* TemplExists *********************************************************** ** ** This function is useful for asserting that the specified label exists ** before using it for printing. The function returns the Any object ** containing the label name as well as the text or an Any list in ** case the name specifies an internal label. ** ** INPUT: the template object (or NULL) [R] ** label name (see TemplWith) [R] ** IMPLICIT: ** templJob (JOBo*) ** RETURNS: ** address of Any object ** NULL: label does not exist ** */ VARo *TemplExists (TEMPLv templ, char *name) { VARo *var=NULL; if (TemplWithImpl (templ, name)) { var = templContext->var; TemplEndWith (); } return var; } /**API* TemplSPrint *********************************************************** ** ** Same as TemplPrint except that it prints into the string with ** specified address rather than the output stream. ** ** INPUT: address of output string [W] ** label name (see TemplWith) [R] ** additional arguments to be inserted into text [R] ** IMPLICIT: ** templJob (JOBo*) ** RETURNS: ** address of output string (same as first argument) ** */ char *TemplSPrint (char *s, char *name, ...) { TEMPLo *templ=templContext->templ; STRv str; va_list ap; TemplWith(templ, name); va_start(ap, name); str = VarGetStrv (templContext->var); vsprintf(s, _Str(str), ap); StrDel (str); va_end(ap); TemplEndWith(); return(s); } /**API* TemplWith ************************************************************ ** ** Sets the template context to a new list. The context can ** be either a list contained in the list represented by the current ** context (relative name) or in another variable which may be ** forced by prefixing ** the label name with a '$' (absolute name). **

    ** The label name can contain indices for specifiying elements in ** the list which must then be inclosed in square brackets (eg, [1], ** TemplN assists in generating labels with an index). ** After printing with the 'template' context TemplEndWith must be ** called to restore to the previous context (The contexts are ** maintained as a stack where TemplWith pushes and TemplEndWith pops). ** ** INPUT: template object (or NULL) [W] ** label name [R] ** */ void TemplWith (TEMPLo *templ, char *label) { char path[200]; if (!TemplWithImpl (templ, label)) { sprintf (path, "%s.%s", TemplContext ("root", NULL, NULL, 0), label); _ErrExit3 (e__objectunknown, "label", path); } } static Int4 TemplWithImpl (TEMPLo *templ, char *label) { VARo *var=NULL, *tmp; Int4 isRoot=0, index; char *name, path[200], *context; if (!templ) { if (!templContext) _ErrExit (e__templNoCurrTemplate); templ = templContext->templ; } if (label && *label == '$') { /* start with root */ isRoot=1; label++; } else if (templContext && templ == templContext->templ) var = templContext->var; /* take root from prev context */ if (label) { strcpy (path, label); context = path; while ((name = strtok (context, ".["))) { context = NULL; if (sscanf (name, "%d]", &index)) { /* access by index */ if (!var || !(var = AnyGetListIndex (var, index-1))) return 0; } else if (var && !isRoot) { /* access by name */ if (!(tmp = AnyFindListAssoc (var, name))) return 0; else var = tmp; } else { /* root or variable name */ var = TemplGetTemplate (templ, name); isRoot = 0; /* prevents treatment of next name compononent as root */ } } } TemplContext ("push", templ, var, isRoot); return 1; } /**API* TemplEndWith ********************************************************** ** ** Destroys the current template context set by the most recent ** call of TemplWith and reinstalls the previous context. ** ** INPUT: ** IMPLICIT: ** templJob (JOBo*) ** */ void TemplEndWith () { TemplContext ("pop", NULL, NULL, 0); } static char *TemplContext (char *option, TEMPLo *templ, VARo *var, Int4 isRoot) { static TEMPLoCONTEXT contexts[TEMPLxMaxContextN]; static INT4 contextN=0; static char path[200]; char tmp[200]; Int4 k; switch (tolower (option[2])) { case 's': /* push */ if (contextN == TEMPLxMaxContextN) _ErrExit3 (f__limitexceeded, "templ contexts", TEMPLxMaxContextN); templContext = &contexts[++contextN]; templContext->templ = templ; templContext->var = var; templContext->isRoot = isRoot; break; case 'p': /* pop */ if (contextN) templContext = &contexts[--contextN]; else _ErrExit (e__templEndOfHistory); break; case 'o': /* root */ /* get the entire path from history */ for (k=contextN, path[0]='\0'; k >= 0; k--) { if ((var = contexts[k].var)) { strcpy (tmp, path); sprintf (path, ".%s%s", VarGetName (var), tmp); } else break; if (contexts[k].isRoot) break; } if (*path) path[0] = '$'; return path; } } void TemplClose (TEMPLv templ) { FileClose (templ->outFile); FileClose (templ->inFile); free (templ); /* should also 'unwind' the context if there is some left */ } static char line[999]; /**API* TemplN **************************************************************** ** ** Assists in creating a label name used when calling, eg, TemplPrint ** The generated label name's first component is an ** index number rather than a name. The specified name is added to ** the number, eg, if the index is 5 and the name is "head" then the ** generated string is "[5].head". **
    ** This function ** ** INPUT: the index number [R] ** the name to go after the index (NULL if not desired) [R] ** ** RETURNS: the string containing the label name ** */ char *TemplN (INT4 index, char *name) { static char line[999]; if (name) sprintf(line, "[%d].%s", index, name); else sprintf(line, "[%d]", index); return(line); } ** the number, eg, if the index is 5 and the name is "head" then the ** generated string is "[5].head". **
    ** This function ** ** INPUT: the index number [R] ** the name to srs/src/templ.h ** ** $RCSfile: templ.h,v $ ** $Revision: 1.8 $ ** $Date: 1996/08/12 20:24:30 $ ** $Author: etzold $ ** ** $Locker: $ ** $State: Exp $ ** ** */ typedef struct TEMPLo *TEMPLv; TEMPLv TemplOpen (char *inFileName, char *outFileName); TEMPLv TemplGet (); char* TemplSPrint (char *s, char *name, ...); char* TemplN (INT4 index, char *name); void TemplPrint (char *name, ...); void TemplWith (TEMPLv templ, char *name); struct VARo* TemplExists (TEMPLv templ, char *name); void TemplEndWith (); void TemplClose (TEMPLv templ); struct FILEo* TemplGetOutFile (TEMPLv templ); #define _s(x) (x) #define _d(x) (x) nFileName, char *outFileName); TEMPLv TemplGet (); char* TemplSPrint (char *s, char *name, ...); char* TemplN (INT4 index, char *name); void Templsrs/src/termio.c char termio_ID[] = "$Id: termio.c,v 1.2 1996/10/11 18:16:54 etzold Exp $"; /* ** ** $RCSfile: termio.c,v $ ** $Revision: 1.2 $ ** $Date: 1996/10/11 18:16:54 $ ** $Author: etzold $ ** ** ** Copyright by Thure Etzold ** ** Authors: Lukas Rosenthaler and Thure Etzold ** ** Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-69012 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #ifdef VMS # include # include # include # include # include # include # include # include #else # include /*# include linux doesn't have that - is in bsd/sys */ # include #endif #include "message.h" #include "strv.h" #include "termio.h" /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** some typedefs for VMS */ # ifdef VMS typedef struct { /* I/O status block */ short i_cond; /* Condition value */ short i_xfer; /* Transfer count */ long i_info; /* Device information */ } iosb; typedef struct { /* Terminal characteristics */ char t_class; /* Terminal class */ char t_type; /* Terminal type */ short t_width; /* Terminal width in characters */ long t_mandl; /* Terminal's mode and length */ long t_extend; /* Extended terminal characteristics */ } termchar; short TTY_CHANNEL_GLOBAL; # else # ifdef BSD # include struct ltchars OLDTTY_LC; struct tchars OLDTTY_TC; struct sgttyb OLDTTY; # else struct termio OLDTTY; # endif # endif /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Describes a line for the line editor in this module */ #define TERMxHistorySize 100 typedef struct TERMoLine { Int4 cursPos; Int4 editN; Int4 backN; STRv line[TERMxHistorySize]; } TERMoLine; /**api* TermInitTty ********************************************************** ** ** Initializes either "/dev/tty" (unix) or "TT:" (VMS) for single ** character input. ** ** Keyboard characteristics may have changed such that normal ** input is no longer possible until TermResetTty is called. ** Therefore TermResetTty *MUST* be called before the ** program terminates, even in case of catastrophic events ** such as exceptions caused by SIG_SEGV or SIG_BUS! */ void TermInitTty (void) { #ifdef VMS $DESCRIPTOR ( Term, "TT:" ); (void) sys$assign ( &Term, &TTY_CHANNEL_GLOBAL, 0, 0 ); #else #ifdef BSD struct sgttyb newtty; struct tchars tc; struct ltchars lc; ioctl(TTY_DESCR, TIOCGLTC,&OLDTTY_LC); ioctl(TTY_DESCR, TIOCGETC,&OLDTTY_TC); ioctl(TTY_DESCR, TIOCGETP, &OLDTTY); newtty = OLDTTY; newtty.sg_flags |= CBREAK; newtty.sg_flags &= ~(ECHO | XTABS); newtty.sg_erase = 0; newtty.sg_kill = 0; tc.t_intrc = 0; tc.t_quitc = 0; lc.t_suspc = 0; lc.t_dsuspc = 0; ioctl(TTY_DESCR, TIOCSETP, &newtty); ioctl(TTY_DESCR, TIOCSLTC,&lc); ioctl(TTY_DESCR, TIOCSETC,&tc); #else /* for non-BSD systems */ struct termio newtty; ioctl(TTY_DESCR, TCGETA, &OLDTTY); ioctl(TTY_DESCR, TCGETA, &newtty); newtty.c_iflag |= CBREAK; newtty.c_iflag &= ~(ECHO); newtty.c_iflag &= ~(IGNCR); newtty.c_iflag &= ~(ICRNL); newtty.c_iflag &= ~(INLCR); newtty.c_lflag = 0; newtty.c_cc[VMIN] = 1; newtty.c_cc[VTIME] = 0; newtty.c_cc[VEOF] = 1; ioctl(TTY_DESCR, TCSETA, &newtty); #endif #endif } /**api* TermResetTty ********************************************************** ** ** Resets the keyboard characterstics of either "/dev/tty" (unix) or "TT:" ** (VMS) to default values. ** */ void TermResetTty (void) { #ifndef VMS #ifdef BSD ioctl(TTY_DESCR, TIOCSETP, &OLDTTY); ioctl(TTY_DESCR, TIOCSLTC, &OLDTTY_LC); ioctl(TTY_DESCR, TIOCSETC, &OLDTTY_TC); #else ioctl(TTY_DESCR, TCSETA, &OLDTTY); #endif #endif } /**api* TermGetChar ********************************************************** ** ** Wait until next keyboard event, then returns the key pressed. Requires ** that TermInitTty has been called before. ** check the cursor position, if it at the beginning of the line do ** pre/post-parsing action. ** ** RETURNS: ascii code of pressed key */ char TermGetChar (void) { char c; #ifndef VMS read(TTY_DESCR, &c, 1); #else int status, trmmsk [2] = { 0, 0 }; short iosb [4]; status = sys$qiow (0, TTY_CHANNEL_GLOBAL, IO$_READVBLK + IO$M_NOECHO | IO$_TTYREADALL, iosb, 0, 0, &c, 1, 0, trmmsk, 0, 0 ); #endif return(c); } /**api* TermGetDimensions ***************************************************** ** ** Get dimensions of terminal screen. ** ** int *cols : number of columns [returned] ** int *rows : number of rows [returned] ** */ void TermGetDimensions (int *cols, int *rows) { #ifdef VMS short fd; int status; iosb iostatus; static termchar tc; /* Terminal characteristics */ $DESCRIPTOR(devnam, "SYS$COMMAND"); /* Assign input to a channel */ status = sys$assign(&devnam, &fd, 0, 0); if ((status & 1) == 0) exit(status); /* Get current terminal characteristics */ status = sys$qiow( /* Queue and wait */ 0, /* Wait on event flag zero */ fd, /* Channel to input terminal */ IO$_SENSEMODE, /* Get current characteristic */ &iostatus, /* Status after operation */ 0, 0, /* No AST service */ &tc, /* Terminal characteristics buf */ sizeof(tc), /* Size of the buffer */ 0, 0, 0, 0); /* P3-P6 unused */ /* The next few lines from Mats Akerberg */ /* De-assign the input device: */ if ((sys$dassgn(fd) & 1) == 0) { exit(status); } /* Jump out if bad status */ if ((status & 1) == 0) { exit(status); } if ((iostatus.i_cond & 1) == 0) { exit(iostatus.i_cond); } *cols = (int) tc.t_width; *rows = (int) ((unsigned int) tc.t_mandl >> 24); #else /* this may need work on other unix-- works for sun4 */ struct winsize wind_struct; ioctl(2,TIOCGWINSZ,&wind_struct); if (((int) wind_struct.ws_col < 1) || ((int) wind_struct.ws_row < 1)) { *cols = 80; *rows = 24; } else { *cols = (int) wind_struct.ws_col; *rows = (int) wind_struct.ws_row; } #endif } /**api* TermGetChar ********************************************************** ** ** Returns either an ASCII code (single character) or a TERM code for a ** function key which produces an escape sequence. ** ** RETURNS: ASCII code or TERM code of pressed key */ int TermGetKey (void) { char c; int key; c = TermGetChar (); switch (c) { case ESC : c = TermGetChar(); if (c == '[') { c = TermGetChar(); switch (c) { case 'A' : key = TERMxUp; break; case 'B' : key = TERMxDown; break; case 'C' : key = TERMxRight; break; case 'D' : key = TERMxLeft; break; case '2' : c = TermGetChar(); if (isdigit(c)) { c = TermGetChar(); switch (c) { case '1' : key = TERMxF10; break; case '9' : key = TERMxDo; break; } TermGetChar(); } break; case '5' : key = TERMxPrevScreen; (void) TermGetChar(); break; case '6' : key = TERMxNextScreen; (void) TermGetChar(); break; } } else if (c == 'O') { c = TermGetChar(); switch (c) { case 'A' : key = TERMxUp; break; case 'B' : key = TERMxDown; break; case 'C': key = TERMxRight; break; case 'D' : key = TERMxLeft; break; case 'P' : key = TERMxPF1; break; case 'Q' : key = TERMxPF2; break; case 'R' : key = TERMxPF3; break; case 'S' : key = TERMxPF4; break; } } break; case TERMxCtrl_P : key = TERMxPrevScreen; break; case TERMxCtrl_N : key = TERMxNextScreen; break; case 13 : key = TERMxReturn; break; default: key = (int) c; } return (key); } /**api* TermNewLineEditor ***************************************************** ** ** Creates a new terminal line editor. ** ** RETURNS: line edit object */ TERMvLine TermNewLineEditor () { TERMvLine led=NULL; if ((led = (TERMoLine *) calloc (sizeof(TERMoLine), 1)) == NULL) _ErrExit2 (e__allocfail, "line editor"); return led; } /**api* TermLineEdit ********************************************************** ** ** Simple line editor. Returns the line submitted with the ** Return key. ** ** RETURNS: current line */ STRv TermLineEdit (TERMvLine led, char *prompt) { STRv ln, *tmp, t; Int4 key, doSubmit=0; char s[2]="*"; TermInitTty (); ln = StrNew (); if (prompt) { printf (prompt); fflush (stdout); } led->cursPos = 0; led->backN = led->editN; /* iterate over keyboard input */ while ((key = TermGetKey ())) { if (_TermIsTypeChar (key)) { s[0] = (char) key; StrAddS (&ln, led->cursPos, s); CURSOR_SAVE (stdout); if (led->cursPos) CURSOR_LEFT (led->cursPos, stdout); fputs (_Str (ln), stdout); CURSOR_RESTORE (stdout); CURSOR_RIGHT (1, stdout); led->cursPos++; } else switch (key) { case TERMxCtrl_A: CURSOR_LEFT (led->cursPos, stdout); led->cursPos = 0; break; case TERMxCtrl_E: CURSOR_RIGHT (StrLen (ln) - led->cursPos, stdout); led->cursPos = StrLen (ln); break; case TERMxCtrl_K: DELETE_CURSPOS_EOL (stdout); StrCut (&ln, led->cursPos, StrLen (ln) - led->cursPos); break; case TERMxCtrl_C: case TERMxCtrl_Y: case TERMxCtrl_Z: exit (0); case TERMxLeft: if (led->cursPos>0) { CURSOR_LEFT (1, stdout); led->cursPos--; } break; case TERMxRight: if (led->cursPos < StrLen (ln)) { CURSOR_RIGHT (1, stdout); led->cursPos++; } break; case TERMxUp: if (led->backN>0) { if ((t = led->line[(led->backN-1) % TERMxHistorySize])) { ln = StrCpy (t); led->backN--; if (led->cursPos) CURSOR_LEFT (led->cursPos, stdout); DELETE_CURSPOS_EOL (stdout); fputs (_Str (ln), stdout); led->cursPos = StrLen (ln); } } break; case TERMxDown: if (led->backN < led->editN-1) { ln = StrCpy (led->line[(++led->backN) % TERMxHistorySize]); if (led->cursPos) CURSOR_LEFT (led->cursPos, stdout); DELETE_CURSPOS_EOL (stdout); fputs (_Str (ln), stdout); led->cursPos = StrLen (ln); } else if (led->backN == led->editN-1) { led->backN++; ln = StrNew (); if (led->cursPos) CURSOR_LEFT (led->cursPos, stdout); DELETE_CURSPOS_EOL (stdout); fputs (_Str (ln), stdout); led->cursPos = StrLen (ln); } break; case TERMxDelete: if (led->cursPos>0) { CURSOR_LEFT (1, stdout); DELETE_CURSPOS_EOL (stdout); StrCut (&ln, --led->cursPos, 1); CURSOR_SAVE (stdout); CURSOR_LEFT (led->cursPos, stdout); fputs (_Str (ln), stdout); CURSOR_RESTORE (stdout); } break; case TERMxCtrl_J: case TERMxReturn: doSubmit = 1; fputs ("\n", stdout); break; } fflush (stdout); if (doSubmit) { /* save line in history */ if (StrLen (ln)) { tmp = &led->line[led->editN++ % TERMxHistorySize]; if (*tmp) StrDel (*tmp); *tmp = ln; } break; } } TermResetTty (); return ln; } cursPos, 1); CURSOR_SAVE (stdout); CURSOR_LEFT (led->cursPos, stdout); fputs (_Str (ln), stdousrs/src/termio.h * $Header: /homes/srs/cvsroot/srs/src/termio.h,v 1.2 1996/10/11 18:16:55 etzold Exp $ *---------------------------------------------------------------------------- * * SRS V3.0 Copyright by Thure Etzold * * Author of this module: Lukas Rosenthaler and Reinhard Doelz * Copyright granted to Thure Etzold for distribution withing the SRS package * Use outside the SRS is strictly prohibited * ***************************************************************************** */ #define TTY_DESCR 2 #ifdef CBRK # ifndef CBREAK # define CBREAK CBRK # endif #else #define CBREAK BRKINT #endif #define ESC '\033' #define BS '\010' enum TERMxKey {TERMxCtrl_SP=0, TERMxCtrl_A, TERMxCtrl_B, TERMxCtrl_C, TERMxCtrl_D, TERMxCtrl_E, TERMxCtrl_F, TERMxCtrl_G, TERMxCtrl_H, TERMxCtrl_I, TERMxCtrl_J, TERMxCtrl_K, TERMxCtrl_L, TERMxCtrl_M, TERMxCtrl_N, TERMxCtrl_O, TERMxCtrl_P, TERMxCtrl_Q, TERMxCtrl_R, TERMxCtrl_S, TERMxCtrl_T, TERMxCtrl_U, TERMxCtrl_V, TERMxCtrl_W, TERMxCtrl_X, TERMxCtrl_Y, TERMxCtrl_Z, TERMxDelete=127, TERMxUp=300, TERMxDown, TERMxRight, TERMxLeft}; #define _TermIsTypeChar(x) ((x) >= 30 && (x) <= 126) #define TERMxPrevScreen 304 #define TERMxNextScreen 305 #define TERMxF10 310 #define TERMxF16 316 #define TERMxDo 316 #define TERMxPF1 316 /* SPECIAL FOR SRS, otherwise 331 */ #define TERMxPF2 332 #define TERMxPF3 333 #define TERMxPF4 310 /* SPECIAL FOR SRS, otherwise 334 */ #define TERMxReturn 13 #define TERMxDelete 127 #define RENDITION_OFF_STR "\033[0m" #define RENDITION_BOLD_STR "\033[1m" #define RENDITION_UNDERSCORE_STR "\033[4m" #define RENDITION_BLINK_STR "\033[5m" #define RENDITION_REVERSE_STR "\033[7m" #define DELETE_CURSPOS_EOL_STR "\033[0K" #define DELETE_BOL_CURSPOS_STR "\033[1K" #define DELETE_LINE_STR "\033[2K" #define DELETE_CURSPOS_EOS_STR "\033[0J" #define DELETE_BOS_CURSPOS_STR "\033[1J" #define DELETE_SCREEN_STR "\033[2J" #define CURSOR_UP_STR "\033[%dA" #define CURSOR_DOWN_STR "\033[%dB" #define CURSOR_RIGHT_STR "\033[%dC" #define CURSOR_LEFT_STR "\033[%dD" #define CURSOR_POSITION_STR "\033[%d;%dH" #define CURSOR_SAVE_STR "\0337" #define CURSOR_RESTORE_STR "\0338" /* #define SET_SCROLL_STR "\033[%d;%dr\033[?6h" #define RESET_SCROLL_STR "\033[;r\033[?6l" */ #define SET_SCROLL_STR "\033[%d;%dr" #define RESET_SCROLL_STR "\033[;r" #define SCROLL_UP_STR "\033D" #define SCROLL_DOWN_STR "\033M" #define SET_RENDITION_OFF(f) (void) fputs (RENDITION_OFF_STR, f) #define SET_RENDITION_BOLD(f) (void) fputs (RENDITION_BOLD_STR, f) #define SET_RENDITION_UNDERSCORE(f) (void) fputs (RENDITION_UNDERSCORE_STR, f) #define SET_RENDITION_BLINK(f) (void) fputs (RENDITION_BLINK_STR, f) #define SET_RENDITION_REVERSE(f) (void) fputs (RENDITION_REVERSE_STR, f) #define DELETE_CURSPOS_EOL(f) (void) fputs (DELETE_CURSPOS_EOL_STR, f) #define DELETE_BOL_CURSPOS(F) (void) fputs (DELETE_BOL_CURSPOS_STR, f) #define DELETE_LINE(f) (void) fputs (DELETE_LINE_STR, f) #define DELETE_CURSPOS_EOS(f) (void) fputs (DELETE_CURSPOS_EOS_STR, f) #define DELETE_BOS_CURSPOS(f) (void) fputs (DELETE_BOS_CURSPOS_STR, f) #define DELETE_SCREEN(f) (void) fputs (DELETE_SCREEN_STR, f) #define CURSOR_UP(n,f) (void) fprintf (f, CURSOR_UP_STR, n) #define CURSOR_DOWN(n,f) (void) fprintf (f, CURSOR_DOWN_STR, n) #define CURSOR_RIGHT(n,f) (void) fprintf (f, CURSOR_RIGHT_STR, n) #define CURSOR_LEFT(n,f) (void) fprintf (f, CURSOR_LEFT_STR, n) #define CURSOR_POSITION(x,y,f) (void) fprintf (f, CURSOR_POSITION_STR,y,x) #define CURSOR_SAVE(f) (void) fputs (CURSOR_SAVE_STR, f) #define CURSOR_RESTORE(f) (void) fputs (CURSOR_RESTORE_STR, f); #define SCROLL_REGION(s,e,f) (void) fprintf (f, SET_SCROLL_STR, (s),(e)) #define RESET_SCROLL(f) (void) fputs (RESET_SCROLL_STR, f) #define SCROLL_UP(f) (void) fputs (SCROLL_UP_STR, f) #define SCROLL_DOWN(f) (void) fputs (SCROLL_DOWN_STR, f) #define VIDEO_OFF 0 #define VIDEO_BOLD 1 #define VIDEO_REVERSE 2 #define VIDEO_BLINK 4 #define VIDEO_UNDERSCORE 8 typedef struct TERMoLine *TERMvLine; void TermInitTty (void); void TermResetTty (void); char TermGetChar (void); void TermGetDimensions (int *cols, int *rows); int TermGetKey (void); TERMvLine TermNewLineEditor (); STRv TermLineEdit (TERMvLine led, char *prompt); (void) fputs (SCROLL_DOWN_STR, f) #define VIDEO_OFF 0 #define VIDEO_BOLD 1 #define VIDEO_REVERSE 2 #define VIDEO_BLINK 4 #define VIDEO_UNDERSCORE 8 typedef struct TERMoLine *TERMvLine; void TermInitTty (void); void TermResetTty (void)srs/src/tm.c char time_srs_ID[] = "$Id: tm.c,v 1.1 1996/05/06 15:17:31 srs Exp $"; /* ** ** $RCSfile: tm.c,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:17:31 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port by Lukas Rosenthaler and Reinhard ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** Requires: time ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #ifdef VMS #include #include #else #include #include #endif #include "message.h" #include "tm.h" /**api* TimeGet *************************************************************** ** ** gets the time elapsed since 1-jan-1970 00:00 in seconds; ** ** IMPLICIT: ** ** RETURNS: 1 */ UINT4 TimeGet () { time_t seconds; time (&seconds); return (UINT4) seconds; } /**api* TimeToString ********************************************************* ** ** converts time into a string; ** ** INPUT: time value [R] ** option: "short", "long", "date" ** IMPLICIT: ** ** RETURNS: pointer to static string */ char *TimeToString (UINT4 userTimeVal, char *opt) { static char timeStr[30]; static char *month[12] = {"Jan","Feb","Mar","Apr","May","Jun","Jul", "Aug","Sep","Oct","Nov","Dec"}; time_t timeVal = (time_t) userTimeVal; struct tm *timeRec; if (timeVal == 0) time (&timeVal); timeRec = localtime (&timeVal); switch (tolower (opt[0])) { case 's': /* short */ sprintf (timeStr, "%0d/%0d/%0d", timeRec->tm_mon+1, timeRec->tm_mday, timeRec->tm_year); break; case 'l': /* long */ sprintf (timeStr, "%02d-%s-19%0d %02d:%02d", timeRec->tm_mday, month[timeRec->tm_mon], timeRec->tm_year, timeRec->tm_hour, timeRec->tm_min); break; case 'd': /* date */ sprintf (timeStr, "%02d-%s-19%0d", timeRec->tm_mday, month[timeRec->tm_mon], timeRec->tm_year); break; default: _ErrExit2 (e__unknownoption, opt); } return timeStr; } /**api* TimeFileCreate ******************************************************** ** ** retrieves files creation and last modification date; ** ** INPUT: address of file descriptor [R] ** IMPLICIT: ** ** RETURNS: file creation time ** 0 if file could not be opened */ UINT4 TimeFileCreate (FILE *file) { struct stat buff; INT4 fileNo; if (!file) return 0; fileNo = fileno (file); fstat (fileNo, &buff); return buff.st_ctime; } } /**api* TimeFileCreate ******************************************************** ** ** retrieves files creation and last modification date; ** ** INPUT: address of file descriptor [R] ** IMPLICIT: ** ** RETURNS: file creation time ** 0 if file could not be opened */ UINT4 TimeFileCreate (FILE *file) { struct stat buff; INT4 fileNo; if (!fisrs/src/tm.h ** ** $RCSfile: tm.h,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:17:31 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** SRS V3.x Copyright by Thure Etzold ** */ UINT4 TimeGet (); char *TimeToString (UINT4 time, char *option); UINT4 TimeFileCreate (FILE *file); could not be opened */ UINT4 Tim@ate (FILE *file) { struct stat buff; INT4 fi(!fisrs/src/toklist.c char toklist__ID[] = "$Id: toklist.c,v 1.17 1997/03/19 20:41:41 srs Exp $"; /* ** ** $RCSfile: toklist.c,v $ ** $Revision: 1.17 $ ** $Date: 1997/03/19 20:41:41 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** Copyright by Thure Etzold ** ** Author: Anatoly Ulyanov ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387451 ** Email: ulyanov@embl-heidelberg.de ** */ #include #include #include #include #include "message.h" #include "futil.h" #include "sm.h" #include "dict.h" #include "strv.h" #include "lst.h" #include "toklist.h" /* * * * * * * * * * Private Domain * * * * * * * * * * * * * * * */ static TOKoLIST *tokListGbl; static void ListDump(FILE *file, void *obj) { TOKoLIST *t = (TOKoLIST *)obj; printf("List/%d %s\n", t->isActive, t->name); } static void ListKill(void *obj) { TOKoLIST *tokList = (TOKoLIST *)obj; if (tokList->dict) DictDestroy (tokList->dict); free(tokList->first); if(tokList->buff) free(tokList->buff); } /****** TokGrowList ********************************************************* ** ** This function implements growing of number of allocated tokens ** into token list class object when number of required tokens ** exceed maximum. ** ** INPUT: address of token list object [R] ** ** IMPLICIT: ** ** RETURNS: */ static void TokGrowList(TOKoLIST *tokList) { TOKoTOKEN *tokenSave; INT4 offsetRead, offsetWrite; tokList->size *= 2; offsetRead = (INT4) (tokList->currTokenRead - tokList->first); offsetWrite = (INT4) (tokList->currTokenWrite - tokList->first); tokenSave=tokList->first; tokList->first = (TOKoTOKEN *) realloc(tokList->first, tokList->size*sizeof(TOKoTOKEN)); if(!tokList->first) _ErrExit2 (e__allocfail, "tokList list"); if (tokList->first != tokenSave && tokList->dict) DictOffset (tokList->dict, displ (tokList->first, tokenSave)); tokList->currTokenRead = tokList->first + offsetRead; tokList->currTokenWrite = tokList->first + offsetWrite; tokList->last = tokList->first + tokList->size; } /* * * * * * * * * * Public Domain * * * * * * * * * * * * * * * */ /**api* TokGetList ********************************************************** ** ** Create and initialise a new token list object if the name is not ** in the list otherwise return pointer to existing token list. ** If token list class object's address is NULL it would be created. ** ** INPUT: name of token list [R] ** address of token list object [R] (initially NULL) ** ** IMPLICIT: ** ** RETURNS: token list object */ TOKoLIST *TokGetList(char *name, TOKoLIST **tokList) { static INT4 TokListClassId = 0; TOKoLIST *tmp; if(!TokListClassId) LstManageClass(&TokListClassId, sizeof(TOKoLIST), NULL, ListKill,ListDump); if (!LstHashSearch((void **) tokList, name)) { LstNewNamed((void **) tokList, TokListClassId, name); tmp = *tokList; tmp->first = (TOKoTOKEN *) calloc(1, TOKxMAXLISTSIZE * sizeof(TOKoTOKEN)); if (!tmp->first) _ErrExit2 (e__allocfail, "tokList list"); tmp->isActive = FALSE; tmp->size = TOKxMAXLISTSIZE; tmp->style = TOKxANY; tmp->buff = NULL; tmp->currTokenWrite = tmp->first; tmp->currTokenRead = tmp->first; tmp->last = tmp->first + tmp->size; } return *tokList; } /**api* TokFindList ********************************************************** ** ** Return pointer to token list object if the name is not ** in the list exit program with error ** ** INPUT: name of token list [R] ** address of token list object [R] ** ** IMPLICIT: ** ** RETURNS: token list object */ TOKoLIST *TokFindList(char *name, TOKoLIST **tokList) { if( !LstHashSearch((void **) tokList, name) ) _ErrExit2(e__toklistFind, name); return (*tokList); } /**api* TokIsListActive ***************************************************** ** ** Return "isActive" attribute of token list object. Token list is ** "active" when read/write operations are allowed with this token ** list ** ** INPUT: address of token list object [R] ** ** IMPLICIT: ** ** RETURNS: isActive attribute */ INT4 TokIsListActive(TOKoLIST *tokList) { return(tokList->isActive); } /**api* TokIsListEmpty ****************************************************** ** ** Check presence of token(s) in token list object. ** ** INPUT: address of token list object [R] ** ** IMPLICIT: ** ** RETURNS: TRUE ** FALSE */ INT4 TokIsListEmpty(TOKoLIST *tokList) { return(tokList->first == tokList->currTokenWrite); } /**api* TokIsListStart ****************************************************** ** ** Check if the current token to read is the first in token list object. ** ** INPUT: address of token list object [R] ** ** IMPLICIT: ** ** RETURNS: TRUE ** FALSE */ INT4 TokIsListStart(TOKoLIST *tokList) { return(tokList->first == tokList->currTokenRead); } /**api* TokSetStyle ********************************************************* ** ** Set style attribute for the token list object. ** ** INPUT: address of token list object [R] ** type of token list [R] ** ** IMPLICIT: ** ** RETURNS: */ void TokSetStyle(TOKoLIST *tokList, char *style) { if(tokList->style == TOKxANY) { switch(tolower(style[0])) { case 'c': /* copy */ tokList->style = TOKxCOPY; tokList->buff = BuffInit(tokList->buff, TOKxMAXTOKBUFFSIZE); break; case 'e': /* echo */ tokList->style = TOKxECHO; break; case 'f': /* file */ tokList->style = TOKxFILE; break; default: _ErrExit2 (e__unknownoption, style); } } } /**api* TokSetFile ********************************************************** ** ** Initialize attributes for the token list object in special case ** when token list is associated with standard input stream (file). ** ** INPUT: address of token list object [R] ** address of file object [R] ** ** IMPLICIT: ** ** RETURNS: */ void TokSetFile(TOKoLIST *tokList, FILEo *file) { tokList->file = file; tokList->isActive = TRUE; tokList->first->code= TOKxUNDEFCODE; tokList->first->isTerminal = FALSE; tokList->currTokenRead = tokList->first; tokList->currTokenWrite = tokList->first + 1; tokList->first->length = 0; tokList->style = TOKxFILE; } /**api* TokResetList ******************************************************** ** ** Deactivate the token list object. ** ** INPUT: address of token list object [R] ** ** IMPLICIT: ** ** RETURNS: */ void TokResetList(TOKoLIST *tokList) { tokList->isActive = FALSE; if (tokList->dict) DictClear (&tokList->dict); if(tokList->buff) BuffReset(tokList->buff); tokList->currTokenWrite = tokList->first; tokList->currTokenRead = tokList->first; } /**api* TokResetAllLists **************************************************** ** ** Deactivate all token list objects. ** ** INPUT: address of token list object [R] ** ** IMPLICIT: ** ** RETURNS: */ void TokResetAllLists(TOKoLIST *tokList) { if (tokList) { LstFirst((void **) &tokList); do { TokResetList(tokList); }while(LstNext((void **) &tokList)); } } /**api* TokRewindList ******************************************************* ** ** Set current input token in the token list objects at the beginning. ** ** INPUT: address of token list object [R] ** ** IMPLICIT: ** ** RETURNS: */ void TokRewindList(TOKoLIST *tokList) { tokList->currTokenRead = tokList->first; } /**api* TokDeleteList ******************************************************* ** ** Delete the token list object. ** ** INPUT: address of token list object [R] ** ** IMPLICIT: ** ** RETURNS: */ void TokDeleteList(TOKoLIST *tokList) { LstDelete((void **) &tokList); } /**api* TokDeleteAllLists *************************************************** ** ** Delete all token list objects. ** ** INPUT: address of token list object [R] ** ** IMPLICIT: ** ** RETURNS: */ void TokDeleteAllLists(TOKoLIST *tokList) { LstDeleteAll((void **) &tokList); } /**api* TokAdd ************************************************************** ** ** Add a new token to the token list objects. ** ** INPUT: address of the token list object [R] ** address of the token [R] ** length of the token [R] ** code of the token [R] ** ** RETURNS: new token */ TOKoTOKEN *TokAdd(TOKoLIST *tokList, char* tokStr, INT4 length, INT4 code) { TOKoTOKEN *token; if(tokList->style == TOKxANY || tokList->style == TOKxFILE) _ErrExit2 (e__toktablenotwritable, tokList->name); tokList->isActive = TRUE; if(tokList->currTokenWrite >= tokList->last) TokGrowList(tokList); token = tokList->currTokenWrite; if(tokList->style == TOKxCOPY) { token->buffOffset = BuffGetCurrOffset(tokList->buff); BuffCopyNChar(tokList->buff, tokStr, length); token->tokStr = NULL; } else token->tokStr = tokStr; token->isTerminal = TRUE; token->length = length; token->code = code; tokList->currTokenWrite++; return token; } static int TokHash (TOKoTOKEN *tok, int max) { UINT4 sum; sum = CharHashLen (TokGetString (tokListGbl, tok), TokGetLength (tok)); _hash (sum, (UINT4) TokGetCode (tok)); return sum%max; } static Int4 TokEqual (TOKoTOKEN *a, TOKoTOKEN *b) { Int4 len, k; char *as, *bs; if ((len = TokGetLength (a)) == TokGetLength (b) && TokGetCode (a) == TokGetCode (b)) { for (k=0, as=TokGetString (tokListGbl, a), bs=TokGetString (tokListGbl, b); kdict) tokList->dict = DictCreate (&cl); tokListGbl = tokList; memset (&token, 0, sizeof (TOKoTOKEN)); token.tokStr = tokStr; token.isTerminal = TRUE; token.length = length; token.code = code; if (!DictWith (tokList->dict, &token)) { tmp = &DictAdd (&tokList->dict, &token, TOKoTOKEN*); *tmp = TokAdd (tokList, tokStr, length, code); return *tmp; } return NULL; } /**api* TokAppend *********************************************************** ** ** Append a token to the current output token in the token list objects. ** ** INPUT: address of the token list object [R] ** address of the token [R] ** length of the token [R] ** code of the token [R] ** ** IMPLICIT: ** ** RETURNS: TRUE if token was appended ** FALSE otherwise */ INT4 TokAppend(TOKoLIST *tokList, char* tokStr, INT4 length) { if(tokList->isActive == FALSE) return(FALSE); if(tokList->style == TOKxECHO) { (tokList->currTokenWrite-1)->isTerminal = FALSE; TokAdd(tokList, tokStr, length, (tokList->currTokenWrite-1)->code); } else { (tokList->currTokenWrite-1)->length += length; BuffCopyNChar(tokList->buff, tokStr, length); } return(TRUE); } /**api* TokReplaceIn ******************************************************** ** ** Replace a part of the current output token on target string ** ** INPUT: address of the token list object [R] ** start position of the replacement in the token [R] ** length of the replacement [R] ** replacement string [R] ** ** IMPLICIT: ** ** RETURN: shift between new and old buffers, if new was reallocated */ INT4 TokReplaceIn(TOKoLIST *tokList, char *tag, INT4 tagLen, char *repStr, INT4 repLen) { TOKoTOKEN *token; char *saveBuffPtr; INT4 shift, diff; if (tokList->style == TOKxFILE) { SmReplace (tokList->file->ln, tag, tagLen, repStr, repLen); return 0; } else if (tokList->style == TOKxCOPY) { saveBuffPtr = BuffGetPtr(tokList->buff); BuffReplace(tokList->buff, tag, tagLen, repStr, repLen); shift = repLen - tagLen; if(shift) { /* the token where the replacement takes place is not the current but one prior! */ (tokList->currTokenRead-1)->length += shift; token = tokList->currTokenRead-1; while(token++ < tokList->currTokenWrite) token->buffOffset += shift; } diff = (Int4)(BuffGetPtr(tokList->buff)-saveBuffPtr); return diff; } else { _ErrExit2(e__toklistReplace, tokList->name); } } /**api* TokCurrent ********************************************************* ** ** Return pointer to the current input token ** ** INPUT: address of token list object [R] ** ** IMPLICIT: ** ** RETURNS: address of the current input token */ TOKoTOKEN *TokCurrent(TOKoLIST *tokList) { return(tokList->currTokenRead); } /**api* TokGet ************************************************************** ** ** Return pointer to the current input token ** ** INPUT: address of token list object [R] ** ** IMPLICIT: ** ** RETURNS: pointer to the next token if it exists ** NULL otherwise */ TOKoTOKEN *TokGet(TOKoLIST *tokList) { TOKoTOKEN *token; if(!tokList->isActive) return(NULL); token = tokList->currTokenRead; if(tokList->style == TOKxFILE) { if (!tokList->file || FileReadLn(tokList->file) == NULL) return(NULL); token->tokStr = tokList->file->ln; token->length = strlen(tokList->file->ln); return(token); } if(token < tokList->currTokenWrite) { tokList->currTokenRead = token + 1; return(token); } else return(NULL); } /**api* TokGet2 ************************************************************** ** ** Return pointer to the current input token. ** If token list object associated with standard input stream ** new line will be read if current is empty. ** ** INPUT: address of token list object [R] ** ** IMPLICIT: ** ** RETURNS: pointer to the next token if it exists ** NULL otherwise */ TOKoTOKEN *TokGet2(TOKoLIST *tokList) { TOKoTOKEN *token; if(!tokList->isActive) return(NULL); token = tokList->currTokenRead; if(tokList->style == TOKxFILE && tokList->file) { if (!(*tokList->file->ln)) if(FileReadLn(tokList->file) == NULL) return(NULL); token->tokStr = tokList->file->ln; token->length = strlen(tokList->file->ln); return(token); } if(token < tokList->currTokenWrite) { tokList->currTokenRead = token + 1; return(token); } else return(NULL); } /**api* TokGetMore ********************************************************** ** ** Return pointer to the next input token when current token ** consist of more that one fragment. ** ** INPUT: address of token list object [R] ** ** IMPLICIT: ** ** RETURNS: pointer to the next fragment of Multioken if it exists ** NULL otherwise */ INT4 TokGetMore(TOKoLIST *tokList, char **ptr, INT4 *length) { TOKoTOKEN *token; if( TokIsMultiTok(tokList) ) { if((token = TokGet(tokList))){ *length = token->length; *ptr = token->tokStr; return(TRUE); } } return(FALSE); } /**api* TokGetFirst ********************************************************* ** ** Return pointer to the first input token ** ** INPUT: address of token list object [R] ** ** IMPLICIT: ** ** RETURNS: pointer to the first token */ TOKoTOKEN *TokGetFirst(TOKoLIST *tokList) { tokList->currTokenRead = tokList->first; return(TokGet2(tokList)); } /**api* TokNext ************************************************************* ** ** Return pointer to the next input token. If counter equals to zero ** return address of the first token ** ** INPUT: address of token list object [R] ** address of counter [W] ** ** IMPLICIT: ** ** RETURNS: pointer to the next(first) token */ TOKoTOKEN *TokNext(TOKoLIST *tokList, INT4 *count) { (*count)++; if(*count == 1) return(TokGetFirst(tokList)); else return(TokGet(tokList)); } /**api* TokNextWithCode ***************************************************** ** ** Return pointer to the next input token that has required code. ** If counter equals to zero start search form the first token. ** ** INPUT: address of token list object [R] ** address of counter [W] ** code of input token [R] ** ** IMPLICIT: ** ** RETURNS: pointer to the next token if it exists ** NULL otherwise */ TOKoTOKEN *TokNextWithCode(TOKoLIST *tokList, INT4 code, INT4 *count) { TOKoTOKEN *token; if(*count == 0) token = TokGetFirst(tokList); else token = TokGet(tokList); (*count)++; while( token ) { if(token->code == code || code == TOKxUNDEFCODE) return(token); else token = TokGet(tokList); } return(NULL); } /**api* TokGetString ******************************************************** ** ** Return pointer to the string content of the token ** ** INPUT: address of token list object [R] ** address of token [R] ** ** IMPLICIT: ** ** RETURNS: pointer to the string */ char *TokGetString(TOKoLIST *tokList, TOKoTOKEN *tokenRead) { if (tokenRead->tokStr) return tokenRead->tokStr; else if(tokList->style == TOKxCOPY) return(BuffGetPtr(tokList->buff)+tokenRead->buffOffset); else return NULL; } /**api* TokGetStringCopy **************************************************** ** ** Return copy to the string content of the token. ** Space for the copy of the string allocated in static buffer object. ** The content of the string is stable until next call of the function. ** ** INPUT: address of token list object [R] ** address of token [R] ** ** IMPLICIT: ** ** RETURNS: pointer to the string */ char *TokGetStringCopy(TOKoLIST *tokList, TOKoTOKEN *token) { static SMoBUFF *buffTokStr = NULL; buffTokStr = BuffInit(buffTokStr, TOKxMAXTOKBUFFSIZE); if(tokList->style == TOKxCOPY) { BuffCopyNChar(buffTokStr, BuffGetPtr(tokList->buff)+token->buffOffset, token->length); BuffCopyChar(buffTokStr, '\0'); } else { BuffCopyNChar(buffTokStr, token->tokStr, token->length); while( !token->isTerminal ) { token++; BuffCopyNChar(buffTokStr, token->tokStr, token->length); } BuffCopyChar(buffTokStr, '\0'); } return(BuffGetPtr(buffTokStr)); } /**api* function ************************************************************* ** ** Returns a string value with content of the token which must be ** deleted by the user. ** ** INPUT: address of token list object [R] ** address of token [R] ** ** RETURNS: new STRv with token */ STRv TokGetStrv (TOKoLIST *tokList, TOKoTOKEN *tok) { STRv s; if (tokList->style == TOKxCOPY) s = StrNCpyS (BuffGetPtr(tokList->buff)+tok->buffOffset, tok->length); else { s = StrNCpyS (tok->tokStr, tok->length); while (!tok->isTerminal) { tok++; StrAppN (&s, tok->tokStr, tok->length); } } return s; } /**api* TokGetCode ********************************************************** ** ** Get the code of the current output token ** ** INPUT: address of token [R] ** ** IMPLICIT: ** ** RETURNS: value of the token code */ INT4 TokGetCode(TOKoTOKEN *tokenRead) { return(tokenRead->code); } /**api* TokGetLength ******************************************************** ** ** Get the length of the current output token ** ** INPUT: address of token [R] ** ** IMPLICIT: ** ** RETURNS: value of the token length */ INT4 TokGetLength(TOKoTOKEN *tokenRead) { return(tokenRead->length); } /**api* TokIsMultiTok ******************************************************** ** ** Check, does specified token consist of fragments ** ** INPUT: address of token [R] ** ** IMPLICIT: ** ** RETURNS: TRUE if token consists from fragment ** FALSE otherwise */ INT4 TokIsMultiTok(TOKoLIST *tokList) { if(tokList->style == TOKxFILE) return(TRUE); if(tokList->currTokenRead < tokList->currTokenWrite) return(!(tokList->currTokenRead-1)->isTerminal); else return(FALSE); } /**api* TokIsUniq *********************************************************** ** ** Check, does specified token is unique ** ** INPUT: address of token [R] ** ** IMPLICIT: ** ** RETURNS: TRUE if string is unique in tokList ** FALSE otherwise */ INT4 TokIsUniq(TOKoLIST *tokList, char *string, INT4 len, INT4 code) { TOKoTOKEN *token; INT4 count; if(tokList->style == TOKxFILE) _ErrExit2(e__toklistIsUniq, tokList->name); count = 0; while( (token = TokNextWithCode(tokList, code, &count)) ) if( len == token->length && strncmp(TokGetString(tokList, token), string, len) == 0) return(FALSE); return(TRUE); } /**api* TokPrintList ******************************************************** ** ** ** Print out all tokens with particular code from specify token list ** object ** ** INPUT: address of token list object [R] ** token code [R] ** ** IMPLICIT: ** ** RETURNS: */ void TokPrintList(TOKoLIST *tokList, INT4 code) { TOKoTOKEN *token; INT4 count; printf("TokList: %s\n", tokList->name); count = 0; while( (token = TokNextWithCode(tokList, code, &count)) ) printf("TOKEN%2d: |%s| -- CODE: %d\n", count, TokGetStringCopy(tokList, token), TokGetCode(token) ); } static SMoBUFF* buff=NULL; static void* BuffToKey(DictElem* e) { Word offs=cast(*e, Word)-TOKxCODESHIFT; return BuffGetPtr(buff)+offs; } static CLASSoDICT CodeDictClass = { (ValComparer)strequal, (ValHasher)strhash, (KeyAccessor)BuffToKey, NULL, FALSE }; /**api* TokStrToCode ******************************************************** ** ** Token list class has global dictionary of token codes defined as ** names. Function converts name to integer and stores unique names ** in dictionary object. ** ** INPUT: name of token code [R] ** ** IMPLICIT: ** ** RETURNS: integer value of the code */ INT4 TokStrToCode(char* str) { static DICTv codeNames=0; IntOrPtr code; char** p; if (!codeNames) { codeNames=DictCreate(&CodeDictClass); buff=BuffInit(buff, 512); } p=&DictSet(&codeNames, str, char*); if (*p) code=(IntOrPtr)*p; /* the string is already in dictionary */ else { code=BuffGetCurrOffset(buff)+TOKxCODESHIFT; /* new string */ *p=(DictElem)code; BuffCopyString(buff, str); BuffCopyChar(buff,'\0'); } return(code); } /**api* TokStrToCode ******************************************************** ** ** Token list class has global dictionary of token codes defined as ** names. Function converts integer to name of the code using the ** dictionary. ** ** INPUT: integer value of the code [R] ** ** IMPLICIT: ** ** RETURNS: name of token code */ char* TokCodeToStr(INT4 code) { return(BuffGetPtr(buff)+(code-TOKxCODESHIFT)); } /**api* TokGetBuff *********************************************************** ** ** Returns the start address of the buffer of the token table. ** Useful to memorize in order to keep track of possible reallocation ** events. ** ** INPUT: the token list object [R] ** ** IMPLICIT: ** ** RETURNS: start address of token list buffer */ char* TokGetBuff (TOKoLIST *tokList) { return tokList->buff ? BuffGetPtr(tokList->buff) : NULL; } /**api* function ************************************************************** ** ** Returns the address of the token list name. ** ** INPUT: the token list object [R] ** ** RETURNS: address of the token list name */ char *TokListGetName (TOKoLIST *tokList) { return tokList->name; } /**api* function ************************************************************** ** ** Returns the address of the token list name. ** ** INPUT: the token list object [R] ** ** RETURNS: address of the token list name */ char *TokListPtrGetName (TOKoLIST **tokList) { return (*tokList)->name; } n list name. ** ** INPUT: the token list object [R] ** ** RETURNS: address of the token list name */ char *TokListGetName (TOKoLIST *tokList) { return tokList->name; } /**api* function ****************************************srs/src/toklist.h ** ** $RCSfile: toklist.h,v $ ** $Revision: 1.8 $ ** $Date: 1997/03/17 23:24:03 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** Copyright by Thure Etzold ** ** Author: Anatoly Ulyanov ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387451 ** Email: ulyanov@embl-heidelberg.de ** */ #define TOKxCODESHIFT 1000001 #define TOKxMAXNAMESIZE 40 #define TOKxMAXTOKBUFFSIZE 20 #define TOKxMAXHASHSIZE 10000 #define TOKxMAXLISTSIZE 512 #define TOKxUNDEFCODE -1 enum style {TOKxANY, TOKxECHO, TOKxCOPY, TOKxFILE}; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ typedef struct TOKoTOKEN { char *tokStr; INT4 buffOffset; INT4 isTerminal; INT4 length; INT4 code; char *codeName; /* name of the code */ } TOKoTOKEN; typedef struct TOKoLIST { char *list; int listId; char name[TOKxMAXNAMESIZE]; INT4 isActive; /* FALSE if empty */ INT4 size; enum style style; /* TOKxCOPY or TOKxECHO */ struct TOKoTOKEN *first; struct TOKoTOKEN *currTokenRead; struct TOKoTOKEN *currTokenWrite; struct TOKoTOKEN *last; struct DICTo *dict; FILEo *file; SMoBUFF *buff; } TOKoLIST; TOKoLIST *TokGetList(char *name, TOKoLIST **tokList); TOKoLIST *TokFindList(char *name, TOKoLIST **tokList); TOKoTOKEN *TokCurrent(TOKoLIST *tokList); TOKoTOKEN *TokGet(TOKoLIST *tokList); TOKoTOKEN *TokGetFirst(TOKoLIST *tokList); TOKoTOKEN *TokNext(TOKoLIST *tokList, INT4 *count); TOKoTOKEN *TokNextWithCode(TOKoLIST *tokList, INT4 code, INT4 *count); TOKoTOKEN *TokAdd(TOKoLIST *tokList, char* tokStr, INT4 length, INT4 code); TOKoTOKEN *TokAddUniq(TOKoLIST *tokList, char* tokStr, INT4 length, INT4 code); INT4 TokAppend(TOKoLIST *tokList, char* tokStr, INT4 length); INT4 TokGetCode(TOKoTOKEN *tokenRead); INT4 TokGetLength(TOKoTOKEN *tokenRead); INT4 TokGetMore(TOKoLIST *tokList, char **ptr, INT4 *len); INT4 TokIsListActive(TOKoLIST *tokList); INT4 TokIsListEmpty(TOKoLIST *tokList); INT4 TokIsListStart(TOKoLIST *tokList); INT4 TokIsUniq(TOKoLIST *tokList, char *string, INT4 len, INT4 code); INT4 TokIsMultiTok(TOKoLIST *tokList); INT4 TokReplaceIn(TOKoLIST *tokList, char *s, INT4 l, char *s1, INT4 l1); INT4 TokStrToCode(char *codeStr); char *TokCodeToStr(INT4 code); char *TokGetString(TOKoLIST *tokList, TOKoTOKEN *tokenRead); char *TokGetStringCopy(TOKoLIST *tokList, TOKoTOKEN *tokenRead); struct STRo* TokGetStrv (TOKoLIST *tokList, TOKoTOKEN *tok); void TokDeleteAllLists(TOKoLIST *tokList); void TokDeleteList(TOKoLIST *tokList); void TokPrintList(TOKoLIST *tokList, INT4 code); char* TokListGetName (TOKoLIST *tokList); char* TokListPtrGetName (TOKoLIST **tokList); void TokResetAllLists(TOKoLIST *tokList); void TokResetList(TOKoLIST *tokList); void TokRewindList(TOKoLIST *tokList); void TokSetFile(TOKoLIST *tokList, FILEo *file); void TokSetStyle(TOKoLIST *tokList, char *style); char* TokGetBuff (TOKoLIST *tokList); TOKoLIST *tokList); void TokDeleteLisrs/src/transl.h ** ** $RCSfile: transl.h,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:17:33 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** from ODD file: "srssdl:srswin.sdl" ** date of ODD compilation: 12-JAN-1996 18:16 ** */ #ifndef _SEQoTranslTable #define _SEQoTranslTable typedef struct SEQoTranslTable { char *name; /* Name of translation table. */ char *code; /* Short name of translation table. */ INT4 id; /* Numeric id. */ char *aa; /* Amino acid encoded by triplett. */ char *aaAlt; /* Alternative (edited) Amino acid encoded by triplett. */ char *saa; /* Amino acid encoded by triplett at translation start. */ } SEQoTranslTable; #endif #ifdef _INITOBJS SEQoTranslTable translTable[] = { {"Standard", "SGC0", 1, "FFLLSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "", "-----------------------------------M----------------------------"}, {"Vertebrate Mitochondrial", "SGC1", 2, "FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIMMTTTTNNKKSS**VVVVAAAADDEEGGGG", "", "--------------------------------MMMM---------------M------------"}, {"Yeast Mitochondrial", "SGC2", 3, "FFLLSSSSYY**CCWWTTTTPPPPHHQQRRRRIIMMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "", "-----------------------------------M----------------------------"}, {"Mold Mitochondrial; Protozoan Mitochondrial; Coelenterate Mitochondrial; Mycoplasma; Spiroplasma", "SGC3", 4, "FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "", "--MM---------------M------------MMMM---------------M------------"}, {"Invertebrate Mitochondrial", "SGC4", 5, "FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIMMTTTTNNKKSSSSVVVVAAAADDEEGGGG", "", "---M----------------------------M-MM---------------M------------"}, {"Ciliate Macronuclear; Dasycladacean Nuclear", "SGC5", 6, "FFLLSSSSYYQQCC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "", "-----------------------------------M----------------------------"}, {"Echinoderm Mitochondrial", "SGC8", 9, "FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIIMTTTTNNNKSSSSVVVVAAAADDEEGGGG", "", "-----------------------------------M----------------------------"}, {"Euplotid Macronuclear", "SGC9", 10, "FFLLSSSSYY**CCCWLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "", "-----------------------------------M----------------------------"}, {"Bacterial", "", 11, "FFLLSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "", "---M---------------M------------M--M---------------M------------"}, {"Alternative Yeast Nuclear", "", 12, "FFLLSSSSYY**CC*WLLLSPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "", "-------------------M---------------M----------------------------"}, {"Ascidian Mitochondrial", "", 13, "FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIMMTTTTNNKKSSGGVVVVAAAADDEEGGGG", "", "-----------------------------------M----------------------------"}, {"Flatworm Mitochondrial", "", 14, "FFLLSSSSYYY*CCWWLLLLPPPPHHQQRRRRIIIMTTTTNNNKSSSSVVVVAAAADDEEGGGG", "", "-----------------------------------M----------------------------"}, {"Blepharisma Macronuclear", "", 15, "FFLLSSSSYY*QCC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "", "-----------------------------------M----------------------------"} }; #endif PPPPHHQQRRRRIIMMTTTTNNKKSSGGVVVVAAAADDEEGGGG", "", "-----------------------------------M----------------------------"}, {"Flatworm Mitochondrial", "", 14, "FFLLSSSSYYY*CCWWLLLLPPPPHHQQRRRRIIIMTTTTNNNKSSSSVVVVAAAADDEEGGGG", "", "-----------------------------------M----------------------------"}, {"Blepharisma Macronuclear", "", 15, "FFLLSSSSYY*QCC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "", "---------------srs/src/trembl.c char trembl_ID[] = "$Id: trembl.c,v 1.1 1996/05/06 15:17:34 srs Exp $"; /* ** ** $Source: /homes/srs/cvsroot/srs/src/trembl.c,v $ ** $Revision: 1.1 $ ** $Date: 1996/05/06 15:17:34 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** Copyright by Thure Etzold ** ** Author: Gerald Schaefer + Thure Etzold ** EMBL, Meyerhofstrasse 1 ** 69012 Heidelberg, Germany ** Tel: 06221 387372 ** Email: schaefer@embl-heidelberg.de ** etzold@embl-heidelberg.de ** ** ** Requires: ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** program translates all CDS features of EMBL sequences. ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include "srs.h" #include "lst.h" #define _INITOBJS #include "transl.h" /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Object that contains the text of a complete data-field. ** The first two attributes are initialized and maintained by ** the list module. The third attribute must be initialized ** by the application modules. If the application module never ** uses a search by name this attribute may be skipped. */ typedef struct { char *internal; /* the first three attributes are necessary */ INT4 type_id; /* for all objects to be managed by the list */ char *name; /* dynamic (flexible) name */ /* char name[20]; /* feature name or refnumber */ SMoBUFF *buff; /* pointer to description */ } FIELDo; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Object with all information from entry that is needed to generate ** a trembl entry. */ typedef struct { ENTRYo *entry; SMoBUFF *id, *accession, *definition, *organism, *featureCurr, *refCurr; FIELDo *links; /* managed by List Module */ FIELDo *features; /* managed by List Module */ FIELDo *references; /* managed by List Module */ SEQo *entrySeq; /* complete entry sequence */ SEQo *resultSeq; /* CDS sequence */ SEQo *protSeq; /* AA sequence */ SLBoFEATURE *feature; /* feature description */ INT4 genCode; char *errorMessage; } CDSoSTORE; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** external or module wide variables */ static INT4 cnt_syntaxerror=0, cnt_trerr=0, cnt_firstcodonerror=0, cnt_correct=0; extern INT4 global_before_f; static char *geneticCodeTable[] = { "Standard", /* id 1 */ "Vertebrate Mitochondrial", /* id 2 */ "Yeast Mitochondrial", /* id 3 */ "Mold Mitochondrial and Mycoplasma", /* id 4 */ "Invertebrate Mitochondrial", /* id 5 */ "Ciliate Macronuclear and Daycladacean", /* id 6 */ "Protozoan Mitochondrial", /* id 7 */ "obsolete", /* id 8 */ "Echinoderm Mitochondrial", /* id 9 */ "Euplotid Macronuclear", /* id 10 */ "Eubacterial", /* id 11 */ "Group II yeasts" /* id 12 */ }; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** static functions */ static void FieldDump (FILE *file, void *obj); static void FieldInit (void *obj); static void FieldKill (void *obj); static FILE *outFile=NULL; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** default function for printing lines */ static INT4 CDSPrintF (char *formatStr, ...) { va_list ap; va_start (ap, formatStr); vfprintf (outFile, formatStr, ap); va_end (ap); if (formatStr[strlen (formatStr) -1] != '\n') fprintf (outFile, "\n"); return 1; } /**api* FieldCopyList ********************************************************* ** ** gets a new initialized feature object; ** ** INPUT: pointer to address of feature object [W] ** pointer to buffer object [R] ** IMPLICIT: ** ** RETURNS: */ INT4 FieldCopyList (FIELDo **fieldList, SMoBUFF *field) { static INT4 fieldClass_id=0; char name[40]; int rv=0; if (!fieldClass_id) LstManageClassFlex (&fieldClass_id, sizeof(FIELDo), FieldInit, FieldKill, FieldDump); rv = LstNew ((void**) fieldList, fieldClass_id); (*fieldList)->buff = BuffDuplicate (field); /* get the first word after the line code: feature name or reference no */ *name = '\0'; /* reset name */ sscanf (field->buff, "%*[^ ] %s", name); if (name[strlen(name)-1] == ';') name[strlen(name)-1] = '\0'; /* remove ; at the end */ LstChangeObjectName(*fieldList, name); return rv; } /****** FieldDump *********************************************************** ** ** dumps all information belonging to the specified object. ** This is the print function set through LstManageClass ** for ftstype objects (see FtsNew). ** ** INPUT: address of an object [R] ** IMPLICIT: ** ** RETURNS: nothing */ static void FieldDump (FILE *file, void *obj) { FIELDo *tmp = (FIELDo*)obj; if (tmp->buff) BuffPrint (file, tmp->buff); } /****** FieldInit ********************************************************** ** ** initializes the specified object. ** This is the init function set through LstManageClass ** for ftstype objects (see FtsNew). ** ** INPUT: address of an object [R] ** IMPLICIT: ** ** RETURNS: nothing */ static void FieldInit (void *obj) { FIELDo *tmp = (FIELDo*) obj; tmp->buff = NULL; } /****** FieldKill ********************************************************** ** ** deletes the specified object. ** This is the delete function set through LstManageClass ** for ftstype objects (see FtsNew). ** ** INPUT: address of an object [R] ** IMPLICIT: ** ** RETURNS: nothing */ static void FieldKill(void *obj) { FIELDo *tmp = (FIELDo*) obj; if (tmp->buff) BuffDelete(tmp->buff); } INT4 CheckTranslationErrors (char *pseq) { INT4 trerr=0; for ( ; *pseq; pseq++) if (*pseq == '*') trerr++; return trerr; } INT4 PrintMessage (MSGo *msg) { if (msg->msg_code == i__readingname) putc ('.', stderr); switch (msg->msg_code) { case i__wroteset: return 0; default: if (msg->msg_t != MSGxINFO) fprintf (stderr, "ERROR: %s, %s\n", msg->primsg, msg->secmsg); else fprintf (stderr, "%s\n", msg->secmsg); return 1; } } static INT4 PrintLine (char *formatStr, ...) { va_list ap; va_start (ap, formatStr); vfprintf (stderr, formatStr, ap); va_end (ap); if (formatStr[strlen (formatStr) -1] != '\n') fprintf (stderr, "\n"); return 1; } /****** TremblErrorPrint ****************************************************** ** ** prints information about entry that was rejected; ** ** INPUT: address of an entry object [R] ** IMPLICIT: ** ** RETURNS: nothing */ static void TremblErrorPrint (CDSoSTORE *val) { INT4 featureNumber=0; char id[20]="", accno[20]=""; LstFirst((void**) &val->protSeq); /* print first translation */ /* ** get the entry-ID and accession number ** and print the ID line and the link to the EMBL parent entry */ sscanf (val->id->buff, "%*[^ ] %[A-Z0-9]", id); sscanf (val->accession->buff, "%*[^ ] %[A-Z0-9]", accno); LstGetPosition((void*)val->features, &featureNumber); featureNumber++; /* 1 .. n */ if (val->protSeq) fprintf(stderr, "\nID %s_%d standard; PRT; %d AA.\n", accno, featureNumber, val->protSeq->len); else fprintf(stderr, "\nID %s_%d standard; PRT; 0 AA.\n", accno, featureNumber); fprintf(stderr, "DR EMBL; %s; %s.\n", accno, id); /* ** print "definition", "organism", "CDS-feature" data-fields */ fprintf(stderr, "%s", val->definition->buff); fprintf(stderr, "%s", val->organism->buff); fprintf(stderr, "%s", val->features->buff->buff); /* print current feature */ /* ** some error statement and both DNA and protein sequences */ fprintf(stderr, "CC ERROR: no valid translation with table \"%s\"\n", geneticCodeTable[val->genCode - 1]); if (val->protSeq && val->resultSeq && val->feature) { char *start, *curr, *illegal_codon; start = curr = val->protSeq->seq; fprintf(stderr, "CC REASON: "); while (curr = strchr(curr, (int)'*')) { illegal_codon = val->resultSeq->seq + (curr-start)*3 + val->feature->codonStart - 1; fprintf(stderr, " '%.3s'", illegal_codon); curr++; /* skip '*' */ } fprintf(stderr, " is an illegal codon\n"); } SeqWriteEMBL (val->protSeq, val->entry->entry_nm, PrintLine); SeqWriteEMBL (val->resultSeq, val->entry->entry_nm, PrintLine); } /****** TremblPrint ********************************************************** ** ** Prints TREMBL entry; ** ** INPUT: address of an entry object [R] ** number of CDS feature in entry [R] ** IMPLICIT: ** outFile (FILE *) [W} ** ** RETURNS: nothing */ static void TremblPrint (CDSoSTORE *store, int cdsN) { FILE *file; static SMoBUFF *buff=NULL; char id[20]="", accno[20]=""; char refName[20]="", fileName[200], *tmp; INT4 rv; sscanf (store->id->buff, "%*[^ ] %[A-Z0-9]", id); /* ** Open output file: one file for each entry, or only a single file ** or stdout. */ if (ParGetNum ("printSeparateFiles")) { sprintf (fileName, "%s_%d.seq", id, cdsN); file = FilOpenW (fileName, &rv); _ErrExit2 (rv, fileName); } else if ((tmp = ParGetStr ("outputFileName")) && *tmp) { if (!outFile) { file = FilOpenW (tmp, &rv); _ErrExit2 (rv, tmp); } else file = outFile; } else file = stdout; /* print to stdout */ if (!buff) buff = BuffNew (100); if (!store->protSeq->len) return; /* ** print the ID line: accession number with the feature number ** appended, a DR line that links to the parent EMBL entry */ sscanf (store->id->buff, "%*[^ ] %[A-Z0-9]", id); sscanf (store->accession->buff, "%*[^ ] %[A-Z0-9]", accno); /* LstGetPosition ((void*)store->features, &featureNumber); featureNumber++;*/ /* 1 .. n */ fprintf (file, "ID %s_%d standard; PRT; %d AA.\n", id, cdsN, store->protSeq->len); fprintf (file, "AC %s;\n", accno); fprintf (file, "DR EMBL; %s; %s.\n", accno, id); /* ** print the DE line ...but the DE from DNA entry at the end! ** print some selected qualifiers from the feature first */ BuffReset (buff); if (BuffLength (store->feature->gene)) BuffPrintF (buff, "gene: %s; ", BuffGetPtr (store->feature->gene)); if (BuffLength (store->feature->product)) BuffPrintF (buff, "product: %s; ", BuffGetPtr(store->feature->product)); /* if (BuffLength (store->feature->note)) BuffPrintF (buff, "note: %s; ", BuffGetPtr(store->feature->note)); */ BuffCollapse (buff); fprintf (file, "%s\n", BuffFormat (buff, 80, 0, 0, "DE ")); BuffPrint (file, store->definition); if (!BuffLength (store->feature->gene) && !BuffLength (store->feature->product) && !BuffLength (store->feature->note)) BuffCopyString (buff, "unnamed ORF;"); BuffPrint (file, store->organism); /* ** print literature references if explicitly listed by "citation" ** qualifier in the feature annotation */ if (store->feature->citation) { LstFirst((void**)&store->feature->citation); do { sprintf(refName, "[%d]", store->feature->citation->citationNum); if (LstFirstNamed ((void**)&store->references, refName)) LstPrint (file, (void*)store->references); else printf("CC ERROR: reference *%s* not found.\n", refName); } while (LstNext((void**)&store->feature->citation)); } LstPrint (file, (void*)store->features); /* print current feature */ /* ** print additional information obtained during evaluation of the ** feature and some warnings */ fprintf (file, "CC translated using genetic code table \"%s\"\n", geneticCodeTable[store->genCode - 1]); if (store->feature->codonStartShifted > 0) fprintf (file, "CC Warning: codon start shifted by %d\n", store->feature->codonStartShifted); if (global_before_f < 0) { fprintf (file, "CC Warning: illegal start codon\n"); cnt_firstcodonerror++; } else cnt_correct++; outFile = file; SeqWriteEMBL (store->protSeq, store->entry->entry_nm, CDSPrintF); if (ParGetNum ("printSeparateFiles")) fclose (file); } /****** TaxaToTranslTable ***************************************************** ** ** Searches various taxa (case insensitive) to find the appropriate ** translation table; ** ** INPUT: address of buffer with organism source information ** IMPLICIT: ** ** RETURNS: the translation table id number */ INT4 TaxaToTranslTable (SMoBUFF *org) { if (BuffSearch(org,"Protozoa") && BuffSearch(org,"Cili") && !BuffSearch(org,"Mitoch")) return 6; if (BuffSearch(org,"Mitochond") && BuffSearch(org,"Yeast")) return 3; if (BuffSearch(org,"Mitochond") && (BuffSearch(org,"Podospora") || BuffSearch(org,"Protozoa"))) return 7; if (BuffSearch(org,"Mitochond") && (BuffSearch(org,"Vertebrata") || BuffSearch(org,"Mammalia"))) return 2; if (BuffSearch(org,"Mitochond") && BuffSearch(org,"Echinoderm")) return 9; if (BuffSearch(org,"Mitochond")) return 5; return 1; /* default table */ } /****** CDSTranslate ********************************************************* ** ** INPUT: entry store [W] ** IMPLICIT: ** ** RETURNS: */ INT4 CDSTranslate (CDSoSTORE *store) { INT4 i, trerr=1; for (i=0; i<=2; i++) { if (SeqTranslate(store->resultSeq, &store->protSeq, store->feature->codonStart+i, store->feature->codon, store->feature->transl_except, store->genCode - 1)) { trerr = CheckTranslationErrors(store->protSeq->seq); if (!trerr) break; } } if (trerr) return 0; store->feature->codonStartShifted = i; return 1; } /****** CDSStoreInit ********************************************************** ** ** INPUT: entry store [W] ** entry [R] or NULL ** IMPLICIT: ** ** RETURNS: */ CDSStoreInit (CDSoSTORE *store, ENTRYo *entry) { if (!entry) { store->id = BuffNew(20); store->accession = BuffNew(20); store->definition = BuffNew(20); store->organism = BuffNew(20); store->featureCurr = BuffNew(20); store->refCurr = BuffNew(20); store->links = NULL; store->features = NULL; store->references = NULL; store->entrySeq = NULL; store->resultSeq = NULL; store->protSeq = NULL; store->feature = NULL; /* feature description */ store->genCode = 1; /* id of default translation table */ } else { store->entry = entry; BuffReset(store->id); BuffReset(store->accession); BuffReset(store->definition); BuffReset(store->organism); BuffReset(store->featureCurr); BuffReset(store->refCurr); if (store->links) LstDeleteAll((void**)&store->links); if (store->features) LstDeleteAll((void**)&store->features); if (store->references) LstDeleteAll((void**)&store->references); if (store->entrySeq) LstDeleteAll((void**)&store->entrySeq); if (store->resultSeq) LstDeleteAll((void**)&store->resultSeq); if (store->protSeq) LstDeleteAll((void**)&store->protSeq); store->feature = NULL; /* feature description */ store->genCode = 1; /* id of default translation table */ } } /****** CDSStoreEntry ********************************************************* ** ** INPUT: entry store [W] ** entry [R] or NULL ** IMPLICIT: ** ** RETURNS: */ CDSStoreEntry (CDSoSTORE *store, ENTRYo *entry) { SMoBUFF *buff = NULL; SLBoFIELD *field; char *name, *ln; while ((field = EntryToNextField (entry))) { name = LibGetFieldName (field); buff = NULL; if (SmEqs(name, "ID")) buff = store->id; else if (SmEqs(name, "Accession")) buff = store->accession; else if (SmEqs(name, "Definition")) buff = store->definition; else if (SmEqs(name, "Organism")) buff = store->organism; else if (SmEqs(name, "RefNumber")) { buff = store->refCurr; if (!BuffIsEmpty (buff)) FieldCopyList (&store->references, buff); BuffReset (buff); } else if (SmEqs(name, "Authors")) buff = store->refCurr; else if (SmEqs(name, "Title")) buff = store->refCurr; else if (SmEqs(name, "Reference")) buff = store->refCurr; else if (SmEqs(name, "Features")) { buff = store->featureCurr; } if (buff) { while ((ln = EntryFieldNextLine(entry))) BuffCopyString (buff, ln); if (buff == store->featureCurr) { FieldCopyList (&store->features, buff); BuffReset (buff); } } else EntrySkipField (entry); } /* save the last reference in entry */ if (!BuffIsEmpty (store->refCurr)) FieldCopyList (&store->references, store->refCurr); } /****** CDSMakeEntry ********************************************************** ** ** INPUT: entry store [W] ** entry [R] ** file position [R] ** number of CDS feature in entry [R] ** IMPLICIT: ** ** RETURNS: */ CDSMakeEntry (CDSoSTORE *store, ENTRYo *entry, FILoL_S *fileSave, int cdsN) { INT4 rv=0; if (store->resultSeq) LstDeleteAll((void**)&store->resultSeq); if (store->protSeq) LstDeleteAll((void**)&store->protSeq); store->feature = NULL; store->genCode = 1; /* id of default translation table */ store->errorMessage = NULL; global_before_f = 0; /* reset flag for next feature */ rv = SlbMakeFeature (store->features->buff, entry, store->entrySeq, &store->resultSeq, &store->feature); FilUBack (entry->file[1], fileSave); if (!rv) return 0; if (_ErrIs (rv) && (rv != e__operatorafternotallowed && rv != e__operatorbeforenotallowed)) { _ErrMsg (rv); cnt_syntaxerror++; return 0; } if (store->feature->isPseudo) /* pseudo gene */ return 0; /* ** if the sequence - for some reason - is not empty, then do the ** translation and, if all is correct, print the ** TREMBL entry, otherwise an error report */ if (!store->resultSeq) return 0; store->genCode = TaxaToTranslTable(store->organism); if (store->feature->codeTableNum>0) /* transl_table = .. */ if (store->genCode != store->feature->codeTableNum) { fprintf(stderr, "\nCC WARNING: used code table id %d instead of %d\n", store->feature->codeTableNum, store->genCode); store->genCode = store->feature->codeTableNum; } if (CDSTranslate (store)) { TremblPrint (store, cdsN); /* print value structure */ return 0; } else { TremblErrorPrint (store); /* print value structure */ cnt_trerr++; return 0; } return 1; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** main section... */ int main (int argc, char **argv) { ARGoLIST *arglist; SLBo *lib; ENTRYo *entry; CDSoSTORE store; INT4 n=0, cdsN; char *libraryName, *fileName; FILoL_S fileSave; SrsEnv (); LibOpen ("srswin"); MsgSetFnct (PrintMessage); CDSStoreInit (&store, NULL); /* ** process command line */ arglist = (ARGoLIST *) LibObjByName ("arglist", "trembl"); argc = ArgGet (arglist, argc, argv); libraryName = ParGetStr ("libName"); if (!(lib = (SLBo *) LibObjByName ("library", libraryName))) _ErrExit3 (e__objectunknown, "library", libraryName); /* ** if a file name is specified then supersede the one defined ** in ODD */ if (*(fileName = ParGetStr ("tremblInFile"))) { char dirName[80], name[80]; FilParse (fileName, dirName, FILxDEST); /* strcat (dirName, "/"); */ /* must be added */ FilParse (fileName, name, FILxNAME); LibSetFlatFileDir (lib, dirName); LibSetFlatFileName (lib, name); } /* ** open databank and iterate over all entries */ entry = EntryOpenStream (lib); while (EntryNext (entry)) { CDSStoreInit (&store, entry); if (SlbNextSequence (entry)) { SlbGetSequence (entry, &store.entrySeq); FilUSave (entry->file[1], &fileSave); } CDSStoreEntry (&store, entry); /* ** if the entry has any features, iterate and process CDS ** features */ if (store.features) { cdsN = 0; LstFirst ((void**) &store.features); do { if (!strncmp (store.features->name, "CDS", 3)) CDSMakeEntry (&store, entry, &fileSave, ++cdsN); } while (LstNext ((void**) &store.features)); } /* print progress */ if (!(++n % 1000)) fprintf(stderr, "...%d\n", n); } /* ** print final report if not translating a single file */ if (!*ParGetStr ("tremblInFile")) { fprintf (stderr, "\n********* Program correctly finished ******\n\n"); fprintf (stderr, "syntax errors: %d\n", cnt_syntaxerror); fprintf (stderr, "translation errors: %d\n", cnt_trerr); fprintf (stderr, "illegal start codon: %d\n", cnt_firstcodonerror); fprintf (stderr, "correct: %d\n", cnt_correct); } exit(0); } ) fprintf(stderr, "...%d\n", n); } /* ** print final report if not translating a single file */ if (!*ParGetStr ("tremblInFile")) { fprintf (stderr, "\n********* Program correctly finished ******\n\n"); fprintf (stderr, "synsrs/src/try.c #include #include #include #include "srs.h" #include "odd.h" #define _INITOBJS #define _CONSTANTS #define _SDL #define _FUNCTION #include "oddclass.h" ICAoSYNTAX *IcaInitSyntax (ICAoSYNTAX *); static INT4 PrintMessage (MSGo *msg); void ReadBuiltin (ICAoSYNTAX *syntax) { FILEo *file; ICAoJOB *job; SDLo *odd; Int4 opt; /* never write C-conversion */ opt = ParGetBool("ica2C"); ParDefBool("ica2C", 0); ParDefBool ("doSection", 1); /* pointers instead of numbers */ job = IcaCreateJob (syntax); /* process class information */ odd = OddInit (def, 1); file = FileNew ("SRSSDL:builtin.ic"); if (!FileOpen (file)) _ErrExit2 (e__filnotok, "SRSSDL:builtin.ic"); IcaNewJob (job, file, NULL); IcaGetTokenList (job, "prog"); IcaEndJob (job); VarExec (job->prog); /* process objects */ odd = OddInit (odd, 2); file = FileNew ("SRSSDL:builtin.i"); if (!FileOpen (file)) _ErrExit2 (e__filnotok, "SRSSDL:builtin.i"); IcaNewJob (job, file, NULL); IcaGetTokenList (job, "prog"); IcaEndJob (job); FileClose (job->file); job->file = NULL; VarExec (job->prog); ParDefBool ("ica2C", opt); } main(int argc, char **argv) { SDLo *odd; ARGoLIST *arglist; FILEo *file; ICAoJOB *job; ICAoSYNTAX *syntax; char line[MAXLINESIZE], *tokStr, *name; INT4 printAll, tokCode, c, rv; SrsEnv (); LibOpen ("srs5"); MsgSetFnct ((FUNC)IcaPrintMessage); arglist = LibObjByName ("arglist", "try"); argc = ArgGet (arglist, argc, argv); if (!ParGetBool ("useIni")) syntax = IcaInitSyntax ((ICAoSYNTAX*)LibObjByName ("syntax", "icarus")); else syntax = (ICAoSYNTAX*)LibObjByName ("syntax", "icarus"); odd = OddInit (def, 1); if (ParGetBool ("doCommandInfo")) { IargPrintInfo (); exit (0); } if (argc != 2) { ArgUsage (arglist); _ErrorExit (); } job = IcaCreateJob (syntax); file = FileNew(argv[1]); if (!FileOpen (file)) _ErrExit2 (e__filnotok, argv[1]); IcaNewJob (job, file, NULL); IcaGetTokenList (job, "prog"); IcaEndJob (job); FileClose (job->file); job->file = NULL; if (job->prog) { if (ParGetBool ("readBuiltin")) ReadBuiltin (syntax); VarExec (job->prog); } if (ParGetBool ("doClassInfo")) { odd = OddInit (odd, 2); OddWriteClassInfo (odd); } } sage (arglist); _ErrorExit (); } job = IcaCreateJob (syntax); srs/src/tryblub.c #include "strv.h" #include "blub.h" #include "objstream.h" typedef struct TRYOBJ { OBJo head; int a; STRv b; struct TRYOBJ* part; } TRYOBJ; typedef struct TRYMORE { TRYOBJ head; STRv more; ListAttr list; int arr[10]; } TRYMORE; int main() { TRYOBJ* o=ObjCpy(Object); TRYOBJ* o1; TRYMORE* o2; void* streamList,**streamElem; void *r1, *r2, *r3,*a1; AttrIter ai; Iter i; int* list; OBJpStream s; ObjInit(); ObjAttrNew(&o, StrTemp("a"), int)=3; ObjAttrNew(&o, StrTemp("b"), STRv)=StrCpyS("ciao"); ObjAttrNewRef(&o, StrTemp("part"),TRYOBJ*)=NULL; ObjPrint(o); printf("\n"); ObjMakeClass(o,StrTemp("TRYOBJ")); o1=ObjCpy(o); ObjChange(&o1,TRYOBJ*); o1->part=ObjCpy(o); ObjChange(&ObjChange(&o1, TRYOBJ*)->part, TRYOBJ*)->a=10; o1->a=5; StrSetS(&o1->b,"containing"); o2=ObjCpy(o1); ObjAttrNew(&o2,StrTemp("more"),STRv)=StrCpyS("someMore"); list=&ObjListNew(&o2,4,int); *list++=1; *list++=2; *list++=3; *list++=4; ObjDebug(o); ObjDebug(o1); ObjDebug(o2); ObjMakeClass(o2,StrTemp("TRYMORE")); ObjListApp(&o2,int)=6; ObjListApp(&o2,int)=7; ObjDebug(o2); ObjListCut((void**)&o2,ObjListWith(o2,1),3); ObjDebug(o2); /* try access by name */ printf("%d %s\n", ObjAttr(o,StrTemp("a"),int), Str(ObjAttr(o,StrTemp("b"),STRv))); printf("%d %s\n", ObjAttr(o1,StrTemp("a"),int), Str(ObjAttr(o1,StrTemp("b"),STRv))); printf("%d %s\n", ObjAttr(o2,StrTemp("2"),int), Str(ObjAttr(o2,StrTemp("more"),STRv))); /* attribute iteration */ printf("iterating:\n"); for (ai=ObjAttrFirst(o2); ai; ObjAttrNext(o2,&ai)) { STRv name=ObjAttrName(o2,ai); printf("%s\n",Str(name)); StrDel(name); } /* testing list iteration */ printf("list:\n"); for (i=ObjListFirst(o2);i;ObjListNext(o2,&i)) { printf("%i:%i\n",ObjListPos(o2,i),ObjListIn(i,int)); } printf("%d",ObjListCard(o2)); /* try stream output */ streamList=ObjCpy(Object); streamElem=&ObjListNew(&streamList,3,OBJv); *streamElem++=ObjCpy(o); *streamElem++=ObjCpy(o1); *streamElem++=ObjCpy(o2); printf("\n-----------------saving\n"); ObjDebug(o); ObjDebug(o1); ObjDebug(o2); s=ObjStreamOpen("blabla","wb"); ObjStore(streamList, s); /*ObjStore(o1, s); ObjStore(o2, s);*/ ObjStreamClose(s); ObjDel(streamList); streamList=NULL; /* try stream input */ s=ObjStreamOpen("blabla","rb"); ObjSet(&streamList,ObjLoad(s)); /*ObjSet(&o, ObjLoad(s)); ObjSet(&o1, ObjLoad(s)); ObjSet(&o2, ObjLoad(s));*/ ObjStreamClose(s); ObjDebug(streamList); /*ObjDebug(o1); ObjDebug(o2);*/ /* release everything */ ObjDel(streamList); ObjDel(o); ObjDel(o1); ObjDel(o2); return 0; } treamList, s); /*ObjStore(o1, s); ObjStore(o2, s);*/ ObjStreamClose(s); ObjDel(streamList); streamList=NULL; /* try stream input */ s=ObjStreamOpen("blabla","rb"); ObjSetsrs/src/unix_map.c char unix_map_srs_ID[] = "$Id: unix_map.c,v 1.5 1996/12/14 16:31:48 etzold Exp $"; /* ** ** $RCSfile: unix_map.c,v $ ** $Revision: 1.5 $ ** $Date: 1996/12/14 16:31:48 $ ** $Author: etzold $ ** ** $Locker: $ ** $State: Exp $ ** ** ** SRS V3.0 Copyright by Thure Etzold ** Unix port: This module has been modified in major parts ** by Lukas Rosenthaler and Reinhard ** ** Author: Thure Etzold ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** Requires: sm, message ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** maps a file to memory and provides functions for ** writing to the file, saving and delteing the mapped ** memory; Either a file can be created with specified ** nr. of blocks or existing file can be extended by ** nr. of blocks. ** before deleting the mapsection the memory is saved to ** the file and the unused space of it is deleted; ** the output file is a ** Two functions for writing are provided for assuring ** that the map section is written to in a sequential ** manner. ** ** map-section-file: ** 1) LF-stream file (C-stream-file) ** 2) first longword contains number of bytes written to file ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include #include "message.h" #include "futil.h" #include "map.h" #define PAGE_SIZE (512*sizeof (char)) #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #define TMPSTR_LEN 256 /***************************************************************************** * * create a map secion. This function is a dummy function which is not used * in the unix version ! It's solely included for compatibilty with the VMS * code. It should be removed later !! * *---------------------------------------------------------------------------- * * Returns : INT4 * success code * * Parameters : * MAPo *m : no meaning * void *buff : no meaning * INT4 buff_z : no meaning * * side effects : none *- ***************************************************************************** */ INT4 MapCreSec (MAPo *m, void *buff, INT4 buff_z) { _ErrRet2 (e__nonounix, "MapCreSec"); return 1; } /***************************************************************************** * * <...> * *---------------------------------------------------------------------------- * * Returns : INT4 * perform page arithmetic * * Parameters : * INT4 a : dividend * INT4 b : divisor * * side effects : none *- ***************************************************************************** */ INT4 MapMOD (INT4 a, INT4 b) { INT4 quot; quot = a/b; return ((a == (quot * b)) ? quot : ++quot); } /***************************************************************************** * * Opens a file and reads it into core memory. The mechanism is read only, * that is, the core memory contents will *NOT* be updated in the file ! * *---------------------------------------------------------------------------- * * Returns : INT4 * success code * * Parameters : * MAPo *m : address of map-descriptor * char *fil_n : address of filename * void *buff : address of buffer or NULL. If NULL is supplied, then * the appropriate amount of core is allocated inside the * routine * INT4 buff_z : amount of core which is to be "mapped". IF "buff" is not * NULL, "buff_z" must *NOT* be larger than the size of the * "buff" ! * * side effects : none *- ***************************************************************************** */ INT4 MapMem (MAPo *m, char *fil_n, void *buff, INT4 buff_z) { char *tmp, t_fil_n[TMPSTR_LEN]; INT4 page_n; INT4 fid, n, nn; strcpy (t_fil_n, fil_n); /* ** open the file, readonly */ if ((fid = open (_FilLN (t_fil_n), O_RDONLY, 0666)) == -1) { _ErrRet (e__filopenerr); } /* ** check, if buffer memory is supplied. If so, pray that it's enough ** memory to hold the data to be read. Otherwise, a friendly core dump... ** If no buffer is supplied, detemine the amount of memory used (given by ** the file size, and allocate the memory. **/ if (buff == NULL) { /* ** get file size */ if ((buff_z = lseek (fid, 0, SEEK_END)) == -1) { _ErrRet2 (e__seekfail, t_fil_n); } /* ** set file pointer back to beginning of file */ if (lseek (fid, 0, SEEK_SET) == -1) { _ErrRet2 (e__seekfail, t_fil_n); } page_n = buff_z / 512 + ((buff_z % 512 > 0) ? 1 : 0); /* ** allocate "page_n" bytes of core */ if ((tmp = (char *) malloc (page_n * PAGE_SIZE)) == NULL) { _ErrRet2 (e__allocfail, "MapMem"); } m->isAllocBuff=1; } else { /* ** calculate the amount of memory. This calculations are remains from ** VMS ... */ page_n = buff_z / 512 + ((buff_z % 512 > 0) ? 1 : 0); m->isAllocBuff=0; tmp = buff; } /* ** now we read in the data from the file, which has been opened ** before, and the file_id is in m->chan... */ m->chan = fid; n = 0; while (n < page_n*PAGE_SIZE) { nn = read (fid, tmp + n, page_n*PAGE_SIZE - n); if (nn == -1) { _ErrRet2 (e__readerr, "MapMem"); } if (nn == 0) { /* EOF detected */ /* ** jump out of loop, we have EOF !! */ goto eof_detected; } n += nn; } eof_detected: if (close ((INT4) m->chan) == -1) { _ErrRet2 (e__filcloseerr, t_fil_n); } /* ** update "m" struct (VMS compatibilty...) */ m->data = tmp; /* pointer to allocated core memory */ m->xbyt = n; /* number of bytes read */ m->wrt_f = FALSE; /* we don't want to write to the file ! */ m->trnc_f = TRUE; /* doesn't matter... */ m->foff = (UINT4 *) m->data; /* m->off = m->data + *(m->foff); not needed and crashes on some sunos */ (void) strncpy (m->filn, t_fil_n, FILxXNAM); return 1; } /***************************************************************************** * * allocates "nbloc" pages (a 512 bytes) of memory and marks them for * "mapping" which means that upon closure/flushing the contents will be * written to a file. * *---------------------------------------------------------------------------- * * Returns : INT4 * success code * * Parameters : * MAPo *m : address of map-descriptor * char *filn : address of filename * INT4 nbloc : number of 512 byte pages which are to be allocated and * marked for mapping * * side effects : none *- ***************************************************************************** */ INT4 MapAlloc (MAPo *m, char *filn, INT4 nbloc) { char *tmp; /* ** allocate "nbloc" pages of memory */ if ((tmp = (char *) malloc (nbloc * PAGE_SIZE)) == NULL) { _ErrRet2 (e__allocfail, "MapAlloc"); } /* ** initialize allocated memory to zero. */ (void) memset (tmp, 0, nbloc*PAGE_SIZE); /* ** update "m" struct (VMS compatibilty...) */ m->data = tmp; m->xbyt = nbloc*PAGE_SIZE; m->trnc_f = TRUE; /* truncate on closure/flushing */ m->wrt_f = TRUE; /* contents of allocated memory is written */ m->off = m->data + 4; m->foff = (UINT4 *) m->data; *(m->foff) = 4; (void) strncpy(m->filn, _FilTempLN (filn), FILxXNAM); return 1; } /***************************************************************************** *+ INT4 MapExtend (MAPo *m, char *filn, INT4 nbloc) *---------------------------------------------------------------------------- * * Description of MapExtend: * * adds "nbloc" 512 byte pages of core to existing "mapped" memory region. * In effect, adding core is done in junks of 64 pages. So "nbloc" is rounded * to be a multiple of 64! * *---------------------------------------------------------------------------- * * Returns : INT4 * success code * * Parameters : * MAPo *m : address of map-descriptor * char *filn : address of filename * INT4 nbloc : number of 512 byte pages to add to existing "mapped" * memory. * * side effects : none *- ***************************************************************************** */ INT4 MapExtend (MAPo *m, char *filn, INT4 nbloc) { INT4 size, orig_size; char *tmp, t_filn[TMPSTR_LEN]; INT4 fid, n, nn; /* ** get size of existing map-file to be extended */ if ((fid = open (_FilLN (filn), O_RDONLY)) == -1) { _ErrRet2 (e__filopenerr, t_filn); } /* ** determine size of file */ if ((size = lseek (fid, 0, SEEK_END)) == -1) { _ErrRet2 (e__seekfail, t_filn); } orig_size = size; /* ** set file pointer back to beginning of file */ if (lseek (fid, 0, SEEK_SET) == -1) { _ErrRet2 (e__seekfail, t_filn); } /* ** calculate new size (multiple of 64 512 byte pages */ size += 64*PAGE_SIZE; size += (MapMOD (nbloc, 64)*PAGE_SIZE); /* add at least nbloc of core */ /* ** */ if ((tmp = (char *) malloc (size)) == NULL) { _ErrRet2 (e__allocfail, "MapExtend"); } n = 0; while (n < orig_size) { if ((nn = read (fid, tmp + n, orig_size - n)) == -1) { _ErrRet2 (e__readerr, "MapExtend"); } if (nn == 0) break; n += nn; } if (close (fid) == -1) { _ErrRet2 (e__filcloseerr, "MapExtend"); } fid = 0; /* ** update map-descriptor with new values */ m->data = tmp; m->trnc_f = TRUE; m->xbyt = size; /* new size */ m->foff = (UINT4 *) m->data; m->off = m->data + *(m->foff); /* m->fid = fid; */ strcpy(m->filn, t_filn); return 1; } /***************************************************************************** *+ INT4 MapFree (MAPo *m) *---------------------------------------------------------------------------- * * Description of MapFree: * * If "mapped" core memory is readonly, then the allocated memory is just * released. Otherwise, the memory content is written to the file with the * filename given in the map-descriptor. Possibly the file is truncated to * the length actually used. This is controlled by the flag "m->trnc_f" of the * map-descriptor. * *---------------------------------------------------------------------------- * * Returns : INT4 * success code * * Parameters : * MAPo *m : address of map-descriptor * * side effects : none *- ***************************************************************************** */ INT4 MapFree (MAPo *m) { INT4 fid; unsigned long n, nn, size; /* ** if "mapped" core memory contents will be written to file, close last ** record by '\n' ! */ if (m->wrt_f) { *(m->off) = '\n'; *(m->off + 1) = '\n'; } /* ** test, if file should be written */ if (m->wrt_f) { /* ** first we have to open the file. We will generate a new file, ** even if a file with the same name already exists ! */ #ifndef dos if ((fid = open (m->filn, (O_WRONLY | O_CREAT | O_TRUNC), 0666)) == -1) { #else if ((fid = open (m->filn, (O_WRONLY | O_CREAT | O_BINARY | O_TRUNC), 0666)) == -1) { #endif _ErrRet2 (e__filopenerr, m->filn); } /* ** let's calculate the number of bytes to write. ** ATTENTION: This code possibly has to be changed: ** to my knowlegde, VMS mapped files are written always ** in PAGE_SIZE junks (also "MapMem" reads PAGE_SIZE junks...). ** ** if the file is to be truncated to the length actually memory has been ** used, then we calculate the file size by the difference of the start ** address and the offset of the last write access to the "mapped" core ** memory. This is possible since all access is (should be !) done by ** routines which update "m->off". */ if (m->trnc_f) { size = (unsigned long) (m->off - m->data) + 1; } else { size = m->xbyt; } n = 0; while (n < size) { if ((nn = write (fid, m->data + n, size - n)) == 0) { _ErrRet3 (e__filwriteerr, m->filn, (size - n)); } n += nn; } /* ** close the file */ if (close (fid) == -1) { _ErrRet2 (e__filcloseerr, m->filn); } } /* ** now we will free the allocated memory */ if (m->isAllocBuff) free (m->data); /* free allocated memory */ m->data = NULL; /* set pointer to NIL */ m->xbyt = 0; /* set size to 0 */ return 1; } /***************************************************************************** *+ INT4 MapTruncate (MAPo *m) *---------------------------------------------------------------------------- * * Description of MapTruncate: * * Truncate a file which was mapped. This function is a dummy function * which is not used in the unix version ! It's solely included for * compatibilty with the VMS code. It should be removed later !! * *---------------------------------------------------------------------------- * * Returns : INT4 * success code * * Parameters : * MAPo *m : address of map-descriptor * * side effects : none *- ***************************************************************************** */ INT4 MapTruncate (MAPo *m) { _ErrRet2 (e__nonounix, "MapTruncate"); return 1; } /***************************************************************************** *+ INT4 MapNew (MAPo *m, UINT4 *fadd) *---------------------------------------------------------------------------- * * Description of MapNew: * * Returns relative section file's address of begin of unused space. * Only MapPutS and MapWrite may be used for writing to the map-section * *---------------------------------------------------------------------------- * * Returns : INT4 * success code * * Parameters : * MAPo *m : address of map-descriptor * UINT4 *fadd : address of address where to put file address (???) * ( too many recursive addresses for me... ;-) ) * * side effects : none *- ***************************************************************************** */ INT4 MapNew (MAPo *m, UINT4 *fadd) { long int ptr_diff; #ifndef dos /* ** the map-memory we return should be aligned at least to the pointer type */ ptr_diff = (long int) m->off % sizeof (char *); if (ptr_diff != 0) { m->off += (sizeof (char *) - ptr_diff); *(m->foff) += (sizeof (char *) - ptr_diff); } #endif *fadd = *(m->foff); return 1; } /***************************************************************************** *+ INT4 MapCNew (MAPoCCH *c, UINT4 *fadd) *---------------------------------------------------------------------------- * * Description of MapCNew: * * Returns relative file address of begin of unused space in cache. * Only MapCWrite may be used for writing to the cache. * *---------------------------------------------------------------------------- * * Returns : INT4 * success code * * Parameters : * MAPoCCH *c : address of cache-descriptor * UINT4 *fadd : address of address where to put file address * (same comment as above...) * * side effects : none *- ***************************************************************************** */ INT4 MapCNew (MAPoCCH *cache, UINT4 *fadd) { #ifdef xxx long int ptr_diff; /* ** the map-memory we return should be aligned at least to the pointer type */ ptr_diff = (long int) cache->off % sizeof (char *); if (ptr_diff != 0) { cache->off += (sizeof (char *) - ptr_diff); *(cache->foff) += (sizeof (char *) - ptr_diff); } #endif *fadd = *(cache->foff); return 1; } /***************************************************************************** *+ INT4 MapPutS (MAPo *m, char *s) *---------------------------------------------------------------------------- * * Description of MapPutS: * * Puts a 0-terminated string at the end of used space in map-section. * map->off and map->foff are updated according to string length. * *---------------------------------------------------------------------------- * * Returns : INT4 * success code * * Parameters : * MAPo *m : address of map-descriptor * char *s : string to add * * side effects : none *- ***************************************************************************** */ INT4 MapPutS (MAPo *m, char *s) { INT4 len; len = strlen(s); if (*m->foff + len + 1 > m->xbyt) return (e__eom); strcpy(m->off, s); m->off = m->off + len + 1; *(m->foff) = *(m->foff) + len + 1; return 1; } /***************************************************************************** *+ INT4 MapWrite (MAPo *m, char *s, INT4 n) *---------------------------------------------------------------------------- * * Description of MapWrite: * * appends "n" bytes to "mapped" core memory * *---------------------------------------------------------------------------- * * Returns : INT4 * success code * * Parameters : * MAPo *m : address of map-descriptor * char *s : address of data to add * INT4 n : number of bytes to add * * side effects : none *- ***************************************************************************** */ INT4 MapWrite (MAPo *m, char *s, INT4 n) { long int ptr_diff; #ifndef dos /* * the map-memory we return should be aligned at least to the pointer type */ ptr_diff = (long int) m->off % sizeof (char *); if (ptr_diff != 0) { m->off += (sizeof (char *) - ptr_diff); *(m->foff) += (sizeof (char *) - ptr_diff); } #endif if (*m->foff + n > m->xbyt) return (e__eom); (void) memcpy(m->off, s, n); m->off += n; *(m->foff) += n; return 1; } /***************************************************************************** *+ INT4 MapMalloc (MAPo *m, INT4 n) *---------------------------------------------------------------------------- * * Description of MapMalloc: * * allocates memory in a "mapped" core memory region. The returned pointer * is aligned to the pointer type (char *). * *---------------------------------------------------------------------------- * * Returns : char * * address of allocated "mapped" memory region * * Parameters : * MAPo *m : address of map-descriptor * INT4 n : number of bytes to reserve * * side effects : none *- ***************************************************************************** */ char *MapMalloc (MAPo *m, INT4 n) { char *off_s; long int ptr_diff; #ifndef dos /* ** the map-memory we return should be aligned at least to the pointer type */ ptr_diff = (long int) m->off % sizeof (char *); if (ptr_diff != 0) { m->off += (sizeof (char *) - ptr_diff); *(m->foff) += (sizeof (char *) - ptr_diff); } #endif if (*(m->foff) + n > m->xbyt) return NULL; off_s = m->off; m->off += n; *(m->foff) += n; return (off_s) ; } /***************************************************************************** * * Description of MapFOpen: * * Open a file for reading/writing * *---------------------------------------------------------------------------- * * Returns : INT4 * success code * * Parameters : * MAPoCCH *c : address of cache-descriptor * INT4 acc_o : access mode (MAPxREAD or MAPxWRITE), is ignored !! * * side effects : none *- ***************************************************************************** */ INT4 MapFOpen (MAPoCCH *cache, INT4 acc_o) { #ifndef dos if ((cache->fid = open (cache->filn, (O_RDWR | O_CREAT), 0666)) == -1) { #else if ((cache->fid = open (cache->filn, (O_RDWR | O_CREAT | O_BINARY), 0666)) == -1) { #endif _ErrRet2 (e__filopenerr, cache->filn); } return 1; } /****** function ************************************************************** ** ** Opens file for block-IO and writes specified number of blocks to ** block offset and closes file. ** ** INPUT: o address of cache-descriptor ** o number of 512 byte pages to write ** o offset in file (in 512 byte pages) where to start ** writing data ** RETURNS: 1: success */ INT4 MapWriteBlk (MAPoCCH *cache, INT4 nbloc, INT4 off) { INT4 size, wtotbytes_n, wbytes_n; if (cache->fid == 0) MapFOpen (cache, MAPxWRITE); /* ** first we skip "off" blocks */ if (off > 0) { if (lseek (cache->fid, (off - 1)*PAGE_SIZE, SEEK_SET) == -1) { _ErrRet2 (e__seekfail, cache->filn); } } /* ** now let's write nbloc * PAGE_SIZE bytes */ size = nbloc * PAGE_SIZE; wtotbytes_n = 0; while (wtotbytes_n < size) { if ((wbytes_n = write (cache->fid, cache->buff + wtotbytes_n, size - wtotbytes_n)) == -1) { _ErrRet3 (e__filwriteerr, cache->filn, (size - wtotbytes_n)); } if (wbytes_n == 0) break; wtotbytes_n += wbytes_n; } return 1; } /***************************************************************************** * * closes file theat was opend for read/update access (for fseek) * writes 1st half of cache to file, shifts 2nd half of cache to begin * and opens file again for read/upd access (no sharing possible); * * REMARK : This routine has *NOT* been undestood. Some more comment would * be appreciated (Dr. L. Rosenthaler, 30-dec-1992). * *---------------------------------------------------------------------------- * * Returns : INT4 * success code * * Parameters : * MAPoCCH *c : addresss of cache-descriptor * * side effects : none *- ***************************************************************************** */ INT4 MapFlush (MAPoCCH *cache) { Int4 shift = cache->hbloc * 512; MapWriteBlk (cache, cache->hbloc+1, cache->fstbloc); (void) memcpy (cache->buff, cache->buff + shift, shift); cache->fstbloc += cache->hbloc; cache->off -= shift; cache->coff = cache->coff + shift; return 1; } /**api* MapCWrite ************************************************************* ** ** appends specified nr. of bytes to end of used cache; ** ** INPUT: cache object [W] ** source buffer [R] ** number of bytes to be written [R] ** ** RETURNS: 1 ** */ INT4 MapCWrite (MAPoCCH *cache, char *s, INT4 n) { memcpy ((void *) cache->off, (void *) s, n); cache->off = cache->off + n; *(cache->foff) = *(cache->foff) + n; if (cache->off > cache->buff + (cache->nbloc - 1) * 512) MapFlush (cache); return 1; } /***************************************************************************** *+ INT4 MapCWriteNA (MAPoCCH *c, char *s, INT4 n) *---------------------------------------------------------------------------- * * Description of MapCWriteNA: * * appned "n" bytes of data to cache region, NOT ALIGNED !!! * *---------------------------------------------------------------------------- * * Returns : INT4 * success code * * Parameters : * MAPoCCH *c : address of cache-descriptor * char *s : address of data to add * INT4 n : number of bytes to add * * side effects : none *- ***************************************************************************** */ INT4 MapCWriteNA (MAPoCCH *cache, char *s, INT4 n) { (void) memcpy( (void *) cache->off, (void *) s, n); cache->off = cache->off + n; *(cache->foff) = *(cache->foff) + n; if (cache->off > cache->buff + (cache->nbloc - 1) * 512) MapFlush (cache); return 1; } /***************************************************************************** *+ INT4 MapReadBlk (MAPoCCH *c, INT4 nbloc, INT4 off) *---------------------------------------------------------------------------- * * Description of MapReadBlk: * * Opens file for block-IO and reads specified number of blocks from * block offset and closes file. * *---------------------------------------------------------------------------- * * Returns : INT4 * success code * * Parameters : * MAPoCCH *c : address of cache-descriptor * INT4 nbloc : number of 512 byte pages to read * INT4 off : offset (in 512 byte pages) where to start reading * (first block is equal 1 !!) * * side effects : none *- ***************************************************************************** */ INT4 MapReadBlk (MAPoCCH *c, INT4 nbloc, INT4 off) { INT4 size, n, nn; size = nbloc * PAGE_SIZE; if (c->fid == 0) MapFOpen (c, MAPxWRITE); /* ** first we skip "off" blocks */ if (off > 0) { if (lseek (c->fid, (off - 1)*PAGE_SIZE, SEEK_SET) == -1) { _ErrRet2 (e__seekfail, c->filn); } } /* ** now let's read nbloc*PAGE_SIZE bytes */ size = nbloc * PAGE_SIZE; n = 0; while (n < size) { if ((nn = read (c->fid, c->buff + n, size - n)) == -1) { _ErrRet2 (e__readerr, c->filn); } if (nn == 0) break; n += nn; } return 1; } void *MapCacheBuff (char *option, void *buff, Int4 size) { static int freeN=0, allocN=0; static void *freeList=NULL; void *tmp; if (option[0] == 'a') /* alloc */ { allocN++; if (freeList) { buff = freeList; freeList = *(void **) buff; } else { if (!(buff = (char *) malloc (size))) _ErrExit2 (e__allocfail, "cache buffer"); } return buff; } else if (option[0] == 'f') { freeN++; tmp = freeList; freeList = buff; *(void **) buff = tmp; } else if (option[0] == 'p') printf ("alloc: %d, free: %d\n", allocN, freeN); } /***************************************************************************** * * initialize cache, that is allocate memory, open files etc. . * MAPoCCH->foff must be set before calling (0 = no existing file) * *---------------------------------------------------------------------------- * * Returns : INT4 * success code * * Parameters : * MAPoCCH *c : address of cache-descriptor * char *fil_nm : filename * unsigned *foff : address of offset in file * INT4 new_f : flag. If set, a new file will be opened * * side effects : none *- ***************************************************************************** */ INT4 MapInitCache (MAPoCCH *cache, char *fil_nm, unsigned *foff, INT4 new_f) { INT4 nbloc; if ((cache->filn = (char *) malloc (strlen(_FilTempLN (fil_nm)) + 1))==NULL){ _ErrRet2 (e__allocfail, "cache buffer"); } (void) strcpy (cache->filn, _FilTempLN (fil_nm)); cache->foff = foff; if (new_f) *foff = 0; cache->hbloc = MapMOD (cache->nbloc, 2); cache->nbloc = cache->hbloc * 2; /* even number */ cache->buff = MapCacheBuff ("alloc", NULL, cache->nbloc*512); cache->fid = 0; if (*(cache->foff) == 0) { cache->new_f = TRUE; cache->off = cache->buff; cache->fstbloc = 1; cache->coff = 0; } else { cache->new_f = FALSE; nbloc = MapMOD(*(cache->foff), 512); if ((cache->fstbloc = nbloc - cache->hbloc + 1) <= 1) { cache->fstbloc = 1; cache->coff = 0; } else { nbloc = cache->hbloc; cache->coff = NULL; cache->coff = cache->coff + cache->fstbloc-1 * 512; } cache->off = cache->buff + (*cache->foff - cache->coff); MapReadBlk (cache, nbloc, cache->fstbloc); } return 1; } /***************************************************************************** * * flushes cache to file and frees allocated memory * *---------------------------------------------------------------------------- * * Returns : INT4 * sucess code * * Parameters : * MAPoCCH *c : address of cache-descriptor * * side effects : none *- ***************************************************************************** */ INT4 MapCloseCache (MAPoCCH *cache) { INT4 nbloc; nbloc = MapMOD (*(cache->foff) - cache->coff, PAGE_SIZE); MapWriteBlk (cache, nbloc, cache->fstbloc); /* ** close file...set file descriptor to 0 to indicate that cache has been ** deleted and free allocated memory */ if (close (cache->fid) == -1) { _ErrRet2 (e__filcloseerr, cache->filn); } cache->fid = 0; free (cache->filn); MapCacheBuff ("free", cache->buff, 0); return 1; } /****** function ************************************************************* ** ** Read a cache file into a private area of core memory. ** ** INPUT: file name [R] ** pointer to address of allocated memory [W] ** ** RETURNS: 1: success */ INT4 MapRdMem (char *fil_nm, void **p) { MAPoCCH *c; char *data; INT4 n, nn, size; /* allocate cache struct */ if ((c = (MAPoCCH *) calloc (1, sizeof (MAPoCCH))) == NULL) { _ErrRet2 (e__allocfail, "MapRdMem"); } c->fid = 0; if ((c->filn = (char *) malloc (strlen (_FilTempLN (fil_nm)) + 1)) == NULL) { _ErrRet2 (e__allocfail, "MapRdMem"); } /* open file */ (void) strcpy (c->filn, _FilTempLN (fil_nm)); MapFOpen(c, MAPxREAD); /* determine size of file*/ if ((size = lseek (c->fid, 0, SEEK_END)) == -1) { _ErrRet2 (e__seekfail, c->filn); } /* set file pointer back to beginning of file */ if (lseek (c->fid, 0, SEEK_SET) == -1) { _ErrRet2 (e__seekfail, c->filn); } /* allocate core memory to hold file contents */ if ((data = (char *) malloc (size)) == NULL) { _ErrRet2 (e__allocfail, "MapRdMem"); } *p = data; n = 0; while (n < size) { if ((nn = read (c->fid, data + n, size - n)) == -1) { _ErrRet2 (e__readerr, c->filn); } if (nn == 0) break; n += nn; } if (close (c->fid) == -1) { _ErrRet2 (e__filcloseerr, c->filn); } c->fid = 0; free (c->filn); return 1; } /***************************************************************************** * * write a 4 byte integer to a specified location in file * *---------------------------------------------------------------------------- * * Returns : INT4 * success code * * Parameters : * MAPoCCH *c : address of cache-descriptor * UINT4 fadd : offset in file where to wwrite integer * UINT4 val : integer to write to file * * side effects : none *- ***************************************************************************** */ INT4 MapCUpdate (MAPoCCH *c, UINT4 fadd, char *fip) { /* ** set file pointer at position given by "fadd" */ if (lseek (c->fid, fadd, SEEK_SET) == -1) { _ErrRet2 (e__seekfail, c->filn); } /* ** now write 4 bytes */ if (write (c->fid, fip, 4) != 4) { _ErrRet3 (e__filwriteerr, c->filn, 4); } return (1); } /***************************************************************************** * * Translates relative byte offset in file into cache address if referring * to location in cache. * *---------------------------------------------------------------------------- * * Returns : INT4 * success code * * Parameters : * MAPoCCH *c : address of cache-descriptor * UINT4 fadd : offset in file * UINT4 *ptr : address in cache memory * * side effects : none *- ***************************************************************************** */ INT4 MapInCache (MAPoCCH *c, UINT4 fip, void **ptr) { if (fip < c->coff) { return 0; } else { *ptr = fip - c->coff + c->buff; } return 1; } /**api* MapDuplicateOverlap *************************************************** ** ** Addresses that need updating may be exactly on the boundary between ** file and memory cache ...in that case both locations need updating. ** This function updates in the cache only those bytes that overlaps. ** ** INPUT: address of IDS-file object [R] ** file pointer to first ID in the list [W] ** IMPLICIT: ** ** RETURNS: length of overlap ** 0 if no overlap exists */ INT4 MapDuplicateOverlap (MAPoCCH *cache, UINT4 fip, void *buff, INT4 size) { INT4 overlapLen; overlapLen = size - (cache->coff - fip); if ((cache->coff > fip) && overlapLen > 0) { memcpy (cache->buff, (char *) buff + size - overlapLen, overlapLen); return overlapLen; } else return 0; } ess of IDSsrs/src/variable.c char variable_ID[] = "$Id: variable.c,v 1.23 1997/03/18 22:52:34 srs Exp $"; /* ** $RCSfile: variable.c,v $ ** $Revision: 1.23 $ ** $Date: 1997/03/18 22:52:34 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** Copyright by Thure Etzold ** ** Authors: Thure Etzold ** Anatoly Ulyanov ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387529 ** Email: etzold@embl-heidelberg.de ** ** ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** Description ** =========== ** ** functions for manipulating 'any' objects which are used to build ** the icarus 'execution tree' ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include "message.h" #include "sm.h" #include "strv.h" #include "listv.h" #include "dict.h" #include "variable.h" /* more arguments */ #define _mA 0,0,0,0,0,0,0,0,0,0,0,0 #define _VarHandleTypeEval(x) \ if ((x)->isDelayedType) { \ if (!(x)->isTypeEval) \ VarGetType (x); \ (x)->isTypeEval = 0; \ } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** global and module wide variables */ extern VARoSCOPE *globalScope; static VARo *VarNewIn (VARoSCOPE **scopePtr, char *name); static char *AnyGetTypeName (INT4 type); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** for the variable dictionary */ static void* VarToKey (DictElem* e) { return (*(VARo **)e)->name; } static CLASSoDICT dictClass = { (ValComparer)strequal, (ValHasher)strhash, (KeyAccessor)VarToKey, NULL, 0 }; VARo *VarUnalias (VARo *alias) { if (alias->code == 1) return (alias->v.alias); else if (!alias->isReadFunction) { if (!globalScope) _ErrExit (f__noVarScope); return (VARo*) ((ULONG)globalScope->var + (ULONG)alias->v.alias); } else return (*alias->v.varGet)(alias); } /***** VarGetType ************************************************************* ** ** Return the type of argument variable ** ** INPUT: variable pointer ** IMPLICIT: ** ** RETURNS: the type of argument variable */ char VarGetType (VARo *var) { _VarUnalias(var); if (!var->isTypeEval && var->isDelayedType) { (*var->typeGet)(var,_mA); var->isTypeEval = 1; } return (var->type); } /***** AnyGetTypeName ********************************************************* ** ** Converts a type (list) into a readable string (mainly used for printing ** error messages). ** Function returns the string and make sure that for at least three ** successive calls different bufferes will be used. ** ** INPUT: one or combination of types [R] ** IMPLICIT: ** ** RETURNS: string with readable type name(s) */ static char *AnyGetTypeName (INT4 type) { switch (type) { case VARxSTRING: return "string"; case VARxSTRV: return "strv"; case VARxINT: return "int"; case VARxREAL: return "real"; case VARxOBJECT: return "object"; case VARxLIST: return "list"; case VARxVAR: return "var"; case VARxALIAS: return "alias"; case VARxUNKNOWN: return "unknown"; default: _ErrExit2 (e__unknownoption, "type in VarError"); } } /***** VarError *************************************************************** ** ** Common error message call ** ** INPUT: variable object [R] ** expected variable type [R] ** message line [R] ** ** IMPLICIT: ** ** RETURNS: */ static void VarError(VARo *var, char *type, char *message) { char *name; if (!(name = VarGetName (var))) name = "unnamed"; _ErrExit4 (e__icavartype, message, type, AnyDebugStr (var)); return; } /***** VarDestroy ************************************************************* ** ** Called from the list management functions. Deletes a variable. ** ** INPUT: pointer to the object ** IMPLICIT: ** ** RETURNS: */ void VarDestroy (void *obj) { VARo *tmp = (VARo*)obj; ANYv *list, *e; if (tmp) { if (tmp->type == VARxSTRV && !tmp->isReadFunction) StrDel (tmp->v.strv); else if (tmp->type == VARxSTRING && !tmp->isReadFunction && tmp->v.buff) BuffDelete (&tmp->v.buff); else if (tmp->type == VARxLIST) { DictDestroy (tmp->v.list.index); list = tmp->v.list.val; if (!_ListShared (list)) { for (e=list;etype == VARxSTRV && !tmp->isReadFunction) StrDel (tmp->v.strv); else if (tmp->type == VARxSTRING && !tmp->isReadFunction && tmp->v.buff) BuffDelete (&tmp->v.buff); else if (tmp->type == VARxLIST) { DictDestroy (tmp->v.list.index); list = tmp->v.list.val; _ListDel (list); } free (tmp); } } /***** VarInit **************************************************************** ** ** Called from the list management functions. Initializes a variable. ** ** INPUT: pointer to the object ** IMPLICIT: ** ** RETURNS: */ static void VarInit (void *obj) { VARo *tmp = (VARo*)obj; memset (tmp, 0, sizeof (VARo)); tmp->isTypeEval = 1; } /***** VarReset *************************************************************** ** ** Called from the list management functions. Initializes a variable. ** ** INPUT: pointer to the object ** IMPLICIT: ** ** RETURNS: */ void VarReset (VARo *var) { if (var->type == VARxSTRING && !var->isReadFunction && var->v.buff) BuffDelete (&var->v.buff); if (var->type == VARxSTRV && !var->isReadFunction && var->v.strv) StrDel (var->v.strv); memset (var, 0, sizeof (VARo)); var->isTypeEval = 1; } /***** VarNew **************************************************************** ** ** Creates a new variable object. ** ** INPUT: ** IMPLICIT: ** ** RETURNS: */ VARo *VarNew () { VARo *var; if (!(var = (VARo *) calloc (sizeof(VARo), 1))) _ErrExit2 (e__allocfail, "variable object"); var->isTypeEval = 1; return var; } /**api* function ************************************************************** ** ** Returns the predefined ANY with the empty list value. ** ** RETURNS: static ANY with empty list and dictionary */ ANYv AnyNewList () { static ANYv emptyList=NULL; if (!emptyList) { emptyList = VarNew (); emptyList->type = VARxLIST; emptyList->v.list.val = _ListNew (ANYv, 3); emptyList->v.list.index = DictCreate (&dictClass); } return emptyList; } /***** VarGet ***************************************************************** ** ** Searches for variable with specified name and creates a new one if ** not found. ** ** INPUT: variable object that represents the variable list [W] ** variable name [R] ** IMPLICIT: ** ** RETURNS: address of variable object */ VARo *VarGet (VARoSCOPE **scope, char *name) { Iter i; VARo *var; if (*scope && (i = DictWith ((*scope)->dict, name))) var = DictIn (i, VARo*); else { var = VarNewIn (scope, name); if (!(*scope)->dict) (*scope)->dict = DictCreate (&dictClass); DictSet (&((*scope)->dict), var->name, VARo*) = var; } return var; } /***** VarTemp ***************************************************************** ** ** Returns 1 of 10 variables for temporary use. ** ** INPUT: ** IMPLICIT: ** ** RETURNS: variable for temporary use */ VARo *VarTemp () { static INT4 count=0; static VARo var[10]; VARo *tmp; tmp = &var[ count++ % 10 ]; VarReset (tmp); return tmp; } /***** VarNewIn *************************************************************** ** ** Creates a new variable in the specified scope. ** ** INPUT: scope object [W] ** name of new variable [R] ** IMPLICIT: ** ** RETURNS: initialized variable object */ static VARo *VarNewIn (VARoSCOPE **scopePtr, char *name) { VARoSCOPE *scope; VARo *tmp, *varSave; INT4 initSize = 1000; /* initial size of scope */ /* scope does not yet exist */ if (!*scopePtr) { if (!(scope = (VARoSCOPE *) calloc (sizeof (VARoSCOPE), 1))) _ErrExit2 (e__allocfail, "variable stack"); if (!(scope->var = (VARo *) malloc (sizeof(VARo) * initSize))) _ErrExit2 (e__allocfail, "icarus stack array"); scope->varN = 0; scope->varAllocN = initSize; *scopePtr = scope; } else scope = *scopePtr; /* check if scope can receive a new variable ...grow if not */ if (scope->varN >= scope->varAllocN) { scope->varAllocN *= 2; varSave = scope->var; if ((scope->var = (void *) realloc (scope->var, scope->varAllocN * sizeof (VARo))) == NULL) _ErrExit2 (e__allocfail, "variable scope"); DictOffset (scope->dict, (char *) scope->var - (char *) varSave); } tmp = &scope->var[scope->varN++]; VarInit (tmp); tmp->name = (char *) malloc (strlen (name) + 1); strcpy (tmp->name, name); return tmp; } VARoSCOPE *VarCopyScope (VARoSCOPE *scope) { VARoSCOPE *tmp; INT4 k; if (!scope) return NULL; if (!(tmp = (VARoSCOPE *) calloc (sizeof (VARoSCOPE), 1))) _ErrExit2 (e__allocfail, "variable stack"); if (!(tmp->var = (VARo *) malloc (sizeof(VARo) * (scope->varN+1)))) _ErrExit2 (e__allocfail, "icarus stack array"); memcpy (tmp->var, scope->var, sizeof (VARo) * scope->varN); tmp->varN = scope->varN; tmp->varAllocN = tmp->varN; tmp->dict = DictCreate (&dictClass); for (k=0; k < tmp->varN; k++) DictSet (&(tmp->dict), tmp->var[k].name, VARo*) = &tmp->var[k]; return tmp; } void VarScopeDestroy (VARoSCOPE **scope) { VARoSCOPE *tmp; if (scope && *scope) { tmp = *scope; if (tmp->dict) DictDestroy (tmp->dict); if (tmp->varN) free (tmp->var); free (tmp); *scope = NULL; } } /***** VarSetStr ************************************************************** ** ** xx ** ** INPUT: xx ** IMPLICIT: ** ** RETURNS: xx */ VARo *VarSetStr (VARo *var, char *s) { _VarUnalias(var); if (var->isReadFunction) _ErrExit2 (e__varisreadonly, var->name); if (!var->type) { var->type = VARxSTRING; /* var->v.buff = BuffInit (var->v.buff, 0);*/ } if (var->type == VARxSTRING) { var->v.buff = BuffInit (var->v.buff, 0); BuffCopyString (var->v.buff, s); } else if (var->type == VARxINT) var->v.num = atoi (s); else if (var->type == VARxREAL) var->v.real = atof (s); else if (var->type == VARxSTRV) StrSetS (&var->v.strv, s); else VarError(var, "string/int", "set"); return var; } /**api* function ************************************************************** ** ** Copies the list contained in the second any in the argument list to ** the first. ** ** INPUT: 'any' object [W] ** 'any' object with the list to be copied [R] */ void AnyDeleteList (ANYv list) { _VarUnalias (list); if (list->isReadFunction) return; if (list->type == VARxLIST) { DictDestroy (list->v.list.index); _ListDel (list->v.list.val); list->v.list.index = NULL; list->v.list.val = NULL; } else VarError (list, "list", "delete"); return; } /**api* function ************************************************************** ** ** Copies the list contained in the second any in the argument list to ** the first. ** ** INPUT: 'any' object [W] ** 'any' object with the list to be copied [R] */ void AnySetList (ANYv any, ANYv list) { _VarUnalias (any); _VarUnalias (list); if (any->isReadFunction) _ErrExit2 (e__varisreadonly, any->name); if (!any->type) { any->type = VARxLIST; } if (any->type == VARxLIST) { if (any->v.list.val) AnyDeleteList (any); if (list->isReadFunction) list = (*list->v.listGet)(list,_mA); any->v.list.val = _ListCpy (list->v.list.val); any->v.list.index = DictCopy (list->v.list.index); } else VarError (any, "list", "set"); } /**api* function ************************************************************** ** ** Creates a new ANY with the copy of the list in another ANY. ** If the input ANY is not a list it is appended to the list of the ** output ANY. This allows also normal ANYs to be treated as lists. ** ** INPUT: ANY object containg a list [R] ** ** RETURN: a new ANY object (use VarDestroy after use) */ ANYv AnyListCpy (ANYv list) { ANYv any; _VarUnalias (list); any = VarNew (); any->type = VARxLIST; VarSetName (any, VarGetName (list)); if (!(list->type == VARxLIST)) { AnySetList (any, AnyNewList ()); AnyListApp (any, list); } else { if (list->isReadFunction) list = (*list->v.listGet)(list,_mA); any->v.list.val = _ListCpy (list->v.list.val); any->v.list.index = DictCopy (list->v.list.index); } return any; } INT4 AnyIsWrite (ANYv any) { return any->isWrite; } void AnySetWrite (ANYv any) { any->isWrite = 1; } INT4 VarIsAlias (VARo *var) { return var->type == VARxALIAS ? 1 : 0; } /**api* VarGetAlias ************************************************************** ** ** Returns the aliased variable. ** ** INPUT: alias any object [W] ** scope object [R] ** ** RETURNS: Any object */ VARo *VarGetAlias (VARo *alias, VARoSCOPE *scope) { if (alias->code == 1) return (alias->v.alias); else if (!alias->isReadFunction) { if (!scope) _ErrExit (f__noVarScope); return (VARo*) ((ULONG)scope->var + (ULONG)alias->v.alias); } else return (*alias->v.varGet)(alias); } /**api* VarSetAlias ************************************************************** ** ** Sets an variable with a pointer to a named variable. ** If the variable with the specified name is not found it is newly ** created. An alias is either automatically 'unaliased' or can be ** explicitly unaliased with VarGetAlias. ** ** INPUT: alias any object [W] ** any object which is to be aliased [W] ** scope object [R] */ void VarSetAlias (VARo *alias, VARo *var, VARoSCOPE *scope) { if (!alias->type) { alias->type = VARxALIAS; } if (alias->type == VARxALIAS) { alias->v.alias = (VARo*) ((char *) var - (char *) scope->var); } else VarError(alias, "alias", "set"); } /***** VarSetSubStr *********************************************************** ** ** xx ** ** INPUT: xx ** IMPLICIT: ** ** RETURNS: xx */ void VarSetSubStr (VARo *var, char *s, INT4 len) { _VarUnalias(var); if (!var->type) { var->type = VARxSTRING; var->v.buff = BuffInit (var->v.buff, 0); } if (var->type == VARxSTRING) { BuffReset (var->v.buff); BuffCopyNChar(var->v.buff, s, len); BuffCopyNChar(var->v.buff, "\0", 1); } else VarError(var, "string", "set"); } /***** VarSetReadStr ********************************************************** ** ** xx ** ** INPUT: xx ** IMPLICIT: ** ** RETURNS: xx */ void VarSetReadStr (VARo *var, SMoBUFF *(*getStr)(char *)) { _VarUnalias(var); var->type = VARxSTRING; var->v.buffGet = getStr; var->isReadFunction = 1; } /***** function ************************************************************** ** ** Sets a function to create the list when reading from the variable. ** ** INPUT: 'any' object ** address of function returning a list ** */ void VarSetReadList (VARo *var, VARo *(*listGet)(char *)) { _VarUnalias(var); var->type = VARxLIST; var->v.listGet = listGet; var->isReadFunction = 1; } /***** VarSetReadStr ********************************************************** ** ** xx ** ** INPUT: xx ** IMPLICIT: ** ** RETURNS: xx */ void VarSetReadStrv (VARo *var, STRv (*strVGet)(char *)) { _VarUnalias(var); var->type = VARxSTRV; var->v.strVGet = strVGet; var->isReadFunction = 1; } /***** VarSetReadVar ********************************************************** ** ** Sets a function for evaluating an alias. ** ** INPUT: xx ** IMPLICIT: ** ** RETURNS: xx */ void VarSetReadVar (VARo *var, VARo *(*varGet)(char *)) { _VarUnalias(var); var->type = VARxALIAS; var->v.varGet = varGet; var->isReadFunction = 1; } /***** VarSetReadType ********************************************************* ** ** xx ** ** INPUT: xx ** IMPLICIT: ** ** RETURNS: xx */ void VarSetReadType (VARo *var, void (*getType)(char *)) { _VarUnalias(var); var->type = 0; var->typeGet = getType; var->isDelayedType = 1; var->isTypeEval = 0; } /***** VarSetReadInt ********************************************************** ** ** xx ** ** INPUT: xx ** IMPLICIT: ** ** RETURNS: xx */ void VarSetReadInt (VARo *var, INT4 (*getInt)(char *)) { _VarUnalias(var); var->type = VARxINT; var->v.intGet = getInt; var->isReadFunction = 1; } /***** VarSetReadReal ********************************************************* ** ** xx ** ** INPUT: xx ** IMPLICIT: ** ** RETURNS: xx */ void VarSetReadReal (VARo *var, double (*getReal)(char *)) { _VarUnalias(var); var->type = VARxREAL; var->v.realGet = getReal; var->isReadFunction = 1; } /***** VarSetType ************************************************************* ** ** xx ** ** INPUT: xx ** IMPLICIT: ** ** RETURNS: xx */ void VarSetType (VARo *var, enum VAReTYPE type) { var->type = type; } /**api* function ************************************************************** ** ** Prints summary information about the 'any' object. ** ** INPUT: 'any' object [R] */ void AnyDebug (VARo *var) { STRv s; char *tmp; printf ("name: \"%s\"\n", (tmp=VarGetName (var)) ? tmp : "unknown"); printf ("type: %s\n", AnyGetTypeName (var->type)); if (var->isReadFunction) printf ("evaluate: value\n"); else if (var->isDelayedType) printf ("evaluate: value+type\n"); else printf ("evaluate: no\n"); if (var->type == VARxLIST && var->v.list.val && !var->isReadFunction) { ListPtrDebug ((void**)var->v.list.val); DictDebug (var->v.list.index); } else if (var->type == VARxSTRV || var->type == VARxSTRING) { s = VarGetStrv (var); printf ("string value: |%s|\n", _Str (s)); StrDel (s); } else if (var->type == VARxINT) printf ("string value: |%d|\n", VarGetInt (var)); if (var->lineN) printf ("line no: %d\n", var->lineN); if (var->type == VARxALIAS) { _VarUnalias(var); printf ("-------------------------\naliased ANY:\n"); AnyDebug (var); } } char *AnyDebugStr (ANYv any) { static STRv str=NULL; STRv s; char *tmp; if (!str) str = StrNew (); else StrClear (&str); StrPrintf (&str, "name: \"%s\"", (tmp=VarGetName (any)) ? tmp : "unknown"); StrPrintf (&str, ", type: \"%s\"", AnyGetTypeName (any->type)); if (any->isReadFunction) StrPrintf (&str, ", evaluate: value"); else if (any->isDelayedType) StrPrintf (&str, ", evaluate: value+type"); if (any->type == VARxSTRV || any->type == VARxSTRING) { s = VarGetStrv (any); StrPrintf (&str, ", value: \"%s\"", _Str (s)); StrDel (s); } else if (any->type == VARxINT) StrPrintf (&str, ", value: %d", VarGetInt (any)); if (any->lineN) StrPrintf (&str, ", line No: %d", any->lineN); return _Str (str); } /***** VarDefName ************************************************************* ** ** Sets the name of the variable. String must be allocated outside and ** will not be copied. ** ** INPUT: variable object [W] ** name ** IMPLICIT: ** ** RETURNS: xx */ void VarDefName (VARo *var, char *name) { var->name = (char *) malloc (strlen (name) + 1); strcpy (var->name, name); /* te!!!*/ } /***** VarSetName ************************************************************* ** ** Sets the name of the variable. String must be allocated outside and ** will not be copied. ** ** INPUT: variable object [W] ** name ** IMPLICIT: ** ** RETURNS: xx */ void VarSetName (VARo *var, char *name) { if (var->name) free (var->name); if (name) { var->name = (char *)malloc (strlen (name)+1); strcpy (var->name, name); /*!!!tesafety measure case var gets deleted */ } else var->name = 0; } /***** VarSetFunction ********************************************************* ** ** xx ** ** INPUT: xx ** IMPLICIT: ** ** RETURNS: xx */ void VarSetFunction (VARo *var, FUNC function) { _VarUnalias(var); var->v.operator.function = function; } /***** VarSetInt ************************************************************** ** ** xx ** ** INPUT: xx ** IMPLICIT: ** ** RETURNS: xx */ VARo *VarSetInt (VARo *var, INT4 i) { _VarUnalias (var); if (var->isReadFunction) _ErrExit2 (e__varisreadonly, var->name); if (!var->type) var->type = VARxINT; if (var->type == VARxINT) { var->v.num = i; } else if (var->type == VARxSTRING) { BuffReset (var->v.buff); BuffPrintF (var->v.buff, "%d", i); } else if (var->type == VARxSTRV) { StrClear (&var->v.strv); StrPrintf (&var->v.strv, "%d", i); } else VarError(var, "string/int", "set"); return var; } /***** VarSetReal ************************************************************* ** ** xx ** ** INPUT: xx ** IMPLICIT: ** ** RETURNS: xx */ VARo *VarSetReal (VARo *var, double r) { _VarUnalias (var); if (var->isReadFunction) _ErrExit2 (e__varisreadonly, var->name); if (!var->type) var->type = VARxINT; if (var->type == VARxINT) { var->v.real = r; } else if (var->type == VARxSTRING) { BuffReset (var->v.buff); BuffPrintF (var->v.buff, "%f", r); } else VarError(var, "string/real", "set"); return var; } VARo *VarSetVar (VARo *var, VARo *ptr) { static char className[]="var"; if (!var->type) { var->type = VARxVAR; var->v.object.className = className; } if (var->type == VARxVAR) { var->v.object.ptr = ptr; } else VarError(var, "var", "set"); return var; } VARo *VarGetVar (VARo *var, Int4 doEval) { if (doEval) _VarHandleTypeEval (var); if (var->type == VARxVAR) { return var->v.object.ptr; } else return var; } VARo *VarFreeze (VARo *var) { var->isTypeEval = 1; return var; } /***** VarSetObject *********************************************************** ** ** Sets an object pointer variable. The class name is optional and ** will be used for comparison if available. ** The class name will not be copied and must be allocated by the ** caller. ** ** INPUT: address of class name [R] or NULL ** variable object [W] ** object pointer [R] ** IMPLICIT: ** ** RETURNS: */ VARo *VarSetObject (char *className, VARo *var, void *ptr) { _VarUnalias(var); if (!var->type) var->type = VARxOBJECT; if (var->type == VARxOBJECT) { if (className) { if (var->v.object.className) if (var->v.object.className && !SmEqs (var->v.object.className, className)) _ErrExit4 (e__varwrongclass, var->name, var->v.object.className, className); var->v.object.className = className; } var->v.object.ptr = ptr; } else VarError(var, "object", "set"); return var; } /**api* function ************************************************************** ** ** Iterates over all elements in the list. The context set to 0 starts ** the iteration with the first element. ** If the variable is not a list then the variable itself is returned. ** The next call using the same variable will return a NULL pointer. ** Thus, a list with one element is mimicked. ** ** INPUT: o variable object of "list" type [W] ** o address of void pointer with the address of the ** iterator [W] ** IMPLICIT: ** ** RETURNS: the variable at current list position ** NULL if the list is exhausted */ ANYv AnyNextInList (ANYv list, Int4 *i) { ANYv elem=NULL; _VarUnalias (list); if (*i >= AnyListLen (list)) *i = 0; else elem = list->v.list.val[(*i)++]; return elem; } /**api* function ************************************************************** ** ** Returns the length of the list. ** ** INPUT: ANY object [R] ** ** RETURNS: length of the list */ Int4 AnyListLen (ANYv list) { return _ListLen (list->v.list.val); } /**api* function ************************************************************** ** ** Inserts a new element into a list. Use VarListAddAssoc to insert ** a new element together with the name. ** ** INPUT: the variable representing the list [W] ** the new element to be added [R} */ void AnyListApp (ANYv list, ANYv any) { ANYv *anyPtr,**listVal; _VarUnalias (list); if (!list->type) { AnySetList (list, AnyNewList ()); } if (list->type != VARxLIST) VarError (list, "list", "add"); listVal=&list->v.list.val; _ListApp (listVal)=any; if (any->name) { anyPtr = &DictSet (&list->v.list.index, any->name, ANYv); if (*anyPtr) _ErrExit2 (e__duplicatekey, any->name); else *anyPtr = any; } } /**api* function ************************************************************** ** ** Returns the list element with specified index. Index of 0 returns ** the first element. ** ** INPUT: any object [W] ** index [R] ** ** RETURNS: ANY object */ ANYv AnyGetListIndex (ANYv any, INT4 index) { _VarUnalias (any); if (any->type != VARxLIST) VarError (any, "list", "get"); if (index < 0 || index >= AnyListLen (any)) return VarNew (); else return any->v.list.val[index]; } /**api* function ************************************************************** ** ** Gets the element with specified name from the list; creates a ** new element if it is not found ** ** INPUT: the variable holding the list [W] ** the name of the element [R] ** IMPLICIT: ** ** RETURNS: the element with specified name */ ANYv AnyGetListAssoc (ANYv list, char *name) { Iter i; ANYv elem; _VarUnalias (list); if (!list->type) AnySetList (list, AnyNewList ()); if (list->type == VARxLIST) { if ((i = DictWith (list->v.list.index, name))) elem = DictIn (i, ANYv); else { elem = VarNew (); VarSetName (elem, name); AnyListApp (list, elem); } } else _ErrExit3 (e__icainvalidselect, name, VarGetName (list)); return elem; } /**api* AnyFindListAssoc ****************************************************** ** ** Searches the element with specified name from the list; ** ** INPUT: the variable holding the list [W] ** the name of the element [R] ** IMPLICIT: ** ** RETURNS: the element with specified name ** NULL if not found */ ANYv AnyFindListAssoc (ANYv list, char *name) { Iter i; ANYv elem=NULL; _VarUnalias (list); if (!list->type) AnySetList (list, AnyNewList ()); if (list->type == VARxLIST) { if ((i = DictWith (list->v.list.index, name))) elem = DictIn (i, ANYv); } else _ErrExit3 (e__icainvalidselect, name, VarGetName (list)); return elem; } /***** VarGetStr ************************************************************** ** ** Retrieves a "buffer" object from variable. If its type is 'int' or ** 'real' then a buffer is created with value represented as ASCII string. ** If the variable pointer is NULL or the varible is existent but ** undefined then a 'default' buffer with a NULL string is returned ** ** INPUT: variable object [R] ** IMPLICIT: ** ** RETURNS: buffer object containing a string value */ char *VarGetStr (VARo *var) { static SMoBUFF *buff[50]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; static INT4 c=0; STRv str; SMoBUFF *tmp; _VarUnalias (var); _VarHandleTypeEval (var); if (var->type == VARxSTRING) tmp = (var->isReadFunction ? (*var->v.buffGet)(var,_mA) : var->v.buff); else { tmp = (buff[c%10] = BuffInit (buff[c%10], 10)); c++; if (var->type == VARxSTRV) { str = VarGetStrv (var); BuffCopyString (tmp, _Str (str)); StrDel (str); } else if (var->type == VARxINT) { BuffPrintF (tmp, "%d", var->isReadFunction ? (*var->v.intGet)(var,_mA): var->v.num); } else if (var->type == VARxREAL) { BuffPrintF (tmp, "%f", var->isReadFunction ? (*var->v.realGet)(var,_mA): var->v.real); } else if (var->type) VarError(var, "string/int", "get"); } return (BuffGetPtr(tmp)); } /**api* VarDuplicate ********************************************************** ** ** Duplicates specified Any. Note that duplication is not the same ** as creation of a copy with VarCopy. ** ** INPUT: Any object to be duplicated [R] ** ** RETURNS: the duplicate */ VARo *VarDuplicate (VARo *var) { VARo *new; new = VarNew (); memcpy (new, var, sizeof (VARo)); return new; } /**api* VarCopy *************************************************************** ** ** Copies a value inside an Any into some other. The other Any ** can be supplied by the client or if left unspecified will be created. ** This function will not simply duplicate the Any as VarDuplicate ** but retrieve values in a standard fashion which can execute evaluation ** functions. ** ** INPUT: Any object to be copied [R] ** the Any which will receive the copy (or NULL) [W] ** ** RETURNS: the Any object with the copy */ VARo *VarCopy (VARo *from, VARo *to) { STRv str; Int4 type; _VarUnalias (from); if (!to) to = VarNew (); else { _VarUnalias (to); VarReset (to); } _VarGetType (from, type); switch (type) { case VARxINT: VarSetInt (to, VarGetInt (from)); break; case VARxSTRING: VarSetStr (to, VarGetStr (from)); break; case VARxSTRV: str = VarGetStrv (from); VarSetStrv (to, str); break; case VARxLIST: AnySetList (to, from); break; case VARxOBJECT: VarSetObject (NULL, to, VarGetObject (NULL, from)); break; case VARxUNKNOWN: break; /* do nothing */ default: _ErrExit2 (e__unknownoption, "type in IopAss"); } return to; } /***** VarExec **************************************************************** ** ** Executes associated 'get' or 'type' function regardless of the type. ** ** INPUT: variable object [R] ** IMPLICIT: ** ** RETURNS: */ void VarExec (VARo *var) { if (!var->isTypeEval) { VarGetType (var); var->isTypeEval = 0; } else if (var->isReadFunction) { switch (var->type) { case VARxINT: (*var->v.intGet)(var,_mA); break; case VARxREAL: (*var->v.realGet)(var,_mA); break; case VARxSTRING: (*var->v.buffGet)(var,_mA); break; } } } /**api* VarGetInt ************************************************************* ** ** Returns an integer value contained in the Any. Does implicit ** conversions from "string", "strv" and "real" Anys. ** ** INPUT: Any object [R] ** IMPLICIT: ** ** RETURNS: the integer contained in the Any */ INT4 VarGetInt (VARo *var) { INT4 num; _VarUnalias (var); _VarHandleTypeEval (var); if (var->type == VARxINT) num = var->isReadFunction ? (*var->v.intGet)(var,_mA) : var->v.num; else if (var->type == VARxREAL) num = var->v.real; else if (var->type == VARxSTRING) num = (atoi(BuffGetPtr (var->isReadFunction ? (*var->v.buffGet)(var,_mA) : var->v.buff))); else if (var->type == VARxSTRV) { STRv str; if (var->isReadFunction) { str = (*var->v.strVGet)(var,_mA); num = atoi(_Str (str)); StrDel (str); } else num = atoi (_Str (var->v.strv)); } else if (!var->type) num = 0; else VarError(var, "string/int", "get"); return(num); } /***** VarGetReal ************************************************************* ** ** ** INPUT: variable object [R] ** IMPLICIT: ** ** RETURNS: buffer object containing a string value */ double VarGetReal (VARo *var) { double real; _VarUnalias (var); _VarHandleTypeEval (var); if (!var || !var->type) return 0; if (var->type == VARxSTRING) real = (atof(BuffGetPtr (var->isReadFunction ? (*var->v.buffGet)(var,_mA) : var->v.buff))); else if (var->type == VARxREAL) real = var->v.real; else if (var->type == VARxINT) real = var->v.num; else VarError(var, "string/real", "get"); return(real); } /***** VarGetObject *********************************************************** ** ** Returns the object pointer from variable. The class name is optional ** and will be used for checking the compatibility if supplied. ** ** INPUT: class name [R] ** variable object [R] ** IMPLICIT: ** ** RETURNS: the object pointer */ void *VarGetObject (char *className, VARo *var) { _VarUnalias (var); _VarHandleTypeEval (var); if (var->type == VARxOBJECT) { if (className) { if (var->v.object.className) if (!SmEqs (var->v.object.className, className)) _ErrExit4 (e__varwrongclass, var->name, var->v.object.className, className); var->v.object.className = className; } } else VarError(var, "object", "get"); return var->v.object.ptr; } /***** VarGetFunction ********************************************************* ** ** xx ** ** INPUT: xx ** IMPLICIT: ** ** RETURNS: xx */ FUNC VarGetFunction (VARo *var) { _VarUnalias (var); return(var->v.operator.function); } /***** VarType **************************************************************** ** ** Return the type of argument variable ** ** INPUT: variable pointer ** IMPLICIT: ** ** RETURNS: the type of argument variable */ char VarType(VARo *var) { _VarUnalias (var); return(var->type); } /**api* VarGetCode ************************************************************ ** ** Return the code of argument variable ** ** INPUT: variable pointer ** IMPLICIT: ** ** RETURNS: the type of argument variable */ char VarGetCode(VARo *var) { /* _VarUnalias(var); */ return(var->code); } /**api* VarSetCode ************************************************************ ** ** Set the code of argument variable ** ** INPUT: variable pointer ** IMPLICIT: ** ** RETURNS: the type of argument variable */ void VarSetCode(VARo *var, char code) { _VarUnalias(var); var->code = code; } /**api* VarSetClassName ******************************************************* ** ** Sets the class name of a variable of type 'object'. ** ** INPUT: variable pointer ** IMPLICIT: ** ** RETURNS: the type of argument variable */ void VarSetClassName (VARo *var, char *className) { var->v.object.className = className; } char *VarGetClassName (VARo *var) { return var->v.object.className; } void VarSetLineN (VARo *var, INT4 lineN) { var->lineN = lineN; } INT4 VarGetLineN (VARo *var) { return var->lineN; } /**api* VarGetName ********************************************************* ** ** Returns the name of the any object. Returns the name ** of the aliased any if input is an alias. ** ** INPUT: any object ** IMPLICIT: ** ** RETURNS: the name of the any */ char *VarGetName(VARo *var) { _VarUnalias(var); return(var->name); } /**api* VarGetRealName ******************************************************** ** ** Return the real name of the variable. Does not, in contrast to ** VarGetName follow a link to an alias. ** ** INPUT: variable object [R] ** IMPLICIT: ** ** RETURNS: the var object's real name */ char *VarGetRealName(VARo *var) { return(var->name); } /***** VarGetPriority ********************************************************* ** ** Return the type of argument variable ** ** INPUT: variable pointer ** IMPLICIT: ** ** RETURNS: the type of argument variable */ char VarGetPriority(VARo *var) { _VarUnalias (var); return(var->v.operator.priority); } /***** VarSetPriority ********************************************************* ** ** Return the type of argument variable ** ** INPUT: variable pointer ** IMPLICIT: ** ** RETURNS: the type of argument variable */ void VarSetPriority(VARo *var, char priority) { var->v.operator.priority = priority; } /***** VarStackNew ************************************************************ ** ** ** INPUT: initial size of the stack [R] ** ** RETURNS: stack object */ VARoSTACK *VarStackNew (INT4 size) { VARoSTACK *stack; size = MAX(10, size); if (!(stack = (VARoSTACK *) malloc (sizeof(VARoSTACK)))) _ErrExit2 (e__allocfail, "variable stack"); if (!(stack->var = (VARo *) calloc (size*sizeof(VARo), 1))) _ErrExit2 (e__allocfail, "icarus stack array"); stack->varN = 0; stack->varAllocN = size; return (stack); } /***** VarStackClose ********************************************************** ** ** Return the stack size ** ** INPUT: stack object [R] ** IMPLICIT: ** ** RETURNS: numer of symbols in the stack */ void VarStackClose (VARoSTACK *stack) { VARo *var; INT4 c; if (stack) { for (c=0; (var = VarInStackNext (stack, &c)); ) #ifdef buff if (var->type == VARxSTRING) BuffDelete (&var->v.buff); #endif if (stack->var) free (stack->var); free (stack); } } /***** VarStackReset ********************************************************** ** ** Return the stack size ** ** INPUT: stack object [R] ** IMPLICIT: ** ** RETURNS: numer of symbols in the stack */ void VarStackReset (VARoSTACK *stack) { VARo *var; INT4 c; for (c=0; (var = VarInStackNext (stack, &c)); ) { #ifdef buff if (var->type == VARxSTRING) BuffDelete (&var->v.buff); #endif memset (var, 0, sizeof (VARo)); } stack->varN = 0; } /***** VarStackSize *********************************************************** ** ** Return the stack size ** ** INPUT: stack object [R] ** IMPLICIT: ** ** RETURNS: numer of symbols in the stack */ INT4 VarStackSize (VARoSTACK *stack) { return (stack->varN); } /***** VarStackIsEmpty ******************************************************** ** ** Check the stack size ** ** INPUT: stack object [R] ** IMPLICIT: ** ** RETURNS: TRUE - stack id empty; ** FALSE - otherwise */ INT4 VarStackIsEmpty (VARoSTACK *stack) { return stack->varN ? 0 : 1; } /***** VarStackDouble ********************************************************* ** ** Doubles the size of the stack. ** ** INPUT: initial size of the stack [R] ** IMPLICIT: ** ** RETURNS: stack object */ static void VarStackDouble (VARoSTACK *stack) { stack->varAllocN *= 2; if ((stack->var = (void *) realloc (stack->var, stack->varAllocN * sizeof (VARo))) == NULL) _ErrExit2 (e__allocfail, "variable stack var list"); memset (&stack->var[stack->varN], 0, (stack->varAllocN - stack->varN) * sizeof (VARo)); } /***** VarPushCopy ************************************************************ ** ** Pushes a copy of the variable onto the stack. ** ** INPUT: initial size of the stack [R] ** IMPLICIT: ** ** RETURNS: stack object */ void VarPushCopy (VARoSTACK *stack, VARo *var) { VARo *tmp; if (stack->varN >= stack->varAllocN) VarStackDouble (stack); tmp = &stack->var[stack->varN++]; /* make sure a string from a previously stored var is freed */ #ifdef buff if (tmp->type == VARxSTRING) BuffDelete (&tmp->v.buff); #endif *tmp = *var; } /***** VarPushNew ************************************************************* ** ** Pushes a 'new' element onto the stack and returns a pointer to it. ** ** INPUT: stack object [W] ** IMPLICIT: ** ** RETURNS: variable object */ VARo *VarPushNew (VARoSTACK *stack) { VARo *tmp; if (stack->varN >= stack->varAllocN) VarStackDouble (stack); tmp = &stack->var[stack->varN++]; /* make sure a string from a previously stored var is freed */ if (tmp->type == VARxSTRING) BuffDelete (&tmp->v.buff); memset (tmp, 0, sizeof (VARo)); return tmp; } /***** VarPushAlias *********************************************************** ** ** Pushes an alias of the variable onto the stack. ** ** INPUT: initial size of the stack [R] ** IMPLICIT: ** ** RETURNS: stack object */ void VarPushAlias (VARoSTACK *stack, VARo *var) { VARo *tmp; if (stack->varN >= stack->varAllocN) VarStackDouble (stack); tmp = &stack->var[stack->varN++]; /* make sure a string from a previously stored var is freed */ if (tmp->type == VARxSTRING) BuffDelete (&tmp->v.buff); tmp->type = VARxALIAS; tmp->v.alias = var; } /***** VarPop ***************************************************************** ** ** Pops last top element in stack into user variable. ** ** INPUT: stack object [W] ** IMPLICIT: ** ** RETURNS: stack object */ VARo *VarPop (VARoSTACK *stack) { VARo *var; if (stack->varN > 0) { var = &stack->var[--stack->varN]; return var; } else return NULL; } /***** VarInStackNext ********************************************************* ** ** Pops last bottom element in stack into user variable. ** ** INPUT: stack object [W] ** IMPLICIT: ** ** RETURNS: stack object */ VARo *VarInStackNext (VARoSTACK *stack, INT4 *count) { if (*count >= stack->varN) { *count = 0; return NULL; } else return &stack->var[(*count)++]; } /***** VarStackPrint ********************************************************** ** ** xx ** ** INPUT: xx ** IMPLICIT: ** ** RETURNS: xx */ static void VarStackPrintOne(VARo *var) { printf("%-10s: ", AnyGetTypeName(VarType(var))); switch(VarType(var)) { case VARxINT: printf("%d", VarGetInt(var)); break; case VARxREAL: printf("%f", VarGetReal(var)); break; case VARxSTRING: printf("\"%s\"", VarGetStr(var)); break; case VARxALIAS: printf("%s", VarGetName(var)); break; case VARxOPERATOR: if(VarGetPriority(var)) printf("%s(%d)", IcaFunctionName(var->v.operator.function), VarGetPriority(var)); else printf(">>>SEPARATOR<<<"); default: break; } printf("\n"); } void VarStackPrint(VARoSTACK *stack) { INT4 i; for (i=0; i < stack->varN; i++) { printf("SYMBOL %d: ", i); VarStackPrintOne(&stack->var[i]); } if(!stack->varN) printf("symbolstack empty !\n"); } /****** VarNextArg *********************************************************** ** ** Returns next argument in the stack. ** ** INPUT: program object [R] ** IMPLICIT: ** ** RETURNS: ** variable object ** argument name, ** number of elements in argument if it is a list ** (0 in case of scalar argument) ** */ VARo *VarNextArg (VARoSTACK *stack, STRv *name, INT4 *listSize) { static STRv unnamed; static STRv str=NULL; VARo *arg; INT4 k=0, code; if (!unnamed) unnamed = StrCpyS ("::::::::::"); if (str) StrDel (str); if (!stack->varN) arg = NULL; else { *listSize = 0; arg = VarPop (stack); if ((code = VarGetCode (arg)) == 111) /* end of the argument list */ arg = NULL; else if (code == 114) { /* end of user argument list */ VarPop (stack); /* delete function name */ arg = NULL; } else { if (code == 113) { /* a list between curly braces */ while (stack->var[stack->varN-k].code != 112) k++; *listSize = k-1; str = VarGetStrv (&stack->var[stack->varN-1-k]); VarPop (stack); /* pop first parent */ } else if (stack->var[stack->varN-1].code == 110) { /* argument name */ str = VarGetStrv (&stack->var[stack->varN-1-k]); VarPop (stack); /* pop arg name */ } else str = StrCpy(unnamed); } } *name = str; return arg; } /**api* VarNextListItem ******************************************************* ** ** ** INPUT: program object [R] ** current execution time [R] ** IMPLICIT: ** ** RETURNS: ** */ VARo *VarNextListItem (VARoSTACK *stack, INT4 *listSize) { (*listSize)--; return(&stack->var[stack->varN-*listSize]); } /****** VarPopList ************************************************************ ** ** ** INPUT: program object [R] ** IMPLICIT: ** ** RETURNS: ** */ void VarPopList (VARoSTACK *stack) { while( VarGetCode(VarPop(stack)) != 112) ; if (stack->var[stack->varN-1].code == 110) VarPop (stack); } /****** VarGetUserCommand **************************************************** ** ** This function gets the name of the user command which is ** unfortunately below its arguments on the bottom of the stack. ** ** INPUT: program object [R] ** IMPLICIT: ** ** RETURNS: ** */ VARo *VarGetUserCommand (VARoSTACK *stack) { VARo *var; INT4 k; for (k=stack->varN-1; k >= 0; k--) { var = &stack->var[k]; if (VarGetCode (var) == 114) return &stack->var[k-1]; } return NULL; } void VarSetArgs (VARo *var, VARo **args) { var->args = args; } VARo **VarGetArgs (VARo *var) { return var->args; } /***** VarPrintf ************************************************************** ** ** Formats a string with printf type format directives. ** '%' characters must be written '%%' if they should appear in the ** formatted string. ** If the input variable does not a list then simply the string value ** is returned. ** ** INPUT: variable object (list or others) [R] ** ** RETURNS: formatted string ** empty string if there was a problem */ STRv VarPrintf (VARo *list) { STRv str; VARo *var; Int4 c=0; STRv t, string; char *s, *tmp, saveChar; if (VarGetType (list) != VARxLIST) return VarGetStrv (list); str = StrNew (); list = AnyListCpy (list); var = AnyNextInList (list, &c); string = VarGetStrv (var); s = tmp = _Str (string); while (1) { while (*s && *s != '%') { if (*s++ == '%' && *s == '%') { /* skip %% */ s++; continue; } } if (!*s) { StrAppS (&str, tmp); break; } s += strcspn (s, "sdfxc"); saveChar = s[1]; s[1] = '\0'; if (!(var = AnyNextInList (list, &c))) { _ErrMsg2 (e__missingarg, "format print"); VarDestroy2 (list); StrDel (string); return str; } switch (*s) { case 's': t = VarGetStrv (var); StrPrintf (&str, tmp, _Str (t)); StrDel (t); break; case 'd': StrPrintf (&str, tmp, VarGetInt (var)); break; default: _ErrMsg3 (e__novalchar, "format directive", *s); return str; } s[1] = saveChar; tmp = &s[1]; } VarDestroy2 (list); StrDel (string); return str; } /**api* function ************************************************************* ** ** Gets the string value held by an 'any' object. ** ** INPUT: 'any' object [R] ** ** RETURNS: a new copy of the string value */ STRv VarGetStrv (VARo *var) { STRv tmp; _VarUnalias (var); _VarHandleTypeEval (var); if (var->type == VARxSTRV) tmp = (var->isReadFunction ? (*var->v.strVGet)(var,_mA) : StrCpy(var->v.strv)); else if (var->type == VARxSTRING) { tmp = StrNew (); StrSetS (&tmp, (BuffGetPtr ((var->isReadFunction ? (*var->v.buffGet)(var,_mA) : var->v.buff)))); } else if (var->type == VARxINT) { tmp = StrNew (); StrPrintf (&tmp, "%d", var->isReadFunction ? (*var->v.intGet)(var,_mA) : var->v.num); } else if (var->type == VARxREAL) { tmp = StrNew (); StrPrintf (&tmp, "%f", var->isReadFunction ? (*var->v.realGet)(var,_mA): var->v.real); } else if (!var->type) tmp = StrNew (); else VarError(var, "string/int", "get"); return tmp; } VARo *VarSetStrvS (VARo *var, char *s) { _VarUnalias(var); if (var->isReadFunction) _ErrExit2 (e__varisreadonly, var->name); if (!var->type) { var->type = VARxSTRV; var->v.strv = StrNew (); } if (var->type == VARxSTRV) { StrSetS (&var->v.strv, s); } else if (var->type == VARxINT) var->v.num = atoi (s); else VarError(var, "string/int", "set"); return var; } /**api* function ************************************************************* ** ** Sets an 'any' object to contain a string value. The string value ** will not be copied, so don't delete the string value after calling ** with it this function. ** ** INPUT: 'any' object [W] ** string value [R] ** ** RETURNS: the 'any' object itself */ VARo *VarSetStrv (VARo *var, STRv str) { _VarUnalias(var); if (var->isReadFunction) _ErrExit2 (e__varisreadonly, var->name); if (!var->type) { var->type = VARxSTRV; } if (var->type == VARxSTRV) { if (var->v.strv) StrDel (var->v.strv); var->v.strv = str; } else if (var->type == VARxINT) { var->v.num = atoi (_Str (str)); StrDel (str); } else if (var->type == VARxREAL) { var->v.real = atof (_Str (str)); StrDel (str); } else if (var->type == VARxSTRING) { var->v.buff = BuffInit (var->v.buff, 0); BuffCopyString (var->v.buff, _Str (str)); StrDel (str); } else VarError(var, "string/int", "set"); return var; } /**api* function ************************************************************* ** ** Appends a string value to the one held by the 'any' object. ** argument string value will not be copied, ** so don't delete the string value after calling with it this function. ** ** INPUT: 'any' object [W] ** string value to be appended [R] ** ** RETURNS: the 'any' object itself */ VARo *VarAppStrv (VARo *var, STRv str) { _VarUnalias(var); if (var->isReadFunction) _ErrExit2 (e__varisreadonly, var->name); if (var->type == VARxSTRV) StrApp (&var->v.strv, str); else VarSetStrv (var, str); return var; } * argument string value will not be copied, ** so don't delete the string value after calling with it this function. ** ** INPUT: 'any' object [W] ** string value to be appended [R] ** ** RETURNS: the 'any' object itself */ VARo *VarAppSsrs/src/variable.h ** ** $RCSfile: variable.h,v $ ** $Revision: 1.11 $ ** $Date: 1997/03/18 22:52:35 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** Copyright by Thure Etzold ** */ enum VAReTYPE {VARxUNKNOWN, VARxINT, VARxSTRING, VARxOBJECT, VARxREAL, VARxALIAS, VARxVAR, VARxANY, VARxOPERATOR, VARxSTRV, VARxLIST=16}; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** object pointer */ typedef struct VARoOBJECT { void *ptr; char *className; } VARoOBJECT; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** operator */ typedef struct VARoOPERATOR { FUNC function; char priority; } VARoOPERATOR; /* for irix 64 - it needs the largest item in the begin of a union - the first member 'intGet' is used for initialization in icainit.c */ typedef struct DUMMY { INT4 (*intGet)(); char *some; } DUMMY; typedef struct VARo *VARv; typedef struct VARo *ANYv; typedef struct ANYoLIST { ANYv *val; struct DICTo *index; } ANYoLIST; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** the variable object */ typedef struct VARo { char *name; char type; char code; char isReadFunction; char isTypeEval; char isDelayedType; char isWrite; short lineN; union { DUMMY dummy; INT4 (*intGet)(); double (*realGet)(); SMoBUFF *(*buffGet)(); struct VARo *(*varGet)(); struct VARo *(*listGet)(); STRv (*strVGet)(); VARoOBJECT object; VARoOPERATOR operator; INT4 num; STRv strv; SMoBUFF *buff; double real; struct ANYoLIST list; struct VARo *alias; } v; struct VARo **args; void (*typeGet)(); #ifdef xxx struct info { unsigned int type:4 code:8 isReadFunction:1 isTypeEval:1 isDelayedType:1 lineN:14 fileX:3 } #endif } VARo; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** var scope - defines a space for contiguous allocation for variables */ typedef struct VARoSCOPE { struct DICTo *dict; VARo *var; INT4 varAllocN; INT4 varN; } VARoSCOPE; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** stack object */ typedef struct VARoSTACK { VARo *var; INT4 varAllocN; INT4 varN; } VARoSTACK; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** stack object for icarus level 4 */ typedef struct VARoStack { VARo **ptr; Int4 n; Int4 allocN; } VARoStack; #define _VarGetType(var,x) \ if ((var)->type == VARxALIAS) {\ (x) = VarGetType (var);} \ else if (!(var)->isTypeEval && (var)->isDelayedType) { \ (*(var)->typeGet)(var); \ (var)->isTypeEval = 1; \ (x) = var->type; \ } else (x) = var->type /* general functions */ VARv VarGet (struct VARoSCOPE **scope, char *varName); VARv VarTemp (); VARv VarNew (); void VarReset (VARv var); VARv VarGetUserCommand (VARoSTACK *stack); void VarSetType (VARv var, enum VAReTYPE type); char VarType(VARv var); char* VarGetName(VARv var); char* VarGetRealName(VARv var); void VarSetAlias (VARv alias, VARv var, VARoSCOPE *scope); VARv VarGetAlias (VARv alias, VARoSCOPE *scope); VARv VarGetVar (VARv var, Int4 doEval); VARv VarCopy (VARv from, VARv to); VARv VarDuplicate (VARv var); VARv VarGet (VARoSCOPE **scope, char *name); char *AnyDebugStr (ANYv any); /* work on 'string' variables */ VARv VarSetStr (VARv var, char *s); void VarSetSubStr (VARv var, char *s, INT4 len); char* VarGetStr (VARv var); void VarSetReadStr (VARv var, SMoBUFF *(*getStr)(char *)); STRv VarPrintf (VARv list); /* work on 'STRv' variables */ void VarSetReadStrv (VARo *var, STRv (*strVGet)(char *)); STRv VarGetStrv (VARv var); VARv VarSetStrvS (VARv var, char *s); VARv VarSetStrv (VARv var, STRv str); VARo *VarAppStrv (VARo *var, STRv str); /* work on 'real' variables */ struct VARo *VarSetReal (VARv var, double real); double VarGetReal (VARv var); void VarSetReadReal (VARv var, double (*getReal)()); /* work on 'object' variables */ VARv VarSetObject (char *className, VARv var, void *object); void* VarGetObject (char *className, VARv var); void VarSetReadObject (VARv var, void (*getObject)(char *)); /* work on 'num' variables */ VARv VarSetInt (VARv var, INT4); INT4 VarGetInt (VARv var); void VarSetReadInt (VARv var, INT4 (*getInt)(char *)); /* work on 'operator' variables */ void VarSetFunction (VARv var, FUNC function); FUNC VarGetFunction (VARv var); void VarSetPriority(VARv var, char priority); char VarGetPriority(VARv var); void VarSetCode(VARv var, char code); char VarGetCode(VARv var); /* work on 'list' variables */ void VarSetReadList (VARo *var, VARo *(*listGet)(char *)); ANYv AnyNextInList (VARv var, Int4 *i); ANYv AnyNextInList (VARv var, Int4 *i); void AnyListApp (VARv list, VARv any); ANYv AnyNewList (); ANYv AnyListCpy (VARv list); ANYv AnyGetListIndex (VARv var, INT4 index); ANYv AnyGetListAssoc (VARv var, char *name); ANYv AnyFindListAssoc (VARv var, char *name); Int4 AnyListLen (ANYv list); /* functions for variable stack management */ void VarStackClose (VARoSTACK *stack); void VarStackReset (VARoSTACK *stack); void VarStackPrint (VARoSTACK *stack); INT4 VarStackSize (VARoSTACK *stack); VARoSTACK *VarStackCopy (VARoSTACK *stack); VARoSTACK *VarStackNew (INT4 size); VARo *VarInStackNext (VARoSTACK *stack, INT4 *c); VARo *VarPop (VARoSTACK *stack); VARo *VarPushNew (VARoSTACK *stack); void VarPushAlias (VARoSTACK *stack, VARv var); void VarPushCopy (VARoSTACK *stack, VARv var); /* functions to treat stack object */ VARv VarNextArg(VARoSTACK *stack, struct STRo **name, INT4 *ListSize); VARv VarNextListItem(VARoSTACK *stack, INT4 *ListSize); void VarPopList(VARoSTACK *stack); /* icarus level 4 stack functions */ struct VARoStack *VarStackInit (struct VARoStack *stack); void VarPush2 (struct VARoStack *stack, VARv var); VARv VarPop2 (struct VARoStack *stack); /* others */ INT4 VarIsAlias (VARv var); void VarSetArgs (VARv var, VARv *args); void VarSetName (VARv var, char *name); VARv *VarGetArgs (VARv var); char *VarGetClassName (VARv var); struct VARoSCOPE *VarCopyScope (struct VARoSCOPE *scope); INT4 VarGetLineN (VARv var); void VarSetLineN (VARv var, INT4 lineN); VARv VarSetVar (VARv out, VARv in); VARv VarFreeze (VARv var); VARo *VarUnalias (VARo *alias); #define _VarUnalias(x) if ((x)->type == VARxALIAS) (x) = VarUnalias(x) ruct VARoStack *stack); /* others */ INT4 VarIsAlias (VARv var); void VarSetArgs (VARv var, VARv *args); void VarSetName (VARv var, char *name); VARv *VarGetArgs (VARv var); char *VarGetClassName (VARv var); struct VARoSCOPE *VarCopyScope (struct VARoSCOPE *scope); INT4 VarGetLineN (VARv var); void VarSetLineN (VARv var, INT4 lineN); VARv VarSetVar (VARv out, VARv in); VARv VarFreeze (VARv var); VARo *VarUnalias (VARo *alias); #define _VarUnalias(x) if ((x)->typesrs/src/view.c #include #include #include "message.h" #include "sm.h" #include "strv.h" #include "dict.h" #include "futil.h" #include "templ.h" #include "library.h" #include "par.h" #include "entry.h" #define _SRS #define _SLB #include "srs5.h" #include "view.h" enum VIEWeFormat {VIEWxTable=1, VIEWxList}; typedef struct VIEWoLIST { VIEWo **views; Int4 viewsN; Int4 viewsAllocN; DICTv dict; VIEWo *(*getUserView)(Int4, TEMPLv); Int4 userViewN; TEMPLv userTempl; } VIEWoLIST; static void ViewUpdateRootLib (VIEWo *view, VIEWoLIB *vlib); static VIEWoLIST staticViewList; static VIEWoLIST *viewList = &staticViewList; static void ViewAddList (VIEWoLIST *list, VIEWo *view) { DictAddPtr (&list->dict, view); *(_addObj (list->views, list->viewsN, list->viewsAllocN, VIEWo*)) = view; } /**api* ViewGetViewsN ****************************************************** ** ** Returns the number of views defined. ** ** RETURNS: the number of views defined ** */ Int4 ViewGetViewsN () { return viewList->viewsN; } /**api* ViewInitDefined ****************************************************** ** ** Initializes all views defined in Icarus programs. ** ** INPUT: array with views defined in Icarus [W] ** number of views in the array [R] ** */ void ViewInitDefined (VIEWo *views, Int4 viewN) { VIEWo *view; VIEWoLIB *vlib; Int4 k, l; if (!viewList->dict) viewList->dict = DictCreate (DictCreateClassStrZKey (NULL, mPtr (VIEWo, name), 0)); for (k=0,l=0; k < viewN; k++) { view = &views[k]; vlib = ViewGetNextRootLib (view, &l); for(l=0; (vlib = ViewGetNextRootLib (view, &l));) ViewUpdateRootLib (view, vlib); ViewAddList (viewList, view); } } /**api* ViewMarkDeleted ****************************************************** ** ** Mark deleted view to be logically deleted. ** Check if a view is deleted with ViewIsDeleted. ** ** INPUT: Address of view Object [R] ** */ void ViewMarkDeleted (VIEWo *view) { char par[80], *tmp; view->isDeleted = 1; /* set the status flag */ sprintf(par,"ViewDeleted_%d", view->n); if (*(tmp = ParGetStrF ("selectedViewNo_%d", view->n))) ParDelete (tmp); ParDefNum (par,1); } /**api* ViewMarkNascent ****************************************************** ** ** Mark view to be nascent. ** ** INPUT: Address of view Object (or NULL) [W] ** view number [R] ** */ void ViewMarkNascent (VIEWo *view, INT4 viewN) { char par[80]; if (view) view->isNascent = 1; sprintf(par,"v%d_isNascent", viewN); ParDefNum (par, 1); } /****** ViewIsDeleted ********************************************************* ** ** Checks for the logical deletion of a view object with ViewMarkDeleted. ** ** INPUT: Address of view object [R] ** IMPLICIT ** ** RETURNS: delete flag */ INT4 ViewIsDeleted(VIEWo *view) { return(view->isDeleted); } /**API* ViewGetEntryNamePrinting ********************************************** ** ** Returns if the printing of the entry name before the selected ** information from entry is selected ** ** INPUT: view object [R] ** ** RETURNS: flag if entry name should be printed */ Int4 ViewIsEntryNamePrinting (VIEWo *view) { return view->isEntryNamePrinting; } /**api* ViewIsTable *********************************************************** ** ** Checks if view is to be displayed as a table ** ** INPUT: view object [R] ** ** RETURNS: TRUE or FALSE */ INT4 ViewIsTable (VIEWo *view) { return (view->format == VIEWxTable); } /**api* ViewIsShortNames ****************************************************** ** ** Checks whether field names in the table header are abbreviations ** rather than the full names. ** ** INPUT: view object [R] ** ** RETURNS: TRUE or FALSE */ INT4 ViewIsShortNames (VIEWo *view) { return(view->useShortFieldNames); } /**api* ViewIs **************************************************************** ** ** Returns TRUE if specified characteristic applies to view. ** ** INPUT: view object [R] ** option: "selected", "nascent", "forAll" [R] ** ** RETURNS: TRUE or FALSE */ Int4 ViewIs (VIEWo *view, char *option) { switch (option[0]) { case 's': return (*ParGetStrF ("selectedViewNo_%d", view->n) ? 1 : 0); case 'n': return ParGetNumF ("v%d_isNascent", view->n); case 'f': /* forAll */ return view->rootN == 0 ? 1 : 0; default: _ErrExit2 (e__unknownoption, option); } return 0; } Int4 ViewIsRootField (VIEWo *view, SLBoFIELD *field) { SLBoFIELD *tmp; VIEWoLIB *vlib; Int4 c1=0, c2; vlib = ViewGetNextRootLib (view, &c1); for (c2=0; (tmp = ViewGetNextField (vlib, &c2));) if (field == tmp) return 1; return 0; } Int4 ViewIsLeafField (VIEWo *view, VIEWoLIB *vlib, SLBoFIELD *field) { SLBoFIELD *tmp; VIEWoLIB *tmpVlib; Int4 c1, c2; for (c1=0; (tmpVlib = ViewGetNextLeafLib (view, &c1));) if (vlib == tmpVlib) for (c2=0; (tmp = ViewGetNextField (vlib, &c2));) if (field == tmp) return 1; return 0; } /**api* ViewNew *************************************************************** ** ** Creates a new empty view which can be later identified by the ** specified number or name. ** ** INPUT: view number [R] ** view name [R] or NULL ** IMPLICIT: ** viewList [W] ** ** RETURNS: the view library object [R] */ VIEWo *ViewNew (Int4 n, char *name) { VIEWo *view; if (!(view = (VIEWo *) calloc (1, sizeof (VIEWo)))) _ErrExit2 (e__allocfail, "view object"); view->n = n; if (name && *name) ViewSetName (view, name); return view; } /**api* ViewAddRootField ****************************************************** ** ** Adds a field to the root library(s). ** ** INPUT: view object [W] ** field type object [R} ** ** RETURNS: the view field object [R] */ VIEWoFIELD *ViewAddRootField (VIEWo *view, SRSoFLD *fieldType) { VIEWoFIELD *vfield; VIEWoLIB *vlib; if (!view->rootN) /* _ErrExit (e__viewMissingRootLib);*/ vlib = &view->root[0]; /* add all fields to the FIRST root library */ vfield = _addObj (view->rootFields, view->rootFieldsN, view->rootFieldsAllocN, VIEWoFIELD); memset (vfield, 0, sizeof (VIEWoFIELD)); vfield->type = fieldType; return vfield; } void ViewSetUserList (VIEWo *(*getView)(Int4 n, TEMPLv templ), TEMPLv templ) { VIEWo *view; Int4 k; viewList->getUserView = getView; viewList->userTempl = templ; for (k=viewList->viewsN+1; (view = (*viewList->getUserView) (k, templ)); k++) { ViewAddList (viewList, view); } } /**api* function ************************************************************** ** ** Returns view with specified name. ** ** INPUT: name of view [R] ** ** RETURNS: the first view with that name ** NULL: view with name has not been found */ VIEWo *ViewGetNamed (char *name) { VIEWo *view; Int4 k; for (k=0; (view=ViewNext (&k));) if (SmEqs (name, ViewGetName (view))) return view; return NULL; } /**api* ViewNext ************************************************************** ** ** Iterates over all views. Assignes a view number which can be obtained ** with ViewGetNo. ** ** INPUT: address of iterator [W] ** ** RETURNS: the next view object ** NULL: end of list */ VIEWo *ViewNext (Int4 *c) { VIEWo *view; Int4 userViewN; if (*c < viewList->viewsN) { view = viewList->views[(*c)++]; if (!view->n) view->n = *c; return view; } else { *c = 0; return NULL; } } /**api* ViewSetWithNo ********************************************************* ** ** Sets or replaces view with specified number. ** ** INPUT: view object [R] ** view number [R] ** */ void ViewSetWithNo (VIEWo *view, Int4 viewNo) { viewList->views[viewNo-1] = view; } /**API* ViewGetWithNo ********************************************************* ** ** Returns view with a certain number. ** ** INPUT: view number [R] ** ** RETURNS: the view object ** NULL: view with number was not found */ VIEWo *ViewGetWithNo (Int4 n) { if (n <= viewList->viewsN && n > 0) return viewList->views[n-1]; else return NULL; } /**API* ViewAddField ********************************************************** ** ** Adds a field to a view library. Use ViewSetFieldFormat to set ** its format, if applicable and ViewAddRootField to add a field to ** the view root library(s). ** ** INPUT: view library object [W] ** field type object [R} ** ** RETURNS: the view library object [R] */ VIEWoFIELD *ViewAddField (VIEWoLIB *vlib, SRSoFLD *fieldType) { VIEWoFIELD *vfield; vfield= _addObj (vlib->fields, vlib->fieldsN, vlib->fieldsAllocN,VIEWoFIELD); memset (vfield, 0, sizeof (VIEWoFIELD)); vfield->type = fieldType; return vfield; } /**api* ViewAddRootLib ******************************************************** ** ** Adds a new root library to the view. ** ** INPUT: view object [W] ** query string [R} ** ** RETURNS: the view library object [R] */ VIEWoLIB *ViewAddRootLib (VIEWo *v, SLBo *lib) { VIEWoLIB *vlib; vlib = _addObj (v->root, v->rootN, v->rootAllocN, VIEWoLIB); memset (vlib, 0, sizeof (VIEWoLIB)); vlib->lib = lib; return vlib; } /**api* ViewAddLeafLib ******************************************************** ** ** Adds a new root library to the view. ** ** INPUT: view object [W] ** query string [R} ** ** RETURNS: the view library object [R] */ VIEWoLIB *ViewAddLeafLib (VIEWo *v, SLBo *lib) { VIEWoLIB *vlib; vlib = _addObj (v->leaves, v->leavesN, v->leavesAllocN, VIEWoLIB); memset (vlib, 0, sizeof (VIEWoLIB)); vlib->lib = lib; return vlib; } /**api* ViewSetLeafQuery ***************************************************** ** ** Sets the query string to be used for linking from the root library ** to specified leaf library. ** ** INPUT: view library object [W] ** query string [R} */ void ViewSetLeafQuery (VIEWoLIB *vlib, char *query) { if (vlib->query) free (vlib->query); vlib->query = (char *) malloc (strlen (query)+1); strcpy (vlib->query, query); } /**api* ViewSetFormat ********************************************************* ** ** Sets the view to be in table format or not ** ** INPUT: view object [R] ** format option: "table", "list" [R] */ void ViewSetFormat (VIEWo *view, char *format) { if (format[0] == 't') view->format = VIEWxTable; else view->format = VIEWxList; } /**api* ViewSetUseShortNames ************************************************** ** ** Sets whether or not to use short field names in the header of ** table views. ** ** INPUT: view object [W] ** flag [R] */ void ViewSetUseShortNames (VIEWo *view, Int4 flag) { view->useShortFieldNames = flag; } /**api* ViewSetLeafView ****************************************************** ** ** Sets a view from entries of the specified leaf library. ** ** INPUT: view library object [W] ** view Name [R} */ void ViewSetLeafView (VIEWoLIB *vlib, char *viewName) { if (vlib->viewName) free (vlib->viewName); vlib->viewName = (char *) malloc (strlen (viewName)+1); strcpy (vlib->viewName, viewName); } /**api* ViewSetLeafPrintN ***************************************************** ** ** Sets flag that only the number of linked entries is printed for a ** leaf library. ** ** INPUT: view library object [W] ** flag [R] */ void ViewSetLeafPrintN (VIEWoLIB *vlib, Int4 flag) { vlib->printOnlyEntryN = flag; } /**api* ViewSetFieldFormat **************************************************** ** ** Sets for both root and leaf library fields the format. The address ** of string argument must be static. This address can be obtained ** by LibFieldFormat. ** ** INPUT: view field object [W] ** address of format name [R] */ void ViewSetFieldFormat (VIEWoFIELD *vfield, char *format) { if (format && *format) vfield->format = format; } /**api* ViewGetNextField ****************************************************** ** ** Returns the next field in the view object. ** ** INPUT: address of view object [R] ** address of context [W] ** ** RETURNS: next field object ** NULL: end of list ** */ SLBoFIELD *ViewGetNextField(VIEWoLIB *vlib, INT4 *context) { SLBoFIELD *field; SRSoFLD *type; if (!vlib) return NULL; if (vlib->fieldsN > *context) { type = vlib->fields[(*context)++].type; if (!(field = LibHasField (vlib->lib, type))) _ErrExit3 (e__dbhasnotfield, LibName (vlib->lib), LibGetFieldTypeName (type)); return field; } else { *context = 0; return NULL; } } VIEWoFIELD *ViewGetNextVfield(VIEWoLIB *vlib, INT4 *context) { if (vlib->fieldsN > *context) return &vlib->fields[(*context)++]; else { *context = 0; return NULL; } } /****** ViewGetNumOfLeafFields ************************************************ ** ** Counts number of leaf fields defined ** ** INPUT: address of view object [R] ** IMPLICIT ** ** RETURNS: number of fields defined ** ** */ INT4 ViewGetNumOfLeafFields(VIEWo *view) { INT4 m,k; for (m=0, k=0; k < view->leavesN; k++) m += view->leaves[k].fieldsN; return m; } /****** ViewGetNumOfLeafFields ************************************************ ** ** Counts number of root fields defined ** ** INPUT: address of view object ** ** RETURNS: number of fields defined ** */ INT4 ViewGetNumOfRootFields(VIEWo *view) { INT4 m,k; return view->rootFieldsN; } /**api* ViewSetName ********************************************************* ** ** Sets the name of a view. The name is entered into ** both the view object and the user context ** ** INPUT: address of view object [W] ** the name [R] ** ** RETURNS: view name ** */ void ViewSetName (VIEWo *view, char *name) { char parName[100]; sprintf (parName,"view%d_Name", view->n); ParDefStr (parName, name); view->name = ParGetStr (parName); } /**api* ViewGetName ******************************************************** ** ** returns the name of the view ** ** INPUT: address of view object [R] ** ** RETURNS: view name ** */ char *ViewGetName(VIEWo *view) { return(view->name); } /**api* ViewDelete *********************************************************** ** ** Deletes the view object obtained with ViewGet. ** ** INPUT: address of view object [W] ** */ void ViewDelete (VIEWo *view) { if (view) { free (view); } } /**api* ViewGetViewNumber *************************************************** ** ** Gets the number of the view with the specified name. ** See also ViewGet, ViewGetLeafView. ** ** INPUT: the name of the view [R] ** ** RETURN: the number of the view ** ** */ INT4 ViewGetViewNumber (char *viewName) { VIEWo *view; INT4 c, l; for (c=0,l=1; (view=ViewNext (&c)); l++) { if (SmEqs (viewName, ViewGetName (view))) return l; } return 0; } Int4 ViewGetNo (VIEWo *view) { return view->n; } static void ViewUpdateRootLib (VIEWo *view, VIEWoLIB *vlib) { vlib->fields = view->rootFields; vlib->fieldsN = view->rootFieldsN; } /**api* ViewGetNextRootLib *************************************************** ** ** Returns next view root library. context must be initially ** set to 0; ** ** INPUT: address of the view object [R] ** address of the context [W] ** ** RETURNS: the view lib object ** NULL: end of list */ VIEWoLIB *ViewGetNextRootLib(VIEWo *view, INT4 *context) { VIEWoLIB *tmp = &view->root[(*context)++]; if (*context <= view->rootN) { ViewUpdateRootLib (view, tmp); return tmp; } else { *context = 0; /* reset for reuse */ return NULL; } } /**api* ViewGetNextLeafLib *************************************************** ** ** Returns next view root library. context must be initially ** set to 0; ** ** INPUT: address of the view object ** address of the context ** ** RETURNS: name of the view leaf library ** NULL if no more leaflibrary */ VIEWoLIB *ViewGetNextLeafLib(VIEWo *view, INT4 *context) { VIEWoLIB *tmp = &view->leaves[(*context)++]; if (*context <= view->leavesN) return tmp; else { *context = 0; /* reset for reuse */ return NULL; } } /**api* ViewLeafIsOnlyEntryN ************************************************** ** ** Returns TRUE if only the number of linked entries should be displayed. ** ** INPUT: leaf library object [R] ** ** RETURNS: 1: yes ** 0: no */ Int4 ViewLeafIsOnlyEntryN (VIEWoLIB *vlib) { return vlib->printOnlyEntryN; } /**api* ViewGetLeafView ******************************************************* ** ** Returns the name of the view associated with the leaf. ** Use ViewGetViewNumber and ViewGet to obtain the view object. ** ** INPUT: leaf library object [R] ** ** RETURNS: the view name ** Null string: no view associated with leaf */ char *ViewGetLeafView (VIEWoLIB *vlib) { static char empty[]=""; return vlib->viewName ? vlib->viewName : empty; } /**api* ViewLeafQuery ******************************************************** ** ** Returns the query string associated with the leaf query. See also ** ViewGetLeafQuery. ** root entry. ** ** INPUT: leaf library object [R] ** ** RETURNS: query string */ char *ViewGetLeafQueryStr (VIEWoLIB *vlib) { static char empty[]=""; return vlib->query ? vlib->query : empty; } /**api* ViewLeafQuery ******************************************************** ** ** Returns the query with which to get the leaf entry set for specified ** root entry. ** ** INPUT: leaf library object [R] ** entry object [R] ** ** RETURNS: query string */ char *ViewGetLeafQuery (VIEWoLIB *vlib, ENTRYv entry) { SLBo *lib=EntryGetLib (entry); static char queryStr[500]; char *tmp, entryStr[200]; if (*(tmp = ViewGetLeafQueryStr (vlib))) { strcpy (queryStr , tmp); sprintf (entryStr, "[%s-%s:%s]", LibName (lib), FieldGetName (LibGetIdField (lib)), EntryGetName (entry)); SmSwapFirst (queryStr, "entry", entryStr); } else sprintf (queryStr, "[%s-%s:%s] > %s", LibName (lib), FieldGetName (LibGetIdField (lib)), EntryGetName (entry), LibName (vlib->lib)); return queryStr; } LIBoFieldFormat *ViewGetFieldFormat (VIEWoLIB *vlib, SLBoFIELD *field) { SRSoFLD *type=LibFieldType (field); VIEWoFIELD *vfield; Int4 c; for (c=0; (vfield = ViewGetNextVfield (vlib, &c));) if (vfield->type == type) return LibFieldFormat (field, vfield->format); return NULL; } /****** ViewCountRootLib ************************************************** ** ** Returns next view root library. context must be initially ** set to 0; ** ** INPUT : address of the view object ** address of the context ** ** RETURNS: name of the view root library ** NULL if no more root library ** ** ** */ Int4 ViewCountRootLibs(VIEWo *view) { Int4 k,j; for(k=0,j=0; ViewGetNextRootLib(view,&k) ;j++ ) ; return j; } /****** ViewCountLeafLib ************************************************** ** ** ** */ Int4 ViewCountLeafLibs(VIEWo *view) { Int4 k,j; for(k=0,j=0; ViewGetNextLeafLib(view,&k) ;j++ ) ; return j; } void ViewSetTemplate (VIEWo *view, TEMPLv templ) { view->templ = templ; } TEMPLv ViewGetTemplate (VIEWo *view) { return view->templ; } void ViewSetTemplateFile (VIEWo *view, char *fileName) { if (view->templateFile) free (view->templateFile); view->templateFile = (char *) malloc (strlen (fileName)+1); strcpy (view->templateFile, fileName); } void ViewTemplateBegin (VIEWo *view) { char *fileName; if (!view->templ) { if (view->templateFile && *view->templateFile) fileName = view->templateFile; else fileName = "SRSICA:ascii.it"; view->templ = TemplOpen (fileName, NULL); } if (ViewIsTable (view)) TemplWith (view->templ, "$entry.inTable.entry"); else TemplWith (view->templ, "$entry.inList.entry"); } void ViewTemplateEnd (VIEWo *view) { TemplEndWith (); } /**API* ViewSetEntryNamePrinting ********************************************** ** ** Sets the printing of the entry name before the selected information ** from entry is printed. ** ** INPUT: view object [R] ** */ void ViewSetEntryNamePrinting (VIEWo *view, Int4 flag) { view->isEntryNamePrinting = flag; } void ViewSetEntryNamePrint (VIEWo *view, void (*func)()) { view->entryNamePrint = func; } void ViewSetEntryNPrint (VIEWo *view, void (*func)()) { view->entryNPrint = func; } void ViewEntryNamePrint (VIEWo *view, ENTRYv entry, Int4 entryNo, Int4 rowN, Int4 isRoot) { (*view->entryNamePrint) (view, entry, entryNo, rowN, isRoot); } void ViewLeafEntryNPrint (VIEWo *view, VIEWoLEAFSET *leaf, ENTRYv entry, Int4 rowN) { (*view->entryNPrint) (view, leaf, entry, rowN); } amePrinting = flag; } void ViewSetEntryNamePrint (VIEWo *view, void (*func)()) { view->entryNamePrint = func; } void ViewSetEntryNPrint (VIEWo *view, void (*func)()) { view->entryNPrint = func; } void ViewEntryNamePrint (VIEWo *view, ENsrs/src/view.h ** ** $RCSfile: view.h,v $ ** $Revision: ** $Date: 1997/03/17 23:18:39 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** SRS V5.x Copyright by Thure Etzold ** ** ** Author: Chenna Ramu ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387372 ** Email: chenna@embl-heidelberg.de ** ** */ typedef struct VIEWoFIELD *VIEWvFIELD; typedef struct VIEWoLIB *VIEWvLIB; typedef struct VIEWo *VIEWv; typedef struct VIEWoLEAFSET { struct VIEWoLIB *vlib; struct SETo *set; INT4 entryN; } VIEWoLEAFSET; #ifndef _SLBoFORM typedef struct SLBoFORM *dummytointroducestructtagSLBoFORM; #endif /* prototypes for view module */ struct VIEWo *ViewGet(int viewN); struct VIEWo *ViewGetForLib(char *libName); struct VIEWoLIB *ViewGetNextRootLib(struct VIEWo *view, INT4 *context); struct VIEWoLIB *ViewGetNextLeafLib(struct VIEWo *view, INT4 *context); struct SLBoFIELD *ViewGetNextField(struct VIEWoLIB *vlib, INT4 *context); void ViewSetName (struct VIEWo *view, char *name); void ViewMarkDeleted(struct VIEWo *query); void ViewDel(struct VIEWo *v ); struct VIEWo *ViewNext (Int4 *c); struct VIEWo *ViewGetWithNo (Int4 n); /* view creation */ struct VIEWo *ViewNew (Int4 n, char *name); struct VIEWoFIELD *ViewAddRootField (struct VIEWo *view, struct SRSoFLD *type) ; struct VIEWoFIELD *ViewAddField (struct VIEWoLIB *vlib, struct SRSoFLD *fieldType); struct VIEWoLIB *ViewAddRootLib (struct VIEWo *view, struct SLBo *lib); struct VIEWoLIB *ViewAddLeafLib (struct VIEWo *view, struct SLBo *lib); void ViewSetLeafQuery (struct VIEWoLIB *vlib, char *query); void ViewSetFieldFormat (struct VIEWoFIELD *vfield, char *format); void ViewSetLeafView (struct VIEWoLIB *vlib, char *viewName); void ViewSetLeafPrintN (struct VIEWoLIB *vlib, Int4 flag); void ViewSetFormat (struct VIEWo *view, char *format); void ViewSetTemplate (struct VIEWo *view, TEMPLv templ); /* view info */ struct VIEWo *ViewGetNamed (char *name); Int4 ViewGetViewsN (); INT4 ViewIsDeleted(struct VIEWo *v); INT4 ViewIsTable (struct VIEWo *view); Int4 ViewIsShortNames (struct VIEWo *view); INT4 ViewGetNumOfRootFields(struct VIEWo *view); INT4 ViewGetNumOfLeafFields(struct VIEWo *view); char* ViewGetName(struct VIEWo *view); INT4 ViewGetViewNumber( char *viewName); char* ViewGetLeafQuery (struct VIEWoLIB *vlib, struct ENTRYo *entry); char* ViewGetLeafQueryStr (struct VIEWoLIB *vlib); char* ViewGetLeafView (struct VIEWoLIB *vlib); Int4 ViewLeafIsOnlyEntryN (struct VIEWoLIB *vlib); struct LIBoFieldFormat *ViewGetFieldFormat (struct VIEWoLIB *vlib, struct SLBoFIELD *field); struct TEMPLo *ViewGetTemplate (struct VIEWo *view); Int4 ViewCountRootLibs(struct VIEWo *view); Int4 ViewCountLeafLibs(struct VIEWo *view); 4 ViewGetViewNumber( char *viewName); char* ViewGetLeafQuery (struct VIEWoLIB *srs/src/wgetz.c char wgetz_ID[] = "$Id: wgetz.c,v 1.37 1997/03/19 20:41:42 srs Exp $"; /* ** ** $Source: /homes/srs/cvsroot/srs/src/wgetz.c,v $ ** $Revision: 1.37 $ ** $Date: 1997/03/19 20:41:42 $ ** $Author: srs $ ** ** $Locker: $ ** $State: Exp $ ** ** ** Copyright by Thure Etzold ** ** Author: Chenna Ramu ** EMBL, Meyerhofstrasse 1 ** W-6900 Heidelberg, Germany ** Tel: 06221 387372 ** Email: chenna@embl-heidelberg.de ** ** ** Requires: message, file, sm ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ** Description ** =========== ** ** call getz from within WWW ...entries are fortified by hypertext links ** ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include "srs.h" #include "srswww.h" /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** prototypes of static functions */ static void PageStart (); static void PageSelectLibrary (); static void PageQueryForm (); static void PageDownloadSetOpt (); static void PageDownloadSet (); static void PageConstructQuery (); static void PageReinspectQuery (); static void PageConstructQuery (); static void PageQueryManager (); static void PageViewCreate (); static void PageViewMgrCreate (); static void PageViewSelectFields (); static void PageViewManager (); static void PageViewEdit (); static void PageViewSelectedEntries (); static void PageEntry (); static void PageLaunchAppl (); static void PageSearchOpt (); static void PageDoSearch (); static void PageDoAppl (); static void PageQueryExpression (); static void PageCombineQueries (); static void PageIndexBrowseOpt (); static void PageIndexBrowse (); static void PageValues2Query (); static void PageLinkOpt (); static void PageLinkToLibs (); static void PageLinkEntryOpt (); static void PageMoreEntries (); static void PageLibList (); static void PageLibNetwork (); static void PageLibInfo (); static void PageLinkInfo (); static void PageIcarusFile (); void WwwGetOddFile(); void WwwMarkDeletedQuery(WWWoQUERY *query, INT4 queryN); INT4 WwwisQueryDeleted(WWWoQUERY *query); char *SmTrimAt (char *s, Int4 n); char *SmFillFrom(char *s, Int4 n, char *fill); INT4 GetEnvp(char **envPtr); void GetEnv(); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** declaration of global or module wide variables */ char pageQuery[3000]; char **envPtr; static struct functions { char name[80]; void (*function) (); } functions[] = { "PageStart", PageStart, "PageReinspectQuery", PageReinspectQuery, "PageDownloadSetOpt", PageDownloadSetOpt, "PageDownloadSet", PageDownloadSet, "PageQueryForm", PageQueryForm, "PageQueryManager", PageQueryManager, "PageConstructQuery", PageConstructQuery, "PageSelectLibrary", PageSelectLibrary, "PageViewCreate", PageViewCreate, "PageViewMgrCreate", PageViewMgrCreate, "PageViewSelectFields", PageViewSelectFields, "PageViewManager", PageViewManager, "PageViewEdit", PageViewEdit, "PageEntry", PageEntry, "PageViewSelectedEntries", PageViewSelectedEntries, "PageLaunchAppl", PageLaunchAppl, "PageSearchOpt", PageSearchOpt, "PageDoSearch", PageDoSearch, "PageDoAppl", PageDoAppl, "PageQueryExpression", PageQueryExpression, "PageCombineQueries", PageCombineQueries, "PageIndexBrowseOpt", PageIndexBrowseOpt, "PageIndexBrowse", PageIndexBrowse, "PageValues2Query", PageValues2Query, "PageLinkOpt", PageLinkOpt, "PageLinkEntryOpt", PageLinkEntryOpt, "PageLinkToLibs", PageLinkToLibs, "PageMoreEntries", PageMoreEntries, "PageLibList", PageLibList, "PageLibNetwork", PageLibNetwork, "PageLibInfo", PageLibInfo, "PageLinkInfo", PageLinkInfo, "PageIcarusFile", PageIcarusFile, "WwwGetOddFile", WwwGetOddFile, "GetEnv", GetEnv, "", NULL }; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** default function for module "arglist" for printing lines */ static INT4 WwwArgPrint (char *formatStr, ...) { static INT4 isFirst=1, isFirstOption=1; TEMPLv templ; va_list ap; char line[2000], tmp[2000], *p; if (isFirst) { printf ("

    \n");
        isFirst=0;
        templ = TemplOpen ("SRSICA:srswww.i", NULL);
        TemplWith(templ,"$argListOption");
      }
      va_start (ap, formatStr);
      vsprintf (line, formatStr, ap);
      va_end (ap);
    
      for (p=line; *p != '\0' && *p == ' '; p++)
        ;
      if (*p == '-') {
        if (isFirstOption) {
          TemplPrint("header");
          isFirstOption = 0;
        }
        line[22] = '\0';
        strcpy (tmp, &line[23]);
        TemplPrint("option",WwwStringEncode (line),  WwwStringEncode (tmp));
      }
      else
        printf ("%s", WwwStringEncode (line));
      return 1;
    }
    
    INT4 WwwGetInput (INT4 argc, char *argv[])
    {
      ARGoLIST *arglist;
      char     *buff, *tmp;
      char     *tmp1, *userId, opt[100];
      INT4     byteN, k, j, argC, isInput=0;
      INT4 funDefined = 0;
      /*
      ** check if input from form 
      */
    
    
      if ((tmp = getenv ("REQUEST_METHOD")) && SmEqs (tmp,"POST")) {
        byteN = atoi (getenv ("CONTENT_LENGTH"));
        buff = WwwReadInput (byteN, _FilTempLN ("SRSWWWTMP:buff"));
        WwwParInput (byteN, buff);
        isInput = 1;
      }
    
      /*
      ** input from command line
      */
    
      else if (argc > 1) {
        arglist = (ARGoLIST *) LibObjByName ("arglist", "wgetz");
        for (k=0; k < argc; k++)
          SmEdit (argv[k], SMxDECODE);
        argC = ArgGet (arglist, argc, argv); 
        isInput = 1;
      }
      
      /*
      ** if the userId was specified by either the form or command line
      ** input then we read the user parameters file ...after that we
      ** must read the form or command line again to give those parameters
      ** the priority they deserve
      */
    
      userId = ParGetStr("userId");
      if (userId && *userId) {
        sprintf (opt, "-id+%s+", userId);
        ParDefStr ("userIdOpt", opt);
        WwwParRead (userId, 1);
        if ((tmp = getenv ("REQUEST_METHOD")) && SmEqs (tmp,"POST"))  {
          WwwParInput (byteN, buff);
        }
        else 
          argC = ArgGet (arglist, argc, argv); 
      }
      
      /*
      ** determine the function to be executed after returning from here
      ** ..set as function parameter "wwwFunction"
      */
    
      if ((tmp = ParGetStr ("wwwFunctionName")) && *tmp) { 
        for (k=0; functions[k].function; k++)
          if (SmEqs (tmp, functions[k].name))
    	ParDefFunction ("wwwFunction", (INT4(*)()) functions[k].function);
        }
    /*
       When no wwwFunction is defined, look for wwwFunctionName1, ...
       which might be defined. get ParGetStr(ParGetStr(wwwFunctionName1)) which 
       is a function name whose value is "submitted" through submit button.
       check for its existence and define wwwFunction
    */
    
      if (!ParGetFunction ("wwwFunction")) { 
        funDefined = 0;
        for( j =0; functions[j].function; j++) {
          if( funDefined ) break;
          if( (tmp = ParGetStrF("wwwFunctionName%d",j)) && *tmp ) { 
    	if(*ParGetStr(tmp)) {
    	  ParDelete (tmp);
    	  ParDeleteF("wwwFunctionName%d",j);
    	  for (k=0; functions[k].function; k++) 
    	    if (SmEqs (tmp, functions[k].name)) {
    	      ParDefFunction ("wwwFunction", (FUNC)functions[k].function);
    	      funDefined = 1; break;
    	    }
    	}
          }
        }
      }
    
      if(!ParGetFunction("wwwFunction"))
        ParDefFunction ("wwwFunction", (FUNC) PageEntry)
     
        ; /*_ErrExit2 (e__functionnotexist, tmp); */ /* take default function!*/
       
      if (ParGetBool ("isHtml3"))
        ParDefStr ("HTML", "H3-");
      else
        ParDefStr ("HTML", "");
      
      if (SmEqs (ParGetStr ("style"),"fancy"))
        ParDefStr("FANCY","FANCY-");
      else
        ParDefStr("FANCY","");
      
      return isInput;
    }
    
    /****** main *******************************************************************
    **
    **      check wwwFunction defined, if,  then call appropriate function
    **      and delete the function parameter name, save the user context.
    **
    **      INPUT:  function name with the arguments defined in arglist under
    **              rwgetz 
    **
    **
    */
    
    main (INT4 argc, char *argv[], char *envp[])
    {
      INT4 (*function) ();
      char *userId=NULL, *tmp;
    
      SrsEnv ();
      LibOpen ("srs5");
      IcaInitSyntax (LibObjByName ("syntax", "icarus"));
    
      MsgSetFnct (WwwPrintMessage);
      setbuf (stdout,NULL); 
      envPtr = envp;
      ParDefStr("view0_Name", "* No View *");
      if (WwwGetInput (argc, argv)) {
        LibInitHyperLinks ();
        if (argv[1] && *argv[1]) {
          strcpy (pageQuery, WwwTransform ("decode", argv[1]));  
        }
        else if (*(tmp=ParGetStr ("pageQuery")))
          strcpy (pageQuery, tmp);  
          
    
        /* might create a new user id */
        userId = ParGetStr("userId");
        if (!( userId && *userId) && ParGetBool ("makeNewUserId")) {
          userId = WwwNewUserId();
          ParDefNum("makeWild",1); /* new user should have this */
        }
        if ((function = ParGetFunction ("wwwFunction")))
          (*function)();
      }
    
      userId = ParGetStr ("userId"); /* may be defined by 'page' function */
      if (userId && *userId)  {
        ParDeleteMatch("wwwFunctionName.+");
        WwwParWrite (userId);
      }
      exit (0);
    }
    
    
    /**api* PageStart *************************************************************
    **
    **      Prints the start page
    **
    */
    
    static void PageStart()
    {
      TEMPLv templ;
    
      templ = WwwInit ();
      TemplWith(templ,"$startPage");
      TemplPrint ("head");
      TemplEndWith ();
      TemplClose (templ);
    }
    
    
    
    /**api* PageSelectLibrary *****************************************************
    **
    **      Lists all databanks that can be searched.
    **
    */
    
    static void PageSelectLibrary()
    {
      TEMPLv    templ;
      SLBo      *lib;
      SRSoGROUP *group;
      char      *libName, *userId, *tmp;
      char      label[40];
      Int4      c1, c2, ngroups, nlib, numCol;
    
      /* create a new user if not already existent */
      userId = ParGetStr("userId");
      if (!( userId && *userId)) {
        userId = WwwNewUserId();
        ParDefNum("makeWild",1); /* new user should have this */
      }
    
      templ = WwwInit ();
      TemplWith(templ,"$selectLibrary");
      TemplPrint("head");
      WwwPrintButtons (templ);
      TemplPrint("submit");
      
      TemplWith (templ, ParGetBool("isHtml3") ? "libs.html3" : "libs.html2");
      for (c1=0; (group = LibNextLibGroup (&c1)); ) {
        /* calculate number of colums */
        numCol = 70 / (LibGetMaxNameSize (group, NULL, "library") + 2);
        if (!(ngroups = LibNofGroups(group))) continue;
        tmp = LibGetGroupName (group, "full");
        if (SmEqs (tmp,"Application")) 
          TemplPrint ("libGroupNameSearch", tmp);     
        else
          TemplPrint ("libGroupName", tmp);     
    
        for (c2=0, nlib=0; (lib = LibNextLib (group, &c2));) {
          if (LibIs (lib, "subentries"))
    	continue;
          libName = LibGetName(lib,"full");
          if (nlib && !(nlib%numCol)) TemplPrint("newRow");
          TemplPrint ("library", libName, WwwChecked (0), 
    		 libName, libName, "");
          nlib++;
        }
        TemplPrint("tail"); 
      }
      TemplEndWith ();
      TemplPrint("tail");
      TemplWith (templ, "colorScheme");
      WwwPresentColorMenu();
      TemplEndWith ();
      TemplEndWith ();
    }
    
    /****** LibNofGroups **************************************************
    **
    **      Counts number of databanks in a group
    **
    **      INPUT:    group object 
    **           IMPLICIT
    **
    **      RETURNS: number of databanks in the group
    **     
    **
    **
    */
    
    INT4 LibNofGroups( SRSoGROUP *group)
    {
      INT4 i,j;
      for( i = 0, j=0; LibNextLib(group,&i) ; j++)
        ;
      return(j);
    }
    
    
    /**api* PageIcarusFile *******************************************************
    **
    **      Prints an icarus file
    **
    */
    
    static void PageIcarusFile ()
    {
      TEMPLv templ;
      SLBo  *lib;
      FILEo *file;
      char  *ln, *fileName, *libName, *type;
    
      templ = WwwInit ();
      TemplWith (templ, "$icarusFile");
      TemplPrint ("head");
    
      libName = ParGetStr ("libList");
      if (!(lib = (SLBo *) LibObjByName ("library", libName)))
        _ErrExit3 (e__objectunknown, "library", libName);
      type = ParGetStr ("icarusFileType");
    
      /* find the Icarus file name */
      if (SmEqs (type, "i"))
        if (!*(fileName = (LibGetIcarusFileName (lib, "structure"))))
          _ErrExit3 (e__objectunknown, "Icarus file", "structure");
      if (SmEqs (type, "is"))
        if (!*(fileName = (LibGetIcarusFileName (lib, "syntax"))))
          _ErrExit3 (e__objectunknown, "Icarus file", "syntax");
      if (SmEqs (type, "it"))
        if (!*(fileName = (LibGetIcarusFileName (lib, "info"))))
          _ErrExit3 (e__objectunknown, "Icarus file", "info");
    
      file = FileNew (fileName);
      if (!FileOpen (file))
        _ErrExit2 (e__filnotok, FileGetName (file, "full"));
      while ((ln = FileReadLn (file))) {
        ln = WwwStringEncode (ln);
        fwrite (ln, strlen (ln), 1, stdout);
      }
      TemplPrint ("tail");
      FileClose (file);
    }
    
    
    
    /**api* PageQueryForm ********************************************************
    **
    **      Builds a queryform page for the selected databanks.
    **
    */
    
    static void PageQueryForm ()
    {
      TEMPLv   templ;
      SLBo      *lib, *libSave;
      SRSoGROUP *group, *groupCurr;
      SLBoFIELD *field;
      char      *tmp, *tmp1, *fieldName, *userId;
      INT4      max, c1, c2, i, currentViewNumber=0;
    
      ParDefNum("listEntriesStartN",1);
      ParDefNum("viewEntriesStartN",1);
    
      /* create a new user if not already existent */
      userId = ParGetStr("userId");
      if (!( userId && *userId)) {
        userId = WwwNewUserId();
        ParDefNum("makeWild",1); /* new user should have this */
      }
    
      templ = WwwInit ();
      TemplWith(templ, "$queryForm");
      TemplPrint("head");
      WwwPrintButtons (templ);
     
      /* loop over selected databanks */
      TemplPrint("searchInfo");
      groupCurr = LibGroupNew (NULL);
      for (c1=0; (group = LibNextLibGroup (&c1)); ) 
        for (c2=0; (lib = LibNextLib (group, &c2));) { 
          if (LibIs (lib, "selected")) {
    	libSave = lib;
    	LibGroupAddDb (groupCurr, lib);
            TemplPrint("listLibs",LibName (lib), LibName (lib));
          }
        }
      if (!groupCurr->libraryN) 
        _ErrExit (e__nolibslct); /* no databanks were selectect */
      TemplPrint("submit");
      TemplWith (templ, "chunkSize");
      WwwPresentChunkSizes (templ);  
      TemplEndWith ();
      WwwPresentActiveViews (groupCurr, NULL, NULL, templ, 0);
      TemplPrint ("searchOptions", WwwChecked (ParGetNum("makeWild")));
      TemplWith(templ, ParGetBool("isHtml3") ? 
    	    "queryInput.html3" : "queryInput.html2");
      TemplPrint("head");
    
    
      max = LibGetMaxNameSize (groupCurr, NULL, "field")+1;
    
      for (c1=0; (field = LibNextGroupField (groupCurr, 
    			 ParGetBool ("isOnlyCommonFields"), &c1));) {
        fieldName = LibGetFieldName (field);
    
        ParDefNum ("l", max-strlen (fieldName));
        if (FieldIs (field, "header")) {
          if (LibFieldHeaderHasWith (libSave, field, "doQuery"))
    	TemplPrint ("fieldHeader", fieldName);
        }
        else if (FieldIs (field, "num") || FieldIs (field, "real")) {
          tmp = ParGetStrF("query_%s_begmod",fieldName);
          tmp1 = ParGetStrF("query_%s_endmod",fieldName);
          TemplPrint("fieldNum",
    		 fieldName, fieldName, "", fieldName,
    		 WwwSelected (SmEqs (tmp,">=")), WwwSelected (SmEqs (tmp,">")),
    		 fieldName, fieldName,
    		 WwwSelected (SmEqs (tmp1,"<=")),WwwSelected (SmEqs(tmp1,"<")),
    		 fieldName, fieldName);
        } 
        else if (FieldIs (field, "doQuery")) 
          TemplPrint("fieldText", fieldName,fieldName,"",fieldName,fieldName); 
        if (FieldIs (field, "subEntry")) {
          tmp = ParGetStrF("%s",fieldName);
          TemplPrint("subEntry",fieldName,WwwChecked (*tmp));
        }
        TemplPrint("rowEnd");
      }
      TemplPrint("tail"); 
      TemplEndWith ();
      TemplPrint("tail");  
    }
    
    
    void WwwPrintFieldGroupInfo (SLBo *lib, SLBoFIELD *fieldGroup)
    {
      SLBoFIELD *field;
      Int4 c;
    
      TemplPrint ("group.lib", LibName (lib));
      for (c=0; (field=LibNextFieldInGroup (lib, fieldGroup, &c));)
        TemplPrint ("group.member", LibGetFieldName (field), LibName (lib), 
    		LibGetFieldName (field));
      TemplPrint ("group.tail");
    }
    
    
    void WwwPrintFieldInfo (SLBo *lib, SLBoFIELD *fieldSelect, Int4 count)
    {
      LIBoINDEX *libInx;
      SLBoFIELD *field;
      STRv name=StrNew(), shrt=StrNew(), type=StrNew(), valN=StrNew(), 
           refN=StrNew(), date=StrNew(), status=StrNew();
      char tmp[500];
      Int4 c, isOk;
    
      if (!count)
        TemplPrint ("head");
      for (c=0; (field = fieldSelect) || (field = LibNextField (lib, &c));) {
        if (FieldIs (field, "group") || FieldIs (field, "header"))
          continue;
        
        StrAppS (&name, TemplSPrint (tmp, "name", LibGetFieldName (field), 
    				 LibName (lib), LibGetFieldName (field)));
        StrAppS (&shrt, TemplSPrint (tmp, "short", LibGetFieldShortName (field)));
        
        if (FieldIs (field, "id"))
          TemplSPrint (tmp, "type", "ID");
        else if (FieldIs (field, "real"))
          TemplSPrint (tmp, "type", "real");
        else if (FieldIs (field, "num"))
          TemplSPrint (tmp, "type", "int");
        else if (FieldIs (field, "index"))
          TemplSPrint (tmp, "type", "string");
        else if (FieldIs (field, "link"))
          TemplSPrint (tmp, "type", "link");
        else if (FieldIs (field, "show"))
          TemplSPrint (tmp, "type", "show");
        StrAppS (&type, tmp);
        
        isOk = FieldIs (field, "index")&&
               (libInx = LibIndexOpen (lib, field, 1)) ? 1:0;
        if (isOk) {
          StrAppS (&valN, TemplSPrint(tmp, "valN", BtrGetRecordN(libInx->btree))); 
          StrAppS (&refN, TemplSPrint(tmp, "refN", IdsGetIdN (libInx->idsFile))); 
        }
        else {
          StrAppS (&valN, TemplSPrint(tmp, "empty"));
          StrAppS (&refN, TemplSPrint(tmp, "empty"));
        }
        StrAppS (&date, TemplSPrint(tmp, "date", isOk ? 
               TimeToString (BtrGetTimeCreated (libInx->btree), "short") : "")); 
        
        if (!isOk)
          StrAppS (&status, TemplSPrint (tmp, "status", "not indexed"));
        else if (BtrIsBusy (libInx->btree))
          StrAppS (&status, TemplSPrint (tmp, "status", "busy"));
        else if (!IdsIsCompressed (libInx->idsFile))
          StrAppS (&status, TemplSPrint (tmp, "status", "not compressed"));
        else
          StrAppS (&status, TemplSPrint (tmp, "status", "ok"));
    
        if (fieldSelect)
          break;
      }
      if (!count)
        TemplPrint ("tail", _Str (name), _Str (shrt), _Str (type), _Str (valN), 
    		_Str (refN), _Str (date), _Str (status));
      else
        TemplPrint ("data", LibName (lib), _Str (name), _Str (shrt), _Str (type), 
                    _Str (valN), _Str (refN), _Str (date), _Str (status));
    
      StrDel (name); 
      StrDel (shrt); 
      StrDel (type); 
      StrDel (valN); 
      StrDel (refN);
      StrDel (date);
      StrDel (status);
    }
    
    /****** PageIndexBrowseOpt ****************************************************
    **
    **      Presents the options of browsing an index.
    **
    */
    
    static void PageIndexBrowseOpt ()
    {
      TEMPLv    templ, libTempl, genTempl;
      SLBo      *lib;
      SLBoFIELD *field;
      SRSoGROUP *group, *groupCurr;
      char      libList[200]="", path[999], *fieldName, *infoName, *tmp, label[200];
      INT4      c1,c2;
    
      templ = WwwInit ();
    
      TemplWith(templ,"$dataField");
      TemplPrint ("head");
      WwwPrintButtons (templ);
    
      /* make string with library list */
      groupCurr = LibGroupNew (NULL);
      if (*(tmp = ParGetStr ("libName"))) {
        if (!(lib = (SLBo *) LibObjByName ("library", tmp)))
          _ErrExit3 (e__objectunknown, "library", tmp);
        LibGroupAddDb (groupCurr, lib);
        strcpy (libList, tmp);
      }
      else {
        for (c1=0; (group=LibNextLibGroup (&c1)); ) 
          for (c2=0; (lib=LibNextLib (group, &c2));) {
    	if (LibIs(lib, "selected")) {
    	  sprintf (libList, "%s%s ", libList, LibName (lib));
    	  LibGroupAddDb (groupCurr, lib);
    	}
          }
        libList[strlen(libList)-1] = '\0';
      }
    
      fieldName = ParGetStr("browseIndex");
      TemplPrint ("title", fieldName);
    
      /* general description */
      if ((genTempl = TemplOpen ("SRSDB:general.it", NULL))) {
        TemplWith (genTempl, "$main");
        if (TemplExists (genTempl, fieldName)) 
          WwwPrintInfoChapter (templ, genTempl, 
    			   "$dataField.description", fieldName);
        TemplEndWith ();
      }
    
      /* description from a single databank */
      for (c2=0; (lib=LibNextLib (groupCurr, &c2));) {
        if ((libTempl = TemplOpen (LibGetIcarusFileName (lib, "info"), NULL))) {
          TemplWith (libTempl, "$dbInfo");
          sprintf (label, "fields.%s", fieldName);
          if (TemplExists (libTempl, label)) {
    	TemplWith (templ, "$dataField.description");
    	TemplPrint ("headFrom", LibName (lib));
    	TemplEndWith ();
    	TemplPrint (label);
    	TemplWith (templ, "$dataField.description");
    	TemplPrint ("tail");
    	TemplEndWith ();
          }
          TemplEndWith ();
        }
      }  
    
      /* status of field/index */
      TemplWith (templ, "fields");
      if (SmEqs (fieldName, "all") || SmEqs (fieldName, "alltext")) {
        TemplPrint ("group.head");
        for (c2=0; (lib=LibNextLib (groupCurr, &c2));) {
          if (field = LibHasFieldNamed (lib, fieldName))
    	WwwPrintFieldGroupInfo (lib, field); 
        }
      }
      else {
        TemplPrint ("head");
        for (c2=0; (lib=LibNextLib (groupCurr, &c2));) {
          field = LibHasFieldNamed (lib, fieldName);
          WwwPrintFieldInfo (lib, field, 1); 
        }
      }
      TemplPrint ("tail");
      TemplEndWith ();
      TemplPrint ("browse", fieldName, libList);
      TemplPrint ("tail");
    }
    
    /****** PageIndexBrowse *******************************************************
    **
    **      Prints all or some values of an index.
    **
    */
    
    static void PageIndexBrowse ()
    {
      TEMPLv templ;
      char   *libList, *fieldName, queryStr[200];
    
      templ = WwwInit ();
      TemplWith(templ,"$browseList");
      TemplPrint ("head");
      WwwPrintButtons (templ);
      
      libList = ParGetStr ("browseLibs");
      fieldName = ParGetStr ("browseIndex");
      sprintf (queryStr, "[{%s}-%s:%s]", libList, fieldName, 
    	   ParGetStr ("browseMatch"));
      TemplPrint ("title", fieldName, fieldName, libList, 
    	      ParGetNum("printIndexValN") + ParGetNum ("printIndexFirstValN"));
    
      ParDefNum ("queryListValues", 1);
      ParDefNum ("isHTMLFormat", 1);
      /* Query prints the values!*/
      QuerySetPrintValue (WwwPrintValue);
      TemplWith (templ, "values");
      Query (queryStr, "");
      TemplEndWith ();
      TemplEndWith ();
    }
    
    
    
    /**api* PageValues2Query *****************************************************
    **
    **      Collects all selected values and combines them to a query.
    **  
    */
    
    static void PageValues2Query ()
    {
      STRv str=NULL;
      char *tmp;
      Int4 valN = ParGetNum ("printIndexValN"), k;
    
      for (k=1; k<=valN; k++)
        if (*(tmp = ParGetStrF ("value_%d", k))) {
          tmp = WwwTransform ("decode", tmp);
          if (!str) 
    	str = StrCpyS (tmp);
          else
    	StrPrintf (&str, " | %s", tmp);
        }
      
      if (str) {
        WwwQueryExpression ("query", _Str (str));
        StrDel (str);
      }
    }
    
    
    
    /**api* PageQueryManager *****************************************************
    **
    **      Shows all successful queries and allows various operations on them.
    **  
    */
    
    static void PageQueryManager()
    {
      WWWoQUERY *query ;
      TEMPLv templ;
      char      *tmp, *par, *userId;
      INT4      Nqueries, k, j, currentViewNumber=0;
    
    /* initialize the parameters */
      ParDefStr("expr","");
      ParDefNum("listEntriesStartN",1);
      ParDefStr ("fieldList", "reset"); 
      Nqueries = ParGetNum("numberOfQueries");
    
      templ = WwwInit ();
      TemplWith(templ,"$queryManager");
      TemplPrint("head");
      WwwPrintButtons (templ);
      if( ParGetBool("isHtml3"))
        TemplWith(templ,"queryOptions.html3");
      else
        TemplWith(templ,"queryOptions.html2");
      TemplPrint("head");
      TemplEndWith();
      TemplWith(templ,"chunkSize");
      WwwPresentChunkSizes (templ);
      TemplEndWith();
      TemplWith(templ,"selectView");
      WwwPresentViewList ("current", templ);
      TemplEndWith();
      if(ParGetBool("isHtml3")) 
        TemplWith(templ,"queryOptions.html3.queryInfo");
      else
        TemplWith(templ,"queryOptions.html2.queryInfo");
      TemplPrint("head"); 
      for ( k = 1; k <= Nqueries; k++) {
        query = WwwGetQuery (k);
        if (SmEqs (query->type, "singleentry") || 
    	SmEqs (query->type, "linkentry"))continue;
        if(WwwisQueryDeleted(query)) continue;
        
        if(*(ParGetStrF("qmstr%d",k))){
          WwwMarkDeletedQuery(query,k);
          continue;
        }
        if (!(ParGetBool("isHtml3"))) {
          TemplPrint("title", k,query->name,query->name,query->type,
    		 WwwStringEncode(query->queryStr),query->entryN);
          for(j=0; query->lib[j].entryN;j++) {
    	TemplPrint("entryN", query->lib[j].entryN, query->lib[j].name);
    	if( query->isSubEntry)
    	  TemplPrint("subEntry");
          }
        }
        else {
          TemplPrint("title",k,query->name,query->name,
    		 query->type,query->entryN);
          TemplPrint("libAlign");
          for(j=0; query->lib[j].entryN; j++) {
    	TemplPrint("library",(query->lib[j].name));
          }
          TemplPrint("numAlign");
          for(j=0; query->lib[j].entryN;j++) {
            TemplPrint("entryN",(query->lib[j].entryN));
          }
          TemplPrint("queryStr",WwwStringEncode(query->queryStr),
    		 k,query->comment);
          if( query->isSubEntry)
            TemplPrint("subEntry");
          TemplPrint("rowEnd");
        }
        WwwDelQuery(query);
      }
      TemplEndWith();
      TemplPrint("tail");
    }
    
    
    
    /****** PageQueryExpression ***************************************************
    **
    **      Does an query expression.
    **
    */
    
    static void PageQueryExpression()
    {
      WwwQueryExpression ("expression", ParGetStr ("expr"));
    }
    
    /****** PageCombineQueries ****************************************************
    **
    **      Combines several queries with a single set operator.
    **
    */
    
    static void  PageCombineQueries ()
    {
      WWWoQUERY *query;
      STRv str;
      INT4 k,j;
      char *tmp, op;
    
      tmp = ParGetStr("operator");
      if (SmEqs(tmp,"AND"))
        op = '&';
      else if (SmEqs(tmp,"OR"))
        op = '|';
      else if (SmEqs(tmp,"BUTNOT"))
        op = '!';
      else 
        return;
    
      for (j=0, k=0; WwwNextSelectedQuery (&j, &tmp); k++) {
        if (!k)
          str = StrCpyS (tmp);
        else
          StrPrintf (&str, " %c %s", op, tmp);
      }
      if (!k)
        _ErrExit (e__wwwNoQueryOrEntriesSelected);
      else
        WwwQueryExpression ("expression", _Str (str));
    }
    
    /**api* PageReinspectQuery ****************************************************
    **
    **      Repeats a query selected in the QueryManager form.
    **
    */
    
    static void PageReinspectQuery ()
    {
      INT4 j=0;
    
      if ((j=WwwNextSelectedQuery (&j, NULL))) {
        WwwQueryRepeat (j);
        WwwQueryPrint (j);
      }
      else 
        _ErrExit (e__wwwNoQueryOrEntriesSelected);
    }
    
    /****** PageSearchOpt *********************************************************
    **
    **      Displays the input form to launch a search program
    **
    */
    
    static void  PageSearchOpt ()
    {
    #ifdef xxx
      TEMPLv          templ;
      LIBoApplication *appl;
      WWWoQUERY       *query;
      SETo            *set;
      SEQo            *seq;
      STRv            s;
      ENTRYv          entry;
      IDoENTRY        id;
      Int4            queryNo;
      char            *tmp;
    
      if (!*(tmp = ParGetStr ("applicationName")))
        tmp = ParGetStr ("libList");
      if (!(appl = (LIBoApplication*) LibObjByName ("application", tmp)))
        _ErrExit3 (e__objectunknown, "application", tmp);
    
      templ = WwwInit ();
      TemplWith (templ, LibGetApplTemplate (appl));
      TemplPrint ("head");
      WwwPrintButtons (templ);
    
      if ((queryNo=WwwQuerySelectedEntries ())) {
        query = WwwGetQuery (queryNo);
        set = SetGet (query->name);
        SetGetID (set, 1, &id);
        entry = EntryOpen (&id);
        seq=SdbGetEntrySeq (entry);
        s = Seq2Pretty (seq, 60);
        TemplPrint ("tail", _Str (s));
        EntryClose (&entry);
        StrDel (s);
        WwwDelQuery (query);
      }
      else 
        TemplPrint ("tail", "");
    #endif
    }
    
    static void PageLaunchAppl ()
    {
      APPLo *appl;
      char  *applName;
    
      applName = ParGetStr ("applicationName");
      if (!(appl = ApplNamed (applName)))
        _ErrExit3 (e__objectunknown, "application", applName);
      WwwApplOpt (appl);
    }
    
    
    
    
    
    FILE *file;
    INT4 wwwWriteFile (char *formatStr, ...)
    {
      va_list ap;
      
      va_start (ap, formatStr);
      vfprintf (file, formatStr, ap);
      va_end (ap);
      
      if (formatStr[strlen (formatStr) -1] != '\n')
        fprintf (file, "\n");
      
    }
    
    
    /****** function **************************************************************
    **
    **         Prepares a c-shell for launching a sequence search 
    **
    */ 
    
    static void PageDoSearch()
    {
      TEMPLv templ, cshTempl;
      SLBo   *lib;
      SEQo   *seq;
      INT4   errCode;
      STRv   searchCom;
      char   *userId = ParGetStr("userId"), *libName=ParGetStr ("libList");
      char   seqFile[200], cshFile[200], s[100], command[200]="", *tmp;
    
      if (!(lib = (SLBo *) LibObjByName ("library", libName)))
        _ErrExit3 (e__objectunknown, "library", libName);
    
      /* write out sequence file */
      seq = SeqReadString (ParGetStr ("inputSequence"));
      sprintf (seqFile, "%s/%s/tmp.seq", "SRSWWWTMP", userId);
      file = FilOpenW (seqFile, &errCode);
      _ErrExit2 (errCode, seqFile);
      if (SmEqs (ParGetStr ("searchSeqFormat"), "gcg"))
        SeqWriteGCG (seq, "tmp", (INT4(*)(char*,...)) wwwWriteFile);
      else
        SeqWriteFasta (seq, "tmp", (INT4(*)(char*,...)) wwwWriteFile);
      fclose (file);
    
      /* prepare a blast c-shell file*/
      sprintf (cshFile,"SRSWWWTMP:%s/script", userId);
      if (!(cshTempl = TemplOpen ("SRSICA:srswww.i", cshFile)))
        _ErrExit2 (errCode, cshFile);
      TemplWith (cshTempl, ParGetStr ("scriptTemplate"));
      TemplPrint ("head");
      TemplSPrint (command, "launch");
      
      /* print the blast command */
      TemplPrintAll ("command");
      searchCom=StrNew ();
      TemplSPrintAll (&searchCom, "command");
      TemplPrint ("tail");
      TemplEndWith ();
      TemplClose (cshTempl);
    
      /* print result page and execute script */
      templ = WwwInit ();
      TemplWith (templ, "$searchResult");
      TemplPrint ("head", libName, libName, libName, libName);
      TemplWith (templ, "chunkSize");
      WwwPresentChunkSizes (templ);  
      TemplEndWith ();
      WwwPresentActiveViews (NULL, lib, NULL, templ, 0);
      TemplPrint ("tail", _Str (searchCom));
    
      fflush (stdout);
      FilChMod (cshFile,"X"); /* there is no 'X' mode opt., but changes */
      system (command);
    
      sprintf (s, "SRSWWWTMP:%s/",userId); 
      ParDefStr ("libGroup", lib->group->com);
      ParDefStr ("libList", lib->nam);
      ParDefStrF (s, "%sDirName", lib->nam); 
    }
    
    static void PageDoAppl ()
    {
      APPLo    *appl;
      APPLoOpt *opt;
      STRv     str;
      TEMPLv   templ;
      SEQo     *seq;
      SLBo     *lib;
      INT4     errCode, i;
      char     *userId = ParGetStr("userId");
      char     seqFile[200], *applName, *optName,  *tmp, s[100];
    
      applName = ParGetStr ("applName");
      appl = ApplNamed (applName);
    
      /* write out sequence file */
      sprintf (seqFile, "SRSWWWTMP/%s/tmp.seq", userId);
      file = FilOpenW (seqFile, &errCode);
      _ErrExit2 (errCode, seqFile);
    
      if (ApplIs (appl, "multi"))
        for (i=1; 1; i++) {
          if (*(tmp=ParGetStrF ("inputSequence%d", i))) {
    	seq = SeqReadString (tmp);
    	SeqSetName (seq, ParGetStrF ("inputSequenceName%d", i));
    	SeqSetComment (seq, ParGetStrF ("inputSequenceComment%d", i));
    	SeqWritePIR (seq, NULL, NULL, (INT4(*)(char*,...)) wwwWriteFile);
    	SeqDel (&seq);
          }
          else break;
        }
      else {
        seq = SeqReadString (ParGetStr ("inputSequence"));
        if (ApplIsInSeq (appl, "gcg"))
          SeqWriteGCG (seq, "tmp", (INT4(*)(char*,...)) wwwWriteFile);
        else if (ApplIsInSeq (appl, "fasta"))
          SeqWriteFasta (seq, "tmp", (INT4(*)(char*,...)) wwwWriteFile);
      }
      fclose (file);
    
      /* create and run a script to init option variables of the appl */
      str = StrNew ();
      StrPrintf (&str, "$userId = $ParStr:userId\n"); 
      for (i=0; (opt=ApplNextOpt (appl, &i)); ) {
        optName = ApplOptGetName (opt);
        StrPrintf (&str, "$opt.%s = $ParStr:%s_%s\n", optName, 
    	       ApplGetName (appl), optName);
      }
      ApplInit (appl);
      ApplEval (appl, _Str (str));
      StrDel (str);
       
    
      /* print result page and execute script */
      templ = WwwInit ();
      TemplWith (templ, "$applResult");
      TemplPrint ("head", applName, applName);
      WwwPrintButtons (templ);
      TemplPrint ("title", applName);
    
      if (ApplIs (appl, "search")) {
        TemplPrint ("search.head", applName, applName);
        TemplWith (templ, "search.chunkSize");
        WwwPresentChunkSizes (templ);  
        TemplEndWith ();
        TemplWith (templ, "search");
        WwwPresentActiveViews (NULL, LibObjByName ("library", applName), 
    			   NULL, templ, 0);
        TemplEndWith ();
        TemplPrint ("search.tail");
      }
      TemplPrint ("tail", ApplGetCommand (appl));
    
      /* create script and execute */
      fflush (stdout);
      ApplLaunch (appl);
    
      /* 'remember' the clustalw directory */
      if (!(lib = (SLBo *) LibObjByName ("library", applName)))
        _ErrExit3 (e__objectunknown, "library", applName);
      sprintf (s, "SRSWWWTMP:%s/", userId); 
      ParDefStr ("libGroup", lib->group->com);
      ParDefStr ("libList", lib->nam);
      ParDefStrF (s, "%sDirName", lib->nam); 
    }
    
    
    
    /****** WwwMarkDeletedQuery *********************************************
    **
    **      Mark deleted query. 
    **
    **      INPUT :   Address of query Object [W]
    **                 query number (INT)
    **
    **      RETURNS:   none
    **
    */
    void WwwMarkDeletedQuery(WWWoQUERY *query, INT4 queryN)
    {
      char par[80];
    
      query->isDeleted = 1; /* set the status flag */
      sprintf(par,"QueryDeleted_%d",queryN);
      ParDefNum(par,query->isDeleted);
    }
    
    /****** WwwisQueryDeleted *********************************************
    **
    **      Checks whether a query marked deleted or not.
    **
    **      INPUT :   Address of query Object [R]
    **
    **      RETURNS:   query status flag.
    **
    */
    INT4 WwwisQueryDeleted(  WWWoQUERY *query)
    {
      return(query->isDeleted);
    }
    
    
    /**api* PageConstructQuery ***************************************************
    **
    **      Constructs a valid query from form input, performs it and 
    **      displays the result.
    **
    */
    static void PageConstructQuery()
    {
      SLBo         *lib;
      SLBoFIELD    *field;
      SRSoGROUP    *group, *groupCurr;
      QASvQUERY    query;
      QASvRETRIEVE r;
      char         *fieldName, *tmp;
      INT4         c1,c2;
      
      query = QasNew ();
      QasSetOp (query, ParGetStr ("query_operator"));
      
      /* set selected libraries */
      groupCurr = LibGroupNew (NULL);
      for (c1=0; (group = LibNextLibGroup (&c1)); ) 
        for (c2=0; (lib = LibNextLib (group, &c2));) {
          if (!(LibIs(lib, "selected"))) 
    	continue;
          QasSetLibrary(query, LibGetName(lib,"full"));
          LibGroupAddDb (groupCurr, lib);
        }
    
      /* set index queries */
      for (c1=0; (field = LibNextGroupField (groupCurr, 1, &c1));) {
        fieldName = LibGetFieldName(field) ;
        r = NULL;
        if(FieldIs(field,"num") || FieldIs (field, "real")) {
          if (*(tmp = ParGetStrF("query_%s_begin",fieldName))) {
    	r = QasNewRetrieve (query, fieldName);
    	QasSetRangeBegin (query, r, tmp);
          }
          if (*(tmp = ParGetStrF("query_%s_end",fieldName))) {
    	if (!r) 
    	  r = QasNewRetrieve (query, fieldName);
    	QasSetRangeEnd (query, r, tmp); 
          }
          if (SmEqs (ParGetStrF("query_%s_beginmod",fieldName), ">"))
    	QasSetRangeBeginExcl (query, r);
          if (SmEqs (ParGetStrF("query_%s_endmod",fieldName), "<"))
    	QasSetRangeEndExcl (query, r);
        }
        else
          if( *(ParGetStrF ("query_%s", fieldName))) {
    	r = QasNewRetrieve (query, fieldName);
    	QasSetRetrieveStr (query, r, ParGetStrF ("query_%s", fieldName));
          }
        if (r && FieldIs (field,"subEntry") &&
    	ParGetBoolF ("subEntry_%s", fieldName))
          QasSetSubEntries (query, r);
      } 
      if(ParGetNum("makeWild"))
        QasSetMakeWild (query);
    
      ParDeleteMatch ("^query_");
      if (QasGetQueryString(query))
        WwwQueryExpression ("query", QasGetQueryString(query));
      else 
        _ErrExit (e__wwwNoQuerySpecified);
      
    }
    
    
    /****** PageMoreEntries ************************************************
    **
    **      Lists entries of already existing query.
    **
    */
    
    static void  PageMoreEntries ()
    {
      WwwQueryRepeat (ParGetNum ("listSetNumber"));
      WwwQueryPrint (ParGetNum ("listSetNumber"));
    }
    
    
    
    /****** PageLinkOpt ***********************************************************
    **
    **       Lets the user link an entire set or an entry selection to other
    **       databanks.
    **
    */
    
    static void PageLinkOpt ()
    {
      TEMPLv    templ;
      SLBo      *lib;
      SRSoGROUP *group;
      char *querystr, *opt; 
      Int4  ngroups = 0, num[10], c1=0, c2,setN;
      Int4  nlib = 0, numCol, queryN;
    
      templ = WwwInit ();
      TemplWith (templ, "$linkPage");
      querystr = ParGetStr("queryString");
    
      /* get either set selected from query manager or the list of
         selected entries */
      if ((queryN=WwwNextSelectedQuery (&c1, NULL)) ||
          (queryN=WwwQuerySelectedEntries ()))
        ParDefNum("linkSetNumber",queryN);
      else
        _ErrExit (e__wwwNoQueryOrEntriesSelected);
      setN = ParGetNum("linkSetNumber");
    
      TemplPrint ("head", querystr);
      WwwPrintButtons (templ);
      opt = ParGetStr ("linkSetType");
      TemplPrint ("linkType", setN);
    
      TemplWith(templ,"$queryManager.chunkSize");
      WwwPresentChunkSizes (templ);
      TemplEndWith();
      TemplWith(templ,"$queryManager.selectView");
      WwwPresentViewList ("reset", templ);
      TemplEndWith();
    
    
      TemplWith (templ, ParGetBool("isHtml3") ? "html3" : "html2");
      for (c1=0; (group = LibNextLibGroup (&c1)); ) {
        /* adjust number of columns */
        numCol = 70 / (LibGetMaxNameSize (group, NULL, "library") + 2);
        if (!(ngroups = LibNofGroups(group))) 
          continue;
        TemplPrint ("dbGroup", group->com);     
        for (c2=0, nlib = 0; (lib = LibNextLib (group, &c2));) {
          if (LibIs (lib, "subentries")) continue;
          if (!(nlib%numCol)) 
    	TemplPrint ("newRow");
          TemplPrint ("library", LibGetName (lib,"full"),
    		  WwwChecked (LibIs (lib,"linkTarget")),
    		  LibGetName(lib,"full"), LibGetName(lib,"full"), "");
          nlib++;
        }
        TemplPrint ("tail");
      }
      TemplEndWith ();
      TemplPrint ("tail");
    }
    
    /****** PageLinkEntryOpt ******************************************************
    **
    **       Lets the user link an entire set or an entry selection to other
    **       databanks.
    **
    */
    
    static void PageLinkEntryOpt ()
    {
      TEMPLv    templ;
      SLBo      *lib;
      SRSoGROUP *group;
      char *querystr, *opt; 
      Int4  ngroups = 0, num[10], c1=0, c2,setN;
      Int4  nlib = 0, numCol, queryN;
    
      templ = WwwInit ();
      TemplWith (templ, "$linkPage");
      querystr = ParGetStr("queryString");
    
      TemplPrint ("head", querystr);
      WwwPrintButtons (templ);
      opt = ParGetStr ("linkSetType");
      TemplPrint ("linkEntry", 
                  ParGetStr ("libName"), 
    	      ParGetStr ("entryName"),
                  ParGetStr ("libName"), 
    	      ParGetStr ("entryName"));
    
      /* now the same as PageLinkEntryOpt */
    
      TemplWith(templ,"$queryManager.chunkSize");
      WwwPresentChunkSizes (templ);
      TemplEndWith();
      TemplWith(templ,"$queryManager.selectView");
      WwwPresentViewList ("reset", templ);
      TemplEndWith();
    
    
      TemplWith (templ, ParGetBool("isHtml3") ? "html3" : "html2");
      for (c1=0; (group = LibNextLibGroup (&c1)); ) {
        /* adjust number of columns */
        numCol = 70 / (LibGetMaxNameSize (group, NULL, "library") + 2);
        if (!(ngroups = LibNofGroups(group))) 
          continue;
        TemplPrint ("dbGroup", group->com);     
        for (c2=0, nlib = 0; (lib = LibNextLib (group, &c2));) {
          if (LibIs (lib, "subentries")) continue;
          if (!(nlib%numCol)) 
    	TemplPrint ("newRow");
          TemplPrint ("library", LibGetName (lib,"full"),
    		  WwwChecked (LibIs (lib,"linkTarget")),
    		  LibGetName(lib,"full"), LibGetName(lib,"full"), "");
          nlib++;
        }
        TemplPrint ("tail");
      }
      TemplEndWith ();
      TemplPrint ("tail");
    }
    
    
    
    /****** PageLibNetwork ********************************************************
    **
    **	Prints the library network in a tabular representation;
    **
    */ 
    
    void PageLibNetwork ()
    {
      TEMPLv    templ;
      SRSoGROUP *fromGroup, *toGroup;
      SLBo      *fromLib, *toLib;
      LINKo     *link;
      LINKvNode path;
      Int4      c1, c2, c3, c4;
      char      *fromLibName, *toLibName, *letter;
    
      templ = WwwInit ();
      TemplWith (templ, "$libNetwork");
      TemplPrint ("head");
      WwwPrintButtons (templ);
      TemplPrint ("title");
    
      /* iterate over all 'from' libs */
      for (c1=0; (fromGroup = LibNextLibGroup (&c1)); )
        for (c2=0; (fromLib = LibNextLib (fromGroup, &c2)); ) {
          if (LibIs (fromLib, "subentries")) continue;
          fromLibName = LibName (fromLib);
          TemplPrint ("fromLib", fromLibName, fromLibName);
          /* iterate over all 'to' libs */
          for (c3=0; (toGroup = LibNextLibGroup (&c3)); ) {
    	for (c4=0; (toLib = LibNextLib (toGroup, &c4)); ) {
    	  if (LibIs (toLib, "subentries")) continue;
    	  toLibName = LibName (toLib);
    	  if (fromLib == toLib)
    	    break; /* link with 'self' - diagonal is reached */
    	  else { 
    	    if ((link = LibGetLink (fromLibName, toLibName))) 
    	      TemplPrint ("link.direct", fromLibName, toLibName);
    	    else {
    	      if ((path = LinkSearchPath (fromLibName, toLibName))) 
    		TemplPrint ("link.indirect", fromLibName, toLibName,
    			    LinkGetPathLength (path));
    	      else
    		TemplPrint ("link.none");
    	    }
    	  }
    	}
    	if (fromLib == toLib)
    	  break;
          }
          TemplPrint ("rowEnd");
        }
      
      /* print all databank names vertically */
      TemplPrint ("toLibs");
      for (c1=0; (toGroup = LibNextLibGroup (&c1)); )
        for (c2=0; (toLib = LibNextLib (toGroup, &c2)); ) {
          if (LibIs (toLib, "subentries")) continue;
          toLibName = LibName (toLib);
          TemplPrint ("toLib.head");
          for (letter=toLibName; *letter; letter++)
    	TemplPrint (*(letter+1) ? "toLib.letter" : "toLib.last", *letter);
          TemplPrint ("toLib.tail");
        }
    
      TemplPrint ("tail");
      TemplEndWith ();
      TemplClose (templ);
    }
    
    
    /****** PageLinkInfo *********************************************************
    **
    **	Prints information about a link between two data banks.
    **
    */ 
    
    void PageLinkInfo ()
    {
      TEMPLv    templ;
      LINKo     *link;
      LINKvNode path, p;
      char      *from, *to, *tmp;
      Int4      isReverse, toN, fromN, totalN;
    
      templ = WwwInit ();
      TemplWith (templ, "$linkInfo");
      TemplPrint ("head");
      WwwPrintButtons (templ);
      TemplPrint ("title");
    
      to = ParGetStr ("toLibName");
      from = ParGetStr ("fromLibName");
    
      if (!(path = LinkSearchPath (to, from)))
        TemplPrint ("noLink", from, to);
      else {
        if (LinkGetPathLength (path) == 1) /* direct link */
          TemplPrint ("direct", from, to);
        else { /* indirect link */
          TemplPrint ("indirect.head", WwwGetLinkedEntriesN (to, from), from,
    		  WwwGetLinkedEntriesN (from, to), to, from);
          for (tmp=NULL, p=path; (p = LinkBackTrack (p, &link, &isReverse));
    	   tmp=isReverse? LibName (link->lib1) : LibName (link->lib2))
    	if (tmp)
    	  TemplPrint ("indirect.pathLib", tmp);
          TemplPrint ("indirect.lastLib", tmp);
        }
    
        TemplWith (templ, "table");
        TemplPrint ("head");
        while ((path = LinkBackTrack (path, &link, &isReverse))) {
          to = LibName (link->lib2);
          from = LibName (link->lib1);
    
          if (LinkOpen (link, "read")) {
    	toN = LinkGetEntryN (link, 1);
    	fromN = LinkGetEntryN (link, 0);
    	totalN = LinkGetLinkN (link);
          }
          else 
    	toN=0, fromN=0, totalN=0;
    	
          if (isReverse)
    	TemplPrint ("names", to, to, toN, from, from, fromN);
          else
    	TemplPrint ("names", from, from, fromN, to, to, toN);
          
          TemplPrint("total", totalN);
          if (link->typ == LNKxREAD)
    	TemplPrint("read", from, link->toField->nam, to);
          else 
    	TemplPrint("index", link->fromField->nam, to, link->toField->nam,from);
    
          /* creation time */
          if (toN)
    	TemplPrint ("creTime", TimeToString (LinkGetCreTime (link), "long"));
          else 
    	TemplPrint ("notCreated");
    
          TemplPrint ("rowEnd");
        }
      }
      TemplEndWith ();
      TemplPrint ("tail");
      TemplClose (templ);
    }
    
    
    Int4 WwwGetLinkedEntriesN (char *from, char *to)
    {
      SETo *set;
      STRv str;
      Int4  n;
    
      str = StrNew ();
      if ((set = Query (_Str (StrPrintf (&str, "%s>%s", from, to)),"linkN"))) 
        n = SetGetSize (set);
      else 
        n = 0;
      SetDelete ("linkN");
      StrDel (str);
      return n;
    }
    
    
    
    /****** PageLibList **********************************************************
    **
    **      Displays information about available databanks
    **
    */
    
    void PageLibList ()
    {
      TEMPLv    templ;
      SLBo      *lib;
      SRSoGROUP *group;
      LIBoINDEX *libInx;
      INT4      c1, c2; 
      char      *tmp, *libName;
    
      templ = WwwInit ();
      TemplWith (templ, "$libList");
      TemplPrint ("head");
      WwwPrintButtons (templ);
      TemplPrint ("title", TimeToString (0, "long"));
    
      for (c1=0; (group = LibNextLibGroup (&c1)); )
        for (c2=0; (lib = LibNextLib (group, &c2)); ) {
          if (LibIs (lib, "subentries"))
    	continue;
          libName = LibName (lib);
          if ((libInx = LibIndexOpen (lib, LibGetIdField (lib), 1))) 
    	TemplPrint ("libraryGood", WwwGetIdParam (), libName, libName,
    		    tmp && *(tmp = IdxGetReleaseName (libInx->idx)) ? 
    		    tmp : " ",
    		    BtrGetRecordN (libInx->btree),  
    		    TimeToString (BtrGetTimeCreated (libInx->btree), "date"),
    		    LibGetGroupName (group, "full"));
          else 
    	TemplPrint ("libraryBad", WwwGetIdParam (), libName, libName,
    		    LibGetGroupName (group, "full"));
        }
      TemplPrint ("tail");
      TemplEndWith ();
    }
    
    Int4 WwwPrintInfoChapter (TEMPLv templ, TEMPLv libTempl,
    			  char *label, char *libLabel)
    {
      if (TemplExists (libTempl, libLabel)) {
        TemplWith (templ, label);
        TemplPrint ("head");
        TemplEndWith ();
        TemplPrint (libLabel);
        TemplWith (templ, label);
        TemplPrint ("tail");
        TemplEndWith ();
      }
    }
    
    
    
    /****** PageLibInfo **********************************************************
    **
    **      Displays information about a databank.
    **
    */
    
    void PageLibInfo ()
    {
      TEMPLv    templ, libTempl;
      SLBo      *lib;
      SLBoFIELD *field;
      LINKo     *link;
      LIBoINDEX *libInx;
      INT4      c, count; 
      char      *tmp, *libName, entryName[200];
    
      templ = WwwInit ();
      TemplWith (templ, "$libInfo");
      TemplPrint ("head");
    
      if (*WwwGetIdParam ())
        WwwPrintButtons (templ);
    
      libName = ParGetStr ("libInfo");
      if (!(lib = (SLBo *) LibObjByName ("library", libName)))
        _ErrExit3 (e__objectunknown, "library", libName);
      libName = LibName (lib);
    
      TemplPrint ("title", libName, libName, libName);
      if ((libInx = LibIndexOpen (lib, LibGetIdField (lib), 1))) {
        tmp = IdxGetReleaseName (libInx->idx);
        if (tmp && *tmp)
          TemplPrint ("release", tmp, BtrGetRecordN (libInx->btree),
    		  TimeToString (BtrGetTimeCreated (libInx->btree), "date"));
        else 
          TemplPrint ("noRelease", BtrGetRecordN (libInx->btree),
    		  TimeToString (BtrGetTimeCreated (libInx->btree), "date"));
      }
      else 
        TemplPrint ("notIndexed");
    
      /* print some general information */  
      if ((libTempl = TemplOpen (LibGetIcarusFileName (lib, "info"), NULL))) {
        TemplPrint ("t.head");
        TemplWith (libTempl, "$dbInfo");
        WwwPrintInfoChapter (templ, libTempl, "$libInfo.t.description",
    			 "description");
        WwwPrintInfoChapter (templ, libTempl,"$libInfo.t.literature","literature");
        WwwPrintInfoChapter (templ, libTempl, "$libInfo.t.literature", "citation");
        WwwPrintInfoChapter (templ, libTempl, "$libInfo.t.www", "www");
        WwwPrintInfoChapter (templ, libTempl, "$libInfo.t.ftp", "ftp");
        WwwPrintInfoChapter (templ, libTempl, "$libInfo.t.email", "email");
        WwwPrintInfoChapter (templ, libTempl, "$libInfo.t.address", "address");
        WwwPrintInfoChapter (templ, libTempl, "$libInfo.t.contact", "contact");
        WwwPrintInfoChapter (templ, libTempl, "$libInfo.t.updates", "updates");
    
        /* example entry */
        if (TemplExists (libTempl, "example")) {
          TemplSPrint (entryName, "example");
          TemplWith (templ, NULL);
          SmEdit (entryName, SMxTRIM);
          TemplPrint ("$libInfo.example", libName, entryName, entryName);
          TemplEndWith ();
        }
        TemplEndWith ();
        TemplPrint ("t.tail");
      }
    
    
      /* print information about the fields */  
    
      TemplWith (templ, "fields");
      WwwPrintFieldInfo (lib, NULL, 0);
      TemplEndWith ();
    
      /* links to other databanks */
    
      TemplPrint ("links.to");
      for (c=0, count=0; (link = LibNextLink (&c));) 
        if (lib == link->lib1) {
          TemplPrint ("links.toLib", LibName (link->lib1), LibName (link->lib2), 
                      LibName (link->lib2));
          count++;
        }
      if (!count)
        TemplPrint ("links.none");
      TemplPrint ("links.from");
      for (c=0, count=0; (link = LibNextLink (&c)); ) 
        if (lib == link->lib2) {
          TemplPrint ("links.fromLib", LibName (link->lib2), LibName (link->lib1), 
                      LibName (link->lib1));
          count++;
        }
      if (!count)
        TemplPrint ("links.none");
      TemplPrint ("links.tail");
    
      /* list of Icarus files */
    
      TemplPrint ("icarusFiles.head");
      if (*(tmp = (LibGetIcarusFileName (lib, "structure"))))
        TemplPrint ("icarusFiles.structure", libName);
      if (*(tmp = (LibGetIcarusFileName (lib, "syntax"))))
        TemplPrint ("icarusFiles.syntax", libName);
      if (*(tmp = (LibGetIcarusFileName (lib, "info"))))
        TemplPrint ("icarusFiles.information", libName);
      TemplPrint ("icarusFiles.tail");
    
      TemplPrint ("tail");
      TemplEndWith ();
    }
    
    
    
    
    
    
    /****** WwwGetOddFile *******************************************************
    **
    **      Display odd description of a databank
    **
    **       INPUT:
    **
    **
    */
    
    void  WwwGetOddFile()
    {
      char *tmp = ParGetStr("getOddFile");
      if (tmp)
        WwwGetODDFile(tmp);
      
    }
    
    
    
    /****** PageEntry *************************************************************
    **
    **      Prints single entry. if the userId is defined AND option -sl
    **      used then a within a session context normal entry list is printed.
    **
    */
    
    static void PageEntry ()
    {
      TEMPLv   templ;
    
      templ = WwwInit ();
    
      ParDefBool ("isHTMLFormat", 1);
      if (ParGetBool ("makeNewUserId") || ParGetBool ("wwwSessionEntryList")) {
        ParSetVolatile ("wwwSessionEntryList");
        WwwQueryExpression ("query", pageQuery);
      }
      else if (Query (pageQuery, "Q")) { 
        WwwPrintSet (templ, "Q", 1, 0);
      }
      else
       _ErrExit2 (i__querynegative, pageQuery);
    }
    
    
    /****** WwwDeleteQueryByNum ******************************************************
    **
    **	deletes the selected query from history;
    **
    **	INPUT:	    
    **	        IMPLICIT:
    **
    **	RETURNS:    
    */ 
    
    INT4 WwwDeleteQueryByNum(INT4 j)
    {
      char parName[80];
      INT4 queryN, k;
      
      queryN = ParGetNum ("numberOfQueries");
      sprintf (parName, "QueryStr%d", j); 
      ParDelete (parName);
      sprintf (parName, "QuerySize%d", j); 
      ParDelete (parName);
      sprintf (parName, "QueryType%d", j); 
      ParDelete (parName);
      sprintf (parName, "isSubEntry%d", j);
      ParDelete (parName);
    
      for (k=1; ; k++) {
        sprintf (parName, "QueryLibrary%d_%d", j, k); 
        if (!ParDelete (parName))
          break; /* no more items */
        sprintf (parName, "QueryLibraryN%d_%d", j, k); 
        ParDelete (parName);
      }
      ParDefNum ("numberOfQueries", --queryN);
    }
    
    
    /****** GetEnv **************************************************************
    **
    **      Get the environment variables
    **
    **	INPUT:	    
    **	        IMPLICIT:
    **
    **	RETURNS:    
    **
    **
    */
    void  GetEnv()
    {
    
      GetEnvp(envPtr);
      
    }
    
    /****** GetEnvp **************************************************************
    **
    **
    **
    **
    **	INPUT:	    
    **	        IMPLICIT:
    **
    **	RETURNS:    
    **
    */
    
    INT4 GetEnvp(char **envPtr)
    {
    #ifdef script
      INT4 i=0;
      char *tmp;
      char name[80], value[80];
    
      SCRIPTo *script;
    
      script = ScriptOpen (ScriptFile,NULL);
    
      ScriptCopyFrom(script,"ENVIRONMENT-VAR");
      for (i=0;*envPtr; envPtr++) {
        sscanf (*envPtr, "%[^=]=%[^:]", name,value);
        ScriptWriteFrom(script,"LIST-ENV-VAR",name,++i,value);
      }
      ScriptCopyFrom(script,"ENV-END");
      return 1;
    #endif
    }
    
    /*** GetEnvByName ***************************************************************
    **
    **     Returns Environment variable values referred.
    **
    **
    **     INPUT : 
    **               
    **    RETURNS:
    **               
    **
    */
    
    char *GetEnvByName(char *ename)
    {
      static char value[80];
      INT4 i=0;
      char name[80];
      value[0] = name[0] = '\0';
      for (i=0;*envPtr; envPtr++) {
        sscanf (*envPtr, "%[^=]=%[^:]", name,value);
        if(SmEqs(ename,name) == 1) 
          return(value);
      }
      return(NULL);
    }
    
    
    /**api* PageDownloadSet ******************************************************
    **
    **      Refine the output with more options like alter flanking 
    **      regions, sequence format etc., 
    **
    **	INPUT:	    
    **
    **	RETURNS:    
    **
    */ 
    
    static void PageDownloadSetOpt()
    {
      TEMPLv templ;
      WWWoQUERY *query;
      char *tmp,  *tmp1, *tmp2, *tmp3;
      INT4 queryN, queryNo=0, c=0;
    
      if ((queryNo=WwwNextSelectedQuery (&c, NULL)) ||
          (queryNo=WwwQuerySelectedEntries ()))
        ParDefNum("queryNumber",queryNo);
      else
        _ErrExit (e__wwwNoQueryOrEntriesSelected);
      query = WwwGetQuery(queryNo);
    
      templ = WwwInit ();
      TemplWith (templ, "$downloadSet");
      TemplPrint("head");
      WwwPrintButtons (templ);
    
      TemplWith(templ, "inputInfo.html3");
      if (query->isSubEntry) {
        tmp = ParGetStr("shiftbeginpos");
        tmp1 = ParGetStr("shiftendpos");
        tmp2 = ParGetStr("checkbegin");
        tmp3 = ParGetStr("checkend");
        
        ParDefBool("isshiftendrelbegin",0);   /* default, keep as it is */
        ParDefBool("isshiftbeginrelend",0);
    
        if( (SmLoc(tmp2,"begin") != -1) &&  (SmLoc(tmp3,"begin") != -1) )
          ParDefBool("isshiftendrelbegin",1);
        
        if( (SmLoc(tmp2,"end") != -1) &&  (SmLoc(tmp3,"end") != -1) )
          ParDefBool("isshiftbeginrelend",1);
        
        TemplPrint("shift",(*tmp ? tmp : ""),(*tmp1 ? tmp1 : "" ));
        TemplEndWith();
        TemplPrint("unComplete");
      }
      else
        TemplEndWith();
    
      WwwPresentChunkSizesMime (templ, queryNo);
      WwwPresentActiveViews (NULL, NULL, query, templ, 0);
    
      tmp1  = ParGetStr ("localDirName");
      TemplPrint("useMime", (WwwChecked(ParGetBool("useMime"))),
    	     (*tmp1 ? tmp1 : "" ));
      TemplPrint("tail", queryNo);
      WwwDelQuery(query);
    }
    
    /**api* PageDownloadSet *******************************************************
    **
    **      Saves the selected set to the user's directory.
    **
    */
    
    static void PageDownloadSet()
    {
    
      TEMPLv  templ;
    
      WWWoQUERY *query;
      char *dirName;
      INT4 queryN;
      INT4 startNo = 0;
      INT4 entryN = 0;
      char *viewBlock = ParGetStr ("viewEntriesBlock");
    
      if( *viewBlock) {
        sscanf(viewBlock, "%d - %d",&startNo,&entryN);
        entryN = entryN - startNo + 1;
      }
      query = WwwGetQuery (ParGetNum ("listSetNumber"));
      if (!ParGetBool("useMime")) {
        WwwPrintContentType ("Content-type: binary");
        templ = WwwInit ();
        ParDefBool ("downloadEntireEntry", 1);
        WwwQueryRepeat (ParGetNum ("listSetNumber"));
        if (ParGetNum ("viewNumber") > 1) 
          WwwPrintSetView (templ, query->name, startNo, entryN);
        else 
          WwwPrintSet (templ, query->name, startNo, entryN);
      }
      else {
        templ = WwwInit ();
        dirName = ParGetStr("localDirName");
        if(!(*dirName))
         dirName = "trash" ;
        TemplPrint ("head");
        TemplPrint ("start","tempfile",dirName,"Ver1","copy",
    	       ParGetStr("seqFormat"));
    
        queryN = ParGetNum ("queryNumber");
        WwwQueryRepeat (queryN);
        ParDefBool ("isHTMLFormat", 0);
        WwwPrintSet(templ,query->name,startNo,entryN);
        ParDefBool ("isHTMLFormat", 1);
        WwwDelQuery(query);
        ParDelete("useMime");
        TemplEndWith();
      }
    }
    
    
    
    /**api*  PageViewEdit *********************************************************
    **
    **      Lets the user edit an existing view.
    **
    */
    
    static void PageViewEdit ()
    {
      TEMPLv templ;
      VIEWo  *view;
      INT4   j, k, viewNo;
    
      templ = WwwInit ();
      TemplWith (templ, "$viewCreate");
      TemplPrint ("head");
    
      WwwInitViews (templ);
      for (j=0, k=1, viewNo=0; (view = ViewNext (&j)); k++) {
        if (SmEqs (ViewGetName (view), ParGetStrF ("selectedViewNo_%d", j))) {
          viewNo = j;
          break;
        }
      }
      if(!viewNo)
        _ErrExit (e__noviewselect);
    
      WwwViewPartI (viewNo, 1, templ);
    }
    
    /**api* PageViewCreate ********************************************************
    **
    **      Lets the user create a new view.
    **
    */
    
    static void PageViewCreate ()
    {
      TEMPLv templ;
      INT4   viewNo; 
    
      templ = WwwInit ();
      TemplWith (templ, "$viewCreate");
      TemplPrint ("head");
    
      WwwInitViews (templ);
      viewNo = ViewGetViewsN () + 1;
      WwwViewPartI (viewNo, 0, NULL);
      ViewMarkNascent (NULL, viewNo);
    }
    
    /**api*  PageViewMgrCreate ****************************************************
    **
    **       Create a new view from  from view manager.
    **
    */
    
    void  PageViewMgrCreate ()
    {
      TEMPLv templ;
      INT4   viewNo;
    
      templ = WwwInit ();
      TemplWith (templ, "$viewCreate");
      TemplPrint ("head");
    
      WwwInitViews (templ);
      viewNo = ViewGetViewsN () + 1;
      WwwViewPartI (viewNo, 0, templ); 
      ViewMarkNascent (NULL, viewNo);
    }
    
    
    /**api* PageViewSelectFields **************************************************
    **
    **      View creation part II - selection of fields for 'root' and 'leaf'
    **      libraries
    **
    */
    
    static void PageViewSelectFields ()
    {
      TEMPLv          templ;
      SRSoGROUP       *group;
      SLBoFIELD       *field;
      VIEWo           *view;
      VIEWoLIB        *vlib;
      INT4            k, c, c2, viewNo, isOnlyCommon, numCol;
      char            viewName[100], *libName;
    
      templ = WwwInit ();
    
      viewNo = ParGetNum ("viewNumber");
      WwwInitViews (templ);
      view = ViewGetWithNo (viewNo);
      ParDelete ("isNewView");
      if (SmEqs (ViewGetName (view), "nascent")) {
        c=0;
        if (!(vlib = ViewGetNextRootLib (view, &c)))
          _ErrExit (e__nolibslct);
        sprintf (viewName, "%s_view%d", LibName (vlib->lib), viewNo);
        ViewSetName (view, viewName);
      }
    
      TemplWith(templ, "$viewSelectFields");
      TemplPrint ("head", viewNo, viewNo, viewNo, viewNo, ViewGetName (view), 
    	      ParGetStrF ("view%d_Name",viewNo));
    
      /* print all root libraries and fields */
      TemplWith (templ, "root");
      group = LibGroupNew (NULL);
      TemplPrint ("lib.head");
      for (c=0; (vlib = ViewGetNextRootLib (view, &c));) {
        numCol = 60 / LibGetMaxNameSize (NULL, vlib->lib, "formatted")+1;
        LibGroupAddDb (group, vlib->lib);
        TemplPrint ("lib.name", LibName (vlib->lib), LibName (vlib->lib));
      }
      TemplPrint ("lib.tail");
    
      isOnlyCommon = ParGetBool ("isOnlyCommonFields");
      for ( c=0, k=0; (field = LibNextGroupField (group, isOnlyCommon, &c));) {
        if (FieldIs(field, "show") || FieldIs (field, "header"))
          WwwPrintSelectField (view, viewNo, field, NULL, numCol, &k);
      }
      TemplPrint ("tail");
      TemplEndWith ();
    
      /* iterate over leaf libraries */
      TemplWith (templ, "leaf");
      for(c=0; (vlib = ViewGetNextLeafLib (view, &c)); ) {
        numCol = 60 / LibGetMaxNameSize (NULL, vlib->lib, "formatted")+1;
        libName = LibName (vlib->lib);
        TemplPrint ("head", libName, "", libName, libName, viewNo, libName);
        for(c2=0, k=0; (field = LibNextField (vlib->lib, &c2));) {
          if (FieldIs(field,"show") || FieldIs (field, "header"))
    	WwwPrintSelectField (view, viewNo, field, vlib, numCol, &k);
        }
        TemplPrint ("extraOptions", viewNo, libName, 
    		WwwStringEncode (ViewGetLeafQueryStr (vlib)));
        WwwPresentViewsForLeaf (view, vlib, templ);
        TemplPrint ("tail", viewNo, libName, 
    		WwwChecked (ViewLeafIsOnlyEntryN (vlib)));
      }
      TemplEndWith ();
      TemplPrint ("tail");
      TemplEndWith ();
    
    }
    
    
    
    /****** PageViewManager ***************************************************
    **
    **      Displays all defined views and some operations on them.
    **
    */
    
    static void PageViewManager()
    {
      VIEWo           *view;
      TEMPLv          templ;
      SLBoFIELD       *field;
      VIEWoLIB        *vlib;
      LIBoFieldFormat *format;
      char            *tmp, *formatName;
      Int4            j, k, m, l, 
                      viewsN, nfield=0 ,nlibs=0;
      Int4            leafLibsN = 0, f;
    
      templ = WwwInit ();
      TemplWith(templ,"$viewManager");
      TemplPrint("head");
      WwwPrintButtons (templ);
      TemplPrint("actions");
      TemplWith(templ,"viewList");
    
      WwwInitViews (templ);
      viewsN = ViewGetViewsN ();
      for (j=0; (view = ViewNext (&j));) {
        if (ViewIs (view, "forAll"))
          continue;
        if (ViewIs (view, "nascent") || ViewIs (view, "selected")) {
          ViewMarkDeleted (view);
          continue;
        }
        leafLibsN = ViewCountLeafLibs(view);
        TemplPrint("head",leafLibsN,j,ViewGetName(view),
    	       ViewGetName (view), leafLibsN,
                   (ViewIsTable (view) ? "table" : "list"), leafLibsN);
        TemplPrint (ViewIsShortNames (view) ? "shortNames" : "longNames", 
    		leafLibsN);
    
        for(k=0; (vlib = ViewGetNextRootLib(view,&k));) { 
          TemplPrint("root",LibName(vlib->lib));
        }
        TemplPrint("tableData",leafLibsN);
        if ((vlib = ViewGetNextRootLib(view,&k)))
          for(m=0;(field=ViewGetNextField(vlib,&m));) {
    	TemplPrint("rootField",LibGetFieldName (field));
    	formatName = ParGetStrF("v%d_RF_%s_format",j,LibGetFieldName(field));
    	if(*formatName)
    	  TemplPrint("format",formatName);
          }
        TemplPrint("tableDataEnd");
    
        /* leaf */
        for(k=0, l=0; ( vlib = ViewGetNextLeafLib(view,&k)); l++) {
          if (l) 
    	TemplPrint("rowEnd");
          TemplPrint("leaf.lib",LibName (vlib->lib));
          for(m=0;(field=ViewGetNextField(vlib,&m));) {
    	TemplPrint("leaf.field", LibGetFieldName (field));
    	formatName  = ParGetStrF("v%d_LF_%s_%s_format",j,LibName(vlib->lib),
    			 LibGetFieldName(field)); 
    	if(*formatName)
    	   TemplPrint("leaf.format",formatName);
          }
          tmp=ViewGetLeafQueryStr (vlib);
          TemplPrint (*tmp? "leaf.query" : "emptyCell", WwwStringEncode (tmp)); 
          tmp=ViewGetLeafView (vlib);
          TemplPrint (*tmp? "leaf.view" : "emptyCell", tmp); 
          TemplPrint (ViewLeafIsOnlyEntryN (vlib) ? 
    		  "leaf.onlyEntryN" : "emptyCell");
        }
        TemplPrint("tail");
      }
      TemplEndWith();
      TemplPrint("tail");
      ViewDelete(view);
    }
    
    
    
    
    /**api* PageViewSelectedEntries **********************************************
    **
    **      Views selected entries.
    **
    */
    
    static void PageViewSelectedEntries ()
    {
      TEMPLv    templ;
      INT4      queryN;
    
      templ = WwwInit ();
      queryN = WwwQuerySelectedEntries ();
      if(!queryN) { /* when no entries then do query for "queryNumber" */
        queryN = ParGetNum("queryNumber"); 
        WwwQueryRepeat (queryN); 
      }
      WwwQueryPrint (queryN);
    }
    
    
    /*** API* SmTrimAt ****************************************************************
    **
    **
    **  	INPUT:	address of string [W]
    **  		position to truncate
    **  
    **  	RETURNS:   
    **
    **
    */
    
    char *SmTrimAt (char *s, Int4 n)
    {
      if(strlen(s) >= n)
        s[n] = '\0';
      return s;
    }
    
    /*** API* SmFillFrom ****************************************************************
    **
    **  	INPUT:	address of string [W]
    **  		position to fill from
    **              address of the string to fill
    **  
    **  	RETURNS:  modified string
    **
    **
    */
    
    char *SmFillFrom(char *s, Int4 n, char *fill)
    {
      Int4 m = strlen(s)+strlen(fill),k=0;
    
      if( (m) > n ) {
        for(k=n; *fill ; k++) 
          s[k] = *fill++;
        s[k] = '\0';
      }
      return s;
    }
    
    
    /****** PageLinkToLibs ********************************************************
    **
    **
    **
    */
    
    static void PageLinkToLibs ()
    {
      INT4 queryN;
    
      if ((queryN = ParGetNum ("linkSetNumber"))) {
        if (SmEqs ("linkStat", ParGetStr ("linkSetType"))) 
          WwwLinkStat (queryN);
        if ((queryN = WwwLinkSet (queryN)))
          WwwQueryPrint (queryN);
        else
          _ErrMsg (i__noentriesfound);
      }
      else if (*ParGetStr ("entryName")) {
        queryN = WwwLinkEntry (ParGetStr ("libName"), ParGetStr ("entryName"));
        WwwQueryPrint (queryN);
      }
    }
    
    
    /**api* WwwPrintButtons ******************************************************
    **
    **      Prints buttons at the top of the page.
    **      The function finds out the current page by looking at what function
    **      is defined.
    **      The function assumes that the "templ" object is already opened.
    **
    */
    
    void WwwPrintButtons (TEMPLv templ)
    {
      Func function;
      char *userId;
    
      if (!*(userId = ParGetStr ("userId")))
        return;
    
    
      TemplWith (templ, "$buttons");
      TemplPrint ("head");
    #ifdef async
      if (FileOpen (FileNew (WwwGetName (userId, "status"))))
        TemplPrint ("busy");
      else if (ParGetBool ("isPendingJob")) {
        TemplPrint ("completed");
        ParDelete ("isPendingJob");
      }
    #endif
      TemplPrint ("selectDatabanks");
      TemplPrint ("queryForm");
      TemplPrint ("queryManager");
      TemplPrint ("views");
      TemplPrint ("databank");
      TemplPrint ("help.head");
    
      function = ParGetFunction ("wwwFunction");
      if (function == (Func)PageSelectLibrary)
        TemplPrint ("help.top");
      else if (function == (Func)PageQueryForm)
        TemplPrint ("help.query");
      else if (function == (Func)PageViewCreate)
        TemplPrint ("help.viewLibs");
      else if (function == (Func)PageViewSelectFields)
        TemplPrint ("help.viewField");
      else if (function == (Func)PageViewManager)
        TemplPrint ("help.viewManager");
      else if (function == (Func)PageQueryManager)
        TemplPrint ("help.queryManager");
      else if (function == (Func)PageLibList)
        TemplPrint ("help.databanks");
      else if (function == (Func)PageLibNetwork)
        TemplPrint ("help.databanks");
      else if (function == (Func)PageLinkOpt)
        TemplPrint ("help.links");
    
      else
        TemplPrint ("help.default");
      TemplPrint ("help.tail");
    
      TemplPrint ("tail");
      TemplEndWith ();
    }
    
     else if (function == (Func)PageViewManager)
        TemplPrint ("help.viewManager");
      else if (function == (Func)PageQueryManager)
        TemplPrint ("help.qusrs/srs.relnotes
    Version 5.0.3 had still problems with EMBL in flat file format. This
    problem is hopefully fixed now. We added also an improved set of files
    for DSSP and IMGT done by Peter Rice.
    
    The file is at ftp://ftp.ebi.ac.uk/pub/software/unix/srs/srs5.0.4.tar.gz
    
    
    Release notes:
    
    
    
    SRS version 5.0.4
    =================
    
    1) Fixed a memory leak in srsbuild, EMBL should index without problems
    2) SRS supports compressed files again, in particular PDB. pdb.i contains
       2 alternatives of PDB_FILE for compressed and uncompressed files
    3) Some internal changes should make srsbuild slightly faster
    4) Improved descriptions for IMGT and DSSP 
     
    
    --
    Thure Etzold,   etzold@ebi.ac.uk
    Giorgio Verde, verde@ebi.ac.uk
    19. March, 1997
    
    ===============================================================================
    
    
    
    SRS version 5.0.3
    =================
    
    SRS 5.0.3 has been compiled and tested on IRIX 5.x, 6.x (32-bit binary),
    OSF1 4.x, Solaris.
    It should work on SunOS, Ultrix and could work on AIX, HP-UX.
    
    
    The numerous problems of version 5.0.2 concerning indexing and entry access
    should all be fixed.
    The main differences to the previous release are the addition of an 'option bar'
    in the entry display and the incorporation of analysis tools (BLAST, FASTA,
    Smith and Waterman search with the Bioccelerator and Clustalw). 
    The way the applications are defined is still new and needs to be documented.
    
    
    Differences in detail:
    
    1)  Many bugs concerning indexing and access to entries have been removed.
        Indexing of GCG formatted databanks is now stable.
    2)  The databank descriptions for many databanks, esp. the Transfacs and 
        Genbank has improved. 
    3)  A few Icarus bugs have been fixed and also the error messages are 
        more informative. Both nodd and icarus should not dump core anymore.
    4)  The example C programs in SRSDEMO have been revised and should all work.
    5)  The regular expressions have been reintroduced into the SRS query language.
        (the documentation for the query language is still for version 4 but has been
        extended for version 5 considerably).
    6)  The chapter "SRS Server Maintenance" has been added to the online
        documentation system. It describes in detail how to set up a separate WWW server
        that runs wgetz under its own account.
    7)  in SRSWWW each single entry display contains an additional 'tool bar'
        for linking the entry to other databanks, viewing the entry and launching
        applications. 
    8)  The applications BLAST, FASTA, SW (Smith & Waterman search with 
        Bioccelerator) and CLUSTALW have been added to SRS and can be called from
        a the page containing a list of entries and a single entry. Documentation of
        how to customize these applications and how to add more is still lacking but 
        please have a look into SRSDB/genes.i. Every application is described by an object
        $application. It has an Icarus command to build the command line and one for launching
        the application. All the customization happens there.
        
    10) The "SRS group" has moved to the EBI in Hinxton!;-)
    
    Known problems with this release:
    
    1) The "Save" option in SRSWWW does still not work properly.
    2) Customization of the applications is easy but still not documented.
    4) The $application objects in appl.i for the four applications BLAST, FASTA, CLUSTALW
       and SW have been rewritten several times. It is possible that some default
       values don't make much sense or are missing - please check and let us know if you
       find bugs.
    3) getz and wgetz can extract feature sequences but it is still not possible
       to modify their begin and end positions as in SRS4.
    
    
    --
    Thure Etzold,   etzold@ebi.ac.uk
    Giorgio Verde, verde@ebi.ac.uk
    13. March, 1997
    
    ===============================================================================
    
    
    
    
    SRS version 5.0.2
    =================
    
    
    SRS 5.0.2 has been compiled and tested on IRIX 4.05, 5.x, 6.x (32-bit binary),
    OSF1 2.x, 3.x, 4.x, Linux 2.x, ULTRIX 4.x, SunOS (gcc), Solaris.
    It could also work on AIX, HP-UX.
    
    Now the new things:
    -------------------
    
    1) The .is files can now run as an independent script and used by
       SRS without changing the script.
       So in 'tfsite.is' the 'entry' production must always have $In:[file:text]
       
       entry:   ~ {$In:[file:text] $Out}
       	      ('AC' {$Not} ln)*
       	      ('AC  ' {$entryFip=$Fip $Wrt} ln {$App} 
       	       ('AC' {$Not} ln {$App})+)?
       	    ~
       
       and the code for testing at the end must use "$TestMode" 
       
       
       if:$TestMode {
         $job = $JobNew:[prod:$rules skip:" " fileName:'/data/transfac/site.dat']
         while:$JobTokens:[$job name:id print:1] {
           $JobNext:$job
           $print:"-------->entry\n" 
         }
       }
       
    2) There is now a very simple Icarus debugger. It is by no means ready but
       even at this stage really useful. It is documented in chapter 6 in the
       WWW manual. 
       
    3) I modified the information pages for databanks and data-fields in 
       SRSWWW. Have a look at .it files in 'SRSDB:' which have the description
       about the databanks and fields which is placed into these pages.
       The library information page has the links to the .i, .it, .is
       files for each databank (btw, our test server is 
       'http://kappa.embl-heidelberg.de:8000/srs/'). The idea is that every 
       databank should be documented by a .it file.
       
    4) There is an emacs lisp file in 'SRSETC:' which defines an Icarus mode -
       defines only coloring with fontlock. I don't know enough emacs lisp to write
       a proper mode with automatic indentation etc. - any volunteers?
       
    5) The indexing of databank partitions runs stable now. This means that
       big databanks like genbank and EMBL can be indexed in chunks of eg, 
       100000 entries and then later merged. srscheck takes care of all
       necessary commands. Have a look in embl.i: attribute 'partSize' of 
       $library sets the partitioning. With a part size of 100000 the indexing
       of EMBL on an alpha takes less than 50mbyte memory.
    
    Known problems with this release
    --------------------------------
    1) high optimisation on OSF1 2.x, 3.x might give problems.
    
    2) On Solaris cc or gcc can now be used. When using gcc a warning message
       gcc: unrecognized option `-Xa' is now given and should be ignored.
    
    3) There is a minor parsing error when installing the documentation - for us it
       is an old friend, but I guess it might be worrying if you haven't been
       introduced to it.....
    
    man_capi.i:928: error: syntax error, production `l_proto' :
    |INT4 (*ParGetFunction (char *parName))()|
    .....^
      no match with |^[a-zA-Z0-9_*]+|
    
    
    --
    Thure Etzold,   etzold@embl-heidelberg.de
    Johnathon Weare, weare@embl-heidelberg.de
    22. January, 1997
    
    
    
    
    
    
    
    
    
    
    
    
    
    gcsrs/srsinstall
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    #
    #    $RCSFile: /home/etzold/srs/RCS/srsinstall,v $
    #    $Revision: 1.21 $
    #    $Date: 1997/03/12 16:26:52 $
    #    $Author: srs $
    # 
    # installs an srs release 
    #
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    #set -e
    # -e flag is used to immediately halt installation if a problem occurs
    
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # analyse command line and print usage if wrong
    #
    ERR='srsinstall: Stopping due to Error'
    
    if [ "$#" = 0 ]; then
      option="usage"
    elif [ "$1" = "make" ]; then
      option="make"
      cd etc
    elif [ "$1" = "commands" ]; then
      option="commands"
      cd etc
    elif [ "$1" = "all" ]; then
      option="all"
    elif [ "$1" = "www" ]; then
      option="www"
    elif [ "$1" = "doc" ]; then
      option="doc"
    elif [ "$1" = "clean" ]; then
      option="clean"
    elif [ "$1" = "cleanall" ]; then
      option="cleanall"
    else
      option="usage"
      echo "unknown option '$1'"
    fi
    
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # print "usage"
    #
    if [ "$option" = 'usage' ]; then
      cat << END
    
      Usage: ./srsinstall option
    
      Options:
    
      all        does a complete installation
      www        install SRS WWW server ...on the SRS side
      doc        installs the SRS documentation on the WWW
      make       compiles all programs
      commands   replaces the "cc", "make" commands by something else
      clean      removes the object and library files for this architecture
      cleanall   removes the bin directory for this architecture
    
      NOTE: Use "./srsinstall all" the first time you run srsinstall
      -----
      
    END
      exit 1
    fi
    
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # insert the correct root into prep_srs and prep_srs.sh
    #
    
    if [ "$option" = 'all' ]; then
      echo "...updating file 'prep_srs'"
    
      rootdir="`pwd`"
      cd etc
    
      sed "s:setenv SRSROOT .*:setenv SRSROOT "$rootdir":" prep_srs > tmp
      mv tmp prep_srs
      chmod +x prep_srs
    
      echo "...updating file 'prep_srs.sh'"
      sed "s:SRSROOT=.*:SRSROOT="$rootdir":" prep_srs.sh > tmp
      mv tmp prep_srs.sh
      chmod +x prep_srs.sh
    fi
    
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # put correct "make" and "cc" commands into srsmake
    #
    
    OS=`uname`
    
    if [ "$OS" = "SunOS" ]; then
        case "`uname -r`" in
    	[56]*)   OS='Solaris' ;;
        esac
    fi
    
    # some echo commands do not support -n
    # generally /usr/bin/echo doesn't but /usr/ucb/echo does, so one can hardwire
    # to be independent of users path.
    if [ -r /usr/ucb/echo ]; then
      ECHON="/usr/ucb/echo -n"
    else
      ECHON="echo -n"
    fi
    
    # OSF/1 v4.0 /usr/ucb is symlink to /usr/bin, but /bin/sh has builtin -n
    if [ "$OS" = "OSF1" ]; then
      case "`uname -r`" in
        V[4]*)  ECHON="echo -n"
    	    # or can
    	    #CMD_ENV=bsd ; export CMD_ENV
        ;;
      esac
    fi
    
    # we did our best, but now let's test
    ECHONT="`$ECHON | wc -c`"
    if [ $ECHONT != 0 ]; then
      ECHONEND="\c"
      ECHON=echo
    else
      ECHONEND=""
    fi
    
    
    if [ "$option" = 'all' -o "$option" = 'commands' ]; then
    
      $ECHON "enter the make command [make]: $ECHONEND"
      read makeCom
      if [ "$makeCom" = "" ]; then makeCom='make' ; fi
    
      # for OSF1 need to know if it is osf1 make or gnu make
      if [ "$OS" = "OSF1" ]; then
    	$ECHON "is this OSF1 make [y]: $ECHONEND"
    	read OSFmake
    	if [ "$OSFmake" = "" ]; then OSFmake='y' ; fi
      fi
    
      if [ "$OS" = "SunOS" -o "$OS" = "Solaris" ]; then
        ccComDef='gcc'
      else
        ccComDef='cc'    
      fi
    
      $ECHON "enter the cc command [${ccComDef}]: $ECHONEND"
      read ccCom
    
      if [ "$ccCom" = "" ]; then ccCom="$ccComDef" ; fi
    
      echo 'choose between optimised code, or code for debugging'
      #echo "or you can have no optimisation if you enter 'noopt'"
      $ECHON "optimised code [y]: $ECHONEND"
      read optimCom
    
      if [ "$optimCom" = "" ]; then optimCom="y" ; fi
    
      # for OSF1 currently use no optimisation
      if [ "$OS" = "OSF1" ]; then
        case "`uname -r`" in
    	V[23]*)   if [ "$optimCom" = "y" ]; then optimCom="noopt" ; fi
    	;;
        esac
      fi
    
      #
      # Possibility for Correction ????
      #
    
      echo "...inserting commands '$makeCom' and '$ccCom' into srsmake for '$OS'"
    
      sed "/  $OS)/,/;;/s@MAKE='[^ '][^ ']*@MAKE='$makeCom@" srsmake> tmp
      mv tmp srsmake
      sed "/  $OS)/,/;;/s@CCOMP=[^ '][^ ']*@CCOMP=$ccCom@" srsmake> tmp
      mv tmp srsmake
      # set another make flag for osf1 make
      if [ "$OS" = "OSF1" ]; then
        if [ "$OSFmake" = "y" ]; then
          echo '...inserting OSF1 make command'
          # use this with the make from OSF1
          OSFmake_flag='\\$\@'
        else
          echo '...inserting GNU make command'
          # use this with the make from GNU
          OSFmake_flag='\\$\%'
        fi
        sed "/  $OS)/,/;;/s@TO=[^ '][^ ']*@TO=$OSFmake_flag@" srsmake> tmp
        mv tmp srsmake
      fi
    
      chmod +x srsmake
    
      echo "...inserting optimisation choice into srsmakefile for '$OS'"
      if [ "$optimCom" = "y" ]; then
        sed -e "/# CFLAGS Optimised/,/CFLAGS     =/s@^#CFLAGS     =@CFLAGS     =@" -e "/# CFLAGS Not Optimised/,/CFLAGS     =/s@^CFLAGS     =@#CFLAGS     =@" -e "/# CFLAGS Debug/,/CFLAGS     =/s@^CFLAGS     =@#CFLAGS     =@" srsmakefile> tmp
      elif [ "$optimCom" = "noopt" ]; then
        sed -e "/# CFLAGS Optimised/,/CFLAGS     =/s@^CFLAGS     =@#CFLAGS     =@" -e "/# CFLAGS Not Optimised/,/CFLAGS     =/s@^#CFLAGS     =@CFLAGS     =@" -e "/# CFLAGS Debug/,/CFLAGS     =/s@^CFLAGS     =@#CFLAGS     =@" srsmakefile> tmp
      else
        sed -e "/# CFLAGS Optimised/,/CFLAGS     =/s@^CFLAGS     =@#CFLAGS     =@" -e "/# CFLAGS Not Optimised/,/CFLAGS     =/s@^CFLAGS     =@#CFLAGS     =@" -e "/# CFLAGS Debug/,/CFLAGS     =/s@^#CFLAGS     =@CFLAGS     =@"  srsmakefile> tmp
      fi
      mv tmp srsmakefile
    fi
    
    
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # now prepare the environment and compile
    #
    
    
    if [ "$option" = 'all' -o "$option" = 'make' ]; then
    
      . ./prep_srs.sh || { echo "$ERR $?" ; exit 1 ; }
    
      if [ "$option" = 'all' ]; then
        srsmake msgdef || { echo "$ERR $?" ; exit 1 ; }
      fi
    
      cd "$SRSSOU"
      msgdef || { echo "$ERR $?" ; exit 1 ; }
    
      # make a dummy srsenv.h file
      touch ${SRSEXE}/srsenv.h 
    
      echo '...making ODD-Compiler'
      srsmake nodd || { echo "$ERR $?" ; exit 1 ; }
    
      echo '...compiling Icarus files to object base'
      srssection || { echo "$ERR $?" ; exit 1 ; }
    
      echo '...make srsbuild'
      srsmake srsbuild || { echo "$ERR $?" ; exit 1 ; }
    
      echo '...make srscheck'
      srsmake srscheck || { echo "$ERR $?" ; exit 1 ; }
    
      echo "...make header file 'srsenv.h'"
      ${SRSEXE}/srscheck -header || { echo "$ERR $?" ; exit 1 ; }
    
      echo '...make getz'
      srsmake getz || { echo "$ERR $?" ; exit 1 ; }
    
      echo '...make icarus'
      srsmake icarus || { echo "$ERR $?" ; exit 1 ; }
    
    
    
      cat << END
    
      srsinstall: make has completed
    
    END
    
    fi
    
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # Installs the SRS documentation
    #
    
    if [ "$option" = 'doc' ]; then
      echo '...Creating and installing the SRS documentation for the WWW'
      . etc/prep_srs.sh || { echo "$ERR $?" ; exit 1 ; }
      makedoc || { echo "$ERR $?" ; exit 1 ; }
    
      cat << END
    
      srsinstall: doc has completed
    
    END
    fi
    
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # installs WWW server
    #
    
    if [ "$option" = "www" ]; then
      . etc/prep_srs.sh || { echo "$ERR $?" ; exit 1 ; }
    
      docRootDef='/srs5/'
      $ECHON "enter httpd alias for doc root of SRSWWW [${docRootDef}]: $ECHONEND"
      read docRoot
      if [ "$docRoot" = "" ]; then docRoot="$docRootDef" ; fi
      docRoot="`echo $docRoot | sed -e 's/\/$//'`"
    
      binRootDef='/srs5bin/cgi-bin/'
      $ECHON "enter httpd alias for bin root or SRSWWW [${binRootDef}]: $ECHONEND"
      read binRoot
      if [ "$binRoot" = "" ]; then binRoot="$binRootDef" ; fi
      binRoot="`echo $binRoot | sed -e 's/\/$//'`"
    
      siteNameEG='EMBL, Heidelberg'
      siteNameDef='unknown'
      $ECHON "enter short name for your institution (eg, '$siteNameEG' ): $ECHONEND"
      read siteName
      if [ "$siteName" = "" ]; then siteName="$siteNameDef" ; fi
    
      srsAdminDef='unknown'
      srsAdminEG='srs@inst.org'
      $ECHON "E-mail address of SRS administrator (eg, '$srsAdminEG' ): $ECHONEND"
      read srsAdmin
      if [ "$srsAdmin" = "" ]; then srsAdmin="$srsAdminDef" ; fi
    
      # do replacement
    
      sed "s#docdir set:'[^']*'#docdir set:'"$docRoot"'#" $SRSICA/srswww.i > tmpsed
      mv tmpsed $SRSICA/srswww.i
      sed "s#cgidir set:'[^']*'#cgidir set:'"$binRoot"'#" $SRSICA/srswww.i > tmpsed
      mv tmpsed $SRSICA/srswww.i
      sed "s#siteName set:'[^']*'#siteName set:'""$siteName""'#" $SRSICA/srswww.i > tmpsed
      mv tmpsed ${SRSICA}/srswww.i
      sed "s#srsAdmin set:'[^']*'#srsAdmin set:'""$srsAdmin""'#" $SRSICA/srswww.i > tmpsed
      mv tmpsed ${SRSICA}/srswww.i
    
      srscheck -header || { echo "$ERR $?" ; exit 1 ; }
    
      srsmake wgetz || { echo "$ERR $?" ; exit 1 ; }
    
      chmod 777 "$SRSWWWTMP"
      ${SRSEXE}/wgetz -top -color yellowWeave -mime none > ${SRSWWW}/index.html || { echo "$ERR $?" ; exit 1 ; }
    
      cat << END
    
      srsinstall: www has completed
    
      Now you must edit the file 'srm.conf' of the httpd.
      Add the two aliases:
     
      -------------------------------------------------------
      ScriptAlias ${binRoot}/ ${SRSROOT}/www/bin/
      Alias ${docRoot}/ ${SRSROOT}/www/
      -------------------------------------------------------
    
      Then restart the server.
    
    END
    
    fi
    
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # cleans the SRS object and lib files for this architecture
    #
    
    if [ "$option" = 'clean' ]; then
      echo '...cleaning the SRS object files and libraries for this architecture'
      . etc/prep_srs.sh || { echo "$ERR $?" ; exit 1 ; }
      cd "$SRSSOU"
      echo '...make clean'
      srsmake clean || { echo "$ERR $?" ; exit 1 ; }
    
    fi
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # cleans the SRS bin directory for this architecture
    #
    
    if [ "$option" = 'cleanall' ]; then
      echo '...cleaning the SRS bin directory for this architecture'
      . etc/prep_srs.sh || { echo "$ERR $?" ; exit 1 ; }
      cd "$SRSSOU"
      echo '...make cleanall'
      srsmake cleanall || { echo "$ERR $?" ; exit 1 ; }
    
    fi
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ~~~~~~~~~srs/tmp/
    
    about SRS 5.0.3
    
    

    This Browser for Databanks in Molecular Biology was created by

    This work has been financially supported in part by a European Union Biomed II grant, and by the EMBnet.

    We would also like to thank a long list of people who have provided support and help, in particular those who suffered our beta releases.

    The SRS WWW server can be easily configured to use a different set of databanks; in fact, almost all HTML files are produced dynamically. The server is layered over the SRS system and both will be released as a software package in the near future.

    References:

    • Thure Etzold, Anatoly Ulyanov, and Patrick Argos, SRS: Information Retrieval System for Molecular Biology Data Banks. Methods in Enzymology v. 266, p. 114, 1996.
    • Thure Etzold and Patrick Argos, SRS an indexing and retrieval tool for flat file data libraries. Comput. Appl. Biosci. 9:49-57, 1993
    • Thure Etzold and Patrick Argos, Transforming a set of biological flat file libraries to a fast access network. Appl. Biosci. 9:59-64, 1993

    ...if you have comments or questions you can send a mail to

    etzold@embl-heidelberg.de,
    verde@embl-heidelberg.de,
    weare@embl-heidelberg.de


    Release SRS 5.0.4 is now available. It includes a command line interface and the SRSWWW server program. The central part of the release is the SRS function library (written in C) that lets you do queries and access and link entries inside of your program.

    srs5.0.4.tar.gz


    BLOCKQUOTE>etzold@embl-heidelberg.de,
    verde@embl-heidelberg.de,
    weare@embl-heidelberg.de


    Release SRS 5.0.4 is now available. It includes a command line interface and the SRSWWW server program. The central part of the release issrs/www/bin/ Blast help

    BLAST

    DESCRIPTION

    This document describes the BLAST version 1.4 programs. BLAST (Basic Local Alignment Search Tool) is the heuristic search algorithm employed by the programs blastp, blastn, blastx, tblastn, and tblastx; these programs ascribe significance to their findings using the statistical methods of Karlin and Altschul (1990, 1993) with a few enhancements. The BLAST programs were tailored for sequence similarity searching -- for example to identify homologs to a query sequence. The programs are not generally useful for motifstyle searching. For a discussion of basic issues in similarity searching of sequence databases, see Altschul et al. (1994).

    The five BLAST programs described here perform the following tasks:

    blastp
    compares an amino acid query sequence against a protein sequence database;
    blastn
    compares a nucleotide query sequence against a nucleotide sequence database;
    blastx
    compares the six-frame conceptual translation products of a nucleotide query sequence (both strands) against a protein sequence database;
    tblastn
    compares a protein query sequence against a nucleotide sequence database dynamically translated in all six reading frames (both strands).
    tblastx
    compares the six-frame translations of a nucleotide query sequence against the six-frame translations of a nucleotide sequence database.

    The fundamental unit of BLAST algorithm output is the Highscoring Segment Pair (HSP). An HSP consists of two sequence fragments of arbitrary but equal length whose alignment is locally maximal and for which the alignment score meets or exceeds a threshold or cutoff score. A set of HSPs is thus defined by two sequences, a scoring system, and a cutoff score; this set may be empty if the cutoff score is suffi- ciently high. In the programmatic implementations of the BLAST algorithm described here, each HSP consists of a seg- ment from the query sequence and one from a database sequence. The sensitivity and speed of the programs can be adjusted via the standard BLAST algorithm parameters W, T, and X (Altschul et al., 1990); selectivity of the programs can be adjusted via the cutoff score.

    A Maximal-scoring Segment Pair (MSP) is defined by two sequences and a scoring system and is the highest-scoring of all possible segment pairs that can be produced from the two sequences. The statistical methods of Karlin and Altschul (1990, 1993) are applicable to determining the significance of MSP scores in the limit of long sequences, under a random sequence model that assumes independent and identically dis- tributed choices for the residues at each position in the sequences. In the programs described here, Karlin-Altschul statistics have been extrapolated to the task of assessing the significance of HSP scores obtained from comparisons of potentially short, biological sequences.

    SEARCH STRATEGY

    The approach to similarity searching taken by the BLAST pro- grams is first to look for similar segments (HSPs) between the query sequence and a database sequence, then to evaluate the statistical significance of any matches that were found, and finally to report only those matches that satisfy a user-selectable threshold of significance. Findings of mul- tiple HSPs involving the query sequence and a single data- base sequence may be treated statistically in a variety of ways. By default the programs use "Sum" statistics (Karlin and Altschul, 1993). As such, the statistical significance ascribed to a set of HSPs may be higher than that ascribed to any individual member of the set. Only when the ascribed significance satisfies the user-selectable threshold (E parameter) will the match be reported to the user.

    The task of finding HSPs begins with identifying short words of length W in the query sequence that either match or satisfy some positive-valued threshold score T when aligned with a word of the same length in a database sequence. T is referred to as the neighborhood word score threshold (Altschul et al., 1990). These initial neighborhood word hits act as seeds for initiating searches to find longer HSPs containing them. The word hits are extended in both directions along each sequence for as far as the cumulative alignment score can be increased. Extension of the word hits in each direction are halted when: the cumulative alignment score falls off by the quantity X from its maximum achieved value; the cumulative score goes to zero or below, due to the accumulation of one or more negative-scoring residue alignments; or the end of either sequence is reached.

    SETTING PARAMETERS

    Many of the BLAST program parameters have one- or two-letter names and default values that can be modified using a name=value syntax on the command line, e.g., E=0.05 or S2=35. Other command line options are flags that appear alone on the command line (e.g., - span). Parameter names are expected to be followed by a new value, separated from the parameter name by white space, as in - filter seg or -dbrecmax 10500. An alternative parameter-value syntax sup- ported by the programs is illustrated in these examples: filter=seg and dbrecmax=10500.

    SELECTIVITY IN REPORTING MATCHES

    The parameter E establishes a statistical significance threshold for reporting database sequence matches. E is interpreted as the upper bound on the expected frequency of chance occurrence of an HSP (or set of HSPs) within the con- text of the entire database search. Any database sequence whose matching satisfies E is subject to being reported in the program output. If the query sequence and database sequences follow the random sequence model of Karlin and Altschul (1990), and if sufficiently sensitive BLAST algo- rithm parameters are used, then E may be thought of as the number of matches one expects to observe by chance alone during the database search. The default value for E is 10, while the permitted range for this Real valued parameter is 0 < E <= 1000.

    The parameter S represents the score at which a single HSP would by itself satisfy the significance threshold E. Higher scores -- higher values for S -- correspond to increasing statistical significance (lower probability of chance occurrence). Unless S is explicitly set on the com- mand line, its default value is calculated from the value of E. If both S and E are set on the command line, the one which is the most restrictive is used. When neither parame- ter is specified on the command line, the default value for E is used to calculate S.

    The values for E and S are interconvertible, given the con- text of the search, which includes: the length and residue composition of the query sequence; the length of the data- base; a fixed, hypothetical residue composition for the database; and the scoring system employed. The scoring sys- tem used by the BLAST programs consists of a scoring matrix, wherein a score is ascribed to the alignment of each letter (residue) in the alphabet with every other letter in the alphabet as well as to itself.

    The significance of an alignment score depends intimately upon the specific scoring matrix employed and the length and residue composition of the query sequence and database, all of which may vary with each search performed. Instead of the having the user guess at an appropriate value for the cutoff score S for each search, an intuitive, general way to set thresholds for reporting matches is via the E parameter, which has the direct statistical interpretation mentioned above.

    KARLIN-ALTSCHUL STATISTICS

    From Karlin and Altschul (1990), the principal equation relating the score of an HSP to its expected frequency of chance occurrence is:
                            E = K N exp(-Lambda S)
    
    where E is the expected frequency of chance occurrence of an HSP having score S (or one scoring higher); K and Lambda are Karlin-Altschul parameters; N is the product of the query and database sequence lengths, or the size of the search space; and exp is the exponentiation function.

    Lambda may be thought of as the expected increase in relia- bility of an alignment associated with a unit increase in alignment score. Reliability in this case is expressed in units of information, such as bits or nats, with one nat being equivalent to 1/log(2) (roughly 1.44) bits.

    The expectation E (range 0 to infinity) calculated for an alignment between the query sequence and a database sequence can be extrapolated to an expectation over the entire database search, by converting the pairwise expectation to a probability (range 0-1) and multiplying the result by the ratio of the entire database size (expressed in residues) to the length of the matching database sequence. In detail:

                       E_database = (1 - exp(-E)) D / d
    
    where D is the size of the database; d is the length of the matching database sequence; and the quantity (1 - exp(-E)) is the probability, P, corresponding to the expectation E for the pairwise sequence comparison. Note that in the limit of infinite E, P approaches 1; and in the limit as E approaches 0, E and P approach equality. Due to inaccuracy in the statistical methods as they are applied in the BLAST programs, whenever E and P are less than about 0.05, the two values can be practically treated as being equal.

    In contrast to the random sequence model used by Karlin- Altschul statistics, biological sequences are often short in length -- an HSP may involve a relatively large fraction of the query or database sequence, which reduces the effective size of the 2-dimensional search space defined by the two sequences. To obtain more accurate significance estimates, the BLAST programs compute effective lengths for the query and database sequences that are their real lengths minus the expected length of the HSP, where the expected length for an HSP is computed from its score. In no event is an effective length for the query or database sequence permitted to go below 1. Thus, the effective length of either the query or the database sequence is computed according to the follow- ing:

              Length_eff = MAX( Length_real - Lambda S / H , 1)
    
    where H is the relative entropy of the target and background residue frequencies (Karlin and Altschul, 1990), one of the statistics reported by the BLAST programs. H may be thought of as the information expected to be obtained from each pair of aligned residues in a real alignment that distinguishes the alignment from a random one.

    HSP SCORE THRESHOLDS

    Using the default parameters, many more aligned segment pairs are typically found by the BLAST programs than are ultimately reported. First, only those segment pairs scor- ing at or above a selectable cutoff score are saved as bona fide HSPs for further consideration of their statistical significance. And second, any HSPs that are found may not satisfy the significance threshold for reporting.

    The cutoff score which defines HSPs is parameterized as S2. A value for S2 can be set on the command line, or its value can be set indirectly via the command line parameter E2. E2 is interpreted as the expected number of HSPs that will be found when comparing two sequences that each have the same length -- either 300 amino acids or 1000 nucleotides, which- ever is appropriate for the particular program being used. S2 may be thought of as the score expected for the MSP between two such sequences. The default value for E2 is typically about 0.15 but may vary from version to version of each program. The default value for S2 will be calculated from E2 and, like the relationship between E and S, is dependent on the residue composition of the query sequence and the scoring system employed, as conveyed by the Karlin- Altschul K and Lambda statistics.

    SEARCH SENSITIVITY

    Sensitivity of the BLAST programs should be considered in two areas. First, there is the question of how well ungapped alignments (HSPs) can capture or represent the similarity between two biological sequences that may have evolved independently and/or contain sequencing errors. Particularly in the presence of insertions/deletions or frameshifts, it may be necessary to increase E2 (or lower S2), in order to detect the remnants of extended similarity. The amount of evidence or information to support the hypothesis that a given alignment is real and not random decreases with each mutation or sequencing error (States et al., 1991; Gish and States, 1993). As a corollary of this, the expected length of a statistically significant HSP increases with each mutation or sequencing error. At some point, accumulated mutations and errors completely obscure the presence of a relationship between two sequences; the BLAST programs' focus on ungapped alignments will sometimes cause this point to be reached sooner than for other align- ment methods.

    The second area where sensitivity may be of concern is in the heuristic nature of the BLAST algorithm for finding HSP alignments. Using this algorithm, the lower the score of an HSP is, the higher is the probability that the HSP will go undetected. At the user's discretion, the speed of the BLAST algorithm and the programs can be sacrificed in exchange for increased sensitivity of detecting these lower significance HSPs, and vice versa; however, the default parameters for all of the programs except blastn have already been chosen to generally obtain moderate (blastx, tblastn, and tblastx) or high (blastp) sensitivity. If sen- sitivity is not an issue but speed is, then one should con- sider adjusting the BLAST algorithm parameters to achieve higher speed (e.g., increase W by one and T by 10-50%).

    Raising E2 or lowering S2 can improve the apparent sensi- tivity of the BLAST programs by reducing their selectivity, permitting the programs to assess larger sets of HSPs for statistical significance. Lower-scoring HSPs are more dif- ficult for the BLAST algorithm to detect, however, due to its heuristic nature. Therefore, merely increasing E2 (or lowering S2) may not significantly increase sensitivity, without also adjusting the BLAST algorithm's W, T, and X parameters to increase the true sensitivity of the programs.

    If E2 and S2 are adjusted much from their default values to observe even lower-scoring HSPs, search speed may suffer significantly because the computational complexity of the statistical methods is nonlinear in the number of HSPs that are found. For Sum statistics, the complexity is a qua- dratic function of the number of HSPs; for Poisson statis- tics, the complexity is even worse, a cubic function. Furthermore, as more HSPs are considered, fuzziness in the HSP consistency rules yield more reports of false positives.

    Without varying the scoring scheme employed, the probability that the BLAST algorithm can detect an HSP having any par- ticular score can be increased by: lowering the neighbor- hood word score threshold, T, while keeping the word size, W, constant; lowering both W and T appropriately (see Altschul et al., 1990); and/or raising the word hit exten- sion drop-off score X (described earlier).

    The default value for W is 3 amino acids for blastp, blastx, tblastn, and tblastx, and 11 nucleotides for blastn. For the first 4 BLAST programs, which perform comparisons of amino acid sequences, W should usually be restricted to values less than 5, unless the value for T is specified disproportionately larger, to avoid consuming too much memory for the neighborhood word list (see below and Altschul et al., 1990).

    X is a positive integer representing the maximum permissible decay of the cumulative segment score during word hit exten- sion. Raising X may decrease the chance that the BLAST algorithm overlooks an HSP, but it may significantly increase the search time, as well. If computation time is of little concern, X might be increased a few points from its default value, but often little or no increase in sensi- tivity is observed by increasing this parameter from its default value.

    For blastp, blastx, tblastn, and tblastx, the default value for X is calculated to be the minimum integral score representing 10 bits of information, or a decay in the sta- tistical significance of the alignment by a factor of 2 to the tenth power (or about 1,000). Since the X parameter is used to terminate extensions independently in both direc- tions, about 1 in 500 alignments are expected to be terminated prematurely that would have attained a higher score had termination not come so soon.

    For blastn, the default value of X is the minimum integral score that represents at least 20 bits of information, or a reduction in the statistical significance of the alignment by a factor of 2 to the twentieth power (or about one mil- lion).

    THE NEIGHBORHOOD

    T is the neighborhood word score threshold for generating all words of length W that yield a score of at least T when aligned with some word of length W from the query sequence. The list of words so generated is called the neighborhood (Altschul et al., 1990). The size of the neighborhood can be increased, thus improving sensitivity, by lowering T. Conversely, raising the value of T decreases the size of the neighborhood and decreases the likelihood of detecting HSPs. Generally, the larger the neighborhood (the lower T is), the slower the programs run, as well.

    The default value for the neighborhood word score threshold is calculated at run-time from the residue composition and length of the query sequence and the scoring matrix employed, using an ad hoc equation that is a function of Lambda and H. Occasionally it may be necessary to manually set the neighborhood word score threshold via the command line, for which 13 may be a good value to try, but a good choice is highly dependent on the particular scoring matrix and word length used.

    The PAM120 amino acid scoring matrix supplied with the BLAST programs, produced to a scale of Natural log(2)/2, yields values for Lambda that are expected to be close to 0.5 bits per unit score for query sequences of typical residue compo- sitions. Under these conditions, an increase in an align- ment score by 2 units is expected to increase the reliabil- ity or informativeness of the alignment by 2 times 0.5 = 1 bit, corresponding to an increase in its statistical signi- ficance by a factor of 2. The supplied PAM250 matrix was produced to a scale of Natural log(2)/3, suggesting that an increase in alignment score by 3 units will be required to increase statistical significance by a factor of 2. These are rules of thumb for the matrices mentioned. Generally, the significance of an alignment score is indeterminate without specific knowledge of the scoring matrix employed. If one communicates scores in a report, it may be useful to attach the values for the Karlin-Altschul parameters Lambda and K, so that statistical significance can be properly ascribed to the scores.

    MORE OPTIONS

    Except where noted, all of the BLAST programs accept the following command line options:
    -matrix matrixfile
    This option is used to specify the name of a file containing an alternate or user-defined scoring matrix. Most of the programs will only accept one - matrix option at a time, but blastp currently accepts as many as eight (8) on a single command line, all of which are used simultaneously during the database search for increased sensitivity.
    -qtype
    This option causes the BLAST programs to exit non- zero if the query sequence appears to be of the wrong type (either amino acid or nucleic acid) for the particular program invoked.
    -qres
    This option causes the BLAST programs to exit non- zero if the query sequence contains an invalid letter code for the type of query sequence expected (amino acid or nucleic acid).
    -dbrecmin first_record_number
    By default the BLAST programs search the entire database. Using the -dbrecmin option, the record number of the database sequence where the search is to begin can be specified. Record numbers are one- based (i.e., 1 is the first record, 2 is the second record, and so on). Statistics are computed using the complete database length, not the length of the subset selected. See also the -dbrecmax option.
    -dbrecmax last_record_number
    By default the BLAST programs search the entire database. Using the -dbrecmax option, the record number of the database sequence where the search is to end can be specified. See also the -dbrecmin option.
    -gi
    When GenInfo gi identifiers are available for the database sequences (in their deflines), this option can be specified to have these identifiers reported in the program output.
    -span2
    While examining each database sequence, the pro- grams use a greedy algorithm to discard any HSP they find which is spanned from start to end by a previ- ously found HSP. When this option is invoked (the default), an HSP is deemed to be spanning another when both the query and database segments from the first HSP completely cover the corresponding segments in the other HSP. When an HSP spans another, the higher scoring one is retained and the lower scoring one is discarded; if their scores are equal, the longer, less information-dense HSP is discarded. Note: this option was previously called -overlap2 in the BLAST version 1.3 programs.
    -span1
    This option relaxes the criteria for judging whether an HSP spans another, prior to discarding one of them if spanning is detected. With this option, it is merely a matter of either the query segment or the database segment (or both) spans the corresponding segment(s) in the other HSP, whereas the -span2 option requires that both segments be spanned. The - span1 option may be useful in suppressing reports of HSPs when the query or a database sequence contains internal repeats. Note: this option was previously called -overlap1 in the BLAST version 1.3 programs.
    -span
    This option turns off entirely the feature of detecting and discarding spanned HSPs. Voluminous output often results from its use. Note: this option was previously called -overlap in the BLAST version 1.3 programs.
    -filter filtermethod
    This option activates filtering or masking of seg- ments of the query sequence based on a potentially wide variety of criteria. The usual intent of filtering is to mask regions that are non-specific for protein identification using sequence similar- ity. For instance, it may be desired to mask acidic or basic segments that would otherwise yield overwhelming amounts of uninteresting, non-specific matches against a wide array of protein families from a comprehensive database search. The BLAST programs have internally-coded knowledge of the specific command line options needed to invoke the SEG and XNU programs as query sequence filters, but these two filter programs are not included in the BLAST software distribution and must be indepen- dently installed. All filter programs must reside in the /usr/ncbi/blast/filter directory, or the BLASTFILTER environment variable must be set to point to the directory containing the desired filter programs. The SEG program (Wootton and Federhen, 1993) masks low compositional complexity regions, while XNU (Claverie and States, 1993) masks regions containing short-periodicity internal repeats. The BLAST programs can pipe the filtered output from one program into another. For instance, XNU+SEG or SEG+XNU can be specified as the filtermethod to have each program filter the query sequence in succes- sion. Note that neither SEG nor XNU is suitable for filtering untranslated nucleotide sequences for use by blastn.
    -echofilter
    This option causes the filtered query sequence to be displayed in the output. Any masked letters are typically indicated with X's (protein) or N's (nucleic acid).
    -consistency
    This option turns off both the determination of the number of HSPs that are consistent with each other in a gapped alignment and an adjustment that is made to the Sum and Poisson statistics to account for the consistency.
    -qoffset offset
    This option permits query sequence coordinate numbers to be adjusted by the value of offset, through simple addition. This may useful when a query sequence must be split into short, overlapping segments in order to complete individual searches within a restrictive time period.
    -codoninfo codoninfofile
    This (blastx version 1.3 only) option is used to specify a file containing codon usage or codon bias information to be used in concert with a traditional scoring matrix to score alignments. The file con- taining codon usage information must have a .cdi extension on its name, but this extension should be omitted from the codoninfofile argument specified on the command line. Codon usage information should be expressed in units that coincide with the scale of the scoring matrix employed, and the scoring matrix employed must also have a .cdi extension to its name. A few such pairs of scoring matrix and codon usage files are provided in the BLAST software dis- tribution. blastx expects to find the codon usage files in the /usr/ncbi/blast/cdi directory, or the program can be directed to look in another directory by setting the BLASTCDI environment variable. NOTE: this option is presently supported only by the pre- vious version 1.3 of blastx.
    -gapdecayrate rate
    This parameter defines the common ratio of the terms in a geometric progression used in normalizing pro- babilities across all numbers of Poisson events (typically the number of "consistent" HSPs). A Poisson probability for N segments is weighted by the reciprocal of the Nth term in the progression, where the first term has a value of (1-rate), the second term is (1-rate)*rate, the third term is (1- rate)*rate*rate, and so on. The default rate is 0.5, such that the probability assigned to a single HSP is discounted by a factor of 2, the Poisson pro- bability of 2 HSPs is discounted by a factor of 4, for 3 HSPs the discount factor is 8, and so on. The rate essentially defines a penalty imposed on the gap between each HSP, where the default penalty is equivalent to 1 bit of information. The suggestion to normalize Poisson probabilities was made by Phil Green (University of Washington, Seattle, WA).
    -top
    Whenever a nucleotide query sequence is used (blastn, blastx and tblastx), both strands or all 6 reading frames are searched by default. The - top and -bottom options may be used to restrict a search to the specified strand or set of 3 reading frames. If both -top and -bottom are specified, both strands will be searched. In the case of the tblastx pro- gram, which translates both the query and the data- base, the -top and -bottom options refer to strands in the query sequence only. See -dbtop and -dbbot- tom.
    -bottom
    See the -top option.
    -dbtop
    For those programs that translate a nucleotide sequence database (tblastn and tblastx), the -dbtop and -dbbottom options can be specified to restrict the search to a particular strand of each database sequence. The top strand consists of the database sequence as stored in the database; the bottom strand refers to the reverse complement of the data- base sequence.
    -dbbottom
    See -dbtop.
    -gcode genetic_code_ID
    This parameter permits the genetic code used in translating nucleotide query sequences to be changed from its default value of the Standard genetic code (sometimes erroneously called the "Universal" genetic code). See the available list of genetic code identifiers below. Note: the C parameter is a synonym for the -gcode parameter.
    -dbgcode genetic_code_ID
    For the tblastx program, which translates both the query sequence and the database, this option permits the particular genetic code used to translate the database to be set separately from the genetic code used to translate the query sequence. This option may also be used to set the genetic code used by tblastn to translate the database. See the avail- able list of genetic code identifiers below.
    -olfraction overlap_fraction
    This parameter (with default value of 0.125) allows the user to define the maximum fractional length of an HSP that can overlap another HSP and still have the two HSPs be considered to be consistent with one another.
    -sump
    This option (the default) causes Karlin-Altschul (1993) "Sum" statistics to be used in assessing the statistical significance of multiple HSPs.
    -poissonp
    This option causes Poisson statistics, instead of the default Sum statistics, to be used in assessing the statistical significance of multiple HSPs.
    -prune
    This option causes HSPs that are not involved in achieving statistical significance to be eliminated from the program output. When Sum statistics are used, the pruning is robust; when Poisson statistics are used, some HSPs may be reported that were not involved in achieving statistical significance.
    -hspmax max_hsps_per_dbseq
    This option can be used to limit the number of HSPs reported per database sequence. The default limit is 100, which is ample leeway for most searches. Notable exceptions are when numerous, significant repetitive regions exist in the query or database sequences, such as the hundreds of copies of human Alu repeats that exist in some longer database sequences.
    -nwstart start_coord
    blastp and blastx support this option and the -nwlen option, for restricting BLAST neighborhood word gen- eration to a specific segment of the query sequence that begins at start_coord and continues for length residues or until the end of the query sequence is reached. HSP alignments may extend outside the region of neighborhood word generation but the alignments can only be seeded by word hits occurring within the region. Through the use of these options, a very long query sequence can be searched piecemeal, using short, overlapping segments each time. The amount of overlap from one neighborhood region to the next need only be the BLAST wordlength W minus 1, in order to be assured of detecting all HSPs; however, in order to interpret adjacent - s1HSPs in a single database match using Sum or Pois- son statistics, more overlapping of the regions is recommended.
    -nwlen length
    See -nwstart.
    -asn1
    This option causes the programs to produce print- able, structured output (not for human consumption, but for accurate automated parsing) in conformance with specifications written in the ISO 8824 standard ASN.1 language.
    -asn1bin
    This option causes the programs to produce binary- encoded, structured output (not for human consump- tion, but for accurate automated parsing) in confor- mance with specifications written in the ISO 8824 standard ASN.1 language and encoded according to the rules established by ISO 8825.
    -outblk
    This option causes ASN.1 output to be encapsulated in a BLAST0-Outblk structure. For a description of this structure, see the ASN.1 message specifications accompanying the BLAST program source code.
    -warnings
    This option turns off the reporting of all WARNING messages.
    -compat1.3
    This option is used to invoke behavior from the BLAST version 1.4 programs that is very similar to that of the previous version 1.3 programs. This option affects the -poissonp, -span1, -olfraction 0.5, -ctxfactor, E and E2 options.

    SORT OPTIONS

    The default sort order for reporting database sequences is by increasing probability (P-value). The following sort options are available and may be combined together in the same search:
    -sort_by_pvalue
    Sort from most statistically signifi- cant (lowest P-value) to least statisti- cally significant (highest P-value), the default sort order.
    -sort_by_count
    Sort from highest to lowest by the number of HSPs found for each database sequence.
    -sort_by_highscore
    Sort from highest to lowest by the score of the highest scoring HSP for each database sequence.
    -sort_by_totalscore
    Sort from the highest to the lowest by the sum total score of all HSPs for each database sequence.

    SCORING SCHEMES

    The default scoring matrix used by blastp, blastx, tblastn, and tblastx is the BLOSUM62 matrix (Henikoff and Henikoff, 1992). The -matrix option can be used to select an alter- nate scoring matrix file (e.g., one of the PAM matrices described below). In version 1.4, the - matrix option can also be used with blastn to define a scoring matrix, in addition to supporting the traditional M and N parameters of this program.

    Several PAM (point accepted mutations per 100 residues) amino acid scoring matrices are provided in the BLAST software distribution, including the PAM40, PAM120, and PAM250. While the BLOSUM62 matrix is a good general purpose scoring matrix and is the default matrix used by the BLAST programs, if one is restricted to using only PAM scoring matrices, then the PAM120 is recommended for general protein similarity searches (Altschul, 1991). The pam(1) program can be used to produce PAM matrices of any desired iteration from 2 to 511. Each matrix is most sensitive at finding similarities at its particular PAM distance. For more thorough searches, particularly when the mutational distance between potential homologs is unknown and the significance of their similarity may be only marginal, Altschul (1991, 1992) recommends performing at least three searches, one each with the PAM40, PAM120 and PAM250 matrices.

    When multiple scoring matrices are used in searches with the same query sequence, additional degrees of freedom for optimizing alignment scores are available, which reduces each score's statistical significance. The reduction may be by a factor that is as large as the number of matrices employed; however, the potential loss of sensitivity from using a suboptimal matrix is typically much greater, sug- gesting that the use of multiple matrices remains advanta- geous (Altschul, 1992). Altschul (1992) has shown that, because PAM matrices are related to one another through a common mutational model and set of initial conditions, statistical significance is reduced by a factor of no more than 4.6 (just over 2 bits of information) regardless of how many PAM matrices are employed.

    In blastn, the M parameter sets the reward score for a pair of matching residues; the N parameter sets the penalty score for mismatching residues. M and N must be positive and negative integers, respectively. The relative magnitudes of M and N determines the number of nucleic acid PAMs (point accepted mutations per 100 residues) for which they are most sensitive at finding homologs. Higher ratios of M:N correspond to increasing nucleic acid PAMs (increased diver- gence). The default values for M and N, respectively 5 and -4, having a ratio of 1.25, correspond to about 47 nucleic acid PAMs, or about 58 amino acid PAMs; an M:N ratio of 1 corresponds to 30 nucleic acid PAMs or 38 amino acid PAMs. At higher than about 40 nucleic acid PAMs, or 50 amino acid PAMs, better sensitivity at detecting similarities between coding regions is expected by performing comparisons at the amino acid level (States et al., 1991), using conceptually translated nucleotide sequences (re: blastx, tblastn, and tblastx).

    Independent of the values chosen for M and N, the default wordlength W=11 used by blastn restricts the program to finding sequences that share at least an 11-mer stretch of 100% identity with the query. Under the random sequence model, stretches of 11 consecutive matching residues are unlikely to occur merely by chance even between only moderately diverged homologs. Thus, blastn with its default parameter settings is poorly suited to finding anything but very similar sequences. If better sensitivity is needed, one should use a smaller value for W.

    For the blastn program, it may be easy to see how multiply- ing both M and N by some large number will yield proportion- ally larger alignment scores with their statistical signifi- cance remaining unchanged. This scale-independence of the statistical significance estimates from blastn has its ana- log in the scoring matrices used by the other BLAST pro- grams: multiplying all elements in a scoring matrix by an arbitrary factor will proportionally alter the alignment scores but will not alter their statistical significance (assuming numerical precision is maintained). From this it should be clear that raw alignment scores are meaningless without specific knowledge of the scoring matrix that was used.

    SCORING REQUIREMENTS

    Regardless of the scoring scheme employed, two stringent criteria must be met in order to be able to calculate the Karlin-Altschul parameters Lambda and K. First, given the residue composition for the query sequence and the residue composition assumed for the database, the alignment score expected for any randomly selected pair of residues (one from the query sequence and one from the database) must be negative. Second, given the sequence residue compositions and the scoring scheme, a positive score must be possible to achieve. For instance, the match reward score of blastn must have a positive value; and given the assumption made by blastn that the 4 nucleotides A, C, G and T are represented at equal 25% frequencies in the database, a wide range of value combinations for M and N are precluded from use -- namely those combinations where the magnitude of the ratio M:N is greater than or equal to 3.

    SEQUENCE LENGTH AND STATISTICAL SIGNIFICANCE

    For the purpose of calculating significance levels, Y is the effective length of the query sequence and Z is the effec- tive length of the database, both measured in residues. The default values for these parameters are the actual lengths of the query sequence and database, respectively. Larger values signify more degrees of freedom for aligning the sequences and reduced statistical significance for an align- ment of any given score. To normalize the statistics reported when databases of different lengths are searched, the parameter Z may be set to a constant value for all data- base searches. Similarly, when querying with sequences of different lengths, the parameter Y can be used to normalize over all searches.

    GENETIC CODES

    The parameter C can be set to a positive integer to select the genetic code that will be used by blastx and tblastx to translate the query sequence. The -dbgcode parameter can be used to select an alternate genetic code for translation of the database by the programs tblastn and tblastx. In each case, the default genetic code is the so-called "Standard" or "Universal" genetic code. To obtain a listing of the genetic codes available and their associated numerical iden- tifiers, invoke blastx or tblastx with the command line parameter C=list. Note: the numerical identifiers used here for genetic codes parallel those defined in the NCBI software Toolbox; hence some numerical values will be skipped as genetic codes are updated.

    The list of genetic codes available and their associated values for the parameters C and -dbgcode are:

    1. Standard or Universal
    2. Vertebrate Mitochondrial
    3. Yeast Mitochondrial
    4. Mold, Protozoan, Coelenterate Mitochondrial and Mycoplasma/Spiroplasma
    5. Invertebrate Mitochondrial
    6. Ciliate Macronuclear
    7. Echinodermate Mitochondrial
    8. Alternative Ciliate Macronuclear
    9. Eubacterial
    10. Alternative Yeast
    11. Ascidian Mitochondrial
    12. Flatworm Mitochondrial

    SUM STATISTICS

    Whereas the version 1.3 BLAST programs use Poisson statis- tics to ascribe significance to multiple HSPs, the version 1.4 programs retain Poisson statistics as an option, but use Karlin and Altschul (1993) "Sum" statistics by default instead. Sum statistics tends to rank database matches in a more intuitive order than Poisson statistics and, in many cases, yields markedly increased sensitivity. The Sum P- value for a set of HSPs is a function of the sum of the information scores of the HSPs (expressed in bits) and the number of HSPs in the set.

    POISSON STATISTICS

    The occurrence of two or more HSPs involving the query sequence and the same database sequence can be modeled as a Poisson process by specifying the - poissonp option. An important result of applying Poisson statistics is that an HSP having a low score and high Expect value (low statisti- cal significance) may be ascribed a statistically signifi- cant Poisson P-value when the HSP appears in the context of additional match(es) of equal or greater score with the same database sequence. The Poisson P-value for any given HSP is a function of its expected frequency of occurrence and the number of HSPs observed against the same database sequence with scores at least as high. The Poisson P-value for a group of HSP events is the probability that at least as many HSPs would occur by chance alone, each with a score at least as high as the lowest-scoring member of the group. HSPs which appear on opposite strands of a nucleotide query or database sequence are considered to be independent, distinguishable events, and are counted separately.

    P-VALUES, ALIGNMENT SCORES, AND INFORMATION

    The Expect and P-values reported for HSPs are dependent on several factors including: the scoring system employed, the residue composition of the query sequence, an assumed resi- due composition for a typical database sequence, the length of the query sequence, and the total length of the database. HSP scores from different program invocations are appropri- ate for comparison even if the databases searched are of different lengths, as long as the other factors mentioned here do not vary. For example, alignment scores from searches with the default BLOSUM62 matrix should not be directly compared with scores obtained with the PAM120 matrix; and scores produced using two versions of the same PAM matrix, each created to different scales (see above), can not be meaningfully compared without conversion to the same scale.

    Some isolation from the many factors involved in assessing the statistical significance of HSPs can be attained by observing the information content reported (in bits) for the alignments. While the information content of an HSP may change when different scoring systems are used (e.g., with different PAM matrices), the number of bits reported for an HSP will at least be independent of the scale to which the scoring matrix was generated. (In practice, this statement is not quite true, because the alignment scores used by the BLAST programs are integers that lack much precision). In other words, when conveying the statistical significance of an alignment, the alignment score itself is not useful unless the specific scoring matrix that was employed is also provided, but the informativeness of an alignment is a mean- ingful statistic that can be used to ascribe statistical significance (a P-value) to the match independently of specific knowledge about the scoring matrix.

    GOVERNING OUTPUT

    BLAST program output is organized into three independently governed sections: a histogram of the statistical signifi- cance of the matches found; one-line descriptions of the database sequences that satisfied the statistical signifi- cance threshold (E parameter); and the high-scoring segment pairs themselves. Each section of the output can be selec- tively suppressed by setting the parameters H, V, and B to 0 (zero).

    The H parameter regulates the display of a histogram of the expected frequency of chance occurrence of the database matches found. If H is assigned a non-zero value, a histo- gram will be displayed. The default value for H is 0 (no histogram displayed).

    Parameter V is the maximum number of database sequences for which one-line descriptions will be reported. The default value for V is 500. A bold warning message is displayed at the end of the one-line descriptions section when more than V sequences yield HSPs satisfying the significance thres- hold. When V is zero, no one-line descriptions are reported and no warning is given. Negative values for V are unde- fined and disallowed.

    As an example of how V can be used advantageously, if a high value for E is desired to virtually assure in all cases that at least one HSP will be found, selecting a small value for V will ensure that the output will not be overly voluminous; only the most statistically significant matches will be reported.

    Parameter B regulates the display of the high-scoring seg- ment pairs (alignments). For positive values, B is the max- imum number of database sequences for which high-scoring segment pairs will be reported. This may be much smaller than the actual number of high-scoring segment pairs reported, since any given database sequence may yield several HSPs. The default value for B is 250. Negative values for B are undefined and disallowed.

    ENVIRONMENT VARIABLES

    The environment variables BLASTDB, BLASTMAT, BLASTFILTER, and BLASTCDI may be set by the user to override the default directories in which the programs look to find database files, scoring matrix files, filtering programs, and codon usage information files, respectively. The default direc- tories are /usr/ncbi/blast/db, /usr/ncbi/blast/matrix, /usr/ncbi/blast/filter, and /usr/ncbi/blast/cdi.

    SUPPORT UTILITIES

    Databases to be searched by the BLAST programs must first be formatted by the setdb program for protein sequence data- bases (re: blastp and blastx) or the pressdb program for nucleotide sequence databases (re: blastn and tblastn). The input database files read by setdb and pressdb must be in FASTA/Pearson format. For each input file, three output files are created for searching by the BLAST programs.

    Point accepted mutation (PAM) matrices of various generations can be produced automatically with the pam program. The output can be saved in a file whose name can then be specified in the M=filename option of a blastp, blastx, or tblastn query.

    SAMPLE OUTPUT

    The BLAST programs all provide information in roughly the same format. First comes (A) an introduction to the pro- gram; (B) a histogram of expectations (see above) if one was requested; (C) a series of one-line descriptions of matching database sequences; (D) the actual sequence alignments; and finally the parameters and other statistics gathered during the search.

    Sample blastp output from comparing pir|A01243|DXCH against the SWISS-PROT database is presented below.

    A. Program Introduction

    The introductory output provides the program name (BLASTP in this case), the version number (1.4.6MP in this case), the date the program source code last changed substantially (June 13, 1994), the date the program was built (Sept. 22, 1994), and a description of the query sequence and database to be searched. These may all be important pieces of infor- mation if a bug is suspected or if reproducibility of results is important.

    The "Searching..." indicator indicates progress that the program made in searching the database. A complete database search will yield 50 periods (.), or one period per database sequence, whichever number is smaller. When searching a database consisting of 50 sequences or more, if fewer than 50 periods are displayed and the program aborted for some reason, dividing the number of periods by 0.5 will yield the approximate percentage (0-100%) of the database that was searched before the program died. If the program had diffi- culty making progress through the database, one or more asterisks (*) may be interspersed between the periods at one-minute intervals.

    B. Histogram of Expectations

    Shown in the output below is a histogram of the lowest (most significant) Expect values obtained with each database sequence. This information is useful in determining the numbers of database sequences that achieved a particular level of statistical significance. It indicates the number of database matches that would be reportable at various set- tings for the expectation threshold (E parameter).

    C. One-line Summaries

    The one-line sequence descriptions and summaries of results are useful for identifying biologically interesting database matches and correlating this interest with the statistical significance estimates. Unless otherwise requested, the database sequences are sorted by increasing P-value (proba- bility). Identifiers for the database sequences appear in the first column; then come brief descriptions of each sequence, which may need to be truncated in order to fit in the available space. The "High Score" column contains the score of the highest-scoring HSP found with each database sequence. The "P(N)" column contains the lowest P-value ascribed to any set of HSPs for each database sequence; and the "N" column displays the number of HSPs in the set which was ascribed the lowest P-value. The P-values are a func- tion of N, as used in Karlin-Altschul "Sum" statistics or Poisson statistics, to treat situations where multiple HSPs are found. It should be noted that the highest-scoring HSP whose score is reported in the "High Score" column is not necessarily a member of the set of HSPs which yields the lowest P-value; the highest-scoring HSP may be excluded from this set on the basis of consistency rules governing the grouping of HSPs (see the -consistency option). Numbers of the form "7.7e-160" are in scientific notation. In this particular example, the number being represented is 7.7 times 10 to the minus 160th power. which is astronomically close to zero.

    D. Alignments

    Alignments found with the BLAST algorithm are ungapped. Several statistics are used to describe each HSP: the raw alignment Score; the raw score converted to bits of information by multiplying by Lambda (see the Statistics output); the number of times one might Expect to see such a match (or a better one) merely by chance; the P-value (probability in the range 0-1) of observing such a match; the number and fraction of total residues in the HSP which are identical; the number and fraction of residues for which the alignment scores have positive values. When Sum statistics have been used to calculate the Expect and P-values, the P-value is qualified with the word "Sum" and the N parameter used in the Sum statistics is provided in parentheses to indicate the number of HSPs in the set; when Poisson statistics have been used to calculate the Expect and P-values, the P-value is qualified with the word "Poisson". Between the two lines of Query and Subject (database) sequence is a line indicating the specific residues which are identical, as well as those which are non-identical but nevertheless have positive alignment scores defined in the scoring matrix that was used (the BLOSUM62 matrix in this case). Identical letters or residues, when paired with each other, are not highlighted if their alignment score is negative or zero. Examples of this would be an X juxtaposed with an X in two amino acid sequences, or an N juxtaposed with another N in two nucleotide sequences. Such ambiguous residue-residue pairings may be uninformative and thus lend no support to the overall alignment being either real or random; however, the informativeness of these pairings is left up to the user of the BLAST programs to decide, because any values desired can be specified in a scoring matrix of the user's own making.
         BLASTP 1.4.6MP [13-Jun-94] [Build 13:58:36 Sep 22 1994]
    
         Reference:  Altschul, Stephen F., Warren Gish, Webb Miller, Eugene W. Myers,
         and David J. Lipman (1990).  Basic local alignment search tool.  J. Mol. Biol.
         215:403-10.
    
         Query=  pir|A01243|DXCH  232 Gene X protein - Chicken (fragment)
                 (232 letters)
    
         Database:  SWISS-PROT Release 29.0
                    38,303 sequences; 13,464,008 total letters.
         Searching..................................................done
    
              Observed Numbers of Database Sequences Satisfying
             Various EXPECTation Thresholds (E parameter values)
    
                 Histogram units:      = 31 Sequences     : less than 31 sequences
    
          EXPECTation Threshold
          (E parameter)
             |
             V   Observed Counts-->
           10000 4863 1861 |============================================================
            6310 3002  782 |=========================
            3980 2220  812 |==========================
            2510 1408  303 |=========
            1580 1105  393 |============
            1000  712  179 |=====
             631  533  161 |=====
             398  372   80 |==
             251  292   73 |==
             158  219   50 |=
             100  169   32 |=
            63.1  137   18 |:
            39.8  119    9 |:
            25.1  110    6 |:
            15.8  104    9 |:
          >>>>>>>>>>>>>>>>>>>>>  Expect = 10.0, Observed = 95<<<<<<<<<<<<<<<<<
            10.0   95    4 |:
            6.31   91    3 |:
            3.98   88    1 |:
            2.51   87    3 |:
            1.58   84    0 |
            1.00   84    2 |:
    
                                                                              Smallest
                                                                                Sum
                                                                       High  Probability
         Sequences producing High-scoring Segment Pairs:              Score  P(N)      N
    
         sp|P01013|OVAX_CHICK GENE X PROTEIN (OVALBUMIN-RELATED) (...  1191  7.7e-160  1
         sp|P01014|OVAY_CHICK GENE Y PROTEIN (OVALBUMIN-RELATED).       949  7.0e-127  1
         sp|P01012|OVAL_CHICK OVALBUMIN (PLAKALBUMIN).                  645  3.4e-100  2
         sp|P19104|OVAL_COTJA OVALBUMIN.                                626  1.2e-96   2
         sp|P05619|ILEU_HORSE LEUKOCYTE ELASTASE INHIBITOR (LEI).       216  3.7e-71   3
         sp|P80229|ILEU_PIG   LEUKOCYTE ELASTASE INHIBITOR (LEI) (...   325  4.0e-71   2
         sp|P29508|SCCA_HUMAN SQUAMOUS CELL CARCINOMA ANTIGEN (SCC...   439  3.5e-70   2
         sp|P30740|ILEU_HUMAN LEUKOCYTE ELASTASE INHIBITOR (LEI) (...   211  1.3e-66   3
         sp|P05120|PAI2_HUMAN PLASMINOGEN ACTIVATOR INHIBITOR-2, P...   176  1.8e-65   4
         sp|P35237|PTI_HUMAN  PLACENTAL THROMBIN INHIBITOR.             473  1.3e-61   1
         sp|P12388|PAI2_MOUSE PLASMINOGEN ACTIVATOR INHIBITOR-2, M...   179  1.8e-60   4
         sp|P36952|MASP_HUMAN MASPIN PRECURSOR.                         198  2.6e-58   4
         sp|P32261|ANT3_MOUSE ANTITHROMBIN-III PRECURSOR (ATIII).       142  4.0e-48   5
         sp|P01008|ANT3_HUMAN ANTITHROMBIN-III PRECURSOR (ATIII).       122  7.5e-48   5
    
         WARNING:  Descriptions of 80 database sequences were not reported due to the
                   limiting value of parameter V = 15.
    
           ... alignments with the top 8 database sequences deleted ...
    
         >sp|P05120|PAI2_HUMAN PLASMINOGEN ACTIVATOR INHIBITOR-2, PLACENTAL (PAI-2)
                     (MONOCYTE ARG- SERPIN).
                     Length = 415
    
          Score = 176 (80.2 bits), Expect = 1.8e-65, Sum P(4) = 1.8e-65
          Identities = 38/89 (42%), Positives = 50/89 (56%)
    
         Query:     1 QIKDLLVSSSTDLDTTLVLVNAIYFKGMWKTAFNAEDTREMPFHVTKQESKPVQMMCMNN 60
                      +I +LL   S D DT +VLVNA+YFKG WKT F  +     PF V   +  PVQMM +
         Sbjct:   180 KIPNLLPEGSVDGDTRMVLVNAVYFKGKWKTPFEKKLNGLYPFRVNSAQRTPVQMMYLRE 239
    
         Query:    61 SFNVATLPAEKMKILELPFASGDLSMLVL 89
                        N+  +   K +ILELP+A      L+L
         Sbjct:   240 KLNIGYIEDLKAQILELPYAGDVSMFLLL 268
    
          Score = 165 (75.2 bits), Expect = 1.8e-65, Sum P(4) = 1.8e-65
          Identities = 33/78 (42%), Positives = 47/78 (60%)
    
         Query:   155 ANLTGISSAESLKISQAVHGAFMELSEDGIEMAGSTGVIEDIKHSPESEQFRADHPFLFL 214
                      AN +G+S    L +S+  H A ++++E+G E A  TG +   +      QF ADHPFLFL
         Sbjct:   338 ANFSGMSERNDLFLSEVFHQAMVDVNEEGTEAAAGTGGVMTGRTGHGGPQFVADHPFLFL 397
    
         Query:   215 IKHNPTNTIVYFGRYWSP 232
                      I H  T  I++FGR+ SP
         Sbjct:   398 IMHKITKCILFFGRFCSP 415
    
          Score = 144 (65.6 bits), Expect = 1.8e-65, Sum P(4) = 1.8e-65
          Identities = 26/62 (41%), Positives = 41/62 (66%)
    
         Query:    90 LPDEVSDLERIEKTINFEKLTEWTNPNTMEKRRVKVYLPQMKIEEKYNLTSVLMALGMTD
                      + D  + LE +E  I ++KL +WT+ + M +  V+VY+PQ K+EE Y L S+L ++GM D
         Sbjct:   272 IADVSTGLELLESEITYDKLNKWTSKDKMAEDEVEVYIPQFKLEEHYELRSILRSMGMED 331
    
         Query:   150 LF 151
                       F
         Sbjct:   332 AF 333
    
          Score = 61 (27.8 bits), Expect = 1.8e-65, Sum P(4) = 1.8e-65
          Identities = 10/17 (58%), Positives = 16/17 (94%)
    
         Query:    81 SGDLSMLVLLPDEVSDL 97
                      +GD+SM +LLPDE++D+
         Sbjct:   259 AGDVSMFLLLPDEIADV 275
    
         WARNING:  HSPs involving 86 database sequences were not reported due to the               limiting value of parameter B = 9.
    
         Parameters:
           V=15
           B=9
           H=1
    
           -ctxfactor=1.00
           E=10
    
           Query                        -----  As Used  -----    -----  Computed  ----
           Frame  MatID Matrix name     Lambda    K       H      Lambda    K       H
    
           Query
           Frame  MatID  Length  Eff.Length   E    S W   T  X     E2  S2
            +0      0      232       232      10. 57 3  11 22    0.22 33
    
         Statistics:
           Query          Expected         Observed           HSPs       HSPs
           Frame  MatID  High Score       High Score       Reportable  Reported
            +0      0    62 (28.2 bits)  1191 (542.5 bits)     330         24
    
           Query         Neighborhd  Word      Excluded    Failed   Successful  Overlaps
           Frame  MatID   Words      Hits        Hits    Extensions Extensions  Excluded
            +0      0      4988     5661199     1146395     4504598    10187        13
    
           Database:  SWISS-PROT Release 29.0
             Release date:  June 1994
             Posted date:  1:29 PM EDT Jul 28, 1994
           # of letters in database:  13,464,008
           # of sequences in database:  38,303
           # of database sequences satisfying E:  95
           No. of states in DFA:  561 (55 KB)
           Total size of DFA:  110 KB (128 KB)
           Time to generate neighborhood:  0.03u 0.01s 0.04t  Real: 00:00:00
           No. of processors used:  8
           Time to search database:  32.27u 0.78s 33.05t  Real: 00:00:04
           Total cpu time:  32.33u 0.91s 33.24t  Real: 00:00:05
    
         WARNINGS ISSUED:  2
    

    BUGS

    The statistics are not fully worked out yet for blastp when multiple -matrix options are specified in a single command.

    blastn by default uses a large value of 11 for the wordlength, W, which severely reduces the program's sensi- tivity but provides for high speed searches. Consequently, the program with its default parameter values is well suited to finding nearly identical sequences rapidly, but poorly suited to finding moderately- or distantly-related sequences. The value for W may be reduced to increase the sensitivity (at the expense of speed), but to identify weak similarity between coding regions, greater sensitivity is obtained by comparing translation products (States et al., 1991); one should use blastx, tblastn, or tblastx. blastn is poorly suited to characterizing PCR primers.

    In the protein-comparing programs blastp, blastx, tblastn, and tblastx, ad hoc equations are used to calculate a default value for the neighborhood word score threshold T when the word length W has a value of 3 (the default) or 4. Equations have not been implemented for calculating a default value of T when W has any value other than 3 or 4.

    When nucleotide sequence databases are compressed into searchable form by the pressdb program, IUPAC ambiguity letters are replaced by an appropriate random selection from the list A, C, G and T. For example, an R (purine) would be replaced on the average half of the time by an A (adenosine) and the remainder of the time by a G (guanosine). If the original database in FASTA format is not available to blastn and tblastn at the time of the search, then the original locations and identities of the ambiguity codes can not be determined by these programs and the alignments and align- ment scores may be in error with respect to the original sequences.

    tblastn and tblastx use only one genetic code to translate the entire nucleotide sequence database, although the code that is used is selectable via the -dbgcode option.

    blastn, blastx, tblastn, and tblastx treat U and T residues in nucleotide sequences as being the same residue (i.e., they match perfectly or translate in exactly the same manner).

    The amino acid alphabet used by the BLAST programs consists of the IUB and IUPAC amino acid codes (ABCDEF- GHIKLMNPQRSTVWXYZ), plus asterisk (*) and hyphen (-). An asterisk signifies a stop codon; and a hyphen signifies a gap of indeterminate length through which BLAST alignments are never permitted to extend. Any letter which is not a member of this alphabet will be stripped from an amino acid query sequence on input and will not contribute to the query sequence coordinate numbers displayed in program output. In protein sequence databases that are processed into search- able form by the setdb program, any non-alphabetic letters are also stripped.

    The nucleotide alphabet used by the BLAST programs consists of the IUB and IUPAC nucleotide codes (ACGTRYMKWSBDHVNU), plus hyphen (-) to signify a gap of indeterminate length. U (uracil) is treated like a T (thymidine). When non- alphabetical codes appear in the FASTA-format input database to the pressdb program, the program complains about their appearance and then halts with a non-zero exit status.

    Unlike its version 1.3 predecessor, blastn version 1.4 can employ a concept of partial matching, such as might be used when two Rs (purines) are aligned with each other. When the blastn scoring system is defined using the M and N parame- ters, the scoring matrix constructed by the program accounts for partial matching of nucleotide ambiguity codes. If the -matrix option is used instead, the user has complete free- dom to decide how to score alignments involving ambiguity codes.

    When calculating the Sum and Poisson statistics, some HSPs may be inconsistent or incompatible with one another in the same gapped alignment, and yet the programs will count them as independent, consistent events, leading to false posi- tives being reported in the output. See the - olfraction option. (However, HSPs appearing on opposite strands of the query or database sequence, or in reading frames on opposite strands, are considered separately in all cases).

    The nucleotide composition of a blastn query sequence is irrelevant to the values reported for the Karlin-Altschul Lambda and K parameters. This is due to the equi-probable 0.25/0.25/0.25/0.25 A/C/G/T residue distribution assumed by blastn for the database sequences. The values of the Karlin-Altschul parameters are still affected by the scoring system employed (defined by the parameters M and N, or the - matrix option).

    On multiprocessor platforms, blastn restricts itself by default to using 3 processors maximum, due to the relatively high initialization cost per processor when the database contains long sequences, as compared to the brief cpu time required for searches that use the default wordlength of 11. More than 3 processors can be recruited using the P command line option.

    SEE ALSO

    blast3(1).

    COPYRIGHT

    This work is in the public domain.

    REFERENCES

    Altschul, Stephen F. (1991). Amino acid substitution matrices from an information theoretic perspective. J. Mol. Biol. 219:555-65.

    Altschul, S. F. (1993). A protein alignment scoring system sensitive at all evolutionary distances. J. Mol. Evol. 36:290-300.

    Altschul, S. F., M. S. Boguski, W. Gish and J. C. Wootton (1994). Issues in searching molecular sequence databases. Nature Genetics 6:119-129.

    Altschul, Stephen F., Warren Gish, Webb Miller, Eugene W. Myers, and David J. Lipman (1990). Basic local alignment search tool. J. Mol. Biol. 215:403-10.

    Claverie, J.-M. and D. J. States (1993). Information enhancement methods for large scale sequence analysis. Computers in Chemistry 17:191-201.

    Gish, W. and D. J. States (1993). Identification of protein coding regions by database similarity search. Nature Genetics 3:266-72.

    Henikoff, Steven and Jorga G. Henikoff (1992). Amino acid substitution matrices from protein blocks. Proc. Natl. Acad. Sci. USA 89:10915-19.

    Karlin, Samuel and Stephen F. Altschul (1990). Methods for assessing the statistical significance of molecular sequence features by using general scoring schemes. Proc. Natl. Acad. Sci. USA 87:2264-68.

    Karlin, Samuel and Stephen F. Altschul (1993). Applications and statistics for multiple high-scoring segments in molecular sequences. Proc. Natl. Acad. Sci. USA 90:5873-7.

    States, D. J. and W. Gish (1994). Combined use of sequence similarity and codon bias for coding region identification. J. Comput. Biol. 1:39-50.

    States, D. J., W. Gish and S. F. Altschul (1991). Improved sensitivity of nucleic acid database similarity searches using application specific scoring matrices. Methods: A companion to Methods in Enzymology 3:66-70.

    Wootton, J. C. and S. Federhen (1993). Statistics of local complexity in amino acid sequences and sequence databases. Computers in Chemistry 17:149-163.


    r coding region identification. J. Comput. Biol. 1:39-50.

    States, D. J., W. Gish and S. F. Altschul (1991). Improved sensitivity of nucleic acid database similarity searches using application specific scoring matrices. Methods: A companion to Methods isrs/www/doc/contents.html SRS functions list

    (1)
    The SRSWWW server

    (2)
    SRS Query Language

    (3)
    SRS Programs

    (4)
    Icarus

    (5)
    Icarus Functions

    (6)
    Icarus Debugger

    (7)
    Adding Databanks - a Guided Tour

    (8)
    SRS Server Maintenance

    (9)
    Programming with the C Language API

    (10)
    The C Language API

    (11)
    The SRS Object Classes

    (12)
    Internal


    * Index *

    SRS Server Maintenance

    (9)
    Programming with the C Language API

    (10)
    Icarus Debugger

    The Icarus Debugger

    The Icarus debugger supports unconditional and conditional breakpoints. For example, by setting one or more breakpoints in the syntax file, one can start the debugger and jump through the parsing procedure from one breakpoint to the next. One can step through every step of the parsing procedure, or a mixture of both of these. At the debugger prompt, the current values of variables can be printing and altered, and even new variables initialized.

    The debugger uses the Icarus interpreter, and so the debugging environment is and extension of the Icarus code being debugged. Multiple Icarus commands can be given on the debugger command line, and command line editing is supported.

    It is important to remember that because Icarus implements lazy parsing, breakpoints must be placed in parts of the code that are used to produce the requested output.

    Starting Debugger Mode

    There are three ways to invoke the Icarus debugger. To take the example from the Guided Tour:

    % genes.is -debug
    % getz '[genes-id:HSU07616]' -e -debug
    % srsbuild genes -d -debug
    

    and here's another example

    % tfsite.is -debug
    % getz '[tfsite-id:hbv$hbve_03]' -e -debug
    % srsbuild tfsite -d -debug
    

    Setting Debugger Breaks

    The command $Break (or $break) sets a breakpoint at the current position in the syntax definition and is evaluated at "pre" execution time.

    Taking the example from the Guided Tour, a break point can be added to the file "SRSDEMO:genes.is" using $Break at, say, this point

      # the data-fields
      fields:    ~ {$In:entry $Out $Skip:1 $Break} id date def cit seq ~
    

    Or a conditional breakpoint can be set like this

      # the data-fields
      fields:    ~ {$In:entry $Out $Skip:1 $Break:[cond:$entry='HSU07616']} id date def cit seq ~
    

    Debugger Commands

    For convenience when debugging, all debugger commands are in lowercase, and are therefore exceptions to the convention that Icarus functions start with an uppercase character. The following commands can be used at the debugger prompt ">"

    Although the Icarus function $Print can be used for printing values of variables, there is also a debugger print function which does the same but formats the output for the debugging environment, and in keeping with the other debugger commands, is lowercase:

    > $dp
    

    Inside the debugger, printing the values of the special scalar variables $Ct, $It, $Fip, $1,$2...$9, $0, where $1 $2 etc are from the last regular expression matches is simple.

    > $dp:$Ct
    > $dp:$It
    > $dp:$1
    > $dp:$Fip
    
    To continue execution of the code until the next node:
    > $next
    
    To continue execution of the code until the next break point:
    > $cont
    
    To print a hierarchical view of the syntax tree. This can be used when "Prod" is displayed.
    > $tree
    

    By typing the return key instead of giving a debugger command, the debugger repeats the last command line given (which could be several commands).

    When you are finished with the debugging session, you can exit the debugger by typing

    > $exit
    

    Debugger Example

    Using the example above in "SRSDEMO:genes.is"
    % genes.is -debug
    [- Prod       fields]> $tree
    ====================================
        Production: fields  { *3 -2 +1 }
            Term 
                ProdName: id 
                ProdName: date 
                ProdName: def 
                ProdName: cit 
                ProdName: seq 
    ====================================
    [- Prod       fields]> $next
    [- ProdName   id]> $dp:$Ct
    [- ProdName   id]> $dp:$It
    LOCUS       HSU07616
    DATE        02-FEB-1995
    DEFINITION  Human amphiphysin mRNA, complete cds.
    CITATION    YAMAR95
    SEQUENCE  
            1 ccaggtgcct actgactcct tcagaaatgt cagttcctgt cccatgccct taatatttcc
           61 cacatgcagg gctctgtgca caatgcgtga caatggcttt tagat
    
    //
    [- ProdName   id]> $exit
    % 
    
    At this moment, one must be careful about entering debugging commands because Icarus will terminate if there is a problem:
    % genes.is -debug
    <...>
    [- Lit        'LOCUS']> $dp $Ct
    Segmentation fault
    %
    

    Debugger Output

    The node of the syntax tree that has just been parsed is shown inside the brackets "[" and "]" (as in the example shown above).

    Shown inside these brackets from left to right are the execution time with respect to the symbol comparison:

    "*" refers to the execution time of init

    "-" refers to the execution time of pre, and

    "+" refers to the execution time of post

    Then the type of node is shown. By example "Prod" means a production

    "ProdName" means a production name etc

    Then the value of the node is shown, in this case "'LOCUS'".

    More Information

    Further information can be found in the manual chapter "Adding Databanks - A Guided Tour" in the section "Additional Tricks for Debugging a Syntax" ime of pre, and

    "+" refers to the execution time of post

    Then the type of node is shown. By example "Prod" means a production

    "ProdName" means a production name etc

    Then the value of the node is shown, in this casesrs/www/doc/icarus.html The Icarus Language

    The Icarus Language

    The Icarus language was originally designed to parse flat file databanks. The syntax of these databanks can be often described in layers: the syntax of the entry within the databank, the data-fields within the entry and the syntax of each data-field. The full layered syntax we call incremental or recursive.

    A syntax definition alone is not enough. During the parsing process it is necessary to save certain information or to modify or reformat the tokens found. An example is the date in the data-field "DATE" which might look like "12-APR-88" and for the purpose of indexing needs to be reformatted to the number "19880412". This is one of many tasks that are conveniently executed during the parsing process.

    The name Icarus stands for Interpreter of Commands And RecUrsive Syntax. Initially, it was used to attach commands to syntax descriptions. In fact, the 'command part' became so powerful that Icarus can be seen as a 'normal' interpreted language such as Perl or Tcl with the added capability of syntax specification.

    The current Icarus is not yet a general purpose language, since functions can still not be implemented in Icarus and since a few operators like % and -- are still missing. We developed Icarus mainly to meet the demands of the SRS system.

    Getting Started: a first Icarus program

    Use your favorite text editor to write the program "first" with the line

    $Print:"hello world\n"

    then start the Icarus program with the command

    % icarus first

    This program should print the string "hello world" on your terminal

    Getting Started: setting up your environment

    On systems that support "magic numbers" you can set up the system so that you can directly execute icarus scripts without explicitly call icarus. To do this you can add a line at the top of the program so that the operating system knows what program to interpret your file with, like this:

    #!/bin/env icarus
    $Print:"hello world\n"

    To use the above format, the icarus executable must be defined in your $PATH environment variable. To accomplish this, you can also simply execute the command:

    source prep_srs

    before starting to work. This command defines everything that is necessary to work with SRS.

    An alternative and less flexible way is to hard-wire the path of the icarus interpreter into your program:

    #!/usr/local/bin/icarus
    $Print:"hello world\n"

    Before 'executing' program "first" you must also set the executable permission on the file with

    % chmod +x first

    Once this is done, all you have to type is:

    % first

    The structure of an Icarus program

    An Icarus program is a list of statements, in which each statement is:

    • an assignment, in which a variable is assigned the value of an expression
    • an Icarus command, which can have parameters initialized with expressions
    • a flow control directive

    Comments are delimited by the # sign and continue to the end of the line. The first line of the program must be the "magic number" (!/bin/env/icarus) that tells to the operating system to use Icarus to execute the program.

    Example:

    #!/bin/env icarus
    #this is my first icarus program
    $sum = (1 + 2) * 3   # an assignment 
    $Print:"hello world" # a command

    Almost all statements have expressions: the next paragraph explains them in more detail.

    Expressions

    Any Icarus expression consists of operands and operators.

    Operands can be

    • literals or basic types: values which can directly be expressed in the icarus language
    • variables
    • function calls
    • expressions within parentheses

    Operators are binary, if they have two operands, such as the * for multiplication, or unary if they act on one operand, such as the ++ for incrementing the value of the operand. An expression with more than one operation is executed by a certain order. The order depends on the precedence of the operators, the order within the expression (since they are normally evaluated left to right), and the grouping by parentheses. Each basic type accepts a certain set of operators.

    Example:

    $sum = (1 + 2) * 3 * $a

    The result from the expression, the number 9, is stored in the variable $sum.

    All identifiers in Icarus are preceded by a $. Identifiers are case sensitive, and can be both function or variable names. So the identifier $a in the expression can refer to a variable or call a function, depending on how $a is defined before. The convention is to let function names start with uppercase letters and variables with lowercase letters. Variables and function will be explained later in more detail.

    The following sections will explain the operands and operators of Icarus expressions in detail.

    Basic Types

    Icarus provides a set of predefined types:

    • signed integers (32bit integers),
    • real numbers (implemented as the C language double, a 64bit floating point number),
    • productions (rule), useful for parsing which will be explained later,
    • strings.
    • lists.

    Strings

    Icarus knows four types of strings:

    • names: a name consists of one or more characters. The first must be an alphabetical letter and the others alpha numerical characters including the underscore ("_").
    • single quoted strings: a string that must begin and end in the same program line, but can contain spaces.
    • double quoted strings: as single quoted strings, but perform string interpretation (see below)..
    • barstrings - The barstring may consist of more than one line and is identified by a vertical bar | at the beginning of every line which belongs to the string. The | at the begin of lines that continue a barstring may be only preceded by blanks or tab characters. Every character after the vertical bar to the end of the line, including the carriage return is part of the string. Also barstrings perform string interpretation.

    Examples:

    $name      = Hello
    $sqstring  = 'Hello World'
    $dqstring  = "Hello World"
    $barstring = |Hello
                 |World.

    Icarus defines a special syntax (escape sequences) for non-printing and special characters. These are very similar to the ones defined for the C language, i.e. a backslash \ followed by the character code:

    \n
    a new line character or line break
    \t
    a tab character
    \a
    an alert (beep)
    \decimal number
    any ASCII character specified by a decimal number, e.g., \10 is the same as \n
    \\
    the \ itself
    \any other character the character itself.

    Depending on the type of strings, other characters must be escaped.

    • in single quoted strings the ' and all non-printing characters must be escaped
    • in double quoted strings the " and all non-printing characters must be escaped. In some cases which will be explained in the string interpretation paragraph, the $ must also be escaped.
    • in barstrings characters normally don't need to be escaped: the string can normally be written exactly as it will be printed. The carriage return can be excluded from the string with an backslash \ at the end of the line. All the escapes can still be used if needed.

    Examples:

    $name      = Hello
    $sqstring  = '"Hello" \\World\\\n\t'Again\'.'
    $dqstring  = "\"Hello\" \\World\\\n\t'Again'."
    $barstring = |"Hello" \
                 |\\World\\
                 |        'Again'.
                  

    prints in all 3 cases:

    "Hello" \World\
            'Again'

    For string management, Icarus provides the functions:

      $StrLen which returns the length of a string

      $StrApp which appends a string to another

      $StrTrans which translates a set of characters in a string into another set of characters

      $StrPad which pads a string with a certain character up to a certain length

    Lists and associative lists

    Icarus has flexible lists where several or all of its elements can be associated with a name. This association of elements with a name is a property of elements in associative arrays and can be also found in other programming languages. The difference here is that the elements in the list are always ordered and hence can always be accessed by position. Lists can have elements of mixed types (e.g., strings and integers in the same list) and any basic type can be inserted, including other lists that can be nested to any degree. In the Icarus syntax members of a list must appear within curly braces (e.g., {1 2 3}).

    Elements can be accessed by position where the first element (list head) has position 1. The number must appear in square brackets after the list variable name. If a name is associated with the element it can be used by adding the name to the list variable name using a dot (.) as separator.

    Examples:

    Initialize or reset a list:

    $list = {}

    Define a list with 5 elements of type string:

    $list = {aa ee ii oo uu}

    Access members in a list by position:

    $a = $list[2]
      $Print:$a

    will give the output

      ee

    Define a nested associative list:

    $list2 = {
      a: {aa: 1 bb: 2}
      b: 2
      c: 'Hello world'
      d: {1 2 3}
    }

    In this example "list2" has 4 elements where the first and the last are lists themselves.

    The following shows four ways of accessing the same element in "list2":

    • Access by associated name:
    • $list2.a.aa 

      If a name isn't defined, an empty variable will be returned (see below in Program Variables).

    • Access by associated name using the name "a" stored in the variable $selector. Note that $selector must be put in parentheses; otherwise the name "aa" would refer to an element in $selector:
    • $selector = "a"
      $list2.($selector).aa
    • Access by list position:
    • $list2[1][1]
    • Access by list position where the position numbers are stored in variables
    • $i = 1
      $j = 1
      $list2[$i][$j]

    A list can be changed in two ways:

    • New list elements can be appended to the list using the += operator:
    • $list2+=5

      The new appended elements don't have an associated name

    • Named elements can be reassigned or created simply by naming them:
    • $list2.b=|Again

      assigns a new string to the element b

      $list2.e='Goodbye All'

      appends the new element named .e to the list and initializes it with a string

    For list management, Icarus provides the function $Key which takes a list element as argument and returns the name of it in the list.

      Variables

      In an Icarus program, variables can store any basic type. They can be assigned using the = operator.

      A variable can have any name that doesn't collide with a function name. Conventionally, variable names start lower case.

      A variable is undefined until it is assigned a value for the first time. An unassigned variable, if used in an expression, returns the empty string. After the first assignment the type of the variable is fixed and cannot be changed any more, while instead the value can be changed at any time. This is also true for list elements.

      Functions

      Icarus functions are all predefined in the Icarus parser during execution. To define new functions, see chapter "Creating New Icarus Commands".

      In the function definition it is specified (together with other things):

      • name and type of the arguments. The function can have zero or more arguments. Only one of the arguments can be unnamed. All arguments can be defined with a default value.
      • type of the return value

      Functions may be called with zero or more arguments which are enclosed in square brackets ([ ]) and separated from the function name by a colon (:). Each argument must be preceded by the argument name with the exception of the eventual unnamed argument. For example, the following calls the function $Print which receives the unnamed argument "hello world" and the argument .f (file) which is assigned the contents of the variable $output, containing the file name:

      $Print:["hello world" f:$output]

      Most arguments have default values. In this case, they normally don't need to be specified unless they need to be assigned a value different from the default. For example, the .f argument defaults to standard output.The function can the be written as:

      $Print:"hello world"

      If the argument list consists only of the unnamed attribute, as in the above example, the square brackets can be omitted.

      A function called without any argument and returning a value is indistinguishable from a variable. The only difference is that a value cannot be assigned to it.

      An example is the function $Ct, which will be explained in the parsing section:

      $Print:$Ct

      Interpreted Strings

      Double quoted and bar strings can perform substitution of the values of variables and even functions every time they are evaluated. All $ characters followed by a letter or digit or _ (underscore) are interpreted as Icarus identifiers and substituted. To avoid substitution, the $ character must be escaped as \$ .

      For instance the variable $x which is assigned the value "World" in the example can be used within a string:

      $x =  'world'
      $Print:"hello $x\n"

      The $Print call will produce the output

      hello world

      A problem arises if the variable name inside a text must be followed by letters or digits. Here it is necessary to enclose the variable in parentheses as in the next example.

      $x = 'llo wo'
      $Print:"he($x)rld\n"

      The parentheses are not printed if the open parentheses is immediately followed by the $, so to print then they must be escaped:

      $x = Moon
      $Print:"hello\($x)\n"

      prints:

      hello(Moon)

      If enclosed in parentheses also more complex constructs that access elements in lists by name or index, or function calls with full argument lists can be inserted . The example

      $list = {a: "hello" b: "world"}
      $Print:|"($list.a) ($list[2])": ($StrLen:"($list.a) ($list[2])") characters

      will produce the output

      "hello world", 11 characters

      Note that in a bar strings double quotes need not be represented by escape sequences. The argument of $StrLen is a string which is interpreted itself. Icarus allows an indefinite amount of recursion in interpreted strings!

      Printing with Format Directives

      The $Print function has the same functionality as the C language function "printf" if given a list of arguments as in

      $Print:{"\"%s %s\", %3d\n" 'hello' 'world' 11} 

      In that case the first element in the list must be the format string which contains directives (starting with a %) where to insert the items that follow next in the list. The syntax and type of the directives is exactly as in the C language "printf". Please consult a C manual for further information.

      Object Definition

      The Icarus language can be used for the definition of data. This feature is still in a very preliminary stage of limited use and historically emerged from the old ODD language. The main limitation is that single attributes of the defined objects cannot be accessed within Icarus. They must be exported first to C functions and can then be accessed there as normal C structures. Also objects are now defined in a file separated from the main icarus program.

      Here data are regarded as a series of object definitions. An object comprises of attributes such as an integer, a character string, a list of objects or a reference to another object. The object definition requires knowledge of the object type or class which "knows" the type and name of all attributes of the object. This knowledge, or meta information, can be specified in objects as well which are then of the type "class". In Icarus both objects and object classes can be specified using the same syntax which is equivalent to function calls where the class name is the equivalent of the function name. The example defines an object of the class $shopping_list:

      $shopping_list:[budget:20 buy:{bread butter cheese milk}]

      The attribute .budget is assigned the number 20 and the attribute .buy a list of character strings. An object can reference other objects by two ways. One way is the nested object definition. The next example defines instances of the class $item within the instance of $Shopping_list.

      $shopping_list:[budget:20 
        buy:{
          $item:[name:bread weight:1000]
          $item:[name:butter weight:250]
          $item:[name:cheese weight:200]
          $item:[name:milk weight:1000]
        }
      ]

      The difference to the previous example is that the values assigned to attribute .buy have been 'promoted' from single strings to objects. In the present implementation the defined instances of $item are only referenced by the object of type $shopping_list, they are not part of it.

      The other way of referencing other objects, the direct reference, makes use of name association which is equivalent to that in Icarus lists. object-IDs. An name given to an object can be used from anywhere within the programs to create a reference to it. In a reference the object name must be prefixed with a @. The next example creates the same objects as the previous but uses references instead of nested definition. Note that in the example all references are all created before the objects themselves.

      $shopping_list:[budget:20 buy:{@Item1 @Item2 @Item3 @Item4}]
       
      Item1:$item:[name:bread weight:1000]
      Item2:$item:[name:butter weight:250]
      Item3:$item:[name:cheese weight:200]
      Item4:$item:[name:milk weight:1000]

      Flow Control

      Statements such as if-then-else, control the flow of a program. In Icarus all control statements have a common syntax which is similar to function calls. It begins with a name, e.g., "for" or "while", which as in function calls may be followed by one or more arguments and must have a body, or list of statements at the end. The body can consist of a single statement or a list which then must be enclosed in curly braces. A simple example is the init which selects a list of statements to be executed at the program initialization time:

      init {$m=5}

      The while statement receives an additional argument

      while:($k < 10)
        $Print:|$k

      The if-then-else statement

      The if statement may consists of three different parts: The if part can be followed by one or more elif parts and then by an optional else part.

      Example:
      if:($count<$min)
        $Print:|$count is below $min
      elif:($count>$max)
        $Print:|$count is above $max
      else
        $Print:|$count is in the range of $min to $max

      The while statement

      Begins with the name "while" followed by the condition and a statement body.

      Example:
      while:($k > 1)
        $Print:$k

      The for Statement

      The for statement is very similar to its equivalent in C. It receives a list of three statements: The initialization before entering the loop, the condition examined before each iteration and the update command executed after each iteration. Since these three statements constitute a list they must be enclosed in curly braces.

      Example:
      for:{$i=1 $i<10 $i+=1} {
        $Print:" $i "
      }

      The foreach Statement

      This statement allows looping over the elements in a list. It takes two arguments, the iteration variable and the list of elements.

      Example:
      foreach:[$i in:{1 2 3 4 5}]
        $Print:" $i "

      Sometimes it is not clear whether a variable contains a list or a single element. The foreach statement allows also iteration over a variable of a simple type as, e.g., an integer. The example shows two nested foreach statements where the outer loops over all elements of $list which hold either a list again or a single integer.

      $list={{1 2 3 4} 22 {5 6 7 8} 33 {9 10 11 12}}
      foreach:[$i in:$list]
        foreach:[$j in:$i]
          $Print:" $j "

      Parsing

      This chapter describes the part Icarus was originally designed for - the parsing of files with a defined format. Two types of syntax or pattern description are available:

      • an extended version of the Backus-Naur format for specifying a context free grammar which naturally describes the hierarchical structure of, e.g., programming language constructs;
      • regular expressions for specifying lexemes or patterns; regular expressions are treated as part of the extended Backus-Naur format;

      Productions

      Icarus has a special data type, the production, which is delimited by a '~' reminiscent of delimiting strings by quotation marks. A production derives or 'produces' all sentences with a certain syntax, e.g.,

      ~ '1' '2'? '3' ~

      derives the string "123" or "13". If the input string to be parsed is within the set of derived strings it matches with the production. Parsing of all other input strings will generate a parsing error. The ? after the second symbol ('2') indicates the occurrence of the "2" to be optional. A syntax or grammar, can be formed by grouping one or more productions into an associative list. The following defines the same syntax as the above but uses for each of the literals '1', '2' and '3' a separate production.

      $rules={
        a:     ~ one two? three ~
        one:   ~ '1' ~
        two:   ~ '2' ~
        three: ~ '3' ~
      }
      $Parse:['123' prod:$rules start:a]

      The variable $rules is assigned a list with four productions named "a", "one", "two" and "three". The production named "a" refers to the other productions by using their name. Parsing of "a" begins with the evaluation of "one" which is a nonterminal since it forwards evaluation to production "one" which consists of the literal '1', a terminal, since the string "1" can be directly compared with the input. Both terminals and nonterminals are called symbols.

      The $Parse command receives as arguments the input string to be parsed ('123'), the production list stored in the variable $rules and the name of the production ("a") to start with. This production, also called start symbol, or goal, represents the syntax of the input string. It can be seen as the top of the syntax tree that can be built from the productions stored in $rules. Note that $Parse could also be called with "one" as the start symbol; in that case the parser would try to match a single '1' against the input stream.

      A production can be seen as an expression with operands and operators which are detailed below.

      Operands

      Symbols (see above) are operands within productions and will be matched with the input in the same order as they occur in the expression.

      Literal:
      A string in single quotes, e.g., '1' must directly match the input. The ' character within a literal must be escaped by a \ as in '\'hello\''.
      Regular Expression:
      A pattern to be matched with the input. A regular expression must be enclosed in forward slashes, e.g., /[123]/ which matches one of '1' or '2' or '3'. Regular expression are explained in detail in a separate section below.
      Production Name:
      The name forwards parsing to a production which must exist in the same production list as the referring production. The reference can be also recursive as in 'a: ~ '1' a? ~' which describes a run of ones.
      Sub Expression:
      An expression contained in parentheses.

      Operators

      Only one binary but several unary operators exist. All unary operators must be placed after a symbol, e.g., "'2'?".

      | (binary)
      Separates alternative operands, or symbols, that can match. The alternatives are evaluated from left to right, e.g.,
      "'1' | '2' | '3'" matches either '1', '2', or '3'.
      ? (unary)
      Makes the occurrence of a symbol optional.
      * (unary)
      Asks for zero or more instances of a symbol.
      + (unary)
      Asks for one or more instances of a symbol.

      Regular Expressions

      Regular expressions are a powerful way to describe patterns.The patterns that they can recognize are simpler than the languages that can be specified in BNF form, but they are faster and more compact. They have very similar operators as productions. Regular expressions are terminals in productions and must appear within forward slashes (/). The characters ^$.[]()?+* have a special meaning and must be prefixed with a double backslash (\\) if they should be matched literally. This includes also the forward slash that must be escaped with a single backslash (\).

      .
      matches any character.
      [...]
      indicates a set of characters to match, e.g. [0123456789] matches a single digit or [()] matches an opening or closing parenthesis. Character ranges can be specified by using a hyphen -, e.g. [0-9] matches any digit. A caret ^ in front of the character set (after the opening square bracket) negates the character set, e.g., [^0-9] matches any non digit character.
      (...)
      Groups a series of pattern elements to a single element.
      |
      Separates two alternative patterns.
      *
      The preceding group may be repeated zero or more times.
      +
      The preceding group may be repeated one or more time.
      ?
      The preceding group may or may not occur.

      Examples of Productions

      The easiest way of learning how to write a production is by looking at examples. The production "expr" consists of three terminals, two regular expressions that describe a number with one or more digits and a literal describing the operator "+"

      expr:  ~ /[0-9]+/ '+' /[0-9]+/ ~

      The production matches an expression as, e.g., "1+10". To allow more complex expressions, the literal "+" can be converted to a regular expression matching both "+" and "-". In addition to that, the next production has the operator and second operand enclosed in parentheses and followed by a star to let the expression consist of a single number or an indefinite number of terms.

      expr:  ~ /[0-9]+/ (/(+|-)/ /[0-9]+/)* ~

      The last example allows the two operators "+" and "-" as well as "*" and "/". The convention to give operators "+" and "-" lower priority over "*" and "/" is reflected in the parsing process. The production "expr" starts with the nonterminal "term" which matches first a factor optionally followed by one or more operations using the "*" or "/" operators. After finding a "+" or "-" or the end of the input control is returned to production "expr" which then tries matching a "+" or "-" operator and another term. This means that the parser tries first to parse operations with "*" or "/" operators, a fact, that will be used later to write a simple calculator for arithmetic expressions.

      expr:   ~ term (/(+|-)/ term)* ~
      term:   ~ factor (/\\*|\/) factor)*
      factor: ~ /(-|+)?[0-9]+/ | '(' expr ')'

      Note that the syntax is recursive since "factor" can be either a number or an "expr" which must occur within parentheses. The recursion allows expressions to be arbitrarily nested, as e.g. "(4+13/((5+7)*12))*10".

      Using Productions

      Productions are evaluated by a recursive descent or predictive parser. This means that the parser can deal with uncertainty expressed in rules like, "a symbol may or may not be there", or, "either of two symbols can be found". The limitation here is that when trying an "uncertain" symbol, the first terminal in it must make a decision whether the symbol matches or not. This is of course not a problem if the "uncertain" symbol has only one terminal but consider the example

      expr:   ~ plusop | multop ~
      plusop: ~ num "+" num ~
      multop: ~ num "*" num ~
      num:    ~ /[0-9]+/ ~

      The production "expr" is invalid since "plusop" and "multop" start with the same symbol which is the terminal in "num". Given the input expression "4*10", the parser will first try production "plusop" which initially matches the input with "num". Once it finds disagreement between the "+" that must follow "num" and the "*" in the input it is already too late for backtracking to "expr" in order to try "multop", and the parser must signal a parsing error. This lack of "look ahead" can be a problem. It can be solved by designing productions that branch to alternatives as late as possible. Another possibility is to use regular expressions which do not have that problem. In particular, it can be useful to have a look ahead using terminal as probes using commands $Not or $Probe.

      In general, it is both easy and difficult to write productions. Easy because only a limited number of operators and operands exist, and difficult since a syntax can be written in many ways with varying degrees of robustness and efficiency. In addition, it is important to avoid a number of pitfalls which are detailed below. 

      Avoid left recursion

      As mentioned above productions can be recursive. If the first symbol in the expression is the nonterminal defined by he production itself, it is said to be left recursive. Consider the example

      a: ~ a b c ~

      During parsing a will be replaced by the expression "a b c". Since the first symbol of the expression is again a, a will be replaced by a ....which will be replaced by a which will... never end!

      Only the last alternative in the list may start with a symbol that is optional (postfixed with * or ?).

      In a list of alternatives the first (!) symbol must decide whether or not a subexpression is applied. Consider the example

      a: ~ x? a | y? b ~

      The first symbol x? of the term 'x? a' will always match since it is optional which means that control is never transferred to the following term 'y? b'.

      Within a list of alternative sub expressions a first symbol must not be a superset of the first symbol of the sub expression that follows.

      A list of alternatives is evaluated from left to right; the next sub expression is only evaluated if the first symbol of the preceding sub expression fails. Using the production

      a: ~ /[a-z]/ | 'abc' ~

      the literal 'abc' will never be found since it is a subset of /[a-z]/. If the order of the alternatives is reversed first the string 'abc' and then the presence of any other string composed of characters between a and z will be tested.

      Actions

      The examples in the previous sections only disseminate the input string, but nothing is returned and no action invoked after and during the parsing process. It is possible to let productions "do" something by adding actions to the symbols of a production. An action is a list of Icarus statements within curly braces that must be associated to a terminal or nonterminal by placing it on its right side, e.g.,

      num: ~ /[0-9]+/ {$Print:"matched a number\n"} ~  

      Normally the list of Icarus statements is executed after the symbol has been successfully matched against the input. This means that in the example above "matched a number" is printed to the screen as soon as the regular expression /[0-9]+/ has been successfully evaluated. If the production starts with an action it is associated with the entire production.

      num: ~ {$Print:"matched a number\n"} /[0-9]+/ ~ 

      will appear to do exactly the same as the previous example but the action is executed after the evaluation of the production "num" instead of the regular expression. Action are only invoked if the associated symbol matches the input. Consider the example

      opnd: ~ (/[a-z]+/ {$Print:"letters\n"} | /[0-9]+/ {$Print:"digits\n})+ ~ 

      Parsing the input "12abc" the production will print

      letters
      digits

      Within the actions it is of course desirable to access information regarding the parsing process such as the input region that matches the current symbol. For that a number of special functions exist, each of which returns a string:

      $Ct

      returns the region of the input that matches the current symbol which can be a terminal or nonterminal.
      $It
      returns the input string or input token from the current parsing position to the end. The size of the returned string can be limited by an additional unnamed argument, eg, "$It:50" returns the first 50 characters of the input token.
      $Itc
      returns the code of the input token (see the chapter "Tokens and Token Tables" for further explanation).
      $1,$2...$9,$0
      Return matching regions from the most recent evaluation of a regular expression. $0 returns the entire match which is equivalent to $Ct. $1 until $9 return a sub-match that must be indicated by parentheses within the regular expression itself where the opening parenthesis is used for counting, eg, the regular expression "/([0-9]+), ([0-9]+)/" describes a pattern like "123, 456", here $1 would return "123" and $2, "456".
      Example:
      expr:  ~ {$Print:"expr: |$Ct|\n"} num op num ~
      num:   ~ /[0-9]+/ {$Print:"num: |$Ct|\n"} ~
      op:    ~ '+' {$Print:"op: |$Ct|\n"} ~

      if applied to the input

      3+7

      will print

      num:  |3|
      op:   |+|
      num:  |7|
      expr: |3+7|

      Using a regular expression the example can be written as

      expr: ~  /([0-9]+)(\\+)([0-9]+)/ 
               {$Print:"num:  |$1|\nop:    |$2|\nnum:   |$3|\nexpr: |$0|\n"} ~

      Execution Times

      Statements within actions, as mentioned before, are normally executed after the symbol comparison. There are, however, situations where one would like to execute statements before the matching, e.g., initializing variables or printing the input stream. This can be achieved by grouping those statements into a pre clause. Syntactically, pre is a flow control statement like while and for, but without additional arguments. The example prints the input stream before and after matching the regular expression /[0-9]+/

      num: ~ /[0-9]+/ {pre{$Print:"before:$It"} $Print:"after:$It"} ~ 

      The pre statement may only occur in symbol actions and not in 'normal' Icarus programs.

      Icarus, like Perl, precompiles the program before execution. It is possible to schedule statements for execution during this initialization phase with the init clause. This is useful for initializing program variables and very much resembles the initialization of static variables in the C language. The following example converts a date such as "1|12|95" into the form "1. January, 1995". It makes use of a list of month names which is created only once before the main program starts. If a pre clause were used instead of the init, the list would be created before every evaluation of the production "date" which is inefficient. The following complete example program uses the function $Parse which receives the input string, the production list and the name of the start symbol.

      $dateConvert={
        dateList: ~ date+ ~
        date:     ~ { init $monthNames={January February March April May June July
                                        August September October November December}
                    } 
                    (/([0-9]+)|([0-9]+)|([0-9]+)/ 
                    { $day=$1 $month=$monthNames[$2] $year="19$3"
                      $Print:"$day. $monthName. year\n"
                    } / */)+
                  ~
      }
      $Parse:['1|12|96 5|7|95 1|1|89' prod:$dateConvert start:dateList]

      The output of the program is

      1. December, 1996
      5. July, 1995
      1. January, 1989 

      Action Symbol

      Actions can be only associated to terminals and nonterminals. This restriction is overcome by introducing a 'dummy' symbol, the action symbol, which is denoted "x" and can be inserted anywhere in the production.

      Example:
      sum: ~ num {$sum=$Ct} 
             ('+' num {$sum+=$Ct})+ 
             x{$Print:"The sum is: $sum"} ~

      Input/Output

      A parsing process requires a syntax description and an input stream. In Icarus this process may produce an output which can be used to start a second process with a different syntax which is very useful to parse text incrementally where one syntax breaks the stream in large components which are subsequently fed to a second process for more detailed parsing. This chapter describes the input and output of parsing processes in detail and and describes the two possibilities of how they can call each other (lazy and forced parsing).

      Tokens and Token Tables

      A common task for a parser is to recognize and extract parts of the input stream. A program language compiler, for instance, converts the input stream, a stream of characters into another stream of groups of characters which are called tokens. An expression such as "10 + 2", will yield the three tokens "10", "+" and "2". The tokens "10" and "2" are integers and "+" a plus operator. To facilitate further processing the three tokens can be labeled according to syntactical meaning, e.g., the tokens "10" and "2" could be labeled "integer" and "+" could be labeled "operator". Thus a token consists of a token string and a label also called token code.

      In Icarus tokens formed during the parsing process can be stored in token tables. A token table must be given a name and be associated with a production. The command $Out, which must appear within an node action creates a new token table which by default has the name of the production within which it is created. The execution time of $Out is always before matching time. The command $Wrt can be used to write a token into the most recently created token table. If called without further arguments the current match ($Ct) is written without token code attached. In the example production "num" creates a new token with the same name. The production consists of a single terminal which matches one or more numbers each of which is written to the token table "num".

      num: ~ {$Out} /[0-9]+/+ {$Wrt} ~

      If the $Wrt command is used in a production that does not create a token table itself, the one most recently opened will be selected. In the next example production "expr" creates a token table with the same name. The $Wrt commands in productions "num" and "op" write to that table adding the token codes "operand" and "operator" respectively.

      expr:  ~ {$Out} num op num ~
      num:   ~ /[0-9]+/ {$Wrt:operand} ~
      op:    ~ '+' {$Wrt:integer} ~

      After parsing of the expression "10 + 2" the token table "expr" will contain the following three tokens:

      | | | | | | | | |
      |Perform operation
      on selected entries

      |
      | | | | launch:{ head: | | | | } download: |
      | | | | | | | | | selectView:{ head: | with | } tail: |
      |

      } entriesStart: | tail: | | | } # to be placed at the bottom of the query result page $chunkSet={ head: |

      | go to entries in chunk | \ |[ .. current: | |(%d).. other: | |%d .. tail: | ] } # | ############################################################################### # # # the querymanager page # # # $queryManager={ head: | | NEWSRS Query Manager Page | |

      | | queryOptions:{ html3:{ head: |

      | | | | | | | | | | | | | | | | |
      |Use one of the six options
      on one or more selected queries. |
      | |
      | \ | | | | \ | | | | \ | | |
      | \ | | | | \ | | | | \ | | | |select queries with | |
      |

      queryInfo:{ head: |

      | | | | | | | | | | | | title: | | | numAlign: | | | | | } } html2:{ head: | | | |      |selected queries with |      | |
      | | | |      |selected queries |
      | | | |      |selected query |
      | | | |      | |
      queryInfo: { head: |

      Successful Queries

      |
      |
      title: |
      | |%s |(%s) |:= " %s " |Total %d entries found numAlign: | libAlign: | queryStr: | entryN: |
      %6d entries from %s subEntry: |
      | set of \ |Sequence Features } } } chunkSize:{ head: |Entry list in chunks of \ | } selectView:{ head: |using the view \ | # | } tail: |
      Successful Queries
      NameTypeN
      total |
      |From Library | |N | |Query Expression | |Comment |
      | \ |%s | |%s | |%d | libAlign: | queryStr: | |\ |
      library: |%s
      \ entryN: |%d
      \ subEntry: |
      set of subentries
      rowEnd: |
      |

      |Save in history queries of type |query |expression |link |selection |

      | | } ############################################################################### # # the data-field browse and help page # $parStr:[fCellCols set:"bgcolor=\"#AA0000\"> | |SRSWWW at ($parStr:siteName): Data-field information | | | |
      title: | |

      | inEntry: | description:{ headFrom: | | } fields:{ group:{ head: |
      Field Name |

      %s

      |
      Description
      |(%s)
      head: |
      Description tail: |
      |Field Group
      Members
      | | | | lib: | } head: | } browse: | tail: |
      DatabankFields in Group
      %s member: |%s tail: |
      |Data-fields
      in SRS
      | | | | | | | | | | name: |%s
      short: |%s
      type: |%s
      valN: |%d
      refN: |%d
      date: |%s
      status: |%s
      empty: |
      data: | | | | | | | | | tail: |
      DatabankNameShort
      Name
      TypeNo of
      Keys
      No of Entry
      References
      Indexing DateStatus
      %s%s%s%s%s%s%s%s
      Browse Index | | | | | |
      | | |that |match |
      and occur in at least | entries |
      | |
      | | } ############################################################################### # # the index Value list page # $browseList={ head: | | |
      title: |

      Values in the index of the %s field

      | | | | | | | | | | | | | | |
      |

      values:{ head: | | library: | value: | | | tail: |
      ValueNo. Entries
      Values in %s
      | |%s%d
      |

      |
      | | } } ############################################################################### # # an entry with various formats - to be included into other pages # $entry={ inList:{ envelope:{ head: { head: | | |
      | # |
      | | | | | | | | | | launch:{ head: | | | | } selectView:{ head: | | | | } tail: # |
      |
      |
      preformatted: |
      \
              topicList:    |
      table: | table2: |
      text: |\ } tail: { preformatted: | topicList: |\ table: |
      table2: |
      text: |\ } } entry:{ name: |
      | | |%s:%s inListNoId: |
      | |%s:%s rootName: |
      |\ |%s leafName: |
      | | \ |%s head:'' tail:'' } } inTable:{ head: | | title:{ library: | field: | tail: | } entry:{ head: '' tail: '' rootNameManyLibs: | leafName: | value:{ leftAlign: | } emptyValue: | onlyEntryN: | } tail: |
      %s | |%s
      | \ |%s:%s\ | |%s\ | rightAlign: | center: | listing: | preformat: |
        	value:      |%s\
              empty:      | 
              next:       |
      \ tail: |
      |%d
      } } ############################################################################### # # # the view manager page # # $viewManager={ head: | | | | |Welcome to bla | |:SRS: NEWSRS VIEW Manager Page | |

      | | actions: | |
      |
      | |Click here with middle mouse button | |

      | | | | | | | | | | | | | |
      | | | | |a new view
      | | |selected view
      selected view
      |

      | | | | | | | | | | | | | | | | | | viewList:{ head: | | | | | | format: |(%s) leaf:{ lib: | view: | onlyEntryN: | noComment: | } emptyCell: | separator: |
      rowEnd: | tail: | | } tail: |
      List of Views
      View NameFormatRootLeaves
      LibrariesFieldsLibrariesFieldsQueryViewComment
      | %s | |%s shortNames: |
      (short field names) |
      longNames: | root: |%s
      rootField: |%s
      \ tableData: |
      tableDataEnd: |%s field: |%s
      format: |(%s) query: |
      %s%sdisplay No of linked entries  
      |

      | | } ############################################################################### # # the link page # $linkPage={ head: | | |LINK Page | | |
      | | | | linkEntry: |

      Link entry "%s:%s" to other databanks

      | | | | | |

      linkType: | | | | | | | | | | | |
      | Find
      all
      entries
      |
      | | |in the selected databanks which are linked to the current set |
      | | |in the current set which are linked to all |selected databanks |
      | | |in the current set which are not linked to any of |the selected |databanks |
      # | # |Display a table with linking statistics
      |

      | | | |

      | html3:{ dbGroup: |


      |%s | | newRow: | | library: | | tail: | |
      %s |%s
      } html2:{ dbGroup: |
            |%s
          newRow:
            |
      library: | \ |%s%-%(l)s \ tail: '' } tail: | | | } ############################################################################### # # the "buttons" part that most pages have at the top # $buttons={ head: | busy: | completed: | help: { head: | } databank: | selectDatabanks: | queryForm: | queryManager: | oops: | views: | tail: |
      |job
      pending
      job
      completed
      |Help
      | | | | | | | | | | | | | | | | | |
      |
      } ############################################################################### # # messages printed during execution # $messages={ head: | | parseError: | | | | |
      |
      %s
      %s
      error: | | | | |
      |
      %s
      %s
      info: |

      Information:

      |%s, %s

      } ################################################################# # # arglist # $argListOption={ header: |

      option: |
      %s |
      %s |

      } ############################################################################### # # link set result # $linkSet={ head: | | SRS link result page | |

      | tableHead: | | | | | | | | libName: | libEntriesH: | libEntries: | endRow: | newRow: | tail: |
      Link result for the set %s
      Selected Databanks Entries in set
      Linked with Databanks
      Databank entries
      Linked with set
      Entries in set
      NOT |
      linked with Databank
      |   | %s %d %d
      |

      |

      | | } ############################################################################### # # # the refine output page # # $downloadSet={ head: | | | SRS:Download query | | |
      | | # |

      # |Sorry, this page is still under construction,
      none of the # |options work yet.

      inputInfo:{ html3:{ shift: |

      |Additional options for saving sequence features: |

      | | |
      | | | | | | | | |
      shift begin | |shift end | |
      | | | |
      } html2:{ shift: |
      |
                 |shift begin \
                 | \
                 |		       shift end \
                 |
                 | \
                 |
                 |
      |

      | } } unComplete: | \ |reject incomplete features |
      |\ |reject incomplete shifted features |

      |
      seqFormat: |
      |List sequences with | |format. |
      mime:{ head: | } useMime:'' # |
      # | Use MIME type # |(for downloading the result to your local directory!) # |
      # |Local Directory Name
      # |If you do not have client support srsmime, fetch a copy of # |\ # |srsmime.c # |
      selectView:{ head: | } tail: | |
      |Download chunk with entries | 
      |Use view | | Save table as |ASCII table with
      |column separator | |
      |record separator |

      |

      | |
      | | | |
      | | } ############################################################################### # # the list refined page # $listRefined={ head: |Content-type: application/srsresult | | | start: |>>>>>>>%s;%s;%s;%s;%s<<<<<<< } ############################################################################### # # the form to launch an application # $applOpt={ head: | | | SRS: application "%s" options page |
      | | title: |

      %s |%s

      |

      sequence:{ head: | multi: | | | | | | | | | | | | single: |

      query protein sequence
      | |

      } submit: |

       
      | | %s |
      | begin | | |
      | end |
      |

      | | | | |   options:{ head: |

      | group:{ head: | | option:{ head: | | } next: | } tail: |
      Options
      %s prompt: |%s menu:{ head: | } radio:{ head: |\ val: | %s tail: |\ } multi:{ head: |\ val: | %s tail: |\ } real: | int: | bool: | string: | checkList:{ head: |\ val: |\ tail: |\ } tail: |
      } tail: |

      | | } ############################################################################### # # the result page of an application # $applResult={ head: | |SRSWWW:%s Result | |
      | | | title: |

      %s Result Page

      search:{ head: |Wait until page is completed | and continue with one of the options |below. | | | | | |
      | |

      | | | | chunkSize:{ head: |

      | in chunks of | | | with view | |
      | in chunks of | |
      token string token code
      12 integer
      + operator
      2 integer

      Using Tokens as Parser Input

      Icarus extends the concept of a token so that also the input string is regarded as a single token. This has the advantage that parsing processes can be chained, i.e., tokens of a token table produced by one parser can be used as input for another parser. If the input token table contains more than one token the parser must iterate over each. The input for the next example is a list of equations, each contained in a separate line.

      a = 10 + 2
      a = 34 + 23
      b = 23 + 7 + 66
      b = 17 + 15 + 8
      a = 103 + 85 + 1

      The input can be processed in two parsing steps. First the production "line" processes the list of equations and writes every line as a single token into the token table "line". Then production "equation" takes the token table "line" as input and parses each equation. The iteration over all tokens in token table "line" is implicit. The command $In in the action of production "equation" requests the token table "line" for input.

      line:     ~ {$Out} /[^\n]+\n/ ~
      equation: ~ {$In:line} variable '=' expr ~
      expr:     ~ /[0-9]+/ ('+' /[0-9]+/)* ~
      variable: ~ /[a-z]/ ~

      The token code can be used to restrict the input to a subset of all tokens in the input token table. The following example shows how to modify the line and equation productions to select only equations assigning variable "a" for parsing. The production "line" parses now the variable name at the begin of the line and uses the name stored in $Ct as the token code. The command $App attached to the regular expression that follows appends the rest of the line to the variable name already in the token table. The production "equation" restricts its input to all tokens with the code "a" which is specified as argument "c" for the command $In.

      line:     ~ {$Out} /[a-z]/ {$Wrt:$Ct} /[^\n]+\n/ {$App} ~
      equation: ~ {$In:[line c:a]} variable '=' expr ~

      In general, production "equation" is a consumer, since it processes the output of a producer, the production "line". Both "equation" and "line" represent different parsing processes which can be coordinated in two ways: production "equation" invokes production "line" in order to obtain its input or production "line" invokes "equation to further process the output it created. Both models have been implemented in Icarus and are called "lazy parsing" and "forced parsing" and can be generally defined:

      • the consumer starts the producer and waits until he receives the input token table (lazy parsing).
      • Upon completion of the output token table, the producer starts the consumer (forced parsing).

      Using these to invocation models the overall parsing process can be separated into layers which call each other. This makes the overall parsing task much more manageable and has the advantage that using the layers parsers for different purposes can be written which can share components.

      Lazy Parsing

      If the parser is called with the command $Parse as described above, a start symbol, or goal, must be specified and the parser will immediately start reading the input. In the lazy parsing mode the process is started by asking for an output token table that is created by one of the productions in the syntax. We call this process "lazy", since nothing happens unless somebody asks explicitly for the output, also, as will be shown later, since the parser minimizes its effort to produce the requested token table.

      After the request of a token table the Icarus execution system must find and call the producer that can creates the output token table with the specified name. Any production that declares an output token table with command $Out is a producer and its output can be requested. The following example demonstrates that a producer can have more than one consumer. Each of the four productions "a", "b", "c" and "d" produces an output token table with the respective name. Production "b" and "c" both take their input from production "a" and production "d" from "c".

      a: ~ {$Out} ... ~
      b: ~ {$In:a $Out} ... ~
      c: ~ {$In:a $Out} ... ~
      d: ~ {$In:c $Out} ... ~ 

      A request for output token table "d" will create the following chain of events: production "d" is identified as the producer of token table "d", but needs input token table "c", so production "c" must be called first. "c" in turn needs input "a" and starts production "a". "a" can directly start processing a primary input source (file or buffer) and upon completion hands over token table "a" to production "c" which upon completion hands over its output token table to "d" which will finally return token table "d" to the caller. Note that the event chain the order of invocation (d => c => a) is inverse to the order of execution (a => c => d).

      All four productions in the example declare an output token table and they can be all requested. A call for each will result in an event chain like the one described for token table "d" where several token tables may have to be created. Once a token table is created it stays alive and can be used later. If the request for token table "d" is followed by one for "c" the following will happen: production "c" is identified as the producer of token table "c" and invoked. Since the input for "c", token table "a" already exists from a previous request it can be directly handed to production "c" which can immediately start execution.

      Lazy parsing requires a context that manages token tables and handles requests for token tables. In Icarus such a context is called "job". With the command $JobNew a new job can be created and associated with the syntax and the parsing input which can be a file or a buffer. $JobTokens returns a token table with a certain name and optionally prints its contents. $JobNext resets the job context so that parsing can continue to the next item in the input. $JobHasInput can be called after $JobNext to verify that the input input is still available for the next job.$JobEnd deletes the job again.

      The example with the equations can be rewritten by using the lazy parsing mode.

      $rules={
        line:     ~ {$Out} /[^\n]+\n/ {$Wrt} ~
        equation: ~ {$In:line $Out:result $Wrt:[s:$sum]} 
                    variable '=' expr ~
        expr:     ~ /[0-9]+/ {$sum=$Ct} ('+' /[0-9]+/ {$sum+=$Ct})* ~
        variable: ~ /[a-z]/ ~
      }
      $job=$JobNew:[$rules skip:' ' s:
        |a = 10 + 2
        |a = 34 + 23
        |b = 23 + 7 + 66
        |b = 17 + 15 + 8
        |a = 103 + 85 + 1
      ]
      while:$JobHasInput:$job {
        $JobTokens:[$job name:line print:y]
        $JobTokens:[$job name:result print:y]
        $JobNext:$job
      }
      $JobEnd:$job

      The syntax is modified so that production "equation" declares the output token table "result" into which it writes the contents of the variable $sum. $sum is computed by production "expr" by adding all numbers of the right hand side of the equation. The call of $JobNew creates a new job variable, associates it with the syntax stored in $rules, with the input specified directly in the command (attribute .s), and sets the space character to be skipped as white space. Note that the input string contains several equations, whereas production "line" which 'feeds' production" equation reads only one equation at a time. When $JobTokens is called to print the contents of the table "result", one line in the equation list will be processed and a single token with the computed sum printed. To process the entire list it is necessary to iterate using the function $JobNext. This function resets all token tables and marks them 'non existent' so that a request to token table "line" will result in the parsing of the next equation. $JobTokens which 'does' the actual parsing returns value 0 at the end of input which will exit the while loop.

      Forced Parsing

      Lazy parsing is a model in which the consumer asks the producer for input and thereby activates it. Forced parsing is simply the reverse in which the producer upon completion finds a consumer who is willing to further process the output token table. A forced parsing link between productions must be associated with a certain "task". A task has a name and a state which can be active or inactive. The state determines if a production associated with the task is invoked or not. Forced parsing is useful for modifying the contents of a token table.

      In the example with the equation we might want to multiply all numbers in the equation with a constant value before its evaluation. This can be achieved by adding the production "mult" which parses and modifies the contents of the token table "line".

      mult: ~ {$In:[line task:mult100]} 
              (/[0-9]+/ {$Rep:($Ct*100)} | /[^0-9]+/)+ ~

      It is again the consumer, in this case the production "mult" which must request the link by using function $In. The only difference to defining a lazy parsing link is that the argument .task must be assigned a name, in this case "mult100". The production itself replaces any number in the input with the result of that number multiplied by 100. The function $Rep replaces the match of the symbol (current token) in the input stream with what is specified as argument. In order to execute task "mult100" it must be activated with the function $JobTask which can precede the while loop in the example.

      $JobTask:[mult100 set:on]
      while:$JobTokens:[$job name:line print:y]{
        $JobTokens:[$job name:result print:y]
        $JobNext:$job
      }

      The request of token table will trigger production "line" to read the line which will be handed over to "mult" for modification and finally given to "expression" which computes the sum of all integers on the right hand side of the equation.

      It is possible that several consumer productions request forced parse links to the same producer production. If more than one task is activated the consumer productions will be invoked in the same order as they requested the link. Both lazy and forced parsing can be used to create a multi-functional and multi-layered parser that performs different actions depending on which tasks are active and which output token table is requested.

      Skipping Whitespace

      An important part of parsing is the treatment of filling characters like a space, a tab or a new line. These characters, also called white space, are used for text formatting, as for example indentation, but have usually no syntactic meaning. In Icarus the construct

      foreach:[$a in:{1 2 3}] {
        $Print:$a * 100
      }

      can be also written as

      foreach:[$a in:{1 2 3}]{$Print:$a*100}

      The few remaining spaces are needed to delimit the variable name "$a" or the numbers 1 and 2. In general white space characters can be ignored which greatly simplifies the parsing process and the syntax specification. A set of white space characters can be specified when calling the parser with function $Parse

      $Parse:[$input prod:$rules skip:"\n\t "]

      which parses the string stored in the variable $input with the syntax rules stored in $rules and skipping the line feed, the tab and the space characters. Sometimes, however, whitespace characters do play a syntactic role and should not be skipped as is typically the case when parsing tables stored in ASCII format where records are often separated by line feeds and cells by tab characters. The following example is a parser for a list of literature citations which are separated by empty lines. Parsing is made complicated by the fact that the citations can contain new line characters themselves. The problem can be solved by dividing the task into two steps:

      1. Extracting the citations delimited by the empty lines
      2. Parsing the isolated citations

      At step (1) line feed characters must not be skipped whereas at step (2) they should be skipped.

      $rules={
        item:     ~ {$Out pre $Skip:0} ln {$Wrt} empty {$Not} ln {$App} ~
        ln:       ~ /[^\n]+\n/ ~
        empty:    ~ '\n' ~
        citation: ~ {$In:item $Out pre $Skip:1} authors journal vol pp year ~
      }
      $Parse:[file:"reflist.doc" prod:$rules skip:" \t\n " start:citation]

      The decision of whether or not to skip white space can be left to the productions themselves. Productions "item" starts with

      item:     ~ {pre $Skip:0} 

      which turns skipping off before the parsing of the "item" starts and

      citation: ~ {$In:item pre $Skip:1}

      turns it on again before parsing each citation. Skipping is turned on by default.

      Creating New Icarus Commands

      Currently all Icarus commands are implemented as C functions. A special interface makes it convenient to add new commands and to let Icarus exchange information with the C functions. A new Icarus command is created in three steps:

      1. Declaration of the command, its arguments and the return value in an Icarus program using commands $Com and $Var.
      2. Creation of the C language implementation
      3. Association of the C function with the Icarus command name using the C function IcaSetFunction.

      The following example creates the command $Toupper that converts all lowercase characters in a string to uppercase. The command can be defined using $Com which must receive the name of the new Icarus command, the name of the C function that implements if, the list of arguments and a description of the return value.

      $Com:[Toupper f:MyToupper
        args:$Var:[s t:string unnamed:y]
        returnType:string
      ]

      $Toupper has the single argument of the type "string" named "s" that may optionally be given without name (the unnamed argument). The value returned is also of type "string". After being defined the command can be used, e.g. in a $Print statement

      $Print:$Toupper:"hello world\n"

      The command definition can be put into the script which also uses the new command, however, care must be taken that the definition is executed before the command itself. If the command is likely to be used by more than one script it can be 'promoted' to a built in command by placing the definition into the Icarus file "builtin.i" that comes with the Icarus distribution. After the insertion the file must be compiled with the command

      % builtin

      which must be followed by rebuilding the Icarus interpreter, but before doing that the new command should be implement in C.

      All 'local' command implementations must be put into the file "local.c". This file already contains at least one example of a command implementation. The implementation function needs support from Icarus for receiving arguments and returning a value. IcaGetArgs retrieves the arguments with which the Icarus was called by their names which are separated by bars in the first argument which is followed by the addresses where the values should be stored. One specialty of Icarus is that it can be converted to a C language program. In that case the functions that implement Icarus commands are called directly with their arguments. To provide for that the first argument of MyToupper must be of type Int4 which will have the value 1 if called from the normal interpreter or 0 if called from a compiled C program. The arguments for both calling modes are declared then in the argument list.

      STRv MyToupper (Int4 runTime, STRv s)
      {
        if (runTime)
        IcaGetArgs ("s", &s);
      
        StrToupper (&s);
        if (runTime)
          IcaReturn ("string", s);
        else
          return (s)
      }

      The function can return values back to the Icarus interpreter using IcaReturn or if called from a compiled interpreter by directly returning the value. The first argument of IcaReturn is the type name which is used to allow type checking which becomes more useful when pointers to C structures are returned.

      At the bottom of local.c you will find the function LocalInitFunctions. In its body insert the statement

      IcaSetFunction ("MyToupper", (Func)MyToupper);

      The type casting of "MyUpper" casts it to a standard function prototype.

      To create a new Icarus interpreter run the command

      srsmake icarus

      which will compile the file local.c and link it to the interpreter. In case the new command was declared in "builtin.i" this will also recompile the interpreter itself.

      Glossary

      Attribute

      Property, data member, or method of an object. Members and methods can be interchangeable to some extent: e.g. the sequence length instead of being stored in the object can also be calculated each time it is requested. An attribute has a value, such as "5" or "Jack" and a type, such as "integer" or "string".

      Class

      A class is a blueprint or prototype that defines the attributes and methods common to all objects of a certain kind. A class can also be said to define a data type.

      Expression

      A meaningful combination of operands and operators, e.g., "2 + 3 * 6".

      Grammatic Rule

      See production.

      Instance

      One of possibly many actual objects that exist for a given class

      Lexeme

      A lexeme is a sequence of characters in the source program that is matched by the pattern for a token.

      Link

      A link is an pointer to any structured data.

      Match

      A match is an agreement between a symbol and the input stream.

      Nonterminal

      A nonterminal is a syntax element defined by a production.

      Object

      a physical and logical unit containing attributes (data members) and behaviour (methods) each object of the same class or type has the same set of attributes and behaviour.

      OR ?

      Objects are software bundles of data and related procedures. Software objects are often used to model real-world objects you find in everyday life.

      Parsing

      Parsing or syntax analysis, as it sometimes known, is a process in which the string of tokens is examined to determine whether the string obeys certain structural conventions explicit in the syntactic definition of the language.

      Pattern

      A pattern is a production describing the set of lexemes that can represent a particular token in source programs.

      Production

      same as (grammatic) rule, production has a name and a list of symbols to be matched against the input stream

      Recursion

      A recursive function or production includes, as one of its steps, the invocation of itself.

      Regular Expression

      Regular expressions are an important notation for specifying patterns. Each pattern matches a set of strings.

      Rule

      Same as Production.

      Symbol

      terminal or nonterminal

      Terminal

      A terminal defines a lexical element of a syntax (literal or regular expression). During the parsing process it is directly compared with the input.

      Token

      A token has a code and a string. The string is often the part of the parsing input that matches against a terminal or nonterminal.

      Token Table

      A token table contains one or more tokens and a name. It can be both input and output of a parsing process.

      arexpression">regular expression). During the parsing process it is directly compared with the input.

      Token

      A token has a code and a string. The string is often the part of the parsing input that matches against a terminal or nonterminal.

      Token Table

      A token table contains one or more tokens and a name. It can be both input and output of a parsinsrs/www/doc/install.html

      Installation of SRS

      The following is for the release SRS4.05 and later. If you have any suggestions or problems with the installation please contact me.
      e-mail: etzold@embl-heidelberg.de

      Instructions

      Before you compile any of the programs edit the file "srs4_0/odd/srsdb.sdl". You must customize the object 'environment' with the name "unix" ("vms" on VMS). Add or modify a 'libenv' definition for each databank that you would like to index with SRS. Remove or outcomment all 'libenv' definitions of databanks you don't have. Each databank must be associated with the name of the directory with the flatfiles.
      Example:
         #libenv /lib=@EMBLNEW_DB    /dir="/data/emnew/"
      

      Some sequence databanks have a special format when used under GCG (EMBL, GenBank, SwissProt). For each of these edit the respective files ("embl.sdl", "genbank.sdl", "swissprot.sdl").

      1. You must change the file name(s) defined in 'file' objects; eg, the EMBL file "fun" is usually called "em_fun" under GCG.
      2. In the 'libformat' definition for these databanks change the 'file_type' attribute so that it points to 'GCGREF_FILE' and 'GCGSEQ_FILE'. It is all there - all you have to do is move the begin-of-comment character ('!'). Now 'go' to the root directory of SRS ("srs4_0") and invoke "srsinstall":
        > srsinstall all
        This script asks you for the 'make' and 'cc' commands, compiles all the programs and, using the ODD compiler, creates a new binary file with all data defined by the files in the 'odd' directory.

        To build the indices 'source' the file "etc/prep_srs" and issue the command

        > srscheck
        If it complains then, if a path or file name is at fault, edit the appropriate file in the directory "odd" (eg, "srsdb.sdl") and run "srssection" to recompile the ODD files.

        If anything went well, build the indices with

        > srsbuild
        "srsbuild" invokes the script that was generated by "srscheck". You can create a crontab file with these two commands to keep the indices up to date automatically.

        The only program you can use for searching is the command line interface "getz". You can invoke it in two ways: Either prepare the SRS environment with

        > source srs4_0b/prep_srs
        or copy the file "$SRSEXE/getz" ("SRSEXE" is by running "prep_srs") to a directory that is included in your path (eg, "/usr/bin"). Try the following commands:
        > getz -help 
        prints all command options (the same is true for "srsbuild", "srscheck")
        > getz -libs 
        prints status of all indexed libraries
        > getz -info swissprot 
        prints more information on a single databank
        > getz '[swissprot-def:elastase]' -f 'id def'
        searches all "elastases" in swissprot and prints the "ID" and "Definition" fields of all found entries

        Additional Steps to Install the SRSWWW Server

        • Run the "srsinstall" again with option "www"
          > srsinstall www
        • The executables and the document files are, at least to the knowledge of the server, situated in two different directories 'srs' and 'srsdoc' respectively. Add the script alias 'srs' in the file 'srm.conf':
          ScriptAlias /srs/ /usr/local/srs/www/
          and the alias 'srsdoc' in the same file:
          Alias /srsdoc/ /usr/local/srs/www/
          or add the symbolic link 'srsdoc' into the httpd's document root.

          If for some reason the names 'srs' and 'srsdoc' are not acceptable you can change them (eg, if you want to run two different SRSWWW servers in parallel).
          To change the directory name with the executable, 'srs', replace the string '/srs/' in 'odd/hyperlink.sdl' and if you you don't make your own network images (see below) 'www/srswww.map'. Edit the file 'www/wgetz.script' and change the assignment to 'cgidir'.
          To change the directory name 'srsdoc' edit the files www/wgetz.script' and 'www/wgetz_text.script' and change the assignments to 'docdir'.

        • For the clickable map the location of the program 'imagemap' must be defined in the file 'www/wgetz.script' (assignment to the variable 'imagemap'). This file contains also variables with the path of the file with the icon link to your homepage ('homePageIcon') and your homepage's URL ('homePageURL') that will both be used in the top page of SRSWWW.

        • You can now access the with the URL "http://serverAddress/srs/srsc"

        • Each user of the server will get his own directory in "srs4_0b/www/tmp". The directory and the file "user.par" don't take much space but will have to be deleted occasionally. A "crontab" job can handle that.

        • SRSWWW inserts many hypertext links into the entries before display. These often request SRSWWW to retrieve an entry from a databank installed locally. You must change the configuration of the hypertext links if one or more of the databanks addressed are missing.
          Edit the file "hyperlink.sdl". There you find definitions of 'linkcall' objects. The first link to medline already suggests a the alternative of a link directly to medline. In other cases you may address SRSWWW servers installed on other nodes; eg, replace "/srs/srsc" by "www.embl-heidelberg.de/srs/srsc". After the changes you must run the command "srssection" to recompile the ODD files!

        Optional

        • SRSWWW builds almost every HTML page during run-time. You can, to some extent, change their layout and content.
          Edit the file "srs4_0b/www/wgetz.script". You find here the templates for all pages. The file contains labels that start with "@@" and directives for the insertion of numbers ("%d") and strings ("%s"). You can change anything except the order and content of labels and directives.

        • You can create your own network image! This is a new feature and the following procedure has been tested only at the EMBL:

          • Set the default to the directory 'www' and run the program 'srsnet.tcl'. It is a tcl script that requires 'wish' with a tk version 3.x or 4.0. Use command 'load' to load all databank icons onto the canvas. At the first time the file 'srsnet.dat'with coordinates is missing and all the databanks will be put into a vertical row. Now move all databank icons around until you are satisfied (use left mouse button) and save the databank's coordinates with the 'save' option.

            If some time later you add new databanks they will appear at the left top corner of your network picture - simply drag them to a more appropriate location.

          • Make the program 'srspict' with
            srsmake srspict
            

          • Run the command
            srspict -n
            
            to create the network picture. This will read the coordinates you saved within 'srspict.tcl' and produce a GIF file and the map file for the httpd.

          • Run the command
            srspict -t
            
            to produce both the GIF file with the network as tabular diagram and the map file (This does not require the coordinates).

          • Tell SRSWWW to use your own GIF files by editing the file 'www/wgetz.script'. Just flip around the comment character ('#') so that 'NEWNETWORK' is defined:
            @@# OLDNETWORK = 'NETWORK'
            @@ NEWNETWORK = 'NETWORK'
            

        srspict.tcl' ansrs/www/doc/internal.html Identification Convention

        Internal Documentation

        The following is intendend for SRS developers only.

        Identification Convention

        This defines naming conventions to be used in all C-language modules

        1. General

        All identifiers should be in NameName format. If identifier name has more that one tag, every tag (except the first) starts from a capital letter.

        Example:
        tokenListName

        2. Public

        2.1 Function names:

        Function names should start from (short) capitalized module tag followed by a function name in NameName format.

        Example:
        IcaFunctionCall 
        

        2.2 Variable Names:

        Variable names (external and static) should start from a module tag and a name in NameName format.

        Example:
        icaGlobalScope
        

        2.3 Names of Macro Functions:

        Macro names should start from the underscore character, a capitalized module tag and a name in NameName format.

        Example:
        #define _IcaPrintError(x) printf("%d\n", (x))
        

        2.4 Names Macro and Enumeration:

        Macro names should start from all capitalized module tag plus "x" and a name in NameName format.

        Example:
        #define ICAxMaxNameSize 32
        enum repeat {BNXxOne, BNXxZeroOrMore, BNXxZeroOrOne, BNXxOneOrMore};
        

        2.5 Type Names:

        Type names should start from all capitalized module tag plus "o" and a name in NameName format. For pointer to the structure instead "o" should be "p", for counted pointer it changes to "v".

        Example:
        typedef struct ICAoProdName { ... }  ICAoProdName,
                                            *ICApProdName,
                                            *ICAvProdName;
        

        3. Exceptions

        3.1 def.h and def.c:

        There are several constants, variables and functions that have common meaning like maximum or minimum macros. All this stuff should be placed in def.h and def.c files. Those file have "personal sections" where every person of SRS team should put his own variables. All variables in those files do not have module tag and start from a capital letter.

        Example:
        #define True 0
        typedef Int4 int;
        

        4. Function Head Description

        Function head has a format represented bellow:

        /****** RegWildToRegexp *************************************************
        **
        **      converts a string containing wildcards into a regular
        **      expression; the world can contain the wildcards '*' (any number
        **      of chars) and '?' (any single character); the function returns
        **      the position of the first wildcard within the word (first
        **      position is 1!); "." is converted to "\."
        **      expression will begin with '^' and end with '$';
        **
        **      INPUT:   o string containing wildcards [R]
        **               o pointer to output regular expression [R]
        **               o flag if wildcards (see above) are to be recognized as
        **                 such and be replaced within a regular expression [R]
        **
        **      RETURNS:  0 if word contains no wildcards
        **                position of the first wildcard in string (1=string begin)
        */      
        

        The first line has the format "/****** FunctionName ********" than a description of the function. The "INPUT" and "RETURNS" are essential part of the head. If argument description too long to fit in one line all the argument descriptions should have a prefix "o" as in the example above. The last line has a format "*/"


        Documentation Convention

        1. Names

        Icarus Functions, Icarus Variables $name
        SRS classes $name
        attributes of SRS classes .name
        names 'string'
        characters courier
        value "string"
        C Functions name
        C structures name
        C variable names name
        examples courier

        short one in quotes

        > attributes of SRS classes .name names 'string' characters courier value t

        Programming in SRS

        Introduction

        It is very easy to write programs that use all of SRS's power to retrieve, link and access entries from all indexed databanks. Just link your program to the SRS library (written in C, documentation will be available). The file "srs4_0b/src/try.c" is an example of such a program:

        #include <stdio.h>
        #include "srs.h"
        
        int main ()
        {
          SrsEnv ();
          LibOpen ();
        
          if (Query ("[swissprot-def:elastase]", "Q1"))
            printf ("query Q1 found %d entries\n", SetSize ("Q1"));
        }
        

        The program must (in that order)

        • include the file "srs.h" (in the directory "$SRSROOT/src");
        • call the function SrsEnv (without arguments) that defines all SRS directory names;
        • call the function LibOpen with the name of the binary file containing all run time data, eg, all information about the indexed libraries.

        The program can be compiled (and run) anywhere:

        > cc -I$SRSSOU -I$SRSEXE try.c $SRSEXE/libsrs.a $SRSEXE/local.o -o try
        

        The variable "SRSEXE" is defined by executing (sourcing) the C-shell script "prep_srs" (or for Bourne-shell "prep_srs.sh") (see above).

        Note that modules without a "main" section must define the macro "DECLARE_ONLY" before including "srs.h".

        Example:
        #define DECLARE_ONLY
        #include "srs.h"
        


        Programming Examples

        All program examples given are complete. Each example can be compiled as shown for the program "try.c" in the introduction.

        Performing queries

        The function Query lets you submit any SRS query language expression. Each query must be associated with a name. If successful, that name lets you access the resulting set or can be used within further query expressions. The following retrieves all "receptor" sequences from EMBL and, using SetSize, prints the size of the resultant set. The next query searches "acetylchol*" and performs an AND operation with "Q1" from the previous query. The last two queries link "Q2" to SwissProt by both link operators.

        INCLUDE EXAMPLE:query.c

        Printing Entries

        Three steps are required to access a single entry from a successful query:

        • SetGet uses the query name to retrieve the set object (SETo).
        • SetGetID retrieves the nth ID-object (IDoENTRY) from the set object.
        • EntryOpen uses the ID-object to create an entry object (ENTRYo). Use EntryClose to delete this object after use.

        Once the entry is opened the annotation and, if exists, the sequence can be obtained. Here only the "ID" and the "Definition" data-fields are extracted from the entry and printed by EntryPrintFields. The two fields are selected using the function ParDefStr to successively assign the global parameter "fieldList" the values "Definition" and "ID". This method to define global parameters accessible by all functions in the library is commonly used. "fieldList" can be reset by assigning the value "reset". You will see more examples of that in other programs where even functions are assigned as parameter values.

        INCLUDE EXAMPLE:prfields.c

        Accessing Information About the Databanks

        This program accesses information about the databanks seen from SRS. The run-time-library provides iterators to access library group, library, and respective data-field information ( LibNextLibGroup, LibNextLib, LibNextField). For iterating over all libraries (databanks) one must first iterate over the group and then descend to the libraries. The function LibIsField can be used to obtain more information about the data-field.

        INCLUDE EXAMPLE:libinfo.c

        Accessing Information About a Single Databank

        The example accesses for the databank "Swissprot" information that is stored in its indices. The function LibIndexOpen can be used to open all index files pertaining to a certain data-field, in this case the ID-field. The indices of the ID-field contain information about the databank such as release name or number of entries.

        INCLUDE EXAMPLE:libinfo2.c

        Redefining Message Processing

        SRS prints quite a few error messages, warnings and informational messages to "stderr". The function MsgSetFnct allows you to redefine the function that prints these messages. When called it receives a pointer to the message object MSGo as argument and must always return 1.

        The message object MSGo contains several fields with the message type, the message name, etc. The message name (eg, "e__objectunknown") is defined as macro, so it can be directly used for comparisons (see switch statement below).

        The example performs three queries, where only the last is successful since the first two specify incorrect databank and data-field names. The assignment to the global parameter "libList" is also incorrect since the data-field name is misspelt.

        INCLUDE EXAMPLE:msguse.c

        Constructing an SRS query expression

        If you write a user interface to SRS you might create a form displaying all the searchable indices plus some more search options. The user input would have to be collected and combined to an SRS query string which can be submitted to the function Query. The functions in the "queryassist" module help you to construct that query expression. It is possible to construct a query step by step and at the end ask for the complete expression. The example first constructs a query with a string search and a range search in two databanks. The resulting string is then used to generated a link expression.

        INCLUDE EXAMPLE:qasuse.c

        Printing Entries with Views

        This prints a set of SWISS-PROT entries with a view defined in the program.

        INCLUDE EXAMPLE:views.c

        construct that query exsrs/www/doc/query.html SRS functions list

        The SRS Query Language

        In SRS any retrieval command, logical operations with sets that were obtained by previous queries, links between sets of different databanks, or a combination of all can be expressed by the SRS query language. This chapter describes the language and gives examples of its use.


        General Syntax

        A query is an expression with operands and operators. In this chapter queries are sometimes shown as equations in the form

        queryName = expression

        The query name will be associated with the resultant set of entries. Expressions can specify index searches, logical operations between sets and link operations or a combination of all.

        List of Operators

        |
        Logical OR.
        &
        Logical AND.
        !
        Logical AND NOT, or in colloquial English, BUT NOT.
        >
        Link to the right operand.
        <
        Link to the left operand.

        The link operators have precedence over logical operators.

        List of Operands

        Name of a Databank
        In SRS only one name for each databank is used (eg, "EMBL"). Currently only the link operators accept the databank name as a valid operand.
        Set Name
        Each query must be given a name (eg, "Q1") which can be later used to operate on the set that results from that query.
        Index Search
        A command to search in one or more indices of one or more libraries.
        Expression
        An expression is treated as an operand if it occurs within parentheses (eg, "(Q1&Q2)>EMBL"). Parentheses can be nested to any degree.
        parent
        Special operand that allows the conversion of a set of subentries (eg, sequence features) into a set of entries (sequence entries). This is achieved by linking the set with the subentries to "parent" (eg, "Q1 > parent").

        A query can be minimally a single operand excluding databank names and the "parent" keyword.


        Searching in Indices

        This command specifies a search in a single index or a group of indices of one or more databanks. An index search must specify within square brackets the databank or databank group name, the index or index group name, and a search expression. The two names must be separated by a hyphen ('-') and be separated from the search expression by a ':' (string search) or a '#' (range search). Both the field name (eg, "Definition") and its abbreviation ("DEF") can be used as index name. All strings, including the search words, are treated case insensitive.

        Example:
        [pir-def:elastase]
        searches "elastase" in the DEFinition field of the protein databank PIR.

        As indicated above two different types of searches, the string search and the range search exist. A string search expression starts with a colon (':') after the index name whereas the range search starts with a hash ('#'). Range searches can be performed only in indices of the types "num" and "real"

        Searching Strings

        A search expression is a single search word or several words separated by a logical operator. Parentheses may be used for grouping.

        Examples:
        [embl-key:insulin]
        [medline-aut:needleman,*!wunsch,*]
        [embl-def:(acetylchol*&receptor)!muscarinic]
        

        Wildcards are useful for searching a group of words or whenever it is unclear how a word is spelt in the databank. You can use two different types of wildcards:

        *
        Matches one or more characters of any value;
        ?
        Matches a single character of any value,

        Any number of wildcards can be placed anywhere in the search word. If you place one at the beginning you might have a slightly longer response time since then all words of the index have to be searched. But don't worry too much about that - it is still quite fast!

        Regular Expressions

        Since search words with wildcards are translated into regular expressions, it is of course possible to enter regular expressions directly. They must appear within forward slashes ('/'). Some characters ("^$.[]()?+*") have a special meaning. They must be prefixed with a backslash ('\') if to be matched literally.

        ^
        marks the begin of a string, eg, "/^phos/" will find all words beginning with "phos", eg, "phosphate".
        $
        marks the end of a string, eg, "/ase$" will find all words ending with "ase", eg, "kinase".
        .
        means any character.
        [...]
        indicates a set of characters to match, eg "[()]" matches an opening or closing parenthesis. Character ranges can be specified by using a hyphen ('-'), eg "[0-9]" matches a digit. A caret ('^') in front of the character set (after the opening square bracket) negates the character set, eg, "[^0-9]" matches any non-digit character.
        (...)
        Groups a series of pattern elements to a single element.
        *
        The preceding group may be repeated zero or more times.
        +
        The preceding group may be repeated one or more time.
        ?
        The preceding group may or may not occur.
        Examples:
        /^j..$/
        finds all 3 character strings with a j at the begining;
        /^5[0-9][0-9][0-9]$/
        finds all 4 digit numbers with a five at the begining;
        /^nif[a-e]$/
        finds the gene names "nifa", "nifb", "nifc", "nifd", "nife";
        /^mue?ller$/
        finds both "muller" and "mueller".

        Note that searches with regular expressions can be slow since all words in the index have to be searched.

        Searching Numeric Ranges

        In a numeric index (integers, reals) it is possible to search numeric ranges. The number index is only applicable where there is a one to one relationship of entry and value (eg, sequence length, creation date, resolution)

        A range can be specified by a single value or two values separated by a colon (':') where the left value must be smaller than the right value. To exclude a boundary value from the range put a '!' in front. A missing number on the left means the minimum, and on the right the maximum value in the index.

        Examples:
        The following are queries in an index of the sequence length.
        400
        selects all sequences with the length of 400
        400:500
        selects all sequences from 400 to 500 residues
        400:
        selects all sequences longer than 400 residues
        :500
        selects all sequences up to 500 residues
        400:!500
        selects all sequences between 400 and 500 residues excluding 500
        :
        is also valid and retrieves ...all sequences

        Note that ranges can be combined by logical operators.

        Example:
        300:!500 | !600:700
        or
        300:700 ! 500:600
        retrieve the same set of sequences, namely all sequences from 300 to 500, excluding 500, plus all sequences from 600 to 700 where the 600 is excluded.

        Using Logical Operators

        The three logical operators OR ('|'), AND ('&') and BUTNOT ('!') can be used to combine search words in an index search, or sets in a query expressions. The figure illustrates the effect of the three operators in an expression of the form "A operator B"

        Within expressions, parentheses with any degree of nesting are allowed.

        Examples:
        [medline-authors:(wu* & rice*) ! (smith* | jones*)]
        (q2 & q2) ! (q3 & q4)
        

        Logical operations can be only performed between two sets of the same type. It is not possible to combine a set of entries and a set of subentries (see below). In those cases an additional link operation must be specified.


        Using Link Operators

        The powerful link operators are unique in the SRS query language. They to some extent resemble the join in relational databank systems. The two link operators '<' and '>' combine two sets from different databanks.

        The figure shows two databanks "A" and "B" where some entries in "A" have cross references to entries in "B" as indicated by red lines. These cross references are processed to build link indices which provide the basis for the link operation.

        A > B
        gives those entries in "B" that are referenced by entries in "A"
        A < B
        gives those entries in "A" that reference entries in "B"

        References are by nature not bidirectional, that is, there is no guarantee that entries in "B" that are referenced by entries in "A" have references back to "A". The link indices in SRS, however, can be always used bidirectionally. The two link expression can now be seen as:

        A > B
        gives those entries in "B" that are linked to entries in "A"
        A < B
        gives those entries in "A" that are linked to entries in "B"

        In this context it is irrelevant which databank contributed the information for building the link index.

        Example:
        [swissprot-def:kinase] > PDB
        The index search retrieves all kinase sequences from the SwissProt protein sequence databank which are then linked to the PDB databank of solved tertiary protein structures. The result is all the PDB entries with atomic coordinates for all kinases for which the tertiary structure has been determined.

        In SRS all the pairwise links are combined to generate a network of databanks. Within this network a link can be performed from any databank to any other. If two databanks are not directly connected by a link then a series of links is performed. The following rules are applied resolve links:

        • The same pairwise link index is used for both directions.
        • SRS tries to find the shortest possible way for linking entries from two libraries. Ideally this is the direct link as, eg, between EMBL and SwissProt; if no direct link is available (eg, EMBL > PDB) then automatically the optimal or cheapest succession of links is performed (eg, EMBL > SwissProt > PDB).
        • If a set contains entries from different databanks (eg, from EMBL and SwissProt) then the subsets of all libraries found in the set are linked independently.
        Examples:
        enzyme < pdb
        The Enzyme databank contains all known reactions catalyzed by enzymes. The number of entries retrieved by the query is the number of different reactions catalyzed by proteins with known structure.
        [swissprot-id: acha_human] > prosite > swissprot
        The index search retrieves the SwissProt entry "ACHA_HUMAN". This entry is then linked to the Prosite entry(s) that documents the protein family where "ACHA_HUMAN" is a member, in this case the family of neuronal acetylcholine receptors. The next link retrieves all SwissProt entries that belong to that family. In Effect, the entry "ACHA_HUMAN" is amplified to all members of the protein family or families it belongs to. the example shows that it is possible to navigate over the databank network with an explicit succession of links that is evaluated from left to right.
        [swissprot-id:tdt_human] > prodom > pdb
        This example shows how the amplification by homologous entries in the same databank can be used to find related information in another databank to which the single entry itself is not linked. The query retrieves a DNA polymerase from Swissprot, expands it by related proteins as documented in Prodom (databank of protein domains, another possibility would be Prosite or HSSP) and links these entries to PDB. The result is the set of PDB tertiary protein structures that are homologous to the SwissProt entry "TDT_HUMAN".
        q = [sequence-def: kinase] q ! (q < swissprot)
        Most protein or DNA databanks overlap to a great extend which creates a lot of redundancy. The annotation of equivalent entries in different databanks can be quite different which ban be very useful for string searching since the probability of finding a certain enzyme name is much greater if you search all sequence databanks. After the search the links come in handy to remove the overlap. The first query in the example searches "kinase" in all sequence databanks (eg, EMBL, PIR, SwissProt, GenBank). The second query removes the overlap. The goal is to have SwissProt entries plus those in other databanks that do not have equivalents in SwissProt. This is achieved by subtracting all entries from "q" that are linked to SwissProt. SwissProt entries in "q" are not linked to SwissProt and won't be removed!. Just change "SwissProt" to "PIR" if you would rather have PIR entries.

        Entries and Subentries

        Sets originating from the same databank may have different set types. Consider the two queries:

        [swissprot-keywords: transmembrane]
        [swissprot-features: transmem]

        The first query retrieves all SwissProt entries that have transmembrane segments, the second finds all transmembrane features contained in SwissProt entries. The second query will retrieve many more entries since most transmembrane proteins have more than one membrane spanning segment. If you requested the sequences for entries in the second set you would get the transmembrane segments and not the parent entry's sequence. The first query returns a set of entries whereas the second returns a set of subentries. The "features" index has a special type: searches in that index will for all sequence databanks result in sets of subentries. Sets of entries and subentries can not be combined with logical operators! Only the link operators may be used between them, ie, it is always possible to link subentries to their respective parent entries.

        Example:
        [swissprot-org:human] > [swissprot-features:transmem]
        returns all transmembrane segments found in human proteins.
        [swissprot-org:human] < [swissprot-features:transmem]
        returns all human proteins that have transmembrane segments.

        Sometimes it is necessary to do an explicit conversion from subentries to entries. This can be done with a link to "parent".

        Example:
        [swissprot-features:transmem] > parent | [swissprot-key:transmembrane]
        returns all entries that have the "transmembrane" keyword or "transmem" sequence features. This may be necessary to ensure all entries with a certain property are retrieved - the annotation is often not complete!
        [swissprot-features:transmem] > parent > pdb
        finds all PDB entries of proteins that have transmembrane segments (even though the known structure may not yet include the transmembrane region).

        ansmembrane]

        returns all entries that have the "transmembrane" keyword or "transmem" sequence features. This may be necessary to ensure all entries with a certain property are retrieved - the annotation is often not complete!
        [swissprot-features:transmem] > parent > pdb
        finds all PDB entries of proteins that have transmembrane segments (even though the known structure may not yet include the srs/www/doc/srsmaint.html SRS Maintenance

        SRS Server Maintenance 

        This section explains in detail some aspects of SRS server maintenance. The chapters that follow are in a loose order and more will be added as soon as possible.

        Installing a Dedicated WWW 

        It is possible to call SRSWWW with any httpd provided that the correct Aliases are set. This worked fine with SRS4 and early versions of SRS5. With the possibility of adding applications to the retrieval engine, however, life has become more complicated for the following reasons:

        • The server, apart from the user context file "user.par" needs to store the results of application programs and their input. Since on a general server these data are owned by user "nobody" or "www" any cgi script can access these data which creates a security problem.
        • The applications are often not available on the machine that hosts the WWW server or to balance the workload should be run on other machines and thus 'rsh's are needed.
        • Applications may take a lot of cpu time and sometimes do not terminate properly.
        • Some applications require environment variables.

        An immediate improvement towards solving these problems is the installation of a dedicated SRSWWW server which runs under a special account. If you want to set up an SRSWWW server and you do not have root privileges then it also spares you a great deal of frustration for both you and the system manager! In fact, the following procedure was suggested by Rodrigo Lopez who was at that time a system administrator at the EMBL-EBI.

        Steps to create a dedicated SRSWWW server running under its own account

        1. Create an account "srs" or "srswww" that may also own the SRS distribution directory and the indices. 
        2. Log in as user "srswww" and install an httpd or copy the "conf" directory from an existing server.
        3. Edit the file "httpd.conf" in the httpd's "conf" directory. There you need to specify a port number for the server since it will not be run with root privilege. We try to use numbers with 5's (SrS5!), eg, 5000 or 5555. Check the  file "/etc/services" of the machine hosting the server to see if the port number is free.
        4. Edit the file "srm.conf" in the httpd's "conf" directory. You can define the SRS directory "srs/www" as document root so that no directory name is needed in the URL of the SRSWWW server, eg, "http://machine:5000/". Likewise the ScriptAlias "cgi-bin" can be set to "/srs/www/bin".
        5. You need to think of where to run the applications you want to be launched by SRSWWW. Edit the file ".rhosts" in the login directory of user "srswww" and add an entry for the SRSWWW host machine, e.g., 
          croma.ebi.ac.uk srswww
          croma           srswww 
        6. Install SRS. If the SRS distribution directory is not visible from all "application hosts" then you must move the directory "srs/tmp" to some place that can be seen from all. This directory must be owned by user "srswww" (srsinstall www)
         

        Automizing Housekeeping

        Certain 'housekeeping' tasks for maintaining an SRS server can be automized and started as cron jobs. These are
        • keeping indices up to date;
        • deleting the temporary user directories created for each SRSWWW session;
        • killing run away jobs started by the SRSWWW server.
        Each of these task can be done either by a script or a single command. The scripts that are provided with the SRS release
        is what we use at our home site and not very portable. You are welcome to change them to your needs and would be very grateful if you could send them to us once you found a more general solution. 
        There is one last thing that could be done using cron, namely the automatic restart of the SRSWWW httpd after a reboot of the host machine. The job could check every half hour or so if the httpd process exists and restart it if not. Up to this point we do it manually - if you write a script that does that please send it to us and we will include it into our distribution.
         

        Keeping Indices up to Date

        As mentioned in the "Guided Tour" the command srscheck examines all indices of all databanks and writes a shell script with the commands to create indices for all databanks that have changed. In our experience we found it useful to separate the tasks of updating or mirroring the databanks and the indexing. To this end we set up a cron job that calls srscheck every half hour and runs the generated script. This means that once a new databank arrived it will take a maximum of 30 minutes until SRS notices that new indices should be built. The SRS release comes with the Perl script "SRSETC/srscronupdate" that first checks if srscheck or
        srsbuild are already running. You can use it and call it as a cron job
        10,40 * * * * /usr/local/srs/etc/srscronupdate 

        Deletion of Session Directories

        Every SRSWWW session creates a new directory in "SRSWWWTMP". In SRS5 these directories will also contain files like Blast output, indices, multiple alignments, so it is important to clean them up regularly. The policy at our site is to keep directories after their last modification date for a certain number of days. This gives people the chance to keep their session going for many days or even weeks if they regularly 'touch' their session files. The following crontab entry deletes any directory that wasn't modified for more than 2 days.
        0 1 * * * find /home/srswww/tmp -mtime +2 -type d -depth -name '*' -exec rm -rf {} \;

        Killing Runaway Jobs

        It occasionally happens that processes created by the httpd are not terminated and run for ever. This affects the programs wgetz and srsbuild. The shell script "SRSETC/killrunaway" checks for processes running either of the two for longer than 15 minutes and kills them. You will have to change the script which has four variables holding the name of the user running the SRSWWW server, the names of the programs that need to be checked, the maximum time these programs may take and optionally a mail address of where to send a report in case a process is terminated. The script reads the output of the UNIX command ps  on IRIX so you might have to modify it for other platforms. The following crontab entry runs the script every 30 minutes.  
        5,35 * * * * /usr/local/srs/etc/killrunaway
        Make sure that you set it on the machine hosting the WWW server and under the user "srswww".

        Launching Applications from SRSWWW

        The Applications that can be launched from SRSWWW are divided into several categories. The assumption is that a common
        way can be used to treat applications from the same category. The "Search Application" is currently the only generalization. It contains programs such as BLAST, FASTA or the Smith and Waterman search with the Bioccelerator. 
         
        In order to add a new application you need to 
        1. Edit "SRSICA:srsgen.i" and add an object $Application and let one or more $ContentType objects point to it.
        2. Edit "SRSICA:srswww.i" and add two templates, one for to create the HTML form that prompts the user for the program parameters and the other that generates the shell script which launches the application program
        3. If the application program's output should not just be displayed but indexed as an SRS databank then an .i, .is and .it file must be created in the "SRSDB" directory. The databank with the application name needs also to be declared in the "SRSDB/srsdb.i"

        Adding or Modifying Search Applications

         

        Parsing and Processing a Protein and DNA Sequence Field

        Still missing.

        Definition of Subentries

        Still missing.

        Adding Java Applets to Display Entries

        Still missing.

        Defining Internal Links

        Still missing.

        Switching Between Original and GCG Sequence Format

        In order to make a sequence databank acceptable for GCG programs it needs to be reformatted. GCG has also its own conventions about file names. SRS supports sequence databanks both in the distribution and the GCG formats. The SRS distribution describes the databanks normally to be in the distribution format so that the description needs to be modified if a databank should be indexed in GCG format. Normally it is enough to modify the .i file of a databank and change

        • the file name(s)
        • the .fileType attribute of $libformat
        • the .token attribute of the $field object describing the sequence data-field

         In all files this three places have separate lines for both formats which are marked '# orig format' and '# GCG format' where one alternative is always outcommented. To switch between formats search the string 'GCG format' and flip around the comment character ('#') so that, eg, 

            EMBLSeq:$field:[@DF_DNASequence token:gcgseq format:embl] #GCG format 
        #    EMBLSeq:$field:[@DF_DNASequence token:sequence format:embl] #orig format
        becomes
        #    EMBLSeq:$field:[@DF_DNASequence token:gcgseq format:embl] #GCG format 
            EMBLSeq:$field:[@DF_DNASequence token:sequence format:embl] #orig format

         Make sure that you find all three locations! 

            EMBLSeq:$field:[@DF_DNASequence token:gcgseq format:embl] #GCG format 
        #    EMBLSeq:$field:[@DF_DNASequence token:sequence format:embl] #orig format
        becomes
        #    EMBLSeq:$field:[@DF_DNASequence token:gcgseq format:embl] #GCG format 
            EMBLSeq:$field:[@DF_DNASequence token:sequence format:embl] #orig format

         Make sure that you fsrs/www/doc/srsman.html Icarus Documentation NASequence token:gcgseq format:embl] #GCG format      EMBLSeq:$field:[@DF_DNASequence token:sequence format:embl] #orig format

         Makeat you fsrs/www/doc/srswww.html Untitled

        SRSWWW

         

        Introduction

        SRSWWW is a World Wide Web interface to the Sequence Retrieval System (SRS). Compared with other SRS interfaces SRSWWW has more users because of the widespread use of web browsers, its easiness to handle and its user friendly interface. It supports HTML3 and lesser versions of HTML. Since HTTP is stateless, a user ID is created to keep the state for the whole session.

        A SRS session is started by clicking on the 'Start' button in the SRS home page. The page appearing next is the 'Select Libraries Page' also referred to as 'Top Page'.

        Most pages in the SRSWWW have six header buttons which contain links to other SRSWWW pages. One header button is the 'Top Page' which links to the start page of the SRSWWW. The other buttons point to the 'Query Form' page, the 'Query Manager' page, the 'View Manager' page, the 'Databanks' page and the 'Help' page.


        SRSWWW

        The Top Page

        The 'Top Page' is used to select the one or more databank(s) to be searched. Selecting databank(s) can be done by clicking the check boxes. In all cases, the databank names are linked to an information page ('Information about …' page). It provides some information about the indices of the respective databank. The data fields of the databank can be browsed directly (see the 'Browse Index' page).

        If you want to change databases for another search you have to go to the 'Top Page'.

        Continue & Reset Button

        The 'Reset' button can be used to deselect all selections done so far. Each databank can individually be deselected by clicking again their checkboxes. Clicking the 'Continue' button finishes the 'Top page' and brings up the 'Query Form' page.

        Common Fields selection

        Some fields in the databanks are common (e.g., ID field). The check box 'Show only fields that selected databanks have in common' is used to list only the common fields in the 'Query Form' page.

        Grouping the Databanks

        In the 'Top Page' all available databanks are collected in groups defined by SRS.

        User defined Databases

        There is a possibility to include user defined databanks. For example with the search engine FASTA or BLAST special databanks can be created. Before such a databank can be selected it has to be created with a search (for instance with BLAST). An existing sequence can be inserted in the 'Enter query sequence' field by "cut and paiste".


        SRSWWW

        The Query Form Page

        With the 'Query Form' page the databank query can be defined. The selected databank(s) is/are listed at the top of the page. Which fields are listed depends on the 'Show only fields that selected databanks have in common ' check box from the Top Page and the searchable fields of the databank(s).

        Do Query & Reset Button

        The 'Reset' button can be used to deselect all selections done so far. Each selection can be deselected individually by clicking again the check box. Clicking on the 'Do Query' button starts the query and brings up the 'Query Result' page.

        FIELD NAME, QUERY, INCLUDE IN LIST & RETRIEVE SUBETNTRIES columns

        The main query form has four columns. The column 'Field Name' lists all data fields of the selected databank which are linked to an information page. By clicking on a 'Field Name' one moves to the 'Browse Index' page. The 'Query' column is the input field for the query. By using the operators "&" (= AND), "!" (= NOT), "|" (= OR) one can use more than one search expression in every 'Query' input field. The 'Include in List' column is a check box for inclusion of the corresponding field in the query result. The 'Retrieve Subentries' column is a check box for the inclusion of subentries in the query result.

        Additional Menus

        Some fields can have additional menus with "greater than" and "greater than or equal to" and "less than" and "less than or equal to" symbols (e.g., SeqLength) for their range selection. (e.g., seqLength > 100 && seqLength < 500).

        Combine Searches with

        If more than one data field is to be searched the 'Query' input fields can be combined with the boolean operators 'AND', 'OR' and 'NOT'. Optionally, a wildcard is appended to every search string to enhance the possibility to find a match.

        Chunk Size & Use view

        Additional options are 'Entry list in chunks of' to define the number of entries shown per page and 'Use view' to select a predefined view with which the query result is shown (see the 'Create a new view' page for more information on 'Views'). A new view can be defined before doing a query. All the 'Views' which are applicable to the selected databanks are listed in the 'Use view' box and one of them can be selected. Note: only the 'Views' are listed which can be used with the selected databank(s). The default is 'Names Only' (i.e. without a special 'View').


        SRSWWW

        Browse Index Page

        From the 'Query Form' page the 'Browse Index' page is opened by clicking on a 'Field Name' (e.g., the 'ID' field).

        List Values Button

        Submits a search string typed in the open box marked with a wildcard (the wildcard can be used in the string or deleted). The result of any matches (referred to as "values") of the search string in the indicated 'Field Name' is listed in the 'Values in the index of the ... field' page. In this list 'Values' can be selected and with the 'Make Query' button a query can be started immediately with the selected 'Value(s)'.


        SRSWWW

        The Query Result Page

        The 'Query Result' page shows the result of a submitted query. The query string, the number of "hits" and found entries with check boxes and included fields (if selected in the 'Query Form' page or in the view definition) are indicated. The found entries are listed by the searched databank and the entry ID. Clicking on the entry opens the 'Single Entry' page. In addition, entries can be selected with the checkboxes. The 'Reset' button can be used to deselect all selections done so far. With the 'Link', 'Receive' and 'View' buttons further manipulations can be performed with the selected entries.

        Link Button

        With this button the whole/selected result entries can be checked whether they are linked to other databanks (see the 'Link Page' for more information).

        Receive Button

        With the 'Receive' button the selected entries can be downloaded.

        View Button

        With this button the result entries can be viewed with predefined 'View' definitions. The 'View' definitions can be selected out of the 'View' box.

        Chunk Hypertext Links

        The last line are hypertext links for any additional chunk set(s). These links are only present if the number of entries found is bigger than the number of the defined chunk size. The chunk set numbers starts from 1 to "number of hits" divided by "entry list chunk size" (selected in the 'Query Form' page). The user can jump to any additional chunkset by the hypertext link. The current chunk set is shown within braces. The left anglebracket hyperlink moves to the first chunkset whereas the right anglebracket hyperlink moves to the last chunkset.


        SRSWWW

        Single Entry Page

        Every entry found and listed in the 'Query Result' page has a link to the complete entry in the databank. By clicking onto a entry, the 'Single Entry' page comes up and shows the complete entry. The complete entry can be saved or printed (refer to the documentation of your web browser).


        SRSWWW

        Link Page

        From the 'Query Result' page one can go to the 'Link' page by pressing the 'Link' button. The 'Link' page is used to find the links between the found entries (the set) and the selected databanks. The user can choose one of three options to display the different entries. The 'Link' page lists all the databanks like the top page. The user should select the databanks which are different from the databanks selected for the query search and should select one of three options of the 'Find all entries' field. Clicking on the 'Continue' button shows the 'Query Result' page. A link can also be done in the 'Query Manager' page.

        (For more information about links refer to the SRS manual)

        Find all entries:

        in the selected DATABANKS which are linked to the current set

        the result are entries out of the selected Databanks, which are linked with the set.

        in the current SET which are linked to all selected databanks

        the result are entries out of the set, which have links to the selected databanks.

        in the current set which are not linked to any of the selected databanks

        the result are entries out of the set, which contain NO links to the selected databanks.


        SRSWWW

        Query Manager Page

        The 'Query Manager' has two functions: one is to store the queries done so far. The queries are listed in a table. Every query is listed with a check box, the query name in the form 'Qn' (e.g., Q1, Q2, ..), a type (e.g., 'query' , 'link' ), the total number of entries found, the library name(s), the number of entries for each library, the query expression (SRS query syntax) and a comment. The user may add own commentary to the query. Users working in HTML3 mode get a table with all these descriptors. In versions below HTML3 the same information is available in different style and in different order.

        The second function of the 'Query Manager' is to make further queries and links.

        There are three functions to control the queries and three functions to do further queries and links.

        Control Functions

        Receive With the 'Receive' function the selected queries can be downloaded.
        Delete The 'Delete' function deletes selected queries.
        View The 'View' function can be used to inspect a single query again or with a different 'View' (choose a 'View' from the 'Using the view' field).

        Query/Link Functions

        Link The 'Link' function is exactly the same as in the 'Query Result' page, see detailed information in the chapter 'The Query Result Page'.
        Combine With this function it is possible to combine one or more queries with the logical operators AND, OR or NOT.
        Expression With this function the user can directly enter a query like "(Q1 & Q2) ! (Q3 | Q4) > PDB" (i.e. query 1 AND query 2 but NOT query 3 OR query 4 linked to the PDB database). In contrast to the 'Combine' function it allows to build more complex queries.

        For more information in using logical operators and link operators see the SRS manual.

        Result Display Options

        The 'Query Manager' offers two options to manipulate the 'Query Result' page:
        Entry list in chunks of... & Using the view… The options 'Entry list in chunks of ' and 'Using the view' are already described in the chapter about the 'Query Form' page.

        The queries done so far will be lost after closing the SRS session. However, it is quite useful sometimes (especially in the case of complex query runs) to store a useful query set in a file (referred to as "history") though it can be loaded and used again in a new SRS session. This task is accomplished by activating one or more checkboxes on the bottom 'Save in histories queries of type' line.


        SRSWWW

        View Manager Page

        The extraction of information from the databank(s) is done with a query created in the 'Query Form' page. In the 'View Manager' you can define how to look at the query results. You can use predefined 'Views' or create your own 'Views'. You can apply them on new created queries or already existing queries. A set of 'Views' can be defined before any query has been performed. But of course, a 'View' can only be used after a query has been created.

        But the 'View Manager' can do a lot more than only to provide a special service on query sets as described above. The 'View Manager' works independently from the 'Query Form' routine. Thus, you can start complex queries within the 'View Manager' to investigate different relations between databanks and/or query sets.

        The following options are offered in the 'View Manager' page: 'Create a new view', 'Edit selected view' or 'Delete selected view'. The 'View Manager' lists all the 'Views' defined so far in a table with View Name, Format, Root Libs, Root Fields, Leaf Libs and Leaf Fields. After doing a query on the selected database(s) the user gets a set of entries as a result. 'Views' can help to recognize whether these entries may have e.g., links to other databases. 'Views' can be configured to see the fields of interest from the set and from the linked database entries. There exist already predefined 'Views' which can be used directly or modified for your own purpose.

        independent View Manager

        Click on the link 'independent View Editor' with the middle or right mouse button; choose 'Open in New Window' in the appearing context menue. A new browser window is opened. By this way one can define several 'Views' at a time or edit a 'View' in one window and use it at once in the 'Query Result' page in the second window.


        SRSWWW

        Create A New View Page

        In the 'Create A New View Page' the available databanks are listed in two columns. The databanks in the first column are called root databanks. The databanks in the second column are called leaf databanks. The root databanks refer to the databanks used for a particular query search. The leaf databank refer to the databanks which will be linked by the result set of the query search done with the root databanks. For example the user can define a view with SWISSPROT as root databank and prosite as leaf databank. In the 'View Select' page the fields which have to be displayed from both databanks have to be selected. Choose this as a current view and make a query on SWISSPROT (which is the root databank). The result will be swissprot entries and for entries with a link to PROSITE the PROSITE entries.

        Name of new view

        In the 'Name of view' field you can assign a name to the new 'View'. Leaving this field blank a 'View' name is created automatically, prefixed by the first root databank name and a viewnumber at the end (e.g., Swissprot_view1, Prosite_view5 etc.).

        Display view as table

        With selecting the 'Display view as table' checkbox the result is displayed in a table form instead of a list form.

        Print short field names in header

        With this checkbox it is possible to place the short field names as the header of the table columns.
        Show only fields common to selected root databanks This checkbox is selected by default. So only common fields of the root databanks are listed.

        Continue & Reset Button

        The 'Reset' button can be used to deselect all selections done so far. Each field and checkbox can individually be deselected by clicking again. Clicking on the 'Continue' button finishes the 'Create new view' page and brings up the 'View Field Select' page.


        SRSWWW

        Edit Existing View Page

        In this page a predefined 'View' can be edited. The 'Edit existing view' page offers the same editing options as the 'Create a new view' page.


        SRSWWW

        View Field Select Page

        Lists the fields of all selected root and leaf databanks. Fields can be selected by their checkboxes and are displayed in the query. The display format of the sequence field can be selected by the format menu selection (e.g., FASTA, PIR, EMBL, Protein Chart etc.).

        The leaf databank selection has additional options:

        Use query instead link

        A query string can be inserted to search for special relations between the root and leaf databank.

        Use view to display entries

        The result of the 'View' can be shown by another 'View'.

        Display only number of linked entries

        Displays only the number of links which exist, not the links itself.

        To submit the view one of the four options ('Top page', 'Query form', 'Query manager' or 'View manager') must be clicked.

        Databanks Page

        The 'Databanks' page lists all available databases in a table form. Every databank is listed as a hypertext link and shown with the release version number, the number of entries, the indexing date, the group (e.g., HomolSearch, Sequence etc.) and a availability flag. This flag indicates whether the respective databank is available (ok) or not (  ) for searches.

        Help Page

        Most of the information about the databanks and their fields description are available through hypertext links. Help is provided wherever possible in a context sensitive way. In addition to providing information, the data fields can be browsed directly (see the 'Browse Index' page).

        ability flag. This flag indicates whether the respective databank isrs/www/doc/tour.html Guided Tour

        Adding Databanks - A Guided Tour

        This chapter is an introduction to SRS seen from the maintenance side and requires knowledge of the basic principles of SRS and, to a lesser degree, the Icarus language. It describes the integration of two 'demo' databanks into SRS. There have to be two databanks in this guided tour in order to demonstrate the specification of links.

        The Databanks

        The first databank which we call Genes is in a 'Genbank like' format. Every entry of this databank consists of an annotation and a DNA sequence part. The annotation has the four data-fields: "LOCUS", "DATE", "DEFINITION", and "CITATION". The "CITATION" field in Genes links the name of an entry from the other example databank - RefList. The RefList databank has an 'EMBL like' format and is a compilation of literature citations which are referenced in Genes. Every entry of RefList has four data-fields: The unique entry name ("ID") and the lines starting with "RT", "RA" and "RL" that describe the title, the author names and bibliographical reference of the literature citation respectively. Samples of the two databanks can be found in the directory "SRSDEMO:" in the files "genes.dat" and "reflist.dat".

        Example of a Genes entry:

        LOCUS       HSAMCC
        DATE        07-JUN-1960
        DEFINITION  Human amphiphysin mRNA, complete cds.
        CITATION    YAMAR95
        SEQUENCE  
                1 ccaggtgcct actgactcct tcagaaatgt cagttcctgt cccatgccct taatatttcc
               61 cacatgcagg gctctgtgca caatgcgtga caatggcttt tagat
        //
        

        Example of a RefList entry:

        ID   YAMAR95
        RA   Yamamoto R., Li X., Winter S., Francke U., Kilimann M.W.;
        RT   Primary structure of human amphiphysin, the dominant autoantigen
        RT   of paraneoplastic Stiff-Man syndrome, and mapping of its gene
        RT   (AMPH) to chromosome 7
        RL   Hum. Mol. Genet. 4:265-268(1995).
        //
        

        The Syntax Description

        To add a new databank to SRS you need to write two files, with a third file being optional:

        1. a file with the syntax of the entry and the data-fields (file extension ".is")
        2. a file describing the logical structure of the databank - the name and type of the databank and its fields, how to index field contents, links to other databanks etc. (file extension ".i")
        3. a optional file with text that extends the SRSWWW server - see the section "Extensions for the SRSWWW Server" for more details (file extension ".it")

        Both files must be written in the Icarus language and should be stored in the directory "SRSDB:". The best strategy is to start with the syntax file since, as it will be shown later, it can be tested independently from the SRS system.

        Before starting with the details a few terms need to be introduced (See chapter "The Icarus language" for more information). A production is a syntax rule that during parsing must match with at least a part of the input stream. A token is a part of the input string identified as syntactic element by the parser, eg, the part that matches with a production. During the parsing process tokens can be written to a token table. To allow identification of an individual token it can be assigned a token code, which is normally a name like "id". The token table can also have a name, eg, "fields".

        The following describes incrementally the creation of the syntax file "genes.is" for the databank Genes. Essentially, the file is an Icarus program with only one statement, an assignment of a list of productions to the variable $rules.

        The productions in the list can be grouped into the those with the syntax of an entry in the flat file (production "entry"), and the those defining the syntax of the data-fields within the entry (production "fields"). The production "entry" starts with a list of Icarus commands within curly braces. The command $Out declares that parsing of "entry" will produce an output token table. By default, the output token table will be named after the production, in this case "entry". The $Wrt command used later deposits parts of the input stream which we call tokens into an output token table. By default the parser skips line feeds, tabs and spaces ("white space") which is convenient when parsing, eg, an author list. However, in this example we need to keep the white space since it is part of the entry. As we will see later it is also of syntactical importance, eg, for parsing "SEQUENCE" data-field which spans the first line starting with "SEQUENCE" and all following lines that start with two blanks. The command "$Skip:0" turns the white space skipping off. By default actions associated to symbols, here the production "entry", are executed AFTER the nodes matched with the input stream. The pre directive ensures that the $Skip command is executed BEFORE the parsing starts.

        $rules={
        
          # the entry
          entry:     ~ {$In:[file:text] $Out pre{$Skip:0}} 
                        ('LOCUS' {$Wrt} ln {$App}
                        ('LOCUS' {$Not} ln {$App})*)?
                     ~
          ln:        ~ /[^\n]*\n/ ~
        
          # the data-fields
          fields:    ~ {$In:entry $Out} id date def cit seq  ~
          id:        ~ {$wrt:id}   'LOCUS'      ln ~
          date:      ~ {$wrt:date} 'DATE'       ln ~
          def:       ~ {$wrt:def}  'DEFINITION' ln ('  ' ln)* ~
          cit:       ~ {$wrt:cit}  'CITATION'   ln ~
          seq:       ~ {$wrt:seq}  'SEQUENCE'   ln ('  ' ln)* ~
        }
        

        The entry itself starts with the literal 'LOCUS' which is written into the token table "entry" by $Wrt. Of course this is not enough and we want the entire entry, so we need to continue and add more to the token we just wrote. The function $App appends the current match to the last token written. The production "ln" is a regular expression and matches the rest of the line. We continue adding lines to the one token we have in the output token table if the beginning of the line does NOT match 'LOCUS' which is specified with the $Not command attached to the literal 'LOCUS'. The production "entry" gets the input directly from the flat file which means that we need to process the input line by line. This will be easier afterwards when the entire entry resides as a single string in memory.

        The other productions are used to divide the entry into its data-fields. The production "fields", like production "entry", has an $Out directive which means that parsing of "fields" will produce a token table with the name "fields". The input for parsing "fields" is not the flat file but the token in the table "entry" which is described by the command "$In:entry". The relationship of "entry" and "fields" exemplifies a very important concept in Icarus and can be used to build lazy and forced parsers as will be shown later.

        The "fields" production describes the order of all data-fields in the entry which are represented by the productions "id", "def" etc. The production "def" specifies that the first line of the field starts with "DEFINITION" but may be continued by lines beginning with two blanks. Note that all data-field productions start with the command $Wrt followed by the production name itself. If the production starts with a command or action it applies to the entire production and is, as mentioned already, executed after the matching of the production with the input. This means that the entire data-field is written to the token table "fields". The name supplied will be attached to each token so that later all tokens in the table "fields" can be distinguished by their token code.

        The general syntax of Genes is now completed and can be immediately tested. For this we need to append the following lines to "genes.is"

        if: $TestMode {
          $job = $JobNew:[prod:$rules skip:'\t ' fileName:"SRSDEMO:genes.dat"]
          while:$JobHasInput:$job {
            $JobTokens:[$job name:fields print:1]
            $JobNext:$job
          }
        }
        
        and add the following line to the top of "genes.is" as explained in the section 'The Icarus Language'.
        #!/bin/env icarus
        

        and also set the executable permission using

        % chmod +x genes.is
        
        Then to test, simply type
        % genes.is
        

        This opens the flat file and creates a new parsing job with the productions we have defined above ($JobNew). The parser needs to iterate over all entries in "Genes" and parse them one by one. The whole process can be viewed as a series of parsing jobs for each entry. $JobNext resets the tables "entry" and "fields" for the next job. The command $JobTokens introduces the concept of lazy parsing, it asks for all tokens in the table "fields" which by default are printed to your screen together with the token codes. It is important to understand that $JobTokens 'does' all the parsing. This is what happens:

        $JobNext associates the file with the parsing job. When $JobTokens is called the file is still at the start and nothing has really happened. However, asking for the token table "fields" triggers a whole chain of events. The parser cannot return the table "fields" since it does not exist yet; in order to produce it it 'knows' it should use the production "fields" which in turn needs the token table "entry" as input. This token table does not exist either but its producer, the production "entry", can directly read from the file. Once parsing the file with production "entry" is completed the output token table can be handed over to production "fields" which produces the token table "fields" which $JobTokens finally prints it to the screen. We call this process "lazy parsing" since nothing happens unless somebody asks for an output token table. Also the parser is 'smart' enough to do the minimum amount of work required to return the desired table. If you replaced the name "fields" by "entry" in the call of $JobTokens, the production "entry" is triggered directly and parsing "fields" is not necessary.

        Having defined "entry" and "fields" we can proceed to add productions that extract words for indexing from individual data-fields.

          # indexing
          word:   ~ /[a-zA-Z0-9_]+/ ~
          i_id:   ~ {$In:[fields c:id] $out:id} word word {$Wrt} ~
          i_date: ~ {$In:[fields c:date] $out:date 
          	     init{$month={JAN:1 FEB:2 MAR:3 APR:4 MAY:5 JUN:6 JUL:7 AUG:8 
          			  SEP:9 OCT:10 NOV:11 DEC:12}
          		 }
          	    } word
          	    /([0-9]+)-([A-Z][A-Z][A-Z])-([0-9]+)/ 
          	    {$Wrt:[s:$3 * 10000 + $month.$2 * 100 + $1]}
          	  ~ 
          i_def:  ~ {$In:[fields c:def] $out:def} word
          	    ( '('? /[^)., \n]+/ {$Wrt} /[).,\n]+/? )* ~
          i_cit:  ~ {$In:[fields c:cit] $out:cit} word word {$Wrt} ~
        

        For each of four data-fields a production is specified. On top of the parsing levels "entry" and "fields" we build another level which consumes tokens from "fields" as input. However, for extracting, (eg the entry name) we do not have to parse all fields, the "LOCUS" line is quite enough! So apart from the table name, the code of the desired token is specified as in "$In:[fields c:id]". Note that supplying more than one argument to an Icarus function, in this case $In, requires them to be enclosed in square brackets. Each production declares its own output token table. In this case we decided not to use the production names that start with "i_" to make them disctinct from the ones parsing the entire fields, but explicitly name them "id", "def", etc. Note that the $Wrt command is used only for the parts of the fields which should be put into the index. After adding the above to "genes.is" we can test each production by replacing the argument "fields" for $JobTokens with "id", "date","def","cit".

        The first symbol in all four productions is "word" which is used to skip the field name. The most complicated production is "i_date" which converts the date in a string form such as "02-FEB-1995" into the number "19950202". This conversion is necessary for allowing range queries like all entries later than the 1. January, 1995. The production shows that $Wrt can write any string into the token table which then needs to be specified as argument "s" since by default it writes the current match. The three components of the string date are parsed in one regular expression and extracted as submatches afterwards. The variables $1, $2, $3 refer to whatever matches within the respective pair of parentheses in the regular expression. Conversion of the month name to a month number uses an associative list defined in an init clause which executes the list definition only once just after the precompilation phase of the Icarus program (See the Icarus Manual for more information).

        The file "genes.is" is now almost ready but one additional command must be added that SRS needs for the indexing process. The indexer needs to know the location, or file address, of the entry in the flat file. This number can be obtained by the command $Fip (Fip stands for File PoInter). The result must be assigned to the Icarus variable $entryFip which is accessed by the indexer. The change affects only the production "entry" which is shown below again.

          # the entry
          entry:     ~ {$In:[file:text] $Out pre{$Skip:0}} 
                        ('LOCUS' {$entryFip=$Fip $Wrt} ln {$App}
                        ('LOCUS' {$Not} ln {$App})*)?
                     ~
        

        The assignment "$entryFip=$Fip" is added to the action of the first token of the entry, the name "LOCUS". The complete file "genes.is" is contained in the directory "SRSDEMO:".

        The format of RefList is simpler than that of Genes and is defined in an analogue manner. The difficult parts here are the parsing of the single author names and the reference line for indexing. The production "entry" allows the flat file to start with some documentation or status information since the production starts by skipping all lines that do not contain the literal "ID" at the begin of the line.

        #!/bin/env icarus
        
        $rules={
        
          # the entry
          entry:     ~ {$In:[file:text] $Out}
                       ('ID' {$Not} ln)*
                       ('ID   ' {$entryFip=$Fip $Wrt} ln {$App}
                       ('ID' {$Not} ln {$App})*)?
                     ~
        
          # the data-fields
          fields:    ~ {$In:entry $Out} id ra? rt? rl?
                     ~
          id:        ~ {$Wrt:id}   'ID   ' ln   ~ 
          ra:        ~ {$Wrt:ra}  ('RA   ' ln)+ ~
          rt:        ~ {$Wrt:rt}  ('RT   ' ln)+ ~
          rl:        ~ {$Wrt:rl}  ('RL   ' ln)+ ~
        
          # indexing
          i_id:      ~ {$In:[fields c:id] $Out:id} 
                       'ID' /[A-Z0-9_]+/ {$Wrt} ~
          authors:   ~ {$In:[fields c:ra] $Out} 
                       ('RA' ( author {$Wrt} /[,;]/ )* )* ~
          title:     ~ {$In:[fields c:rt] $Out} 
                       ('RT' /[";]/? /[^ .,";\n]+/* {$Wrt} ln )* ~
          ref:       ~ {$In:[fields c:rl] $Out} 
                       unpubl | journal ~
          author:    ~ name /[^,;]+/ ~
          unpubl:    ~ 'RL   Unpublished' ln ~
          address:   ~ ( 'RL' ( /[^ .,\n]+/ {$Wrt:adr} /[.,]+/? )* ln )*
                     ~
          journal:   ~ 'RL' /[^0-9]+/ {$Wrt:jrn}
                       /([0-9]+):([0-9]+)-([0-9]+)\\(([0-9]+)\\)/
                       {$Wrt:[vol s:$1] $Wrt:[pg1 s:$2] $Wrt:[pg2 s:$3] $Wrt:[year s:$4]}
                     ~
        
          # useful
          name:      ~ /[a-zA-Z0-9_'-]+/ ~
          num:       ~ /[0-9]+/ ~
          ln:        ~ /[^\n]*\n/ ~
        }
        
        if: $TestMode {
          $job =  $JobNew:[prod:$rules skip:'\t ' fileName:"SRSDEMO:reflist.dat"]
          while:$JobHasInput:$job {
            $JobTokens:[$job name:entry print:1]
            $JobNext:$job
          }
        }
        
        which can also be tested using
        % chmod +x reflist.is
        % genes.is
        

        Additional Tricks for Debugging a Syntax

        Above, a few lines of Icarus were appended to the production list for testing the syntax on the flat file. If the command $JobTokens does not print the desired result we can use a number of tricks to find out what is wrong. The main strategy is to use special Icarus variables to print out information about the parsing process. Theses variables are:

        $Ct
        the match of the current symbol
        $It
        the input stream from the current position onwards

        We can add additional $Print commands to any symbol in the syntax. By default the commands are executed after the symbol matched. The pre directive lets us print before the symbol is parsed. The example shows again the "fields" production from "genes.is" but 'embellished' with $Print statements 'around' production "id"

        fields:    ~ {$In:entry $Out} 
                     id {pre{$Print:"...before: $It\n"} $Print:"...after: $It\n"}
                     def cit ref seq  ~
        

        To compare the diagnostics with the input from the file itself you could add $Print commands to the production "ln":

        ln:      ~ /[^\n]*\n/ {$Print:"...the line is |$Ct|\n"} ~
        

        Icarus is an interpreted language, so debugging with diagnostic messages can be quite rapid since no compilation is required.

        Further information can be found in the section describing the Icarus debugger.

        The Structure Description

        You are probably quite happy using Icarus up until this point, but now you shall use the same Icarus syntax in a very different way - completely changing it's symantics. Hold tight!

        SRS needs to have more information about the databank than just the syntax : the number and type of its data-fields, which tokens should be put into which type of index and, how to establish links to other databanks. This section describes the creation of the other Icarus file for each Genes and RefList. In contrast to the syntax file, it must be compiled before use and after any modification with the command

        % srssection
        

        We start with "genes.i" which consists entirely of object definitions of various predefined classes such as $library, $libformat, $field, $link. Objects can be associated with a name. In the example below, the object created by $library is named "GENES_DB". The name can be used as a reference to the associated object by prefixing it with a @.

        GENES_DB:$library:[GENES group:@SEQUENCE_LIBS 
          format:@GENES_FORMAT maxNameLen:10 files:{
            $file:genes
          }
        ]
        
        We define first the object of type $library. It is the top level object in the hierarchically organized description of Genes and represents it to SRS. The name "GENES", defined as the unnamed attribute of $library, is used by all SRS programs, e.g., in the list of active databanks created by the SRSWWW server.

        The three attributes .group, .format and .file reference other objects: .group points to the library group object ($libgroup) "SEQUENCE_LIBS" which is defined in the file "SRSICA:srsgen.i". Every databank must belong to a group - you can let the new databank be a member of an already existing group or of a new group which you define. .file contains a list of $file objects which name all flat files of the databank, in our case there is only the one named "genes". Note that the file name is given without directory name and file extension which will be defined later inside the objects $libloc and $filetype respectively. Attribute .format points to the object "GENES_FORMAT" of type $libformat with the format description which we define next:

        GENES_FORMAT:$libformat:[fileType:@SEQ_FILE syntax:@GENES_SYNTAX
          fields:{
            $field:[@DF_ID code:id index:id indexToken:id]    
            $field:[@DF_Description code:def index:str indexToken:def]
            $field:[@DF_Date code:date index:int indexToken:date]
            $field:[@DF_Citation code:cit]
          }
        ]
        

        Here, .fileType and .syntax reference objects described later and .fields is a list of $field objects, one for each data-field in Genes. The unnamed attribute for $field is the pointer to the description of an abstract field type ($srsfield). Attribute .code is very special in our guided tour since it links to information in the file "genes.i"; eg, the first $field object which represents the ID or locus line has the .code "id" which means that in order to obtain the ID line from the entry we must ask for the token table "fields" and get the token with code "id". This, of course, requires for every databank that the production with the ouput list "fields" must be defined. If the contents of the data-field should be indexed attribute .index must specify one of the 5 index types "id", "str", "int", "real" and "link". Each databank must have exactly one index of type "id" where a unique name represents each entry. All other indices are optional. Attribute .indexToken is another link to the syntax and specifies the name of the token table which contains the words to be indexed for each data-field. As a reminder the production to extract the index token for the "ID" field from "genes.is" is repeated:

        i_id: ~ {$In:[fields c:id] $Out:id} word word {$Wrt} ~
        

        The production writes into the token table "id" and reads the token with the code "id" from the "fields" table. The name of the syntax file is defined in a separate object of the class $syntax:

        GENES_SYNTAX:$syntax:[file:"SRSDB:genes.is"]
        

        To allow queries and the presentation of query forms a data-field needs to have a name. the class $srsfield allows the definition of short and long names. If two fields from different databanks are very similar, eg, the creation date or the short description, the $srsfield object should be shared by both data-fields. The file "SRSDB:srsgen.i has a list of 'shareable' data-field types - more can be added. Below are the two field type definitions for the data-fields "Date" and "Description" of the databank Genes:

        DF_Date:$srsfield:[Date short:dat]
        DF_Description:$srsfield:[Description short:des]
        

        This means that later, when making a query, we can use either the long or the short names of the two data-fields to search all kinase genes that were entered into Genes after the 1.January, 1995 like this:

        getz -s -demo "[genes-description:kinase] & [genes-dat# 1-jan-1995:]"
        

        An important part of the databank structure is the description of the flat file where the databank is stored.

        SEQ_FILE:$filetype:[typename:dat maxline:100]
        

        The definition contains the file extension name "dat" which will be added to the name in $file defined above. Attribute .maxline contains the maximum line length of the flat file - be generous, it does not add much to storage requirements.

        The last object in "genes.i" defines the link between Genes and Reflist.

        $link:[@GENES_DB to:@?REFLIST_DB fromField:@DF_Citation toField:@DF_ID
          token:cit]
        

        SRS links two databanks usually by comparing the contents of a certain data-field from one data-bank with those from another data-field from the other databank. In this case the name listed in the "Citation" field (.fromField) of Genes must match a name in the "ID" field (.toField) of RefList to link the Genes entry to one from RefList. The attribute .token specifies the name of the token table with the names (see also production 'i_cit' above) to be used for comparison. Note that the reference assigned to .fromField has a ? after the @. This means that the object named "REFLIST_DB" may be absent which will invalidate the link. This feature facilitates exchange of the file "genes.i". If it is used on another site that has the Genes databank but not RefList the $link definition can be left in the file.

        The file "genes.i" is now complete and can be stored in the directory "SRSDEMO:". The file "reflist.i" can be created in an analogous manner. It does not contain a $link definition since that would duplicate the one in "genes.i".

        REFLIST_DB:$library:[REFLIST group:@SEQUENCE_LIBS 
          format:@REFLIST_FORMAT cachesize:512 maxNameLen:10 files:{
            $file:reflist
          }
        ]
        REFLIST_FORMAT:$libformat:[fileType:@SEQ_FILE syntax:@REFLIST_SYNTAX
          fields:{
            $field:[@DF_ID code:id index:id indexToken:id]    
            $field:[@DF_AUTHORS code:refaut index:str indexToken:authors]
            $field:[@DF_Title code:title index:str indexToken:title]
            $field:[@DF_Reference code:ref index:str indexToken:ref]
          }
        ]
        
        DF_Reference:$srsfield:[SeqReference short:rff group:@DF_ALL]
        DF_Citation:$srsfield:[Citation short:cit] group:@DF_ALL]
        REFLIST_SYNTAX:$syntax:[file:"SRSDB:reflist.is" level3:1]
        

        Adding Genes and Reflist to the System

        The next step is to tell SRS that the two new databanks exist and where they physically reside. Within the file "SRSDB:srsdb.i" all databanks are declared and assigned a location and a library ID. At the beginning of the file there is a long list of include statements, eg, file:"SRSDB:swissprot.i" which includes a ".i" for databanks installed. For Genes and RefList you must add

        file:"SRSDEMO:genes.i"
        file:"SRSDEMO:reflist.i"
        

        For each databank a library -ID must be defined. The library ID is a number between 1 and 255 and is used to unambigously identify the databank source within an entry-ID which SRS stores as representative of a retrieved entry. We chose the numbers 254 and 255 for Genes and RefList respectively.

        The two $libid definitions must be inserted in the list .libIds of the $srsdb definition.

        $srsdb:[ 
          libIds:{
            $libid:[254 lib:@?GENES_DB] 
            $libid:[255 lib:@?REFLIST_DB]
          } 
        ]
        

        Finally two objects of class $libloc must be inserted in the list .libs of the $site definition.

        $site:[name:unix
          libs:{
            $libloc:[@GENES_DB dir:"SRSDEMO:"]
            $libloc:[@REFLIST_DB dir:"SRSDEMO:"]
          }
        ]
        

        The directory name "SRSDEMO:" refers to the environment variable (UNIX) or logical name (VMS) defined by the command script "SRSETC:prep_srs" for UNIX C-shell users ("SRSETC:prep_srs.sh" for UNIX Bourne shell users, "SRSETC:prep_srs.com" for VMS). Names like that are always separated from the file name with a colon.

        We are now finished with the modifications to the file "srsdb.i" and can save it. To bring the changes into effect, the file "srs.i" which includes among other files "srsdb.i" must be compiled with the command

        srssection
        

        If the compiler reports errors you must correct them and run the command again.

        Testing and Debugging Phase

        Before indexing Genes and RefList we should convince ourselves that the information in the ".i" is correct and that it properly connects to the token tables defined in the ".is" files. The command

        srsbuild -s demo -info genes
        

        displays the information SRS has about Genes. The "-s" option tell srsbuild to select the site demo (and not the main site containing all the databanks). This allows the demo site to be kept separate but switchable.

        After checking their correctness run

        srsbuild -s demo -d genes
        

        This parses the databank for indexing all data-fields but instead of putting the extracted words into the index it prints them onto the screen. If printing to the screen is slow, one can redirect the output to a file like so:

        srsbuild -s demo -d genes> genes.debug
        

        It is possible to run the command for individual data-fields.

        srsbuild -s demo -d genes -f 'id date'
        

        prints only the contents of the "ID" and the "Date" fields. If you find errors then either the name of the index token specified in "genes.i" or one or more syntax rules in "genes.is" can be incorrect. Again, after corrections in the "genes.i" the command "srssection" must be run whereas after corrections in "genes.is" you can immediately try again.

        Links must be built separately from the indices. The "-l" option directs srsbuild to process link information only. The command

        srsbuild -l -d genes -s demo
        

        should display the references in the "Citation" field of Genes.

        If everything is well build all indices manually with the "-w" option added. This will inform you of any syntax errors found and of any cross-reference that could not effectively used for building a link. The following commands build all indices for both Genes and RefList and then the link between Genes and RefList. The "-c" option directs srsbuild to compress the indexes.

        srsbuild -s demo -w genes
        srsbuild -s demo -c genes
        srsbuild -s demo -w reflist
        srsbuild -s demo -c reflist
        srsbuild -s demo -w -l genes
        

        One final check you can do is to analyse the contents of individual indices. The command

        getz '[reflist-authors:*]' -lv -s demo
        

        searches all values in the "authors" index of RefList that match the wildcard '*' and prints them alphabetically sorted to the screen.

        Databank Maintenance

        Indices must be built separately for each databank which needs to be done whenever a new release of that databank is installed. For instance the EMBL nucleotide sequence library is released about every 3 months. New entries that come in between releases can be accumulated in a separate file which can be updated daily together with the indices. For both tasks which are normally handled by scripts an srsbuild command for the generation of indices could be easily added.

        However, besides the search indices, the link indices must be built as well. These are a bit more complex since they depend on two databanks. Once either partner changes a new link index is required. So when a new release of, e.g., the EMBL nucleotide databank is installed, all the link indices from or to EMBL must be recreated. To do that we need the knowledge about all links and their types.

        The good news is that there is a program that can deal with all these complications and manage the entire task of updating indices: srscheck, once called, examines the status of each installed databank and writes a script with all the commands to build new indices. By default this script is called srsupdate. It is advisable to set up a periodical job that minimally has the following three commands (if you are using a C-shell or equivalent):

        source etc/prep_srs
        srscheck
        srsupdate
        
        (or if you are using Bourne-shell or equivalent):
        . etc/prep_srs.sh
        srscheck
        srsupdate
        

        Such a job could run every hour or even on a shorter period - of course it should check if the index updating is already under way.

        Controlling Memory Requirements

        During building of a search index, all of the index must be kept in memory until it is finished, when it will be saved into the file with the "inx" extension. If this becomes too heavy a burden on your computer system, the indexing process can be configured so that instead of building the index all at once, it will build it in several iterations over the databank.

        To do this, you must first modify the Icarus programs of the databanks that you cannot build in one round. Edit the attribute .maxindexsizekb of the $library object which sets an estimation size of the largest index file (with the "inx" extension) of the databank. You can obtain it by looking at the files in the SRS index directory - a rough estimate should work! The attribute .relindexsize in the $field object allows to specify relative to the global maximum size of an index. This number ranges from 0 to 1. The default value for this number is 1.

        Having specified those number you can now call srscheck with the option "-s" which specifies the maximum number of kilobytes you want to let the indexing process use for allocating the indices.

        srscheck -s 20000 
        

        srscheck takes this number and then for each databank with a total index size above 20 megabyte issues several srsbuild commands.

        Assigning Release Numbers

        Often biologists need to specify a release number if they publish results that were obtained from analysis involving a particular databank (e.g., homology search). In SRS it is possible to assign a release number, or name, to a set of indices with the command:

        srsbuild -s demo -rel "22" genes
        

        This assigns the current release of Genes the release number "22". Unfortunately this must be done by hand for most if not all databanks since there is no commonly accepted way of specifying the current release number (e.g. in the first line of the flat file or in a special file called "release").

        Extensions for the SRSWWW Server

        If you have an SRSWWW server installed there are a few optional additions for the two databanks Genes and RefList you should consider to do:

        Add a description of a databank to be included into the databank information page.

        Tell the system how to add hypertext links into entries to be displayed.

        Adding Text to the Databank Information Page

        The databank information page in the SRSWWW server lists all indices and links for a given databank. This information is generated automatically; however, the page can also contain handwritten text which may even have hypertext links to, e.g., the site producing that databank.

        Those texts are contained in the ".it" file in $SRSDB directory, For Genes and RefList databaks there are "genes.it" and "reflist.it" files. Every ".it" file has only one Icarus list variable - $main. The $main list has several elements : .description, .more, .citation, .ftpSite, .fields, .signature and .date. The meaning of every element is obvious. The .fields element usualy is a list also and contains information about entry fields. You may take a look at "general.it" file in $SRSDB directory that contains desctiptions of most common fields in SRS.

        Specifying Hypertext Links

        The entries of Genes and RefList are linked by SRS links. For a single Genes entry the related RefList entries can be obtained with a single SRS query. Since the link to RefList is actually shown in the "Citation" field of Genes it can be converted into a hypertext link that on clicking calls the RefList entry identified by the highlighted name. SRS supports the insertion of hypertext links into entries before they are displayed to the user. First, the hypertext link to RefList needs to be declared in the file "srsdb.i" as an object of class $href.

        $href:[reflistR link:"<A HREF=wgetz?[reflist-id:%s]>%s</A>"]
        

        This defines the HTML code with wich a RefList name should be replaced and associates it with the name "reflistR". Within string assigned to .link all places where the actual RefList entry name must be inserted is indicated by a "%s". This link uses the local "wgetz" program to search and display the RefList entry with the specified "ID". It is also possible to use SRSWWW servers installed or to point to completely different systems, eg, Medline or GDB.

        SRS needs to be instructed where and how to insert the hypertext links. This information is added to the syntax in "genes.i" as a separate production

        h_cit: ~ {$In:[fields c:cit t:html]} 
                 word word {$Rep:{$ParStr:reflistR $Ct $Ct}} ~ 
        

        This example introduces forced parsing. The command "$In:[field c:cit t:html]" asks for tokens with the code "cit" from the token table"fields". The additional argument "t:html" specifies that the production "h_cit" should be only called if the task "html" is active. This means that after production "fields" has successfully completed it checks if the task "html" is active and then calls the production "h_cit" which is in contrast to lazy parsing where, eg, the consumer "i_cit" activates the producer "fields".

        The $Rep command replaces the current match ("word") with the hypertext link which is specified as a list of the print format define in the $href object above followed by instances of $Ct which are the entry names to be inserted at the positions marked with "%s". $ParStr returns the string value of the global variable "reflistR" which is a way in which the the parts in SRS written in Icarus can communicate the the ones written in C.

        You can check the correctness of hypertext link insertion with the SRSWWW server or with the program getz. The following command extracts the the "Citation" field from a single entry. The second does the same but activates the task "html" with the additional "-html" on the command line

        getz -s -demo '[genes-id:?] -f cit
        getz -s -demo '[genes-id:?] -f cit -html 
        
        h the the parts in SRS written in Icarus can communicate the the ones written in C.

        You can check the correctness of hypertext link insertion with the SRSWWW server or with the program getz. The following command extracts the the "Citation" field from a single entry. The second does the same but activates the task "html" with the additional "-html" on the command line

        getz -s -demo '[genes-id:?] -f cit
        getz -s -demo '[genes-id:?] -f cit -html srs/www/doc/usage.html
        
        
        
        
        
        
        
        
        
        
        

        Program Descriptions

        GETZ

        getz is the command line interface to the SRS query system. It offers access to all the functionality that there is in SRS albeit lengthy command lines must be typed.

        The most complicated part of a getz command is the query expression which is explained in the chapter "The SRS Query Language" on page 0. The command line options mostly influence the output you get after a successful query. With GETZ you usually make a query and you get back a set of entries in some form:

        • only entry names and entry-IDs;
        • the entry annotation;
        • the sequence selected data-fields;
        • complete features;
        • features with their begin and/or end positions redefined.
        It is also possible to obtain a list of all accessible databanks or information about individual databanks.

        Command Line Summary

        getz was originally written as a workbench for testing new functionality within SRS which means that new options will be added all the time. Some options might have been added since this documentation was written!

        INCLUDE OPTIONS getz

        Examples

        getz -libs
        

        Lists all available databanks.

        getz -info swissprot
        

        Displays information about SwissProt: the data-fields and their index types and the links. Note that for retrieval both the short and the long names can be used.

        getz '[swissprot-id:acha_human]' -t
        

        Retrieves the SwissProt entry "Acha_human" and displays the annotation part.

        getz '[embl-def:insulin&receptor]' -td -sf gcg -fil
        

        Searches all insulin receptor sequences from EMBL as defined by the definition field and displays for each entry both text and sequence part in the GCG sequence format. The entries are written into separate file with the name of the entry and a ".gcg" appended.

        getz '[medline-authors:smith,j.]' -f 'id aut ref'
        

        Searches all articles in Medline where J. Smith is an author and displays for each entry the ID line, the author names and the reference line. The example shows that both short and long data-field names can be used (Use the option "-info" to obtain the list of all data-fields available for searching).

        getz '[embl-key:*glu*]' -rep -pmin 100
        

        Searches all words containing "glu" in the keyword index of the EMBL databank. As a result of the query only the strings that represent at least 100 entries will be listed.

        getz '[prosite-def:protease]' > q.dat
        getz '@q.dat > swissprot'
        

        The first query retrieves all "protease" entries in Prosite and writes the resulting entry list into the file "q.dat". The second query accesses the list stored in "q.dat" and links the set of Prosite entries to SwissProt. Note that any file of entry names can be used as input.

        getz '[embl-org:escherichia]' -link ecdc -f def
        

        Retrieves all EMBL sequences from E.coli and prints for each entry, if available, the corresponding entry from ECDC. Prints for both entries the definition line.

        getz '[sequence-all:homeobox]' -libs 'swissprot pir trembl'
        

        Searches "homeobox" in all text fields of the databanks SwissProt, PIR and TREMBL.

        getz '[embl-features:cds]&[embl-org:yeast]' -f 'id fts' -d
        

        Retrieves all CDS features (coding sequences) from yeast as a list of entries that contain the ID line of the parent entry, the feature description and its sequence.

        getz '[embl-features:cds]&[embl-org:yeast]' -pos
        

        Returns the same set of features as a GCG compatible list of names. The begin and end positions of each CDS feature are given together with the name of the parent entry. "joins" are converted into separate lists of subentries.

        getz '[embl-fts:cds]&[embl-org:yeast]' -d \
             -fbegs 50 -fends 50 -fendsrbeg
        

        Searches all introns from yeast and extracts for each intron found the sequences 50 bp upstream and 50 bp downstream of the intron begin, that is, all exon-intron boundaries.

        WGETZ

        Command Line Summary

        INCLUDE OPTIONS wgetz

        SRSBUILD

        The program srsbuild builds the indices in SRS. It must be called separately for every databank. For building the indices it is not really necessary to invoke srsbuild directly. The program srscheck checks for each databank if indices have to be built and writes a script with the srsbuild commands necessary to get the index system up to date.

        However, there are a few occasions such as testing a newly written ODD file for a new databank or for assigning a release name/number to the set of indices of a databank where srsbuild must be used directly.

        Command Line Summary

        INCLUDE OPTIONS srsbuild

        Examples

        srsbuild swissprot 
        

        Builds all search indices (not the link indices!) for the SwissProt databank.

        srsbuild swissprot -c
        

        Compresses the indices build by above command. Compression means here not just a reduction in space but a reorganization of the index that makes its use more efficient.

        srsbuild swissprot -d -f -w 'aut tit ref'
        

        This command is very useful for testing new databank formats written in ODD. It displays all words to be indexed for the authors, title and reference fields of SwissProt. The "-w" option turns on the printing of syntax errors found by the parser. These errors may reflect errors in the databank as well as errors in the grammar written in EBNF.

        srsbuild swissprot -l -d
        

        Displays cross-references read from the databank without creating the link index.

        srsbuild swissprot -rel "23.1"
        

        Assigns a release number to a set of indices.

        srsbuild swissprot -t
        

        Sets the time stamp within the indices to the current data. This becomes necessary after the databank files have been moved to another location which changes the modification data of these files. SRS will think the indices out of date since the file date is now more recent than the indexing time stamp.

        SRSCHECK

        When maintaining indices for a large number of flat file databanks a huge number of indices has to be created and maintained. Whenever a new release of a databank supercedes an old file the indices for that databank have to be build again. But also all link indices to or from the new databank must be rebuild. This might inolve reading cross-reference information from databanks other than the new one.

        The program srscheck relieves you of having which indices have to be build at a given time. It compares the status of indices and the databank files and writes a command procedure with all srsbuild calls necessary to rebuild the indices that are out of date.

        Using srscheck the maintenance of indices can be completely automized. You can write a script to be executed daily, or even hourly that has to commands:

        srscheck
        srsupdate
        

        The latter command invokes the script produced by srscheck.

        Command Line Summary

        INCLUDE OPTIONS srscheck

        Examples

        srscheck
        srscheck -l 'swissprot embl'
        

        ICARUS

        Command Line Summary

        INCLUDE OPTIONS icarus

        NODD

        The ODD compiler processes all information stored in the files in the "odd" directory and produces a binary file that is not platform independent at the moment. After every change in one of the files in the "odd" directory the this section file must be produced again.

        It is normally not necessary to know more details about the command line interface since the alias

        srssection
        

        takes care of the recompilation

        Command Line Summary

        INCLUDE OPTIONS nodd

        Examples

        odd -ds srswin
        

        Compiles all files that pertain to the "srswin" collection of ODD files. This command is defined by the alias srssection ; directory the this sectiosrs/www/images/ ^^{=F[rlN6 $RB"zH' "EČTrNHRÄS;DHJio5X/m!j+V dcs&85tPq-f&i&,O$Nl; _UDOU6;79+GS(y*)s **[2*t R'hclD B Wu(m;V<_yiB*. 7NxENX4`3%'v+q]hYBflP~Y0A``V@WGy€1)=ta .r>*'$0#-J 2MpA ց1!"GMg|YWX5j2o)FyY$(P ~B)aSq( \ ' Aɗ70y`!0gP`BE `5Hz,pGMElKysO*L^L| >f Q  \ЅOHZ_)D n\Q4mrwPhv=Z@ k$TJ `) DbzR9vCQ),$bOj6J P_-! $ak  ZQR%̂; p\sDS|$d NDf=cmiŰ-Hу,>nI 14FD^(հU$ ȵdQ$ D`Cƪ}C`>pAB*lht`t*~ HG(5aVO, C. M|#1$9cYD 1 hDr'2P׆%a2GIϵ$E du !C)0U0`l z$\T<3Hx-2`49 g &p0k^Xy6CF'6m NJ!B @_#Vp@ R+Ihh%pxi=F0%_JȠG *<Po<%:G\ x ,0y}UbAtb&tWRqv6@=`j6 dg @/Ӑ.9 ;8 '0%e($&.V@- "#>PWjXX%%m p=E%Yk@?Pgx&N 1la `T#TZVV@Eg $`$^GjBb$#$Ӑ-_לiiUU-@N A`AIsȚ"ʐHo'Lz}=8WXЖH. "T]́U"0pL `$Te 6$+P(r6P`5% W!#7*ѳ0J9FCgTQ0PK RWbH5F/`Vi:iAq^l26 k$z-+ X0zΣ7 R4_o13dsYa[c8;:M+ x3ᄋ" 绱Ӱ%u!4uH_qeHdebaOܕg'Ťz`JNp3a-kЖ; `%e2|3P.qR .TB bq782>@tc 8c js.I=joC#S6>cK ګy]Yvcq$ 8>o$а R2ankP8dQ&$@kis*3_TttE1AEkK|,$I Q((5@È ]f'2"d`Jjܿgu`4zl`۴ 8"MsAImxN[9[?))-%x }81cgjf|2zJ "[rk[ 20%t9;Q(IW:`A`@JVcK2Z0;bdVE3P531KM.:T`F-MTl̈1D kE w4҆AZLi%#;^@! S$]R9*5a7ZtT <r mJ L āQc9V__1LE(IL c[/*aRac2А+~:8Ca jK# eD=5K%!Y\d 0%>$3*aD 3fDݡ1R1[€4 y }ƒg ebIPBCCc4$H&poGuYX A"dò/!1)@ ij!R|6(* ]xDajS RrKO#[3 AʙFT@ ij@w8TR Rl;`0bP% cGјÅY) z129\(*?n 3 A(SD覊_Wۺ|,v#Da"ӑY6HƂH(ga- ϱ8X|4 )6b,N[&7:6K"]⯇_Unt7=M% $MTDIFVRET#yMYuWdӒp80wrF%VIh"Ԑ$(Aa*ҩ'2ײ*) !CC.10Lj`Xn] v"2,0@[\L,b Y*\*`:8~,&D: $ 6  Q !uʲ("U'B;TɐtAdD h !CC.10Lj`Xn] v"2,0@[\L,b Y*\*`:8~,&D: $ 6  Q !uʲ("U'B;TɐtAdD h `8ȥyi]J~P@JBw%`n^i gcGXI0j LNL \$Y0 "c;C<0Gn/3$ٌt+]-Ųgp$6|풶4nI?)U'9+RW˶BYSyU y4i^ͺk c˞]s۸s" XȰÅ ᭁ>S^݄)o ,]O]V6q25jܸi3(2]chN/#yۻO)gJϿ[~O}Ё" XȰÅ hJ*Ч'Yu*S J:֫Qn4۔ѫaU^in״=s.-koЋEۮ-lXdIV:n XȰÅ XȰÅ XȰÅ 8gzX-H_J*i"WK ea XȰÅ XȰÅ .R0\K $ ]Q'w y3戚6tΤ`\uӮT4Q¤s+.jc+'~^9ᯍ3EΕ:g?$ b^g+F?t;N9}W~i$H 5`B XȰÅ өRarPT&XA]xӭܜ@emT$ݧIty/b 5j''Ve|6ַh/r^ vl~92f Wy5a.kΕ>np~RN-:ڷs'=ݡUoZD׏Ws{u_>~ٱg~GId Y 5`B XȰÅ February 12, 1996 This GIF file was assembled with GIF Construction Set from: Alchemy Mindworks Inc. P.O. Box 500 Beeton, Ontario L0G 1A0 CANADA. This comment block will not appear in files created with- a registered version of GIF Construction Set Alchemy Mindworks Inc. P.O. Box 500 Beeton, Ontario L0G 1A0 CANADA. This comment block will not appear in files created with a registered version of GIF Construction Set February 12, 1996 This GIF file was assembled with GIF Construction Set from: Alchemy Mindworks Inc. P.O. Box 500 Beeton, Ontario L0G 1A0 CANADA. This comment block will not appear in files created with- a registered version of srs/www/images/gray_aluminum.gif > RR[] PȬY ܖUdŞBO(-E;D]xPsA?5\EZ'qޑ\&*b *DD?fC+GɴDDatL3zmv8XZ}Ro8džU(9{0 /p'v@>V@ sƆmZl % $]Ձ%R'zHw*Lq? #nLryRnMiI ) vf@ݷI']op@2$?&7_5cFnʟixX5wqzr; >j0[,dI(!wE#c! 9iؗfU?o-1uѪnX4ЇD ]PtT ڃtA |L@(pj`ZV0+>D3T)Ya g6g\A#+x˓%@,UYebBZ3U~$Bz'L͚:ƣ4lE(\Nu03vUr-L=}] Y8$Z>G5>!7Rn6Y oVfb39%P]g!w:KӺiPGQ6M `;&;z.-`P0-QBKCW'ݳ63H`ƷAAyfW@cj"FAF]z- y| D{&{YcD`7A6QuhT6e![pnmDC AX,YXzDWX!E h/l7Uq#z.t)C`;.nI@oz/gn^,.CsB|S c &+Lw C=qxWsbO|JZ|*Bdd[lDOzftwh:(%pТwI䕪M P 6lVp :a+ 1PS =9Nizj _9&Mb!x:@mh8rc,h rm31CH7ىu 3kU ypT8P q ʢ:i,A)|36#;J)V au֔3McFsRO >\﫧>jYRF]I\fiNnz7Id),Q+ɕ5&uč7 ̨[|,&rd0P_8$virk%dn([}t`fz [IqtAA7JBb @'O_v!ۀE E k7v@,ݲ QWqd4 wrDvh<\M vQbYYz6f!HBr@]9Sxb CBf\ٛkKA,֢%[E?إO 1k˩!>ë(0|Iޥ[$96.L \ t8k":$= @yF2A5l} ҷK,JZ C@B'0 `/"hr᜺?M<(rv$"uLVlX/=!M\5oZ M3ąH*'G?LGF;hp\ӉaO BRHCT/;s8q+Q;ŅK|C[G#=eMmT %*u.?0 pqE$w=`/XrFD\bl!K6Ud]$$AbF3QKA&A^X`!\!IVvof'.=Fule ?l$jl0ވ CDN_:xXŦ U!d\T@Ztff* 8@R0-~ E/'DK c>0L/17U|PBa{w{M2>N[3NYS igr5o5 -skcY)婰o!&;`@ F,KƊDEWB"U Ξ8-pUm8\FQ (UʆT[>!'0IhK 57Ak*Uޫ/z|fLIgYR `\M8 :@iEL K K= @# [F]!@BpI/u1uGˁW[:eG&d6|Ǯ dlhepKXW[8IsW@< U FJʍ=  } tHLfN%U.e P!cjh@qɦЁRk8d~3 `Fgp L=ˆ`2<Ƚ U"\/΅Gʎ<ޢTd`!(O͖Q?jmW0`WK|G `S L͹pO`*ILxJraV/ T2أҊ 6G Pe)A#Lsћ DPQ_C:x}l?5Iʇq(R+?mՍ]g `Ah*ifŌ1!:O-\LP Md4`A<G1BVޗT( !baap/gʙ>P#=ZVͅ"v @ɀQIK0mDT?ԠםdLSnR! Pv}fTz7WhLLuWp`, LtjBIr#N]Bd!Ma# !E]i)” Rn! Vgi(*x=o `]~ e6pT\M 4͞.ЅxJRZMK B(M '} iZ,nVD6:!ED}^E*1Шk lB.᙭j W&nK!+hU&]/?P32)Ĕ| U hM3za+VekGD4\Ijtʀ+ӅՉLtÄ !E]i)” Rn! !&&- #(?$.!'#&-"!*) !!$"1(*7- *15#../* '4-(# %#&Сj0 * $$J0MjM3# $)@u#((ؠ7@lS{ z+T{2 )ȥA еON0LhR(%|'h`X\,2 Jry6\pk (j0)z/-xRY4A$+͛\ #74d,IZ !d@ETBp,E#. cyJ.zF҂p8o^@3`6zۨR'\+  0t,TTBxpM2^"*G*6\(!h`>G]g2)t4<U9˘%87 H ,p(x 0l2}1 -ߖФ T/O ~ Ǡ )I69B /A} `q PCs0)BI3ySN18E:w@3 Ĥqmax/D@P@/f(9c2##dq ("%xA\T03jYOZf‚\BtY x, ^0 67IMWDBCdQJQ6TGNmZRE5>a}78z&o@A jЂ0b z xDs/pPz"l } 1ٌ 3>biGS> ;-8eb.lw t/v,kc nPڊBM ((JA0q^!R~^zj3P`0.+KJQp@Y% PsJeNr,o#VP2Np*@$+% jr4@L4# 4>/fӨL C5E-@~Ii3AXBcƵA$15"d*>^FN njDca %Y., |>i#m h@SV]#P0!TD@LC`c_q6G( 20 jB h4Z r ^P~ y4 C]$[sWM: ɣܧg)HJn%iXd W$`\+B5(xW$֍r" H+`E$>Oj{l5( / l!Am7 p+[ wCBЖ 3 GG!  6 6w+@x603o%NMP xp# da3 @qa Y '.qAG#b'(P% 7f-  7F,0QC TZj$rK1@|I`  ̐> 'h@P@P 5AV4>B 5pwX$P#5p` . #<(Ӂ# +܀Gik1 #ԀTBH36Δ&#0&2 Ar@0b;@S eRA 0\ *$WXpe QAuɀ@,԰N *@I waVpȁ'‰^ P 46  f t2Wn5 {/FA5.hJTL`m.@7 C/ `(H C9U =!h,`0J=UPL@ PP'Po |RP8 A/3zA/.)Hh B"|M,N/2 2B $d& 4 `lC" R !h 4p 1x/`ތ$(L l h ľ〉# >l l ЁAnB-PJ0H'-D  ~@3 > GJ pttKKqQǤ{Dt+&`1 a @5jm6BghQ 8 ,@ O $?A qF4 l:]%Q`3@N< (XnI kі^qAJW :p+$&v \p2? !Lq S84! ̈́93`d@ \_0j 4 <`G> B_"p2WQ*< ?2 OS"00, v ABL0v3#*K+@B @ G Δ (M*s^hC@7tq#7e2E[ EU#لf=P)f:(2>(@Pp.Q/'f `E09@sLl_-0+e @06 :` @f ˁ0-`.DG",RY$ 4,3q%1dz90WQA`_p# !&5X"- @ {R U$եUDS\Qkb-%GL20`w?rs9'}W# ;0m*4q'R KE @prJ?YC%s0_x-fu^&"^rKn6J#V9 /@`?|c"<0 VT>@?f7#fC-)"$ F33-(j`RaxXqGt!*1`<}BJ&y5q P65+33vDq?R '< R!F~fA ?^Tc /"0m$0 pa) c4{!iP D p" DGP # DPU5  V`#'!@aC. c- }%N5  0"p*] @E7uV Ԧ k(CyT&- [ewbV jS *O< [30QcfC 0^$!d!)^0"NŌ % |pPSh l0BVFÅdH1Auka,8 aąF'OCUJ`X' v 1UC qQ@a$u0b :õR+ObX ~.PИ $  d pC)UM"] x`0TW.P *p*| -/d1uB,$@o1r| ^ (8w` 7(1@[#p$ U  h 3T"7+ ,DDIpA7a B $h` TA @+ׂ,S h1p ь , M4XIP@ Af60~`= g iA+4p8\ 'xBBysGt~ޜB8sh0F4"@D hV'Hdh5j \jCB 2 #$PÁ -43*h& ՀX'- 6xd#liH 2p 2T e*'MГq`fIUaTqh?r~pyd"jr|hL*.s0ACG3_' 11.u F`Aҁ X^ I|pxR rޘ`^" ā5I -S*ܮ̪Zj4 ^<(=N]͋LKD!`A e`FЃL.h X fd ,,f"햖j0eU g$ k3b(& $j0 xКjV+9DŽ4  XAE`2L:a`#dM* 07$4l+n&Ylq,RB| @тqu+ J` )A7,kb Rp:hGU(E " hlK.Vh,/k݀a.Wl@L9X  + @^Cw' xy9${Ĥ: ɛ'^ٚX `iM,=[|' fM8Wd@U<@",`B**!2c, $ "7F(<αhIo`XBA!R )@]o!&RKij27<2vȡ.?E@'\CQ2ȷAU12~# F s 8'aI%$ - kr^%Zf)@/(Qbg,KRR7Kh c ]U8ޠys|0PCZ$BxQq$7 a!&߃5% 2v%8'tG Kزƴ#l7Ke)2+#&d Dcr HܒTh$eU" h+ vTnATHAb%JPkV r2h 4r0!{41+A/0T .@{E9Д.lX7"0$ղ3!T,!+23A-EI63f|&*4pZp(1%  ->I5 vm(D eG-T#' - T U60H&@M0|tD Q]Mt B = 6 8GT5/!`0" \Qu2'P 3P0F[ZD9p7tM5M7G3D*ITE'07S' Ys20rV'CeZOZ37?uE 8F=TV'&ς1(.p<* 7B!+m3rfI70h8DTI`RAcoO#N:o2T&pu X&b1ܷ/&`11`yh*aMc 1 /6Q D@:' YB^B+J"{BIՎuF2j:)I#0mrBk  )JN,SP$8&,b)Tpt0H-r F-t|һA!rEc9TM#*+2 X&b1ܷ/&`11`yh*aMc 1 /6Q D@:' YB^B+J"{BIՎuFsrs/www/images/greenred_marble.gif j2$vv|0lA ECJfe`QPV^TV[LHNHIH eBk<;w+=i JebNaYVT\ЕRg Dly<*l?>= D P RX P'8*c4k7Qċ|څ+#D:$B'IN< ͙JW5y@|&1MD@S#18>lɨOOi2JU11 Lk> {cгdB ʎts`ؑ]tf@VLESDE+$75p+;mYheXf u5,ⱊˆUQ66jv\F ̗VUB틘 vc4lzONE Cj]t\$2B&=_ioС=oFDԏbJ*C!0^f4gRDE{}^F>d8"1H1 W"%zms 8q򢂈46O]&7C /]X ؀(fMuhOm'(( ` q]D,N4ЅVZ'wީqJ ]NeI EЛ%\iP?-*,}z([gͦL`1-,?<ǩPOl=%eq!`|P `|ޓ@ٍ/|](Ex͆jfubG$B F۞:9Ju88ٽ8A pQ+֙)!N_4HiD%YID&8 q$v1Ghh ؁\ 5ڋ| Bҙli;/C  Pl@zO C2ުc=Oў$uf)=IJ(E[Ԡ&P`!COYdRzU`q$iftjwt*X,8~W_C06mP ӳ`7gA?> DzQc i2Br h d^0RI% P&?6|\ȏHI3ƍKtАV y:DY EƉU 2q :**6 <4b-6??HKʡklz qZE&#WPU7_%!Ł?ەWX )*jꭓJnAٓ# SVE- 5` 5Ue'e ؑʭi9(ˡi! = m(jriQ Z98[g`:"+JЙ-ۦʡN{g*tuK@r92Z G+Ί_HWlʌ[Xʦ )າ)؏m[kg1HZS:ƅjE &I+jߪPk) ҥBw%?5)$J$ oiK r r˴u˹iwEiy}˔S̫"4W'PxUҪ5k겚K۴(;ʙ~Y[!!^0jysTg뇧)y !j`lH"ٖW YV #dnl_eb`Zٚ٭Hj j`* ll'f.ΒeK1 ڳK-gSg7lFK,'P; v,ܶbgRePS$ї3yNU*c*n*,tqa)q~6ov't~vXvbJ̌U+Z.x2*+܏X R.x5dfPWwZˉ þ .l"bN2.$;Ș_gB;yġ s M]bŕ ;'Ћ.]n5{JkqG&>Ǘ:IZ._U 4Y>D.Ydu O?v@ <9y!mɗC @בSA,YqefYsv@)H &8C T}.y*Ȉ uT/J9\hR0rDOhJ8rX aB %FQ|ʤa)* gm!_Ȩ(1i>HţlrwkHTxJj{Jֶ#WB(k-xS .8ª/ `g|6ɪ>ed XR AUMc2 M\vFԉV@P2TH^=r6,g|-1I=pVp=öDkgMG37$"LLizuԹEu"AQW+v<8(AYt"wZ5 |sud&uMSY{^[<Ҧ.ɰ',?22۱ɶC>^)hr)rt Kac=cjd;b8>qI o+^ V]"&_gx㐟 #xz5" wmy?CMp4}"-:˻& DFB47)GRq}  X@M=b趋pGY3fE+#6%b sRt=#ǐǏ d9ăH1Ri@F(2@7? rc8LI|>+r.&cSQ<2"/`ncFsdLPgx| 2 ,{d$M"NQxHbq3g|= ^q sqŏ*b!25:kR'vCZʸre-ed41rɐl$P7;ث^5Un _dYOeӈ#^<2bN@jVϴ)`o-l KH9m/p,g  "7вޑ+ kœLOr _]" N`4&` b๱26ȴ5auKy*ʠ6*n4N*r冑|[BU dN_J\ X^B6^MřbQPe=e^Ƣ A.PI$-beNB_Z; `V>) bRd ]XE_U^!:m =f EY$#-|f Wa-ȼoY0Q`Ib\ _]" N`4&` b๱26ȴ5auKy*ʠ6*n4N*rsrs/www/images/greenwhite_paper.gif 罥޵֭Υεƭ޽ֵέֽ֭ε޵֭εƭƥ޽ֵέ֭֭νΥֽεƭ޽ֵέεƭƭΜֽε޽֥νƵƵέƔֽεޜֽ޵֜νƵέΥƔνޥΜֵέƽ֭ΥƵޭ֥Μ _ȥDvlytC.^N "L!! :U Lci$ |xØ^0QlxA`B(x5)1F~$V{B  cy1BuxC 40w\⊫}&H: j%YhlyA]:LZ{DDaq*a&B5La8M2`"[i%q9eHd,“::H Z HlEz"РA"bT5yE"]`;A -a +v@%BL ,ȁxP ʠdar0/c9/l!J@<@Zx?d2@gPrpKj.P x 9P+RSļ`p:g3 hx%as'4`;` <L2d$P.Sp&LpvKJDjUm~0OaJC)gLPR#J4|M.VK A E FEd1\\k}R#@rc 0q<6(ذ @_@C`~JnHd"i Pe ^4dmB< ӀI9(Lg?#<Q0j;̉ Q$"K EQ Gl Tz4\B UHi'@ 悗 *X F&$aOAcvLU3hh",n8K:7B  18yP*@t9B24]'IHU+h@ZB>5UaYv1 Fh05`L@ h D wkH J * U@ZnS4: /T+I P]lmy ~ s Ƞ1@"` hPT01SVJ6D×]w*D v@|pkU|Y* Y f?) V,] D@`ba(D0 PNJ ( ]?` ; ? w A X@Ϡ]L T^v ө C{`  ^w@ 04 e$;4bLLA MPlP| y* U L B P  p0*. BF` i` Mđ? 9`! t94Dѿ= W5`eOD~0: @S -y` bUTNL&p^? a  a  6. NJP p B*eH Yys%Iee0 P lp: Q @ː.4r @ r o rZYUsP xpP hLPr|0O P ' AJπEU汻m*0Wv S."}o  0߫p % v?09 yMюP=7^Vp` Ƣf%@if$' b ab L1P =[ Up \.h`hIJ)5 u0zWBT0 V@F ɀԅ@?]py04p]sa%al ,\^g @ 1PU0J}u [` Y l.3t ]m*PM<8Ol 0 u ;, %9r* c˺ ")=*g?z TA"U 4]tʔ-2D4ɡA;r3&440PQDFrqs=lhȕD1)2DG' A)1ܫX0RFȣI”< ‹<iWhB0@Ð<0` 8&.$zy<@4c\"΃DC (Ot c,TVDd[@,@ @ p$$hȁ - P>C7 AB SfŘ/U8d%SDA3.A7Myd GP<Ɂ$at vHPYA΀ ,b pĂ3 ASIƑ;8$‡ fa LHHXaE $ WrC6pjrG\ .pE1zDahXIrx_!zw ;$]&6B %`r45;&!E,C/NР ?ÑE^Ab``^ɂP Gb* eQnP 6 JpE P^)^1 Wg/ DP`I .J!bb5Jy @,` :`%,D83$JQ0~ L ر: 1S8:]hGHDvBhZec1OB|&TM H @!PLhCX`l9PQXWpjЅKp3,% -XV G\bWH #$ӅCQKG;r 8M]P҃`[:kO8.FkE:hAG]p? ؁1G6  [KS݉LsW?@D B21x.@2okkⲃIE@rQxwʃ2F&"$xA\iUA3\hj `lCh-r8: STBhrM%/@A'0;xf`,hj%< 4=5$&_]ȅ:(G'x  4yC ÃI@x 4I9WrIh4 : HxA` l!dD P4x%hIDJb y,2Byd1d聆;p#g`Edq$AVdA i@F$ hI6wF#hr5ʪn1kkc܁ChxGe&k ^qX#@0#&d8#`@!I'N`%-@]+\'l8`4hmр0@ZrE p!ȋ"5X(BT/<% E<`lE#`R0! v: yt+, D^GD2#](A  )  ܁ ` `@ )<+AfA&x0Ƥ}.x pM$A)$#4ArĀ!1ND\֡@D tW=)B rl*“ -3+aYЌX| 44MVZg04 ^\љ#Wưdɢh P(xr  D(F`,hA,`2񌔄 ذj(4`@aRpVT!6 *  kp 0hف 4)v2bwp |hH/eb%)+t* MD j$*P$ | )'&MB+涀@;hžr@152FHCwdCXc(^Қ$@.8tђd t`PB)J+~ @jT7ĭFG4B5z\`@[ #1%Ћ<`Bo: .@ 4dgp)PDD`^ \\8U`, $ `C^<PKQe@8 `z`vP\dr C \O -^ Atz!0h`!pe4d X菖I`$,@. F!53R@q&-58 J@9ԇTa 3!^!`4`b  p  tVt~ F (Pt4`a ` n_~@ aU,&!T0c1 aҀ<$ ԫ f$ȅ  +@F' ` `jF`. P  ,-p+@71q h D & 8L ) r\D8Au` 74ma \΀#f 0+ W5XrbL@u4A`%S8^ T MKhЀ 0aan kdP5@ ^`Ԙs 3v 9! 9 lxI>@ :8Fm! l j T 0!dyAh@>! tSs&< r0A @ !A  dv-%zG Q  Bn;&m` < u@:*|JdFЀ@U`hA`]R R8 M4(Evx I!C9M)rƒ2yA6sȡ.#骕'2JԱs C6lX_0uy*L0!'ǖC`р"W^̢HQ08ädrr.v<0T.,b;BâIhRyT&݅AUN(1[y| ":0:HYDY&(h1JΠ+Z4 *0H`^$@"hxI00.(*(gh@E Y@T:9JM4A4a))(2)u9ud8J-v J@"4#d^v`Z:h 4cxq%YT'9D2HaDlA H&4 1"L噢 .x`D-lB420Q$Ud!I*>6Fl|BcRzPBFU2 VB JR9h ]؈ : +zE# p@ &z|3qG#|A-341I.Ȑy8~C#Fq$tJ1,"jbZ z\H*bm$h:qrlR(1xB@ Q7BL9d).vNz!AvD4FГC^1ZL?D`"M$'E.‰-%`  g P `wpV4 ҂܄$cpukMp|^0' |Dђ`%34*0s ͡ct8 ?j x H) - /2kg@LM1Pxp+?AZ Z0h z)~x2] UP:^RC`g H Q6Cpsi ,dw@ZBI  (%l` WVy2Nclv0 ]0*sK 5_ ^(#CpKC}?0@dnY ;^Q pV PPQit[j{x: Q{$hʤsj1suPri0 **n^#C|`!1#_r`#` blD |D ʼn)Di sH:pR"*L?yP˸3p- _"2y | ͳ5` $Q `gp Z [B u 2R^OBF Q+SZ"Aq}7%LiV(Z HB|2)ZA;VЯuc-br`\%GLgA BRj(s 0;t;6\dPFT<><з#LMVTLg|i] x"8wxsLYp!V ( f_lG1hHpVp `!Rz;]P!L! & |\oO|#>6 6VuV#@4V γv@ P)@m^ %>]+.S!z:b 0BHPy_ན7gp.?d0l)"<,v*[-"R&3=rS&iZqj` e !:=*;P d&P;_*0yLyx8[10 w Wv JCy#tByp }W^h)Ba¨@" ;s`yϘ%b @92fPe'B| a`xJ¸Y-Ccd\W"+&]OP:c{x&h2Kt$ G*ա_D;3DOC,%Wi1#D3 A@g +,\GY$E*eyzKf ^F0E }AY ձ*" UqE>Y#+RP<$'@oI\"#F+` 4b*e&4z@ tabʒ(eZHb%7,|g(ߩa)ۼ@`‹lASB%rqG1QI8 ( Ja!* nb8SY50@^"` fwR+' c- ;hʅ+!A+5@?l.+T;('y, r.mjD ZZsͻw\m@ȓ+_O]Spśk9ܲGgi:ӧPwxW7gj_k=5}٧otI75Y!WgRrw ׄH@b!uQg` /p`B3h_%))Mƽ&{7y5[u ض =HHk9%f5woäۄ$:!-Wb۳Zk.;`⚂%'!1;ň[Eh__mc2#)֭ UQ;AƗ:08J aW.Z7z ł|X f.m{մ񕅜ka[QfHkljKWnr=]i^\ٵ(,uQd*7zl^hNwiyQԦ j{YyFucPӋGN,fa*iO[&>E 8T.wu\F\HRDo{b;6nzә1'Ą,W&l{ Bv Ij+̤\_8fSǕ ~`.__^Kw9X2>h%fFի=˽O."Eц471O3FOs'7v* }wr""CL1a*Zիe|cĚVیC׼=E*.jR)`i A"6nS*#IJ6tY7bw6szdMkn|W7Æ4qCP$ {v3Is-8X'amP5Kyt'>D]8P-l?Tx/Mv‡d.Mݮ-M`u1Lu _Zzx^|Y0}&UtȖYO5nؓw^d^~^֫ԐӼ|pw<ɳfgJZ|=stOOYs:Z?r?EzprߟKc?Y ]GDo0 |QDvqx{C}ɏ]#فg]&8ˡBk7~.ph}tqQWz8t'qwVi\{%qH=(g(^!8|D F,tcXr#j!7'}#Hho1O&S!H_Hhu~{hjr&rz&wxVg,~x])%ZW>'8T\geqaY}G`aK6Zaֆdxs?Vp4yhAQG4؅ZAWs' 8f]Uc7eMg8h?8whXD|kaj{熙zG{؆Cp8E׃BzeGCC(47.t׳!UHwM-7ӌUBvhSRhVY扫-&xh8ߧIx}Q7M#($os)u;72tw'Xȇ9_s+JՄ7Vh{&+Q-q@)f(2'`|Dѓ&#c胦WTvH Fw~9NYW> K.RbfI{ -f}cmd@?ຳ !!@J#6eH3hGۀa{"N&E 1+tC!$NF%'Jw-@~ߠj^whAH9% HaE`d[P-c (< /vLW=A$McY^/: Ua%U pbǖzPM$H!a$Cw}tQ@豪{58A 3p"i@^԰u(0jX䳗oBtq"D5È9$&n=+&Pf `ebOC.DFK.F1# +-  H\u%w #B*a2޸mݐ "G? Jb ФXH#Ǣ+"l >$GTz#"*rE&] b ҭR5t#(CE9"„`Ch >L5-EHNDMD;n?z˛h)5&ǰt1.z.r=KUЇ4`-{EIs5`;%U!CLOBi͇wŐճ(e;sLZC >\[Y1r@֒>Ԍ\p8C!)ũ?lRbٹn8N4#LiJ=/Z Lu`L b~$̟CgysQ[Ua沄 O~1Н 5U+K*{2C >yڀFr["d*Wk#aOQ)A#>@g;>"ZCx i;B^&S#=*T i=J4b=F}l$fz6],@3G% ~+&afq0$[! w g2+BQ!?0$BsY#XXc#ABFR7EU0>dL( h-}Qbl 2cb@C MOtV9P~Q6B OTEG#g8 B_#"$ p J5 !  GY  hF00g8iP.ձ~$>EG--C(qܨ@RaaV {l =dTA.ڈ0p: "+V#dcYDd5* ^+*8=tP"b9s7 )5?s8PIk !;@&G!bgEA %2A,QiU\c!,%V 5 sDŇ9[?Dy,;"ZPCw"x °s [I"ŢeKv΃6` 8D=ۈWt[1RC" 5%r$I*J -H#kF8Fbd8:> <,""n.ыbOPfpBB鎁+<=1; G@"|jEK65QYzRGxVI-#SSp1YqbXtq3InK ERJ߀su4U6fm+GKsBssڒ9/7.l#$f`cfLZ7#? ~qC!aqQ'Z \'@fɫͪ8>eeGP 0FFSkjbzI I$ї&Yi(. } Y%RO?2J^d*((] r3ë䀌6HSWK1<:70#уp>w7`W%Z9SaAPjs *lk_O`%a|13{K0{t#d90,)+b )%@" l'Rjbkf-nbiSEAְ衮d;y7@96*K (5+ j *h 3"jB QCQp`KסE8_8A9tUQel W><J O)VX {6TT@vW6R<R<0BuI,Fe8dznp(aZ2PYq^˚#QpzD1D8 3P3GkJZDxBdri8HImhZbrH p*.>} (gDGy: u#SĀJ:qy)QQjJ5iredgIOn1ܜbh% tJ>J𗆰IEp$)D")}d8d&"M$h>V΅b.2%ߺC˨vlͨ$ՏIhd -Q4b9(*J\&H,8&k5) ~?LmmDbri4:tb$0p [ JYJBH-mfoP@\:&.QĈȖ,u&q-^-Ƽnt=PD+h⪤B0thcvݢGR8O*Dl̉@F)3ψO$msqb &p)D+K tDr.Ka]n,-f*CZXjd팅šM38lfD ,8QŃٮN:nb_ <&/EFzꁐ&&h :j *hNJo] /zOQv[3BD`gV9Q·ypXIPnѢ.ð?m+mrDk SS\¼8xi[`6 O& z,5ߋxq%-;9R>ef L ~0r va@8LV3C0#}^<ȭqPx\cBֺۍ_xAn0,C\DGb~ ֝BӲ:~BD7Jv`t "Y.ikY݆HD tvE5r9"e5yݸj`Ov2 4eRK*L IkaM(c CU#aνf tDr.Ka]n,-f*CZXjd팅šM38lfD ,8QŃٮN:nb_ <&/EFzꁐ&&h :j *hNJo] /zOQv[3BD`gV9Q·ypXIPnѢ.ð?m+mrDk SS\¼8xi[`6 O& z,5ߋxq%-;9R>ef L ~0r va@8LV3C0#}^<ȭqPx\cBֺۍ_xAn0,C\DGb~ ֝BӲ:~BD7Jv`t "Y.ikY݆HD tvE5r9"e5yݸj`Ov2 srs/www/images/logop.gif 3f̙̙ F!FHQm螇رH[* b[1fݍ8^u9fHِo!edpKb3dmdaTrY"[J`J eho\Ryfc`$fjٛ*UgNe)axX%&l yWKjp &iA\ש&iaii}ɵiHobYeq"sI!'qji꫙:\Q+iڪp*+Zk򊣰+탐(,wdݸdR"Z1RjwNnF߾~/Wkٛmݭ\簪™6hS̳o_St<Ž#W_C_pG+yY-|-fΉ.yR׸M vkzV.9&=}~!, 9X@H+M_DAډ(b>uq=%pDL D-ꐌS)%Be#3/揍G<>]ľ"ƎY>5Ao3dH?b I1^Q3I5nMtc Oks(Q 4GP9Ќ*B%GSFъ?aJk׺iysM= [>i^-IZ4pSד5vLjibh~mhm1i]\6n M{-.>ve ;YM)wwcxlܶv=n" 慏\o?˼恎5UCO9cS/x7=u/`w}ZcY^{W|523٥9 ?7{.u+v< >_]߈g{{kcc28S`g.8O_]߈g{{kcc28S`g.8O#K1Ro`PyD ~|eYs&7y{S-0@€` YB  6%(%@/y;A'1S~r^1 W"`W*mi6- vpm8$ K-ڳ⍥Q_ ]@rVYx `p!!M qdb myBKZO_`70R'FiUBx ^%FgBX#f>q2&1w f. cM3Q? B#@ AÒ逘"y6ÐxF -+cE >D ؑY& Pq~Q0B652xrO@ VH D@[g Fl<HS!Q.)f$+!:@^n(`TO"E&td}OEKZ8&Pg +@*05I Fc(ѾeK`Y#e$r,4A.&HI zx4،nU>#P+uqZ28p #ZfCW'"2 Qԏnj\6xyOU% pBњ1ơ/9 |~!HCνjɌLb ;J2 bX3D{cP0YUkк7)po~IG(<WKN y4߫YTcҪəmrm9\63yT @VB+ mg#OH]xxQu+#h}xӱM_:*nQG716R =Bl-Pܗn @P>ոGTln>]Чl*$!`qo@ >j7B{xdJ[caށ0Ɏ1Ԏ!jUK<a[!ĥ3 $Ԣ ( Ppqr~Ԛ_|cظFI3-FS]- B'lo:]79_*Q`M*RdQϵEKEYd#bZbL@?xذ lx8i3'GݯՅp8`<44. Fm"4Ɨ 8Ű4.l,G(kQRXnR jJkjm(0ju #!CAÈsU)ub#oB7NJMˠa7) q¨`/sQ)a s۱H`Tu%$(ā (> ~{4WTq5|:e\ *2i#SpfkeX),e6L \KQ85U; 4~s-Khb[$bQƑ$wò"x8"'+M:>*Ñs;+#q WXff'&x`LG{>ʲ=pis 9g"E r,Mrcٙe(B 3E5.*=GCɥ]jȆ6A>.q0N1Et.I> &8 a`;^q[[[@eeEz +d+OQ]|" O%\ .QӶ`3`>B Ѯ0@m[M$z%"Ve5-9c Q,('&"FI'&J0ƱJbPoȩnG|-4|:pfPV p&BbZQbD-t5B$ $ H1F8!6&Z)V. Ɂp "B*q03. .~cxOG<' !ZBL $ykHlFm5a(YdMEIE 5L^@?꾧s[a}e) `g*$E/4 >!*jBd T<AѣP)) 1YU8BCe*^"[iX%4&QʣkF " ٜV4Kann(A\Hم "hU iFt2k 8RV!KFQ53hl >J"20MM"\bd >e&MK0GdnfKH!܁Y aRQQƋ u/x*\$+Qg2/ 'HrTsc{ b$ 9ꀪ8"rȮs Xbt# iT8?fLUq" ,ngor>N1L>L=K=K&z /a1H`T) I(2!H `'^T 1Ӽ-FB '3 >mx2,qE`Na Fc^@1%8:-\LL7@0t CC l`*+ӃT~yu~th;5S*ПBL: ՙ .0 $lbDW~ 'G <ACFl79<М2ąH hLc[QE<®`Ygr@٠fRN7 #$i5,l)9=@h7툸:a&TR ּJZ!\evt(]v&RӉy :{ ,G0"t A'%r C{H5p5fE-;. 5=0i|0Rg|'t1 'P U P%Ǻ u 1 ~C0DB0ggppڥpqkǀ0.W\@VK9Hca!;Lz06pQX '*ec0ɔq2t# _X3&@Z 10ypoR1)v ,|p ('ʑV!P  &?E&? #5kHRoU%  TW4$g D >yDiHdS=M!@p m*'L`Hrzbj.7(@X P #@f3n"G%(]*@Ƕކ S5 [6 ټ :2n+? Kb1pqa`C0O  Пp2◜@VUEqkP a -; =~@$c7P CP1k cgd #H.0J@tD#w $WOF3ZEU6Rt5@0r< 2 E75Ƞ&w&.X=0F"^!oH1Afm 6$Y=@=404P RWqP=P $P7$cd=U W'mq! fq.Tf(#FqYZ GAPzj0b}O_)m26c:&0 )bkDs~Ao-~% nsyފ*bĘKE$7r!ވ(XHR/A,Hi #asPX*dJhqCU$ɁЄ>@AbC!f@E )?HD:I+^B+ )qа RP tqyB A.v"h@1 d`_7ЈV=PA)BМ*3 =LC"|^a0'B12 Azc% H CBZ,&H2OzҼP @y dX') k#L 0 |b w!u# ,l v"k&LPC&% (h"' 4(4u0A&$6 0COQ f0*DpX̣OC- @2`G`C hC50@ @c '_:X hAE+  A npk [18$ i@0pT^e(9f.b \͘ybM g3˙0 `Ѐ8$hxI 8`Ml)BFPU摔\I+3K=^H= A3O0xd!G_RI|W5O+؀$siM(x!z`rl [BF.f耋˘V.4 SA^T*#TRr+%&r&]$1 R+PL ȭ 1&$hdhέ.`ў7ؼ XbcxPœ:ΎҘV`૰0% R ]}G(_mY$D{2H|!퉅:PdO%*mE} :wJͣ 6I,逴4Iy? +pt~' :+ p Wj,؞/mxizl(O ,]Cb 3l$k1%! |$zAw0!6?@9H,G~(:$VnQ2@KN dD i ,]iqV*-b&QP(XG]! p"0 Ԫ+ZL>"Pkٵ:PCir` . rQ({a4v((!$Hgx)iO j@7Fc>ѹ0N3@Ob`(@F| ǙgA  )`'1X8z>`LP4`W RrqRrx$!5U@_<@ dOR% R P~~K H ( &1j߈f) ARP  A% i4T5=)@|'$m Ai5x 1LWS20 ;3d! 1Fd:")\sX6%-iStMB*q 1^ @33 MBROm'$ǤC\T4?R@p 0T2F@u`i$6 JӔZR)_5="l$* V 8/_# - }Dh%&]h'L?3 r +:Q4$.CEÅ52P^<?tp~ "D0eP*:P[94c#*HD%- d1cjDb 06, A1.m}B,. %6DwPH;D*mRFr?QaƳ8 BwB*o }Ci^b* SF /pŔ Qz"3++p#v=(6 &( B+ 5sV(!2" a قx:=E 3 WD%Rq,p `"5[WB>'a3l1D) "#60<@) 0P0>Ag&"ŷ`DjB9%Иf^ @ ,PHӅ TZ%>3Nd 0G?) tw 48yl}4FaEb W;)FoɁEnEc:0@n=Xa9 ?ۺ8 `q %)6A2B9)MT KvճSK!fָ!Poȑ`,Ipϧ45HA啩+6aĂ<9c !ڑ0'nPS IZ :5D2+Iv@Mu * 9`9Nvk!Id)?`@}!7 ,$'6ML!>\{!PI3 Dz\70z 0 V"K7? .X1DV @$`'%ӴL9st#2< 87E z\wM'}1i -0|oą $tTzbF .;<#{]@ n(rʼn& 8 hB , 6B p 2Qs 86 @ 09D hOAI"Dؐ0YSR; u Am )qP $LЂ[04~, @)`0A /0xPze)HR@C $ ׉-UC (B&+`c ' !t0Bt 0\ 뀀19xBD i$Z&dv6p3 u  7j#|@~0̉AuB{5.+V8e|ЁY-T#dW 9u0%2lܺAP0 6v;v ) D % m F, r#4A d0B*Xq_4YMWBy5yhA`T QeK(3 !fK]W&*L B vB$eB e Ċ&JDa%>1AV 7*ݑM2 >ÙP+v 7 EJTЃwx@`ETPz >pL,qh Z TE &Na@m6 BA8V" g^ .*XtpU)/TS 2Iy`\(Vx7Y Ђт1M^`* d@<ʣV!@P|BCTdA:(PG=,ˆDD ;$ -(P78Z\Hr |11O5 GyIbJjPnW 1Mr0h$8}.r$(,9JW:m(QaS4Ag \Q:=%x DP&{ +u WAbJЀcڥO3 H`'@5U"q7 :Cp4np]HWsT Hq+*$cmFt\*P8 5`>{<ʃA6"SrH@"0 ?bw 2VS 2@ %B$";@D B2j"@L3: * '<)./nZ\=l@|*dc$~"#? /: `\u Q%S qېa#dԲ8`nQҰ`-16,:%@- >N'0q1Dh wc!(a#1E 젅o&` ? 7@\AP04 9#3  BE7<H:; AP\$?#G: A-䏄08kfJ"zt # 0+bu͓Qv5P4H% 60F:683 400e@ 70*0Fr > Dh1 7#TW5F'h ezO2Vૣ[=Pa5 ! KD16@lX YA>@kc'w SQP$2 h!F ^!$QV<Gv2%79qWۓ -osj,`~)+S81&0Q)v,{<!1 f"0?Zs77гQ![&t9`V7' B dg#76g#:G&Z,w-' ^Qf\ac[!1 6$B+)6`,\(!:>J˃P.b p\K( "d!\1%`(di <*1/)qh@ruE\su5`! ц^h'18F!P& B9J $Kd! 7@c)p ~[}N20x4 !ȰӅ21`)Et 2 5 2%_h'C+( wq0 *`K )49pxXSIiFvp14.>] qu"FY3L"MCj#f&0'1t 8m+&zDFUy"; r@akYnnvw iBP Bү0T 4; m]zV~cXS1 ! "9@=8W":˨ՙ[ #3<( SF)Cv"q 5?@ւXʕH :j(+^䈙 dp@5!~PQS f@cZ1a-d#yx1 1@ntjbk58("G"%Xn @@\$ )Ѕ[4#ԯjA`dS{ vԋc2x˵gqbA ^/d%S ͼ-,R+59ۍZeG*)iR!'F(7@$8Mz((8~LA|@I= ha SKWl0C3?8O8hI5OMBU$t,u,"UPE`1-H>5H .X)~XDA/41c&\R@(cH{)X D#)5oXH P(#3j#.OH=nr @ j QPb@ T<2bfXg#ō .X)~XDA/41c&\R@(cH{)X D#)5oXH P(#3j#.OH=nr @ j QPb@ T<srs/www/images/red_stucco.gif E3x\ 4{ 6\9f,P`邥#K`c%XQ L=FlG^@0U1qXw 9@@n 'p 2G *KVMYBXF\ AzE@0 '[)^^"DOHO ! }/|&2N+ $L;J UbTon*#/~@ JPN" gD(8 UUȰ!E C\ O xa% GMv )3ee ~ *D.Px`'0[K-HVp8d]nS~ Hvv6 @ + T(N:2k (% C+c>z)PO, 4#EOp F8,`p)8R@@pA'b^>+:<WXqiB271"6*08.h9pa?h0h5q/8r0MPK@e|Ai#<a2YR BX?N"WѵG^mAmN:Gf:N !;^qd(T\9B/P81Ç%W@B*WXqÊKT :bX1! /BʼnBr2Ę4pyb˗-T 2f )H ċ$jㅈ8r (9F@\rL@y\c t.ax`R`eHxB'\H 8 l@3"ƈ8 0"l "S 02-dCD֜6. A p'h1f B ;AU4 ̠&Z(󼅆/ `PT."0p`:ML$ *`pzA# lJ' +A P X(5  B:,ab8 H"4`@hT;",Q~h`tFRUZ.$ ? 0>% "L^+  !P|dQIio CmɊJj豉I+C8k l (+ *D > _Z^i"A 0)##1h a1&pAz юc(d!#6?$z7<$ 2/ &>  ` +T<A$e4/N#Ё  {"*@D/> IŁ ($Nai $&y"+#P P -SāGZ3@h } Y(RJQ G Ґbp1@.,X5Ϋ<"m 3x6X!-8 k PIHJ86<؃-`(ـ # 7$tƨm#У-P@#bicPrV *؛)Y~؁ X'82B358J<J -}$0E ܂9ڀ؁-؂_8 9 O*.(' GڣQh .9 rx/Xh\#ܚHEsDZY*ґ>h'hG7)0 ,iA \ɂ.Р>{ ؀xH;æ >8$.\1GY D8 .HPhD-B@ eqD 00GXFrdXhF\hqlTD40OlQ9 (/ iG@O!Dg! .nX`qC y60`zo i1 8 NpYJ8@sǨf L8K3 d' z@vj$rkń4zP)La0 2,#?Π6"#–|!KS`Bh/jd   8] @# BL@ WB0(@L$P@hMP|nKAp+ Ơ=`0 X,D # ăAxwS7 O` ~ PAN"P*P )a6Gh8$ 0,V&,@qnR0 sqBEhܯP1*SbdpvP¬ ;8SM e㋾!d&,M^XC0!^#b Ipnr+yC5N4P?#8`B _T dPA t,@W Q J! bdW؍T Ὄ^YNC1XHf@0 @ "B D %  | dRF@ >Ym @N 0A|Lm !\C"ZfIHmC N`h&ء)+ hk>"%(bるI_h%xS) pC)b L 4 Jk B`h!@5 %$kgP8aC584#j c#&жmS\x! |{A&*lk8Zb03T0a m'bȡG7x GA0:,0Pzl "n3- 섁3X @"V3l XHd3TkV"Lu#H$d~ PrȠwP M!K >0̀ g ;s phʆ&+ ;I# MXwP4:BX(,̄P`p@3A ^Z@ ͪ1HFmt1 r(f2xO3yph1&4!& Wh ^ WFHj Gb`X`q4%` +( dB ƀ#o74Ãzhk @ldFB . #0@ `~k~v  b΂n"eZ|$-L "U%BBC ljfBB-\H fO2/i` :Xn {\ @ cmg@`^` FL `Po!@`6n  Td@ Þ.O/#, ZGTe РV\ t@E; w` ,YFNYX kln k2(zk.Bb&V( >rd?g' &i029C2tf@ ` @+bX@LOE\d` "}@^nQ\c" pvDͤ p @28qt>|-Q%+2. xgXmbF(cB Hc".D . b,Ex-v4@ 8NM{^`x@t--C&~7XqZDf zT `pxeF&T.f ln+v H4 y|~HD@hL0% "3Vav` @fBlz@c( ̃^)`N3&K<&% &F y|Tvs8xQTd@gE$f`GLr.r:dtwPEv8t ⿎ 42$j Rt*^%^ FdSbZr- bQLÁFFmmznmzUxDm0"w#4"Nw &3J-GBGn^P$% #Τ$̓Dnes[%Gl@DGFD8`*6Ӡ@6g*¤VFjZ@p V 5\2l`I#(f? RWlNCbj mߒNdMd9Bpݠ.^pF(nNWzn `Pv`C$؁FbH-v3#d - 0 c=+X΢NV T,OP)b%  21Ȩ B<@#bpC۠6X @('v*DzWv"$^nF'䁐XbpG<8%vWD$&/F"FB<,0c,jDr`n 4R%MaOc$xac~`6b^$&\/(CNF`Eav4R" ]W-D+&b-F9WyD@ uEQX s >B~[Ht /(nӳ$gA" )wW.@ ȯ_ FEn^˩dsV"Bċ] K^ ey/ћ""75qoھ? f#}R W% ZrÜ؜ŕ$mvZkg.7Zv*S: 1cEG jX؍#?&P|bX-ǰ|dU8VKuj$+vVgBƔDfʯUl-n .B:ְ& O` ڠ}`P.g؆`za Hijj${X[b[;rrz`Bl ?,˲$"`GxaҨ{;= ]7֑AI ʅKulXKprSPDбʳ9F![zt#ڦpIĶ)FEO$llvkŖZ%˃iճ?׮ kuP ;U-]Za _}A.L57IW_$+~$:ypORp[E.aluy* X[LG_ǿI}jKԎ%}Nb.Įrʑi:Fe@RTԕ,Ώ%,;`SJ!p#0o5 @u 0 JD+k+ ,n .n,pnAj[* LLMuOϐ7҂¯CUC{<||yFX bE$k.&uRm`r vj]Tm@`a)H̀M7Mke@ X8[ s<&&m"Qjcp>Ѻ` =2BH0 p)5ڂT@` oc4GvIـc6(,L ,1Z M@ =>'%ºm@ܠ`uB,=Z t@C\!"@'X#twQ:{dǿ{#  A]!"|Dn0# LxiQ$ESTG!+M_;<ؔIيU\"=Q$]YT'UDi!l&$%;]> Xj[ `*8ŦRJ%Ly^nh ,8 j ݱs1+ǑEbC"^(6XO8+vt]yx]w-94vcHs[*X - 1 ? T"5ت qUvs$E.MA`1 q$(ޕ2qZ욆  Bƻ /դYҊ~3 蹆VNeBg:)E4 Ӗӥ3^aijw x0\(u$ G,n~9Ys_Mh( *8#tEw+ )V:}S3+ꩭ(0X=IȫQkT"6Tjh&T @2+ZFd]jqxG =h Z6e>`#lHnuYaf6Z|foaW) њ)xiپ)/?iGM# 6V_WRfHLb6uK\Hߚ$ RjqWNKػa`黀tY"dLD1g_y[|Wfٲgb ZcaUl5Up&.CNd鬴5[hLʬHfacv{e'~dO0kSx,=ޜe"wlD"IWd$"LRB Ȟe 8rU{>v[Xtcޑ^m1 1ע$=r3;{vAt.42i qdpQ M6$HU4R4j.VAܢhG(cCX0 l@ y@B-XPT`a4A:4xalGPj!:&W|6z(z+cBm;ɨw"7FyUjiSiescSusL=)8Z68;P=#tpȊ>pp'h('T nukWWgocVAUlWEf8ч3xZ}p&PP*s $T3 z IhxLiIhNx'FӲZs+D4\.0E\el#) Uw  vu`+>R'E4RL騊mhcZA9D%B_ys{?Fjᴤ~ I2ƞ@c)5EfWSop6ghZjzxhکf(9iPA'7XF:~ZJFDXO&zV'0Dɓ/bݥ\݅8汩gl*"x=:clJתDnFjڧGꗱRʞVS7 ,nzjl#cQ8yKwtbNۜd'j(y@ V )[V~3дG9wPd rN,c U&2>V_ZCHd;*۳K[51Ā0;R஭s'(0h;U.LK۩oKçuKt5xQyvdM {KڄS 2@>v%% SNW kjlo;Q_,[yx@1I0@MiL ꓟ1I@eJZ+aœ ʈ͏y[Ȱk*Ǥz<jC =K#p,ZK{L'Z˽<ޗ[ū͹[JʦK'|Q;LcM҅[= ={ᛪJBԼj!yjJ*x5!OZBkһëXjSX?~9&әJE.eYO^תG W=,.K`}=^̬S )>ƚopդn[3lh= mpͪ+m⊤η߮/.⋸$fk.ksjdn<ʳ0uǪqN-˲)p6 ;[W9ɖ FΚ 4;j :(,ȵp6ZbɄkN0ɞ>z*N벎߅ڶh]5o.q\m˜LH2u,J./U嚌Z|$u8޴ӃvLHo^)9#!قzO2R5xlO7&n#<& %!J6aUUQi1iz ˵-543 lY VDJFF :6>"roogVZOcޡx&ʛؠs*t 0CM7B % |rOSqڲ҆Y1T+Z ⤓Etбkɦ53pd +\k[e܀{,B˟OWnto&]9i!Qԉ ^j y}!LvK=wXnk "(ad7qA$QKO Rc,bi6cu5SڕgXdBd`x nX"KW&ni֤TPRKH68W#~ąWgDSwb5hN!Y",Zٖ5=@D1案j"fYD[ВZZ֖` g j(B&z*W!,rH(ŨF4[mQFDbKmǙ*&TB/EQm[u (̜?-2!H>4|1.~3̪V_Y+`ʲV{t<}U%]ӤDg\ FxblATN-P(i-Վ 8AAB̄cm`A2ag5% Uv [xA΀=/a X02>o[[ p*;Jn+"It+b>dBӷqNav*pyu!^9rH.wiuAy6jT~E)O@WEW -Uh.|hG{X8rahw8v/4"O(ow#QX\C[ydS w2f!^/BX0YfQDh&焊y` 4W G" Xi5-H.wwPW' e؆P#o1mXk%~X$QyEܑ'mAl(;H9"U#ԕN!+e#ZP]N9 Py\66VY]ڕrHxbtt9HqgIF=#Gu05tGxwZ&$zV5DVQkԍ oT0gUCJ9r$U,?ybywF)GV.b)y+V -pȩty2SWG0 =|YIc KH4Y??%թ9zzwṌ 9k)mRqsI0t$I'9Ts߀R&1aVʕqnENh|WVf gycZJ'*ꎮ*g㧧 cr3H:eJާ"E/ڬjk:[ZšZzʭӺ=cjnb VۊvY;eyx㺍 :l;!Ү [ 2ڰ s!Z$JBzc&! "[f!kh_4ˉ-֯!3VѲ*6/kh:+ݺr Z(x{Xtvfy n["[4cI}yDI@Mn|[k 8yH:pˏ"չӴs V;lĆ5'%qF|Ky?\߹ț{.S=XG) 򋡏 5JC)x"tnqMj~2I ̽fjٚeYXB|{EQ|2և ŋ뽟i :8b[){d@`TÝc`v k)y*[0ܘ<&5!\oڡ*'\ ;e<+9QcOiT~Z"V HsufeOusj tWqB G6S;`0RƸGnȝ,`Ǫ@&JQU|5fXo:[ɹsɩ% L/CwJ;Ú4 9 ռ4@4J̣1ìQk̝H0̮ ܺ@ Ntb O[Ι{΋ 4i?ܾl{ :T зo;0+ٌ͒Gp9z; h~ooƺ[6~sa&Mnea<3&VXSw3&$cD?+Q{ {hl, [oܡ&ziϭ ='-0W?.TQsҟvUd PF ?RH*#|ˁ4 $ Atg_Y&У \0sښ$*[8mpy?P V!rQ<=IAEvaHM[;EY4┕q <$f'HBæ4`u>u}"N53"lXY='NErUx `j(Rg.4pvF'& HƳ>N@m뷨#*i->89 )fr:owZ # h? 3PNgi;IQ RTS6=hb4x$HBxP C3wr1?Tj8T,﹔0jtLCӈ͓F;TƧ9ڊ~| FWUUcj)KU QT!Biq6=IVU{DҳU3iE[3|elcj{I-dVgj 5lf K$džVb,,#MImZKPK9Z涯̢|[Wnk?&WerZJ24Dt{Жnw{zW%/90*&2xkF@m-_WM}p4o # ifPK3\L& abE|b ',S_Om/FrJq:M)Ah 9<ـ>zL=;:ϛEpXK Nt:x*cr_gD6QqttbLDB">D2Ă%FHGa㏼P&\y+ꄏ=tAfy(*/xZ>~~!?euI\ſSԓ|Uξ'`&"sB;QzZ4d<o™Jr?S<һA;쳿k*:#Sr z,GQ@c@"?g8A3y*;8;ۆ0 `Ap:|: S4D6 <8!Bf{@9)<t.iAI9$%&BC(YB"B,D89(qC]+y;;,"K1Bɝ;8,D(8BKKBt:D=dBCYXˎKħDM 2:rDA>x/?$>U|B5,Nu9DALoDÉP4;Y^lZ:[5@cx/?$>U|B5,Nu9DALoDÉP4;Y^lZ:[5@c7"+ ^8f`0d' 7`kAD`-T13 #jX9)md u JXQ9@v%LBYC!<5v:y ڀͥmTC 8*T ` #Ip!v 5ɉB&0aJ Q&{IRB%`AfP8К@(B{(\LdC`/ C+W39)6+hK53 `l@P>2 h5@8[rf0Dx%.Bl9l@z%ȠB.䧗sK yR砂P8zYS/N K-/X h..Ae 6b}r&yc 2aբE]Hʛ L eoA;h {ifpeeoyKso8;)VW4 "C>+( N]XقyBpdFB;!x3b6ɀ,AyDnK R@F&a_怈zAH(* c=DG!D F^QPbfiG`Q0X *ADe32yT4\PP\)Nm?0Dd@9 @~9*sbW BwH;O0[U˲ٿD@Xp PX@'y  0 $6.:4A#;gR"?s5NkU hd3HlpR ^0'cpCI /AXi%IXb zP$ @ A}‹9uԒ11&lPB xl  $6.:4A#;srs/www/images/tan_paper.gif fB<6_(03620,&ə0&͂ᓔ,f ɉ`682@Q T ٕYy'M:6k  Cg>74"A؄Ml4>|jbfR¬p"M <Æ 23#!8 &a*dƃ 4cS:TlXm"&bXe eX$-(x*]L8 }^UIdB e x )!വD 5 > * 9XQ6M.;kD,9$%psLC-Ğ 'Xl/ %8{D(L;64 ^4;5 pD. $&Hh.p)0H(1'[GWqMa0$LS &e"rX æB  G8?v&"`T%R>44D@1/-_aLg.5ƒcl_GB/j!`Dd06-Gj HOK1TXFd :%bp3Dn ]H fح-E;h(>~ Bi hD!@`9c)kۗHyYL@Tbl6C ZLjUsdX$ Hy p[#h-*pkbD|_`( v < f 4Jyaihp`d" 8! B@0 JgAg{1'+$`M!y$ ac E3b9t簞‚T=5jHXa `1@#!76g=i8qPt 2L+,` >8/ZU@?'+x T ;!`o ˰4I2T x.BW5 0(x%`Tj}Aq7 &*!( XM3!44<3SZAfe a.3ETR1ITO N6pG 2ҭCwJea%Hh z\[? ;Pq{>x5@Ib a H M5XW Q E@  `YP )j<,$ߑF* k19V(Hq6 i)t/GX6PP>ܢ=* H'D1y@(yE2, kZ!!E7m0KwۘTHC]6XEs$Z]7P4 ?pRh/:@:p 8U7  `o 1!Ćˢ)2Log^{IA;N֟eSf"#cԀӕ2RB còCH9 Snc2s#S@h#bbcCR#e"deC`l0±1G XX *;!dF1XBG.LIH/쬁 ȊH"@# a,*\  .V qoX) ̘b -L8o/ABm.xT $2y.&K2_f7U,2e8PQHX<SH;fDk93v+r _ W4` [&sj`~q .fL 1V qR`PC*T  Ԅ=լTkT!k$?ذa[> l%`RuTLX핐 O@L 3AJでW[ka@00C Q?R S pf8&*f#D*QR1`F.;D! rDn MC@ZM2C B9NZ=–,dr AʬH 5} $ ` `3=_2qOqO9+ӎ!Uj )CM'(>kXp.2T]e¤^LTPa XJ1Ee @ bL0 @$ш,xnQJ$Ie+C ~ Mnzo`q /p^-JW3\T{Մ$f"0 Y7@T<V[x 6! \Ch*A : 18x6 ,|L>@ R!%R@[)x7އ^8P{БPV- 1JY 11^Jd `  %LA N8Acfp $g / 7߈/#z=>0EeP C&V2 8 *B@$Q/᠎H +2t_O<* XS1(T_+1aMI`'As! %0.[R <^2-=4 $F p_Hr5gDb%&!{  'eAܡBhw@jo8d`Ќ5NB'7 !' P;D@&V@5z !u}y/J# !10Xlq?0&CV( /7,(@b`0f@e P *PY>C "Q6`e, *44l1W` Փ?p|<` $% fҜJsf~upT}'e\SK SA78m Pb!Pw7,x 0 <[2nU,݈E t$.&s/1,t,@"\D9XBT z#乓=/%K!Eh (1Jl$1E#&HO%dB:A&@ du8A!#H $%)$/u i|BDia&iZĹȲf |. P P`93"H <_0 U<#E(]dNJ b.\&@{X]@nR)Pt@WU~9@)WAbp+:ܢ.XΑ;I!X A_@BAp [ ܀@ăX!"EnBWj݈8LCN ,X" &+0VHK܈A > ob4B8r )LpCH8@' A@u_J<x Fqoͭ%*U,  <@y"Q\ |eɴpSL!7   /B ?/ @( 5 ~ 7 V-C&WEc49Ef r2gL?r|2 a  7'xD-CF #M$>%;YVE] M I jcymU>2it<.Yb}PД2:6oǴA]ϑP ob!'. }@@CmP&Dg0nҶ %8`-utfX64 c;3c#Cj3sC,Ã+6#c;0EmcP p48 b2"?fA4H83.JHVD1` f6Bf j͢W($J6 >" B(`B,4P̓0L+㸒J;EfKؠ4,$46erT 7 õo?, c 3[# (<|FS20Z.zc@8 e(%₅R@&8 95+4f7185k.AʂV qf%Ӑ $Y$ːXfZ͑"BQDINB Y"L[$N @:e7@_zv P+0 $!(Wp T0Pek VX8@]+OcKL$543"IR6 ,8 |9" # %H #%&~ |`F mP Upc Ҩf(E:UYP\jdxޔ2g~Up \@'>u!A!$ BDQ0npǚ[}ր \`E@G,  !x!1L(V!"hźg.xuqU@Q(0ba)B=Ơ2DA0TI7l9NX] PQ %ЅC;Lpa x@ uV% Xצ (C`-ap!~IFT߁ ^9 @v#'x $G2 ҠXn܇ XׯF9 wNW?ɩw)ʗD&d# 7`a+? 1W G3̙:d3,vCcڔ[6C;@hDoN/- MAVQBPAmg ʌ.s1@'0ތ0TCJ )|):#8&%+q,r)Oh QhNekR @%r!6V!o?!B&XM& H%FS6&pPg0g~$Yގ~r l0}K TV '9/Vrgd|J! ~%>@daP }n.!P.3D#イΖ=wMj!+c[,丶!k A2EQ K҇Qy.V Z&n e0WRu3{aVqVtG ݥ}`%CFPPXȗE':f r4SoTp.|`<\Kj߀ @_~b ڐ>S آ`>yj7 {vs i_ T"EӘDu hG+3FB pi P\`׈Z1`cg0 #OiqhapHi4K( G>~Nζs qh6(2jXǷ@nlwSL SMfiH4dǫ覷RC9J35;e)3 *3 4[ 9pƈB!:s‰f&aVlTn=@Phj3Q*@k !Kxd?D ޢIp B['̘)2ػJJKγA sW#! ! Hӑ -r1AEpӆ!!&g6P"1 PO`"'Z\Q.C@#spMR+  sH )j0/1]OHi:OS)E-95gD2!P[w\ Ax!L>4 /#FCG uRv_ G1  Dj9`%1X`T s #ZCuFb_Ypq[wLahvwA%A*F8qF/j qu +2XrFlұ(7&Z0W  FImLE-2/1#a4s,O/a-Qb: R:GQZi:uLI ua@`<&n UprKR?xBIê$&&do0)<@c)b^ab8JJ 4$K'4EL f pA )  BJ;/gLayʭ\42 NHb8) cƳ :J.Oa 2 $;䔶U"'LSP(hlỏ+A5wIB(X?bO0[]M (DFҬvDQA5 B~Q)fiP T89AeE_N; =/2hs@HG*[ %N'Ư騌$yH P T  B1Q+!Ln&%MPKB"6^9RL]D5bP";cQl!D৓R Q!#gx𹦘ULZ-U"؝ev>C>n/4Q~$< ԈQ3%[6՗2!Nu sԉjW(j1/-(u#_$p`Nv+4{ajI'H2@QlbP(| a`GՕL1oE@!;**93@!$y)G9i=tYZSѠ_dFP&Q I cJ쐯,0e+4#^ٰ <(C3 yaR2 nOd,4"~'̈/~Zf $AT-G -ߢv0" *M-Yd d,  * 6 KYҏ {@`~h s?z8H lC @Ld"ALIN 1! 02Q?, $ha@@n &"VH iiڣp(2 csf iI!ȯJ+ aZAvR4$6'F! @ugC(8:A .@$\J%CAAnyBOE;*e+O↾uJ>epQ s&(0">6%b0f?4,b-7*_pF~`0hk"t85A!0bw@Z a 6O pD- @8bK[wCt >]T/WSrKl  J`m?ai'߄a)}3ج +~.xxB# VPkJ% VKHp!U8'> ݠ1F ԵRtҲN 5 bU@ CU=@-Nf%>Q%/ 0Ui ]~]:eڈD" hʨaIXP&'n:e5#5s- 2DAsV8]v:Q|.f$KEa%n†/`R&: BKU"5 3wH_b^fNEH[ 3!$>fV/VLڴ6$ȏ% B8btQ ݀fcRn* ]cpϷf 0+<& ##/"o[CH,cbk\blQJ۳Sd #1Zl kdd&͛25E'"WhY7\X$zNJD0!/ NlZPFP}L)0^ j1 `Ì&$~i#y2jhF2sAћSlqaj%!?>$G"6vN9N`ী4Y`iqe8?%.vQs݁%;eomDRL:.&82/7INsI}vju6 Haf"+FEPI$%04+D+v_i@iaɅ!@uyum1E=5<,-f9UU<XV]21`!i1!!-<IT Fː!UrqchmQ15UG-=`Ե))0Q4bwP'`pS8HSGanY ŵ 7 Fː!Urqsrs/www/images/yellow_paper.gif o-Eպ(R"/PT*K動%Ul#G,=zz=j]hz *ԭ]*Zt֯H)yǒeʪbH)S EkY.\.V/0s 3(sJ2̵օR. &#<52#xa1-z-}ՍBJ/6$\%8/ JqŻ-c#\/E]4#GpETh\* QbDHA $"ᱰh-ud!!I.3"F D$D`_`"l j.a PA q CfXt)r/ =O]/~ITl(L_\0*G$4gDN dQk1{aʐ3!. w(`pd)`zvCPxf0 Щ)!w ?D1;eJQ0|Q]C\C +0ޫMj P{ߕ0Ct]84-$;tac˂p_cX 2aoe# P69PEde202X#Sد) QȏYYWW׿Xzi dPCP/^("@$^O;XGVA=H"V gdHEXV{p^??A@h#VY4 {a]&~<sENKd&e 4t0>q G- @J R 7RV'v B~  touY A "-d f3e O F؁ 2(̐ b 1+{ r'0JD ` jS *d"~!-ς%  H0= T‡Q P  V A x P Hm ڠ d @1* kp:8Lp0huD>Ft Z g fME x&eDP p b=z"` p x ̀ PjGb3B ~V8@VX6ZQ%R` T!(-J@ X{ & = | I X ldV ˀfP~:P]C&V۵Sc NA P@F^ar @,p PSSTp1a [6!0AcyVE&*'MlUo @J\ 0 EQ E` ( <է饬ڐ xYUIH)QȀ 2MH(j4# ~50-ǔЇ:rLcy~%d U!=;RHW,R2ok& ܨ 8T +Z l  : _0 /'Db0 2 1pB+&C B6 Q;2i[8B 1=`gHx!,I$AV e `P4p< O6 & 5Qo| U k` Z5 ,Xhx p 2\( ;]ayh Ⱥ ı xB R  ? pa?u ʠ X́NG3k =P t/s; {[rF  Qᴟ`ҪT 8 | $=)<[WE¾0F{'YkT( 0Լ@ of ptьY _~ܗ1g T6PqHo 7t|w =ʠ  1 @ {bfY }h o c .ZZM J[cy-ʗ` pXhmhE ( 0*n ` pt;}ѭ@NЩy QD0 b> `c1ٰ 8! [b4A^mvР軲P1Ϡ p)X8⺟/o{w  `9 0 ~@ ! hId}7 t0P!@  5J.ѝ, ~=[` (R3m.`Mcχb05뵞 P +  V8Ves `Ă^{ B`"Ԝ`DP DU Za?G- z ׭fJ/*=-/|ڵKWϛ{ T_P *?V0PxW[zJ%i="IRhpU^VjW\B:eJTMtAʧ\OٙIUI)_V)N$Zq!GS(`p94VTڀx-]̅ WBk >Rfӧ_NB"ATbUݻyEr8㠱ē1SR$"|!3@3E,* I"%\*2C@1]rqZTFrѸ[r*2T&Q|SD %\䬐 nRT0rUw#f$qp$ S ]OPQX#Q] Ko\)R^1MO#< @"Ib؃ph#RV/>`W<*H#A[8/BQ)y{H +0&qBD+Mʃ/3d ^؉OTPd؅`RH[PClSx0EQ> SPN؄p+e`XG0 PH@TH\p GTЃG@ hkCd i==EVSG`]jL^[bdHV kUkHBkIDHN0f4d^^4݅X)EȆ700އ ͦJ>yJCۦIЃFhPj/Qhv2SXP@ Obi 2Qp(B+.0+5 h ړt=B =Ѓ' /]@Bժ RaIR=dIDRֶ*Z%/]:ryj%|,Q%K~LzJY.^%ĕ-;PIXHT$- ɔHz%I*+)GBuKUflSlW:T]>% Ujש -"׮RD-S*REiÉC/\Z|bN 0JXP/>b˷/^esc꪿|ji;"A*$IL n)F╋gpy굋)qa 0(!r BJCGI% {iZGm4 /Ė m-Ƌ- *"8*L)"2xP/2)U2$NRIDS *' rK$,P@praaOAz /P`- 2ؘ $`&I*JZRVz{i%gKt2J#8+0L3 .`( ( ) ]T%2 }PS8Bz0(hU|  **v=q p* p\$ h,ml 3 KJTH83أ0M.H)@$BI q dBE.FC0E(F Ç(N+A0e!PFN_F^ T7bc0 $0eP B3Ѐ^< ȚFv >)LCXuvRrD#DAme#Phc((„Jebh%+,(K"(@>xT[EAA.! 0(TBpלV,:ZRa[0%ZJH<jй<l<?41 QE|_&f%2a $CE(@rQR$!?IyT٨O~b `3iI%CJ/0Lt h g()l6\T=(sPI"-( Uf"lgO(10"kR仐0>Pa lVC$Rx`-p.r=T"8ZYh@*dQTF1ۉ )ld"ِ."+_BiQx=^'[I 8QX{Ft@\E)2_B!"P H )BH?schf3g셲kGp{6x!Dt)H Q0.lq Z6M$hLZv&!vQ+0;g-!HH|Zy^ *xl) xqd7-8ZPHb}+ D`-Bi b--4/v !٨*_y8jN"4Ce1&~]VbϺ3%D$ ڐ>Lo6# Hv~p/p *0B)H?IW2(3`+ uz$aI)Mi\T00M%P_=' i@M/`.$6A 65@0$6y)d$LF`H$/ $ &EE(LMHä†p gB" @T# 106B f8$)l)002A/AADXH%M*4y/"d.'$IVyG!6(TIp`l#Ē:e 9{e|B( -I RC Y䘘՝!ɯG%Df!C"(ZbB$,YDBt*M0C(_"EĀ VђI[xЃ%ȥE^hB qZ@hF2܊Z* / !xZ3X 塂Mt1\ ~pۣ?H-qtUQBwo0Z*>PQ PE3_'ROI ĻPAw NPlnTt ]) Tۥ2x hqS"/&u@㰹 9dDJѭCNI%$Z#X!p!~hA)Lv!jBǤG pHal8D&`( B8*榊A@A qX' %BdJRH,PA\8ʎ4j nM>  @nVdLa JH^faB!._İ:6!Vflad.%bBra k!2PQTl013fm:菒lخ1 c%eN KjP(A8:VrasqvAB~.Mmn320V~rl!6)WO, vISY- !PrRqF?!XGH, `l1>A.P .PEp3q  s*fWDSVTݯ!naaPV!~>ZaV  s 2 d-KJ!J*Q4|dA")}pWK"K~5 .X 04 /'/o%.0M^S5LMbJ)xE$xHG$"R%z3Ήb'4&ڕK/&V_*i .K-8)!I~"ʔW)L*20 -d) $c.,czI( u3k˅3d.r.pL6b R,5%F*+Y"%횡`t($RR%`)-41#$8R#DY-L2J)K* }1f)Š[)lP KdL2\_r`~54Ê%I~Fb %"$y! " ZHe,J'bqy{a9Js8b\s ͈RJ)H#ԢKru SD`(B [`b^FxPe Д79OtQ I" $c.,czI( usrs/www/images/yellow_rock.gif TXS h0*|M&EhQ D!̚-p8_bD$ܮZ)i/tڮ^33o.Sl%뢄a59$i"ܫ Lj1 W4P!d+Wg2*1)$Yq=vQI ʹKQjx"S#W 3d#SXf3$@MQpE;u6B# d=# 'Qi5O0U_VR) -xlp$Y <0VHAP[ \W&3(p"ΌdZXA 6p*dbc*PLD/Vq(`M -*@pp! F)`ʌpk#@6ФDJ:ra$ !6H Ixa)[ZmİNڸ&#qu #lo@ @!]X !@!oqk, &c P$Lly<Lb09n:ҝA<>2Rr]A+?qÙ`Џ5!"@TĠɲMj$@~#jbzCJe%`l (5{( T;`. u! .[gO =D A63?L9Df ĘIǣz8`vY@[q`Y-ȉΨV=ۮ_oA Jؚm J} mDM,XiBAxg?'`Xt90jtļ1 !! rfj 6g kڼE$,pNFa?3GřKP4TFJ>x ŒhDb ue2Axt Q 6a G%K1'n#?FC=(T k.1tH `(i'rjo&Qe`8P  w0ĔCćcFTMBG[c"'>/_0<`W& .GFjh q$dô2A PaCgJ ?be:"cQD-6DR#u0t{ slbϐ1n*Mtc>G=(Ia!+Dz42JMӒHW Z#Dw #r,Wnv x=pn AfC]&-Wejz ?uD} 2 b3g0 8<9 +ŔFv!' Vz$ Pfb3dХ]T gU@n":4P gF08'(JPs`ް; @EN73$OƐPsmGVA,9aU3b s!j-`R6Q%4v'~.JO1038e{ӵ",x v+Qeb,ŚL#@d:O3(@0=F= " ): oV17.x4#)[a0n:xA"VU2$,y LFU2M3Ɨa'Z3mnW =,vk Z`M5dGq:4  90.`mI#p!1Wzs 57


        ;0ԢQ bH‡aH||9!g$:FC#C ԱaJ  I ET〇(npKP5bp$EPh11bQEd#q4~"w ,X l:VTKR6` 20 L*^ vS b\ACCUAPGGXBCTsWl}BH; DrG*c8y1?XuIM dn @fEa'IbV  lM1\Q=e( kY8`: c=4~4QD|Aq@c! iCi뱅7 ZՂmkV f2j su0xuϒ ^%, ԽE\G`V؆,Jg1L ygiMDăg$<\\ 2IKj')Z0-_*]abTiCP dV!T _(u\<)T XE|d\ mKD0TN a MlՉl !#SUڝoţyJTZ91 LѸ&Of`=X^4KJCe/Q4)^2⯧P^-rq$↉mZpжX*wMV@|.@\Vh5t ;\H~0I"a*J 8ɔOp>rxմmZ 9zsnm_LmpLټ l0 włJj^0m\MGCEVVcDDX*_{3Ӓ![e|CWm(D$r(.vp܈K*"Km_vDqq¢6 8c4vՈ𨙩)0JĶ, G4c/aR" J*lDP CͅvsM PKhq~MU/QΘ LѸ&Of`=X^4KJCe/Q4)^2⯧P^-rq$↉mZpжX*wMV@|.@\Vh5t ;\H~0I"a*J 8ɔOp>rxմmZ 9zsnm_LmpLټ l0 włJj^0m\MGCEVVcDDX*_{3Ӓ![e|CWm(D$r(.vp܈K*"Km_vDqq¢6 8c4vՈ𨙩)0JĶ, G4c/aR" J*lDP CͅvsMsrs/www/images/yellow_stucco.gif *1971"*370' %-!܏!.46&%l@ub#P@;Q"V L"'$R@a(D,$D`E.%XБ#P|p!P4lᢅ # .qcm-plA\G%封C 4 [+Fxpu |`pB($ω "u Bxh؜Za@DHO b %1,Z[80Z%yG^ &)`-$t 4B *P.} 5|Ne( sf%l0 )w C" :F$| /BTP@_$O[b?ifs 1`9'P}Q7 / >@ODb&m89V ' d\VH = NZ@\V-PӁ0Ж+G*O٬Ss@Hh$0_/}V j9AlAD,^ Qp_6!+`!4` )$`0"gԐ@X re |P@m Ϋ>qʾANAh ` Sp6@ĺ)HtbVTA$bft);Ӗ)bC!|JF™6@0 .w}x]1 l "D#4t"`zXi;T mb [vc1A% fDҁ{7 p{[I(ѐ <8 D3 +q @6 pZ=mAgq!`v/AV UiC4B"" V ?K."=S@FIn PA4%.J#K(YG?J(@?`:%Q&)@.|m"' 3s&r3 F0h  A p .u!g&) 4T9&yc\ ~aws  `"b[[܆ \~a&o*`0E Xvts>=@TFaF $e#Ÿ+8T k'1ߡ |80 Cp#p@9N]aNf1Rg=c5O" 4 9(gs es #;_:`=(  Am" e<@C)ڕ) Vp!a\GaDq?mm;* JB r ĕ& "\fxP ?-`('?m,w >!a,PƈA BO<kEQ{ Q`% .8 '+p8-?l@}`&CRl^C2E@`z AaQ&d[@< *rf"9 "!b4#/hf=w/` Z4X-p\8A'"@cm0E1(ޤ @\ P\7< }2<3 - idG 3J%jP|곺{w 9 xo#0N@h:t|(^;Ѯ&a8("$(-*!"+((.11''37*693"76( !"*030*%39, ҂UhƐ T hxl?.E0~dZGUGR"܂ \3|.άp6'.!D" R M &`w2#V5no_<;5R p e &@:v 䦋`odzLԄR Du8n}˸T~QNpy1PA\9P QHP9[b T P"`QD,c!)`竏rl1b'<. $P#lZ\2B dH3רY)r11P=I `*BY@1@A b d! r$D|` ` `dnDUt '^` =dd@uZƬϱ@:p <B9I{P@iAt6;@ aT -@o'0`a$ =uVY*pF( C0SrT5OR^EE9Jd B8#y" !O6. V&Feco *s>- @`QB^Q $|7&e+kC5 #M0b86#-`F2o._̀,}( tfd4V)Q]6  ` a?2^r q>Q5}$bS=09Cd, 5ZS<$!1X.J ) 3E> -s>Z ut,`j1v q9iPC }Ie>C7 9p %}+'{}9 b# peD0Yo1sNp ,n:aC FuǤuh !*Be'g0l$"1Nh_jH7#-# ,X}QV >`A°aDhC f40@ $%ʤ }FW4f s1 kt gCa⃫0K: `T$I4aaJ?0,YnB:-/ ?Vs8D`o1:W%%Mc _E9Iĕ a)3#10!+Cx͠g5dxcrCCQG#7:/%P/Qхrh  tkE 0!5%bg`ab)) uzֺޑmhYtA)J D8o!rD?a6RS=94Q4 q&@~@AP;AOy6'YC 8@$ %pl6Q)5KI#@% )t/P9%"݆- 'Xnv85 B&2L<2%.:R!093`:_X + 7X$'0,A+e'(Z) 3BZW 7 #btV\;mC!D#03SHȔ& 4j+ l ?L9ײ&b r>AOq0TR )gc1' X#PW:V!""Ơ-+0bn HH%p!$Ik7 psqj)7HC p~BG#%ttĢ '32pk<4  V2/Cr3-@Qн`;j; C$ҳ 5\;IZ4$. `Ԁ+" ްb?ct$,R/p-:=+I"gp)P'shR@@Q&0)FtY)2&B%Vgu uk5 *`Av4"T!}һ\rO#1"g('s[g)Қ9RI$P:@x $(,.0.'$%*+--*'"%+13+#!!%'*.-+%%%""(0430*31$#-.+*(+.%"3==3$&(0640&"!(6<˓'+(""*00,-/*=6( (+!,  F4Ԫl Ph$ 2h7I'TU*"7lhQ'6`!CG4jC =@+`XP7xXq@8"w$@0AhβӨ3r3E}'`pєbV$B'%j7fh6ք0z A&@D .EaщM 8o EZ-}!&H9TY4ch8o.Å/6aRWTĘiE vb I-}`X$PxIBxtC( -0 704!s:FRHO*cu 23F8B9iUatner$3*hm(O ;ApLde##UkGrDm1yN4Q)B!Z/p3AS}!,2`|Lb h<xbUa#z" ;-RД<3s K= Nݔ"3D748he!Vi("PAOI}dLA9R}N Hp !VO"A֥G# v`GD,pdQ3,JwH pbhpր)r&0R!ucG,).o6#&K\c (@ k V;"گ$H30@ NHGRcǏĘARI Bl>CQ!6CuTE'U w"1htxdjiC Wuw`= &/pBLRxe1F")67A"&  hy<߲ y6xG,X0 N:d(i"/2&ءz rdbL':myc #2wu:`/XQy@lVF# +!]C]05[!A w:30$#[e 'KC98" "T$kyaLV9) i7iE6+5@OpXul0!(b F;O@yѶPӱ'ۀ+r  sϝŃh-IB !h!E1U1Q&3;ئ䄑O*߹32lKх..8s8KT[Jv?q 0G2XZs{۔0ra<1[Q`otdGtd/`G&&NNV?`c"DQw8luؘcv  8ގռt䏲0u$cݣ5>O}|11R *7 ϱ)+nU&{:IiLpRznQ7 8Ҭ~vXa sғ\H`YHdj-6`=CN k8!BpepR['֒R|5p |8rxt nR $vD5N'x8f Wyy\CRY>VBtRp!ubImn|mE) 1!I˩DŽjDITHp' $ %\%Y:k빓H (D. H8H͛1IC#-M ׹EHntT4thSD߁CBƝSY QՁ FB\SɈ@QSFJMe EDd$S\3Br]ƃ8F͡LUwbΧ6Ł+ ##eYIKM hՃA ab) 6iCe&Q=GNfT &a(1dq/HH#gXQ"͉y1 ( 4C4R-aB`L/DRm4"<0mOjvMsD!d:q~챊T\hIHd&#`@hȡUA  Z䚉khBpxQ7^='AB!ABX D}W۠ >jS ¯6`,P_,Xŭ.greXb58f;6#"%W7+ H (e ȵD%Ճ$Z*#` D`xڷ.(&$.W)A1UP_~:{K~Q%cZh !463dS_I$B<E1]p"h[pA7 VTN2U)D:_0Ȫ&!85NŌ;6ٻ!6$Tٻ/liu]1AA} 5E9֜ Cb$ ,\B;g|rܗM~Q`,N[X ²|1))h]!D "ak0G6O"PeZODwĮ!DT@ Ae4ᜃ堉D7Q}o,Y"!ܫ]lD@LHA$TU,zD雤N*T 4DU B ;cT׿ em|^u[:`,Q ݈KBޅ E#}l‰Mha\uc1H`\(i€"8GA$D$kuĔ_ySv5H IɽR%JF,ul$U\\Ÿ}U ʉӲTjr1ODW~hT@8Iހ^ơX0Q"H% PيF]~[SU:ߞ8QV TVAhbJb)R dr,$.dF3XJ˨` D8'P IAFH˨ DA|8GpgH:b)ME-:YPǠ@ua!6WY@u#5F P@J'xd? Tq]j S@=O;ǂ yZ$p `m\@ٌ @ sؒNYXG5 )MW$]Q~ЃŃF"i EG0M/UhdOП8 >L _F9Z٥Ld3V& ȅB' ŵ4ޫ xTݖWzGT" HsJXa6 ͹P[HMP2C)>a#& 7j, |$̡<{f.u }R4 $c όB'8CTSgw݄ ~ Y'{J$hL_򓘰"}(lX6\hC(/݊OS@TH*afhްSk4[br: ;I\6哵 ˎڐ J&`),hs܇ ='JOr:F}*Ċp_xEOس)=[ =m o AB~Z *F5Ju5eNURH-'" fL0-_\QLV.N~6eBZ!ނ<  _qZ謄HYM"BZrIy |fn!$NmӑÇVA``XJL\Zh`͟U[M *]ƢQl@Mp1F3†4R^$~T C/teHp4XdAF͸*zbXPNZ6jZ$DAš$R Б .