Next version of JABA
[jabaws.git] / binaries / src / fasta34 / lib_sel.c
1 /* copyright (c) 1996, 1997, 1998, 1999 William R. Pearson and the
2    U. of Virginia */
3
4 /* $Name: fa_34_26_5 $ - $Id: lib_sel.c,v 1.16 2006/12/06 17:30:52 wrp Exp $ */
5
6 /*      modified Dec 13, 1989 requires different FASTLIBS */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <math.h>
11 #include <ctype.h>
12 #include <string.h>
13
14 #include "defs.h"
15 #include "structs.h"
16
17 #ifdef NCBIBL13
18 #define LASTLIB NCBIBL13+1
19 #else
20 #define LASTLIB 11
21 #endif
22
23
24 int getlnames(char *tname, struct mngmsg *m_msg);
25 void addfile(char *, char *, struct mngmsg *);
26 void libchoice(char *lname, int nl, struct mngmsg *m_msg);
27 void libselect(char *lname, struct mngmsg *m_msg);
28 void subs_env(char *dest, char *src, int dest_size);
29 char *ulindex(char *str, char *chr);
30
31 static char ldname[MAX_FN];
32 static char *libenv;
33
34 int
35 getlnames(char *iname, struct mngmsg *m_msg)    /* read in the library names */
36 {
37   char *bp, tsave[MAX_STR], *tname;
38   char lline[MAX_FN], *llp;
39   FILE *tptr;
40
41   /* expand environment variables */
42   
43   tname = tsave;
44   subs_env(tname, iname, sizeof(tsave));
45
46   if (*tname != '@') {addfile(tname,"\0",m_msg); return 1;}
47   else tname++;
48
49   /* remove ' ' before deftype if present */
50   if ((bp=strchr(tname,' '))!=NULL) *bp='\0';
51
52   if ((tptr=fopen(tname,"r"))==NULL) {
53     fprintf(stderr," could not open file of names: %s\n",tname);
54     return 0;
55   }
56
57   while (fgets(lline,sizeof(lline),tptr)!=NULL) {
58     if (lline[0]==';') continue;
59     if ((bp=strchr(lline,'\n'))!=NULL) *bp='\0';
60     subs_env(tsave, lline, sizeof(tsave));
61     if (tsave[0]=='<') {
62       strncpy(ldname,&tsave[1],sizeof(ldname));
63       ldname[sizeof(ldname)-1]='\0';
64       libenv=ldname;
65     }
66     else addfile(tsave,libenv,m_msg);
67   }
68   fclose(tptr);
69   return 1;
70 }
71
72 /* libchoice displays a list of potential library files
73    in the new &lib& version, only traditional 1-letter files will be
74    shown initially
75 */
76
77 void
78 libchoice(char *lname, int nl, struct mngmsg *m_msg)
79 {
80   FILE *fch;
81   char line[MAX_STR], *bp;
82   char *chstr[MAX_CH],*chfile[MAX_CH];
83   char *chtmp, *charr;
84   int i,j,k,chlen;
85
86   charr = NULL;
87   if (strlen(m_msg->flstr)> (size_t)0) {
88     chlen = MAX_CH*MAX_FN;
89     if ((chtmp=charr=calloc((size_t)chlen,sizeof(char)))==NULL) {
90       fprintf(stderr,"cannot allocate choice file array\n");
91       goto l1;
92     }
93     chlen--;
94     if ((fch=fopen(m_msg->flstr,"r"))==NULL) {
95       fprintf(stderr," cannot open choice file: %s\n",m_msg->flstr);
96       goto l1;
97     }
98     fprintf(stderr,"\n Choose sequence library:\n\n");
99
100     for (i=j=0; j<MAX_CH; i++) {
101       if (fgets(line,sizeof(line),fch)==NULL) break;/* check for comment */
102       if (line[0]==';') continue;
103       if ((bp=strchr(line,'\n'))!=NULL) *bp='\0'; /* remove \n */
104       if ((bp=strchr(line,'$'))==NULL) continue;  /* if no '$', continue */
105       *bp++='\0';             /* replace $ with \0, bp points to libtype */
106
107       /* if libtypes don't match, continue */
108       if ((*bp++ -'0')!=m_msg->ldnaseq) continue;
109
110       /* if the library file name is too long, quit */
111       if ((k=strlen(line))>chlen) break;
112
113       /* save the library file name */
114       strncpy(chstr[j]=chtmp,line,chlen);
115       chtmp += k+1; chlen -= k+1;
116
117       if ((k=strlen(bp))>chlen) break;
118       strncpy(chfile[j]=chtmp,bp,chlen);
119       chtmp += k+1; chlen -= k+1;
120       fprintf(stderr,"    %c: %s\n",*chfile[j++],line);
121     }
122   l2:  fprintf(stderr,"\n Enter library filename (e.g. %s), letter (e.g. P)\n",
123                (m_msg->ldnaseq==0)? "prot.lib" : "dna.lib");
124     fprintf(stderr," or a %% followed by a list of letters (e.g. %%PN): ");
125     fflush(stderr);
126     if (fgets(line,sizeof(line),stdin)==NULL) exit(0);
127     if ((bp=strchr(line,'\n'))!=NULL) *bp='\0';
128     if (strlen(line)==0) goto l2;
129     strncpy(lname,line,nl);
130   }
131   else {
132   l1: fprintf(stderr," library file name: ");
133     fflush(stderr);
134     if (fgets(line,sizeof(line),stdin)==NULL) exit(0);
135     if ((bp=strchr(line,'\n'))!=NULL) *bp='\0';
136     if (strlen(line)> (size_t)0) strncpy(lname,line,nl);
137     else goto l1;
138   }
139   if (charr!=NULL) {
140     fclose(fch);
141     free(charr);
142   }
143 }
144
145 /* libselect parses the choices in char *lname and builds the list
146    of library files
147 */
148 void
149 libselect(char *lname, struct mngmsg *m_msg)
150 {
151   char line[MAX_FN*2], *bp, *bp1;
152   char *llnames[MAX_LF]; /* pointers into new list of names */
153   int new_abbr,ich, nch;          /* use new multi-letter abbr */
154   FILE *fch;
155
156   new_abbr = 0;
157   m_msg->nln = 0;
158   if (strlen(lname) > (size_t)1 && *lname != '%' && *lname != '+') {
159     getlnames(lname,m_msg); /* file name */ 
160     return;
161   }
162   else {
163     if (*m_msg->flstr=='\0') {
164       fprintf(stderr," abbrv. list request but FASTLIBS undefined, cannot use %s\n",lname);
165       exit(1);
166     }
167
168     if (strchr(lname,'+')) {
169       /* indicates list of database abbrevs (not files) */
170       new_abbr=1;
171       nch = 0;
172       bp = lname+1; if (*bp == '+') bp++;
173       for (bp1=bp; bp!=NULL && bp1!=NULL; bp=bp1+1) {
174         if ((bp1=strchr(bp,'+'))!=NULL) *bp1='\0';
175         llnames[nch++] = bp;
176       }
177     }
178     else if (*lname=='%') {     /* list of single letter abbreviations */
179       lname++;  /* bump over '%' to get letters */
180     }
181
182   /* else just use a single character abbreviation */
183
184   if (strlen(m_msg->flstr) > (size_t)0) {
185     if ((fch=fopen(m_msg->flstr,"r"))==NULL) {
186       fprintf(stderr," cannot open choice file: %s\n",m_msg->flstr);
187       return;
188     }
189   }
190   else {
191     fprintf(stderr," FASTLIBS undefined\n");
192     addfile(lname,"\0",m_msg);
193     return;
194   }
195
196   /* read each line of FASTLIBS */
197     while (fgets(line,sizeof(line),fch)!=NULL) { 
198       if (line[0]==';') continue;       /* skip comments */
199       if ((bp=strchr(line,'\n'))!=NULL) *bp='\0';       /* remove '\n' */
200       if ((bp=strchr(line,'$'))==NULL) continue; /* no delim, continue */
201       *bp++='\0';       /* point to library type */
202       if ((*bp++ -'0')!=m_msg->ldnaseq) continue; /* doesn't match, continue */
203
204       /* if !new_abbr, match on one letter with ulindex() */
205       if (!new_abbr) {
206         if (*bp=='+') continue; /* not a &lib& */
207         else if (ulindex(lname,bp)!=NULL) { 
208           strncpy(m_msg->ltitle,line,MAX_FN);
209           getlnames(bp+1,m_msg);
210         }
211       }
212       else {
213         if (*bp!='+') continue;
214         else {
215           bp++;
216           if ((bp1 = strchr(bp,'+'))!=NULL) {
217             *bp1='\0';
218             for (ich = 0; ich<nch; ich++) {
219               if (strcmp(llnames[ich],bp)==0) {
220                 strncpy(m_msg->ltitle,line,MAX_FN);
221                 getlnames(bp1+1,m_msg);
222                 break;
223               }
224             }
225             *bp1='+';
226           }
227           else fprintf(stderr,"%s missing final '+'\n",bp);
228         }
229       }
230     }
231     fclose(fch);
232   }
233 }
234
235 void
236 addfile(char *fname, char *env, struct mngmsg *m_msg)
237 {
238   char tname[MAX_STR], *bp, *bp1;
239   char *lbptr;
240   int len, lenv, l_size;
241
242   /*  check for default directory for files  */
243   if (env != NULL && *env != '\0') lenv = strlen(env)+1;
244   else lenv = 0;
245
246   len=strlen(fname)+1+lenv;
247
248   if (lenv > 1 && *fname != '#') {      /* add default directory to file name */
249     strncpy(tname,env,sizeof(tname)-1);
250 #ifdef UNIX
251     strcat(tname,"/");
252 #endif
253     }
254   else tname[0]='\0';
255
256   /* add fname to tname, allocate space, and move to space */
257   strncat(tname,fname,sizeof(tname)-strlen(tname)-1);
258   len=strlen(tname)+1;
259   if ((lbptr=calloc(len,sizeof(char)))==NULL) {
260     fprintf(stderr,"no more space for filenames: %s ignored\n",fname);
261     return;
262   }
263   else {
264     strncpy(lbptr,tname,len);
265     lbptr[len-1]='\0';
266   }
267
268   if (m_msg->nln< MAX_LF) {
269     m_msg->lbnames[m_msg->nln++]=lbptr;
270   }
271   else fprintf(stderr," no more file name slots: %s ignored\n",lbptr);
272 }
273
274 char *
275 ulindex(char *str, char *chr)
276 {
277   char c;
278  
279   c = tolower((int)(*chr));
280
281   while (*str != '\0' && tolower(*str) !=c ) str++;
282   if (*str=='\0') return NULL;
283   else return str;
284 }