1 /* taxcs.c
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * File Name: taxcs.c
27 *
28 * Author: Vladimir Soussov
29 *
30 * File Description: taxonomy server/client common utilities
31 *
32 *
33 * $Log: taxcs.c,v $
34 * Revision 1.3 1998/09/01 15:41:39 soussov
35 * removing warnings
36 *
37 * Revision 1.2 1998/04/01 17:34:06 soussov
38 * changed tp include <>
39 *
40 * Revision 1.1 1998/02/10 20:11:59 soussov
41 * taxon2 related soft
42 *
43 * Revision 1.2 1997/05/12 18:32:33 soussov
44 * 05/12/97
45 *
46 * Revision 1.1.1.1 1997/04/30 21:29:41 soussov
47 * initial tree for taxon2
48 *
49 *
50 */
51
52 #include <time.h>
53 #include <stdlib.h>
54 #include <txcommon.h>
55
56 /*
57 typedef struct t_nameClass {
58 Int2 priority;
59 char class_txt[34];
60 } TaxNameClass, PNTR TaxNameClassPtr;
61 */
62 static Int2 class_alloced= 16;
63 static TaxNameClassPtr name_class= NULL;
64
tax_getBaseTime(void)65 Int4 tax_getBaseTime(void)
66 {
67 static Int4 basetime= 0;
68 static Boolean baseTime_set= FALSE;
69
70 if(!baseTime_set) {
71 Int4 yy, vv, dd= 0;
72 time_t t= 0;
73
74 vv= gmtime(&t)->tm_year;
75
76 if(vv > 0) {
77 for(yy= 1900; yy < (1900 + vv); yy++) {
78 if(yy%4 == 0) dd+= 366;
79 else dd+= 365;
80 }
81
82 dd--;
83
84 basetime= (dd*24)*60;
85 }
86 baseTime_set= TRUE;
87
88 }
89
90 return basetime;
91 }
92
tax_prntTime(Int4 t)93 CharPtr tax_prntTime(Int4 t)
94 {
95 time_t ttt= (t - tax_getBaseTime())* 60;
96
97 return asctime(localtime(&ttt));
98 }
99
tax_getTime(void)100 Int4 tax_getTime(void)
101 {
102 time_t ttt= time(NULL);
103 Int4 t= ttt/60 + tax_getBaseTime();
104 return t;
105 }
106
tax_addNameClass(Int4 class_cde,CharPtr class_txt,Int4 priority)107 Boolean tax_addNameClass(Int4 class_cde, CharPtr class_txt, Int4 priority)
108 {
109 Int2 i;
110
111 if(name_class == NULL) {
112 name_class= MemNew(sizeof(TaxNameClass)*class_alloced);
113 if(name_class == NULL) return FALSE;
114
115 for(i= 0; i < class_alloced; i++) {
116 name_class[i].priority= 1000;
117 name_class[i].class_txt[0]= name_class[i].class_txt[33]= '\0';
118 }
119 }
120
121 if(class_cde < 0) return FALSE;
122
123 if(class_cde >= class_alloced) {
124 TaxNameClassPtr tmp= MemMore(name_class, sizeof(TaxNameClass)*(class_cde + 8));
125
126 if(tmp == NULL) return FALSE;
127
128 name_class= tmp;
129 for(i= class_alloced; i < class_cde + 8; i++) {
130 name_class[i].priority= 1000;
131 name_class[i].class_txt[0]= name_class[i].class_txt[33]= '\0';
132 }
133 class_alloced= class_cde + 8;
134 }
135
136 name_class[class_cde].priority= priority;
137 StringNCpy(name_class[class_cde].class_txt, class_txt, 33);
138
139 return TRUE;
140 }
141
tax_getNameClass(Int4 class_cde,Int4Ptr priority)142 CharPtr tax_getNameClass(Int4 class_cde, Int4Ptr priority)
143 {
144 if((class_cde < 0) || (class_cde >= class_alloced)) {
145 if(priority != NULL) *priority= 1000;
146 return "";
147 }
148
149 if(priority != NULL) *priority= name_class[class_cde].priority;
150 return name_class[class_cde].class_txt;
151 }
152
tax_getClass_cde(CharPtr class_txt)153 Int4 tax_getClass_cde(CharPtr class_txt)
154 {
155 Int2 i;
156
157 if(class_txt == NULL) return -1;
158
159 for(i= 0; i < class_alloced; i++) {
160 if(StringICmp(name_class[i].class_txt, class_txt) == 0) return (Int4)i;
161 }
162
163 return -1;
164 }
165
tax_dumpNameClasses(void (* dmpFunc)(VoidPtr,Int2,Int2,CharPtr),VoidPtr usrData)166 Boolean tax_dumpNameClasses(void (*dmpFunc)(VoidPtr, Int2, Int2, CharPtr), VoidPtr usrData)
167 {
168 Int2 i;
169
170 if((name_class == NULL) || (dmpFunc == NULL)) return FALSE;
171
172 for(i= 0; i < class_alloced; i++) {
173 if(name_class[i].class_txt[0] != '\0') {
174 (*dmpFunc)(usrData, i, name_class[i].priority, name_class[i].class_txt);
175 }
176 }
177 return TRUE;
178 }
179
180 /*
181 typedef struct t_rank {
182 char rank_txt[64];
183 } TaxRank, PNTR TaxRankPtr;
184 */
185
186 static Int2 rank_alloced= 48, d_rank= 1;
187 static TaxRankPtr tax_rank= NULL;
188
tax_addRank(Int2 rank_id,CharPtr rank_txt)189 Boolean tax_addRank(Int2 rank_id, CharPtr rank_txt)
190 {
191 Int2 i;
192
193 rank_id+= d_rank;
194
195 if(tax_rank == NULL) {
196 tax_rank= MemNew(sizeof(TaxRank)*rank_alloced);
197 if(tax_rank == NULL) return FALSE;
198
199 for(i= 0; i < rank_alloced; i++) {
200 tax_rank[i].rank_txt[0]= tax_rank[i].rank_txt[63]= '\0';
201 }
202 }
203
204 if(rank_id < 0) return FALSE;
205
206 if(rank_id >= rank_alloced) {
207 TaxRankPtr tmp= MemMore(tax_rank, sizeof(TaxRank)*(rank_id + 8));
208
209 if(tmp == NULL) return FALSE;
210
211 tax_rank= tmp;
212 for(i= rank_alloced; i < rank_id + 8; i++) {
213 tax_rank[i].rank_txt[0]= tax_rank[i].rank_txt[63]= '\0';
214 }
215 rank_alloced= rank_id + 8;
216 }
217
218 StringNCpy(tax_rank[rank_id].rank_txt, rank_txt, 63);
219
220 return TRUE;
221 }
222
tax_getRank(Int2 rank_id)223 CharPtr tax_getRank(Int2 rank_id)
224 {
225 rank_id+= d_rank;
226
227 if((rank_id < 0) || (rank_id >= rank_alloced)) return "";
228
229 return tax_rank[rank_id].rank_txt;
230 }
231
tax_getRankId(CharPtr rank_txt)232 Int2 tax_getRankId(CharPtr rank_txt)
233 {
234 Int2 i;
235
236 if(rank_txt == NULL) return -d_rank;
237
238 for(i= 0; i < rank_alloced; i++) {
239 if(StringICmp(tax_rank[i].rank_txt, rank_txt) == 0) return i - d_rank;
240 }
241
242 return -d_rank;
243 }
244
245
tax_dumpRanks(void (* dmpFunc)(VoidPtr,Int2,CharPtr),VoidPtr usrData)246 Boolean tax_dumpRanks(void (*dmpFunc)(VoidPtr, Int2, CharPtr), VoidPtr usrData)
247 {
248 Int2 i;
249
250 if((tax_rank == NULL) || (dmpFunc == NULL)) return FALSE;
251
252 for(i= 0; i < rank_alloced; i++) {
253 if(tax_rank[i].rank_txt[0] != '\0') {
254 (*dmpFunc)(usrData, i - d_rank, tax_rank[i].rank_txt);
255 }
256 }
257 return TRUE;
258 }
259
260 /*
261 typedef struct t_division {
262 char div_cde[4];
263 char div_txt[64];
264 } TaxDivision, PNTR TaxDivisionPtr;
265 */
266
267 static Int2 div_alloced= 16;
268 static TaxDivisionPtr tax_div= NULL;
269
tax_addDivision(Int4 div_id,CharPtr div_cde,CharPtr div_txt)270 Boolean tax_addDivision(Int4 div_id, CharPtr div_cde, CharPtr div_txt)
271 {
272 Int2 i;
273
274 if(tax_div == NULL) {
275 tax_div= MemNew(sizeof(TaxDivision)*div_alloced);
276 if(tax_div == NULL) return FALSE;
277
278 for(i= 0; i < div_alloced; i++) {
279 tax_div[i].div_cde[0]= tax_div[i].div_cde[3]=
280 tax_div[i].div_txt[0]= tax_div[i].div_txt[63]= '\0';
281 }
282 }
283
284 if(div_id < 0) return FALSE;
285
286 if(div_id >= div_alloced) {
287 TaxDivisionPtr tmp= MemMore(tax_div, sizeof(TaxDivision)*(div_id + 8));
288
289 if(tmp == NULL) return FALSE;
290
291 tax_div= tmp;
292 for(i= div_alloced; i < div_id + 8; i++) {
293 tax_div[i].div_cde[0]= tax_div[i].div_cde[3]=
294 tax_div[i].div_txt[0]= tax_div[i].div_txt[63]= '\0';
295 }
296 div_alloced= div_id + 8;
297 }
298
299 StringNCpy(tax_div[div_id].div_cde, div_cde, 3);
300 StringNCpy(tax_div[div_id].div_txt, div_txt, 63);
301
302 return TRUE;
303 }
304
tax_getDivision(Int2 div_id,CharPtr * div_cde,CharPtr * div_txt)305 Boolean tax_getDivision(Int2 div_id, CharPtr* div_cde, CharPtr* div_txt)
306 {
307 if((div_id < 0) || (div_id >= div_alloced)) return FALSE;
308
309 if(div_cde != NULL) *div_cde= tax_div[div_id].div_cde;
310 if(div_txt != NULL) *div_txt= tax_div[div_id].div_txt;
311 return TRUE;
312 }
313
tax_getDivisionId(CharPtr div_cde,CharPtr div_txt)314 Int2 tax_getDivisionId(CharPtr div_cde, CharPtr div_txt)
315 {
316 Int2 i;
317
318 if(div_cde != NULL) {
319 for(i= 0; i < div_alloced; i++) {
320 if(StringICmp(tax_div[i].div_cde, div_cde) == 0) return i;
321 }
322 }
323
324 if(div_txt != NULL) {
325 for(i= 0; i < div_alloced; i++) {
326 if(StringICmp(tax_div[i].div_txt, div_txt) == 0) return i;
327 }
328 }
329
330 return -1;
331 }
332
tax_dumpDivisions(void (* dmpFunc)(VoidPtr,Int2,CharPtr,CharPtr),VoidPtr usrData)333 Boolean tax_dumpDivisions(void (*dmpFunc)(VoidPtr, Int2, CharPtr, CharPtr), VoidPtr usrData)
334 {
335 Int2 i;
336
337 if((tax_div == NULL) || (dmpFunc == NULL)) return FALSE;
338
339 for(i= 0; i < div_alloced; i++) {
340 if(tax_div[i].div_txt[0] != '\0') {
341 (*dmpFunc)(usrData, i, tax_div[i].div_cde, tax_div[i].div_txt);
342 }
343 }
344 return TRUE;
345 }
346
347 /*
348 typedef struct t_genCode {
349 char gc_name[128];
350 } TaxGenCode, PNTR TaxGenCodePtr;
351 */
352 static Int2 gc_alloced= 20;
353 static TaxGenCodePtr tax_gc= NULL;
354
tax_addGC(Int2 gc_id,CharPtr gc_txt)355 Boolean tax_addGC(Int2 gc_id, CharPtr gc_txt)
356 {
357 Int2 i;
358
359 if(tax_gc == NULL) {
360 tax_gc= MemNew(sizeof(TaxGenCode)*gc_alloced);
361 if(tax_gc == NULL) return FALSE;
362
363 for(i= 0; i < gc_alloced; i++) {
364 tax_gc[i].gc_name[0]= tax_gc[i].gc_name[127]= '\0';
365 }
366 }
367
368 if(gc_id < 0) return FALSE;
369
370 if(gc_id >= gc_alloced) {
371 TaxGenCodePtr tmp= MemMore(tax_gc, sizeof(TaxGenCode)*(gc_id + 8));
372
373 if(tmp == NULL) return FALSE;
374
375 tax_gc= tmp;
376 for(i= gc_alloced; i < gc_id + 8; i++) {
377 tax_gc[i].gc_name[0]= tax_gc[i].gc_name[127]= '\0';
378 }
379 gc_alloced= gc_id + 8;
380 }
381
382 StringNCpy(tax_gc[gc_id].gc_name, gc_txt, 127);
383
384 return TRUE;
385 }
386
tax_getGCName(Int2 gc_id)387 CharPtr tax_getGCName(Int2 gc_id)
388 {
389
390 if((gc_id < 0) || (gc_id >= gc_alloced)) return "";
391
392 return tax_gc[gc_id].gc_name;
393 }
394
tax_getGCId(CharPtr gc_txt)395 Int2 tax_getGCId(CharPtr gc_txt)
396 {
397 Int2 i;
398
399 if(gc_txt == NULL) return -1;
400
401 for(i= 0; i < gc_alloced; i++) {
402 if(StringICmp(tax_gc[i].gc_name, gc_txt) == 0) return i;
403 }
404
405 return -1;
406 }
407
tax_dumpGCs(void (* dmpFunc)(VoidPtr,Int2,CharPtr),VoidPtr usrData)408 Boolean tax_dumpGCs(void (*dmpFunc)(VoidPtr, Int2, CharPtr), VoidPtr usrData)
409 {
410 Int2 i;
411
412 if((tax_gc == NULL) || (dmpFunc == NULL)) return FALSE;
413
414 for(i= 0; i < gc_alloced; i++) {
415 if(tax_gc[i].gc_name[0] != '\0') {
416 (*dmpFunc)(usrData, i, tax_gc[i].gc_name);
417 }
418 }
419 return TRUE;
420 }
421
422
423 #ifdef TAX_LOG
424
425 #include <rex_util.h>
426
get_token(CharPtr str,CharPtr token)427 static CharPtr get_token(CharPtr str, CharPtr token)
428 {
429 int i;
430
431 token[2]= '\0';
432
433 while(IS_WHITESP(*str)) {
434 if(*str == '\0') return NULL;
435 ++str;
436 }
437
438 if(*str == '\0') return NULL;
439
440 for(i= 1; i < 250; i++) {
441 if(IS_WHITESP(*str)) {
442 token[i]= ' ';
443 token[i+1]= '\0';
444 return str;
445 }
446
447 if(*str == '\0') {
448 token[i]= ' ';
449 token[i+1]= '\0';
450 return NULL;
451 }
452
453 token[i]= TO_UPPER(*str);
454 str++;
455 }
456
457 token[i]= ' ';
458 token[i+1]= '*';
459 token[i+2]= '\0';
460 return str;
461 }
462
tax_matchName(CharPtr orgName,CharPtr str,Int4 mode)463 Boolean tax_matchName(CharPtr orgName, CharPtr str, Int4 mode)
464 {
465 if(StringICmp(orgName, str) == 0) return TRUE;
466
467 if(mode == TAX_RE_SEARCH) {
468 /* regular expression search */
469 char nBuff[256];
470 Int4 k;
471 rex_handler rh;
472 Boolean res;
473
474 strncpy(&nBuff[1], str, 250);
475 nBuff[0]= '@';
476 k= strlen(nBuff);
477 nBuff[k]= '@';
478 nBuff[k+1]= '\0';
479 rh= rex_setExpr(nBuff, REX_NO_CASE | REX_NO_SPACE);
480 if(rh == NULL) return 0;
481
482 nBuff[0]= '@';
483 for(k= 0; (k < 250) && (orgName[k] != '\0'); k++) {
484 nBuff[k+1]= toupper(orgName[k]);
485 }
486 k++;
487 nBuff[k]= '@';
488 nBuff[k+1]= '\0';
489
490 res= rex_cmp(rh, nBuff);
491
492 free(rh);
493 return res;
494 }
495
496 if(mode == TAX_TOKEN_SEARCH) {
497 char nBuff[256];
498 Int4 k;
499 rex_handler rh[16];
500 Int2 nof_rh, j, res;
501 CharPtr tail= str;
502
503 nBuff[0]= '*';
504 nBuff[1]= ' ';
505 for(nof_rh= 0; (nof_rh != 16) && (tail != NULL); nof_rh++) {
506 tail= get_token(tail, nBuff);
507 rh[nof_rh]= rex_setExpr(nBuff, REX_NO_CASE | REX_NO_SPACE);
508 if(rh[nof_rh] == NULL) nof_rh--;
509 }
510 if(nof_rh < 1) return FALSE;
511
512 nBuff[0]= ' ';
513
514 tail= orgName;
515 for(k= 0; (k < 250) && (tail[k] != '\0'); k++) {
516 nBuff[k+1]= toupper(tail[k]);
517 }
518 k++;
519 nBuff[k]= ' ';
520 nBuff[k+1]= '\0';
521
522 for(res= 1, j= 0; (j < nof_rh) && (res > 0); j++) {
523 res= rex_cmp(rh[j], nBuff);
524 }
525
526 for(j= 0; j < nof_rh; j++) {
527 free(rh[j]);
528 }
529 return (res != 0)? TRUE : FALSE;
530 }
531
532 return FALSE;
533 }
534 #endif
535