NCBI C Toolkit Cross Reference

C/access/ent2api.c


  1 /*   ent2api.c
  2 * ===========================================================================
  3 *
  4 *                            PUBLIC DOMAIN NOTICE
  5 *            National Center for Biotechnology Information (NCBI)
  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 do not place any restriction on its use or reproduction.
 13 *  We would, however, appreciate having the NCBI and the author cited in
 14 *  any work or product based on this material
 15 *
 16 *  Although all reasonable efforts have been taken to ensure the accuracy
 17 *  and reliability of the software and data, the NLM and the U.S.
 18 *  Government do not and cannot warrant the performance or results that
 19 *  may be obtained by using this software or data. The NLM and the U.S.
 20 *  Government disclaim all warranties, express or implied, including
 21 *  warranties of performance, merchantability or fitness for any particular
 22 *  purpose.
 23 *
 24 * ===========================================================================
 25 *
 26 * File Name:  ent2api.c
 27 *
 28 * Author:  Jonathan Kans
 29 *
 30 * Version Creation Date:   7/29/99
 31 *
 32 * $Revision: 1.117 $
 33 *
 34 * File Description: 
 35 *
 36 * Modifications:  
 37 * --------------------------------------------------------------------------
 38 *
 39 * ==========================================================================
 40 */
 41 
 42 #include <ent2api.h>
 43 #include <urlquery.h>
 44 #include <ncbithr.h>
 45 
 46 #ifdef OS_UNIX
 47 #include <sys/times.h>
 48 #include <limits.h>
 49 #endif
 50 
 51 #define ENTREZ_TOOL_PROPERTY "Entrez2Tool"
 52 #define ENTREZ_TOOL_VERSION 1
 53 
 54 /* utility functions */
 55 
 56 NLM_EXTERN void EntrezSetProgramName (
 57   const char* progname
 58 )
 59 
 60 {
 61   MemFree (GetAppProperty (ENTREZ_TOOL_PROPERTY));
 62   SetAppProperty (ENTREZ_TOOL_PROPERTY, (StringHasNoText (progname)
 63                                          ? NULL
 64                                          : StringSave (progname)));
 65 }
 66 
 67 static const char* EntrezGetProgramName (
 68   void
 69 )
 70 
 71 {
 72   char         path [PATH_MAX];
 73   const char*  ptr;
 74 
 75   ptr = (const char*) GetAppProperty (ENTREZ_TOOL_PROPERTY);
 76   if (StringHasNoText (ptr)) {
 77     Nlm_ProgramPath (path, sizeof (path));
 78     ptr = StringRChr (path, DIRDELIMCHR);
 79     if (ptr != NULL) {
 80       ptr++;
 81       EntrezSetProgramName (ptr);
 82       ptr = (const char*) GetAppProperty (ENTREZ_TOOL_PROPERTY);
 83     }
 84   }
 85   return ptr;
 86 }
 87 
 88 /* override service name */
 89 static const char*  e2_service = NULL;
 90 
 91 /* use EntrezTest to override default Entrez ncbi named service */
 92 
 93 NLM_EXTERN void EntrezSetService (
 94   const char* service
 95 )
 96 
 97 {
 98   MemFree ((void*) e2_service);
 99   e2_service = StringSaveNoNull (service);
100 }
101 
102 /* low-level connection functions */
103 
104 static const char* GetDbFromE2Request (Entrez2RequestPtr e2rq)
105 
106 {
107   Entrez2BooleanExpPtr   e2be;
108   Entrez2EvalBooleanPtr  e2eb;
109   Entrez2GetLinksPtr     e2gl;
110   Entrez2HierQueryPtr    e2hq;
111   Entrez2IdPtr           e2id;
112   Entrez2IdListPtr       e2il;
113   Entrez2TermPosPtr      e2tp;
114   Entrez2TermQueryPtr    e2tq;
115   ValNodePtr             vnp;
116 
117   if (e2rq == NULL) return NULL;
118 
119   vnp = e2rq->request;
120   if (vnp == NULL) return NULL;
121 
122   switch (vnp->choice) {
123     case E2Request_get_info :
124       break;
125     case E2Request_eval_boolean :
126       e2eb = (Entrez2EvalBooleanPtr) vnp->data.ptrvalue;
127       if (e2eb == NULL) return NULL;
128       e2be = e2eb->query;
129       if (e2be == NULL) return NULL;
130       if (StringDoesHaveText (e2be->db)) return e2be->db;
131       break;
132     case E2Request_get_docsum :
133       e2il = (Entrez2IdListPtr) vnp->data.ptrvalue;
134       if (e2il == NULL) return NULL;
135       if (StringDoesHaveText (e2il->db)) return e2il->db;
136       break;
137     case E2Request_get_term_pos :
138       e2tq = (Entrez2TermQueryPtr) vnp->data.ptrvalue;
139       if (e2tq == NULL) return NULL;
140       if (StringDoesHaveText (e2tq->db)) return e2tq->db;
141       break;
142     case E2Request_get_term_list :
143       e2tp = (Entrez2TermPosPtr) vnp->data.ptrvalue;
144       if (e2tp == NULL) return NULL;
145       if (StringDoesHaveText (e2tp->db)) return e2tp->db;
146       break;
147     case E2Request_get_term_hierarchy :
148       e2hq = (Entrez2HierQueryPtr) vnp->data.ptrvalue;
149       if (e2hq == NULL) return NULL;
150       if (StringDoesHaveText (e2hq->db)) return e2hq->db;
151       break;
152     case E2Request_get_links :
153       e2gl = (Entrez2GetLinksPtr) vnp->data.ptrvalue;
154       if (e2gl == NULL) return NULL;
155       e2il = (Entrez2IdListPtr) e2gl->uids;
156       if (e2il == NULL) return NULL;
157       if (StringDoesHaveText (e2il->db)) return e2il->db;
158       break;
159     case E2Request_get_linked :
160       e2gl = (Entrez2GetLinksPtr) vnp->data.ptrvalue;
161       if (e2gl == NULL) return NULL;
162       e2il = (Entrez2IdListPtr) e2gl->uids;
163       if (e2il == NULL) return NULL;
164       if (StringDoesHaveText (e2il->db)) return e2il->db;
165       break;
166     case E2Request_get_link_counts :
167       e2id = (Entrez2IdPtr) vnp->data.ptrvalue;
168       if (e2id == NULL) return NULL;
169       if (StringDoesHaveText (e2id->db)) return e2id->db;
170       break;
171     default :
172       break;
173   }
174 
175   return NULL;
176 }
177 
178 NLM_EXTERN CONN EntrezOpenConnection (
179   Entrez2RequestPtr e2rq
180 )
181 
182 {
183   char         arg [128];
184   const char*  db;
185 
186   db = GetDbFromE2Request (e2rq);
187   if (StringDoesHaveText (db) && StringLen (db) < 100) {
188     StrCpy (arg,    "DB=");
189     StrCpy (arg + 3, db);
190   } else
191     *arg = '\0';
192 
193   return QUERY_OpenServiceQueryEx
194     (StringHasNoText (e2_service) ? "Entrez2" : e2_service, NULL, 30, arg);
195 }
196 
197 #ifdef OS_MAC
198 #include <Events.h>
199 #endif
200 
201 NLM_EXTERN Entrez2ReplyPtr EntrezWaitForReply (
202   CONN conn
203 )
204 
205 {
206   AsnIoConnPtr     aicp;
207   time_t           currtime, starttime;
208   Entrez2ReplyPtr  e2ry = NULL;
209   time_t           max = 0;
210   EIO_Status       status;
211   STimeout         timeout;
212 #ifdef OS_MAC
213   EventRecord      currEvent;
214 #endif
215 
216   if (conn == NULL) return NULL;
217 
218 #ifdef OS_MAC
219   timeout.sec = 0;
220   timeout.usec = 0;
221 #else
222   timeout.sec = 100;
223   timeout.usec = 0;
224 #endif
225 
226   starttime = GetSecs ();
227   while ((status = CONN_Wait (conn, eIO_Read, &timeout)) == eIO_Timeout && max < 300) {
228     currtime = GetSecs ();
229     max = currtime - starttime;
230 #ifdef OS_MAC
231     WaitNextEvent (0, &currEvent, 0, NULL);
232 #endif
233   }
234   if (status == eIO_Success) {
235     aicp = QUERY_AsnIoConnOpen ("rb", conn);
236     e2ry = Entrez2ReplyAsnRead (aicp->aip, NULL);
237     QUERY_AsnIoConnClose (aicp);
238   }
239   CONN_Close (conn);
240 
241   return e2ry;
242 }
243 
244 /* ent2api silently maintains entrez2 server session cookie */
245 
246 static TNlmTls e2cookie_tls = NULL;
247 
248 /* high-level connection functions */
249 
250 NLM_EXTERN Entrez2ReplyPtr EntrezSynchronousQuery (
251   Entrez2RequestPtr e2rq
252 )
253 
254 {
255   AsnIoConnPtr     aicp;
256   CONN             conn;
257   char*            e2cookie = NULL;
258   Entrez2ReplyPtr  e2ry;
259   char*            tempcookie = NULL;
260 #ifdef OS_UNIX
261   Boolean          logtimes;
262   clock_t          starttime;
263   clock_t          stoptime;
264   struct tms       timebuf;
265 #endif
266 
267   if (e2rq == NULL) return NULL;
268 
269 #ifdef OS_UNIX
270   logtimes = (Boolean) ((getenv ("NCBI_LOG_SYNC_QUERY_TIMES")) != NULL);
271 #endif
272 
273   conn = EntrezOpenConnection (e2rq);
274 
275   if (conn == NULL) return NULL;
276 
277   aicp = QUERY_AsnIoConnOpen ("wb", conn);
278 
279   tempcookie = e2rq->cookie;
280   if (NlmTlsGetValue (e2cookie_tls, (VoidPtr PNTR) &e2cookie)) {
281     if (e2rq->cookie == NULL && e2cookie != NULL) {
282       e2rq->cookie = e2cookie;
283     }
284   }
285 
286   Entrez2RequestAsnWrite (e2rq, aicp->aip, NULL);
287 
288   e2rq->cookie = tempcookie;
289 
290   AsnIoFlush (aicp->aip);
291   QUERY_AsnIoConnClose (aicp);
292 
293   QUERY_SendQuery (conn);
294 
295 #ifdef OS_UNIX
296   if (logtimes) {
297     starttime = times (&timebuf);
298   }
299 #endif
300 
301   e2ry = EntrezWaitForReply (conn);
302 
303 #ifdef OS_UNIX
304   if (logtimes) {
305     stoptime = times (&timebuf);
306     printf ("EntrezWaitForReply %ld\n", (long) (stoptime - starttime));
307   }
308 #endif
309 
310   if (e2ry != NULL && e2ry->cookie != NULL) {
311     if (NlmTlsGetValue (e2cookie_tls, (VoidPtr PNTR) &e2cookie)) {
312       e2cookie = MemFree (e2cookie);
313       e2cookie = StringSave (e2ry->cookie);
314       NlmTlsSetValue (&e2cookie_tls, (VoidPtr PNTR) e2cookie, NULL);
315     }
316   }
317 
318   return e2ry;
319 }
320 
321 NLM_EXTERN Boolean EntrezAsynchronousQuery (
322   Entrez2RequestPtr e2rq,
323   QUEUE* queue,
324   QueryResultProc resultproc,
325   VoidPtr userdata
326 )
327 
328 {
329   AsnIoConnPtr  aicp;
330   CONN          conn;
331   char*         e2cookie = NULL;
332   char*         tempcookie = NULL;
333 
334   if (e2rq == NULL) return FALSE;
335 
336   conn = EntrezOpenConnection (e2rq);
337 
338   if (conn == NULL) return FALSE;
339 
340   aicp = QUERY_AsnIoConnOpen ("wb", conn);
341 
342   tempcookie = e2rq->cookie;
343   if (NlmTlsGetValue (e2cookie_tls, (VoidPtr PNTR) &e2cookie)) {
344     if (e2rq->cookie == NULL && e2cookie != NULL) {
345       e2rq->cookie = e2cookie;
346     }
347   }
348 
349   Entrez2RequestAsnWrite (e2rq, aicp->aip, NULL);
350 
351   e2rq->cookie = tempcookie;
352 
353   AsnIoFlush (aicp->aip);
354   QUERY_AsnIoConnClose (aicp);
355 
356   QUERY_SendQuery (conn);
357 
358   QUERY_AddToQueue (queue, conn, resultproc, userdata, TRUE);
359 
360   return TRUE;
361 }
362 
363 NLM_EXTERN Int4 EntrezCheckQueue (QUEUE* queue)
364 
365 {
366   return QUERY_CheckQueue (queue);
367 }
368 
369 NLM_EXTERN Entrez2ReplyPtr EntrezReadReply (
370   CONN conn,
371   EIO_Status status
372 )
373 
374 {
375   AsnIoConnPtr     aicp;
376   char*            e2cookie = NULL;
377   Entrez2ReplyPtr  e2ry = NULL;
378 
379   if (conn != NULL && status == eIO_Success) {
380     aicp = QUERY_AsnIoConnOpen ("rb", conn);
381     e2ry = Entrez2ReplyAsnRead (aicp->aip, NULL);
382     QUERY_AsnIoConnClose (aicp);
383   }
384 
385   if (e2ry != NULL && e2ry->cookie != NULL) {
386     if (NlmTlsGetValue (e2cookie_tls, (VoidPtr PNTR) &e2cookie)) {
387       e2cookie = MemFree (e2cookie);
388       e2cookie = StringSave (e2ry->cookie);
389       NlmTlsSetValue (&e2cookie_tls, (VoidPtr PNTR) e2cookie, NULL);
390     }
391   }
392 
393   return e2ry;
394 }
395 
396 /* request creation functions */
397 
398 static Entrez2RequestPtr CreateRequest (
399   Uint1 choice, Pointer data
400 )
401 
402 {
403   char*              e2cookie = NULL;
404   Entrez2RequestPtr  e2rq;
405   ValNodePtr         vnp;
406 
407   e2rq = Entrez2RequestNew ();
408   if (e2rq == NULL) return NULL;
409 
410   e2rq->version = ENTREZ_TOOL_VERSION;
411   e2rq->tool = StringSaveNoNull (EntrezGetProgramName ());
412 
413   vnp = ValNodeNew (NULL);
414   if (vnp == NULL) return NULL;
415   vnp->choice = choice;
416   vnp->data.ptrvalue = data;
417   vnp->next = NULL;
418 
419   e2rq->request = vnp;
420 
421   if (NlmTlsGetValue (e2cookie_tls, (VoidPtr PNTR) &e2cookie)) {
422     e2rq->cookie = StringSaveNoNull (e2cookie);
423   }
424 
425   return e2rq;
426 }
427 
428 /* history needs to be used for Boolean ids and key queries */
429 
430 NLM_EXTERN void EntrezSetUseHistoryFlag (
431   Entrez2RequestPtr e2rq
432 )
433 
434 {
435   if (e2rq == NULL) return;
436   e2rq->use_history = TRUE;
437 }
438 
439 NLM_EXTERN Entrez2IdListPtr EntrezCreateEntrezIdList (
440   const char* db,
441   Int4 uid,
442   Int4 num,
443   const Int4 uids[],
444   ByteStorePtr bs
445 )
446 
447 {
448   Entrez2IdListPtr  e2il;
449 
450   e2il = Entrez2IdListNew ();
451   if (e2il == NULL) return NULL;
452 
453   e2il->db = StringSaveNoNull (db);
454 
455   if (uid != 0 && uids == NULL) {
456     uids = &uid;
457     num = 1;
458   }
459 
460   if (uids != NULL && num > 0 && bs == NULL) {
461     bs = BSNew (4 * num);
462     if (bs == NULL) return NULL;
463     BSWrite (bs, (Uint4Ptr) uids, num * sizeof (Uint4));
464   }
465 
466   e2il->uids = (Pointer) bs;
467   e2il->num = BSLen (bs) / sizeof (Uint4);
468 
469   return e2il;
470 }
471 
472 NLM_EXTERN Entrez2RequestPtr EntrezCreateGetInfoRequest (
473   void
474 )
475 
476 {
477   return CreateRequest (E2Request_get_info, NULL);
478 }
479 
480 NLM_EXTERN Entrez2LimitsPtr EntrezCreateEntrezLimits (
481   Int4 begin_date,
482   Int4 end_date,
483   const char* type_date,
484   Int4 max_uids,
485   Int4 offset_uids
486 )
487 
488 {
489   Entrez2DtFilterPtr  e2df;
490   Entrez2LimitsPtr    e2lm;
491 
492   if (begin_date == 0 && end_date == 0 &&
493       StringHasNoText (type_date) &&
494       max_uids == 0 && offset_uids == 0) return NULL;
495 
496   e2lm = Entrez2LimitsNew ();
497   if (e2lm == NULL) return NULL;
498 
499   e2lm->max_UIDs = max_uids;
500   e2lm->offset_UIDs = offset_uids;
501 
502   if (begin_date == 0 && end_date == 0 &&
503       StringHasNoText (type_date)) return e2lm;
504 
505   e2df = Entrez2DtFilterNew ();
506   if (e2df == NULL) return NULL;
507 
508   e2df->begin_date = begin_date;
509   e2df->end_date = end_date;
510   e2df->type_date = StringSaveNoNull (type_date);
511 
512   e2lm->filter_date = e2df;
513 
514   return e2lm;
515 }
516 
517 NLM_EXTERN Entrez2RequestPtr EntrezCreateBooleanRequest (
518   Boolean return_uids,
519   Boolean return_parsed,
520   const char* db,
521   const char* query_string,
522   Int4 begin_date,
523   Int4 end_date,
524   const char* type_date,
525   Int4 max_uids,
526   Int4 offset_uids
527 )
528 
529 {
530   Entrez2BooleanExpPtr   e2be;
531   Entrez2EvalBooleanPtr  e2eb;
532   Entrez2RequestPtr      e2rq;
533 
534   e2be = Entrez2BooleanExpNew ();
535   if (e2be == NULL) return NULL;
536 
537   e2be->db = StringSaveNoNull (db);
538   e2be->limits = EntrezCreateEntrezLimits (begin_date, end_date,
539                                            type_date, max_uids, offset_uids);
540 
541   e2eb = Entrez2EvalBooleanNew ();
542   if (e2eb == NULL) return NULL;
543 
544   e2eb->return_UIDs = return_uids;
545   e2eb->return_parse = return_parsed;
546   e2eb->query = e2be;
547 
548   e2rq = CreateRequest (E2Request_eval_boolean, (Pointer) e2eb);
549   if (e2rq == NULL) return NULL;
550 
551   if (! StringHasNoText (query_string)) {
552     EntrezAddToBooleanRequest (e2rq, query_string, 0, NULL, NULL, NULL,
553                                0, 0, NULL, NULL, TRUE, TRUE);
554   }
555 
556   return e2rq;
557 }
558 
559 NLM_EXTERN void EntrezAddToBooleanRequest (
560   Entrez2RequestPtr e2rq,
561   const char* query_string,
562   Int4 op,
563   const char* field,
564   const char* term,
565   const char* key,
566   Int4 uid,
567   Int4 num,
568   const Int4 uids[],
569   ByteStorePtr bs,
570   Boolean do_not_explode,
571   Boolean do_not_translate
572 )
573 
574 {
575   Entrez2BooleanExpPtr   e2be;
576   Entrez2BooleanTermPtr  e2bt;
577   Entrez2EvalBooleanPtr  e2eb;
578   Entrez2IdListPtr       e2il;
579   ValNodePtr             vnp;
580 
581   if (e2rq == NULL) return;
582   vnp = e2rq->request;
583   if (vnp == NULL || vnp->choice != E2Request_eval_boolean) return;
584 
585   e2eb = (Entrez2EvalBooleanPtr) vnp->data.ptrvalue;
586   if (e2eb == NULL) return;
587 
588   e2be = e2eb->query;
589   if (e2be == NULL) return;
590 
591   if (! StringHasNoText (query_string)) {
592     ValNodeCopyStr (&(e2be->exp), Entrez2BooleanElement_str, query_string);
593 
594   } else if (op > 0) {
595     ValNodeAddInt (&(e2be->exp), Entrez2BooleanElement_op, op);
596 
597   } else if ((! StringHasNoText (field)) && (! StringHasNoText (term))) {
598     e2bt = Entrez2BooleanTermNew ();
599     if (e2bt == NULL) return;
600 
601     e2bt->field = StringSaveNoNull (field);
602     e2bt->term = StringSaveNoNull (term);
603     e2bt->do_not_explode = do_not_explode;
604     e2bt->do_not_translate = do_not_translate;
605 
606     ValNodeAddPointer (&(e2be->exp), Entrez2BooleanElement_term, (Pointer) e2bt);
607 
608   } else if (! StringHasNoText (key)) {
609     ValNodeCopyStr (&(e2be->exp), Entrez2BooleanElement_key, key);
610 
611   } else {
612 
613     e2il = EntrezCreateEntrezIdList (e2be->db, uid, num, uids, bs);
614     if (e2il == NULL) return;
615 
616     ValNodeAddPointer (&(e2be->exp), Entrez2BooleanElement_ids, (Pointer) e2il);
617   }
618 }
619 
620 NLM_EXTERN Entrez2RequestPtr EntrezCreateDocSumRequest (
621   const char* db,
622   Int4 uid,
623   Int4 num,
624   const Int4 uids[],
625   ByteStorePtr bs
626 )
627 
628 {
629   Entrez2IdListPtr  e2il;
630 
631   e2il = EntrezCreateEntrezIdList (db, uid, num, uids, bs);
632   if (e2il == NULL) return NULL;
633 
634   return CreateRequest (E2Request_get_docsum, (Pointer) e2il);
635 }
636 
637 NLM_EXTERN Entrez2RequestPtr EntrezCreateGetTermPositionRequest (
638   const char* db,
639   const char* field,
640   const char* term
641 )
642 
643 {
644   Entrez2TermQueryPtr  e2tq;
645 
646   e2tq = Entrez2TermQueryNew ();
647   if (e2tq == NULL) return NULL;
648   e2tq->db = StringSaveNoNull (db);
649   e2tq->field = StringSaveNoNull (field);
650   e2tq->term = StringSaveNoNull (term);
651 
652   return CreateRequest (E2Request_get_term_pos, (Pointer) e2tq);
653 }
654 
655 NLM_EXTERN Entrez2RequestPtr EntrezCreateGetTermListRequest (
656   const char* db,
657   const char* field,
658   Int4 first_term_pos,
659   Int4 num_terms
660 )
661 
662 {
663   Entrez2TermPosPtr  e2tp;
664 
665   e2tp = Entrez2TermPosNew ();
666   if (e2tp == NULL) return NULL;
667   e2tp->db = StringSaveNoNull (db);
668   e2tp->field = StringSaveNoNull (field);
669   e2tp->first_term_pos = first_term_pos;
670   e2tp->number_of_terms = num_terms;
671 
672   return CreateRequest (E2Request_get_term_list, (Pointer) e2tp);
673 }
674 
675 NLM_EXTERN Entrez2RequestPtr EntrezCreateGetTermHierarchyRequest (
676   const char* db,
677   const char* field,
678   const char* term,
679   Int4 txid
680 )
681 
682 {
683   Entrez2HierQueryPtr  e2hq;
684 
685   e2hq = Entrez2HierQueryNew ();
686   if (e2hq == NULL) return NULL;
687   e2hq->db = StringSaveNoNull (db);
688   e2hq->field = StringSaveNoNull (field);
689   e2hq->term = StringSaveNoNull (term);
690   e2hq->txid = txid;
691 
692   return CreateRequest (E2Request_get_term_hierarchy, (Pointer) e2hq);
693 }
694 
695 NLM_EXTERN Entrez2RequestPtr EntrezCreateGetLinksRequest (
696   const char* db,
697   Int4 uid,
698   Int4 num,
699   const Int4 uids[],
700   ByteStorePtr bs,
701   const char* linktype,
702   Int4 max_uids,
703   Boolean count_only,
704   Boolean parents_persist
705 )
706 
707 {
708   Entrez2GetLinksPtr  e2gl;
709   Entrez2IdListPtr    e2il;
710 
711   e2il = EntrezCreateEntrezIdList (db, uid, num, uids, bs);
712   if (e2il == NULL) return NULL;
713 
714   e2gl = Entrez2GetLinksNew ();
715   if (e2gl == NULL) return NULL;
716 
717   e2gl->uids = e2il;
718   e2gl->linktype = StringSaveNoNull (linktype);
719   e2gl->max_UIDS = max_uids;
720   e2gl->count_only = count_only;
721   e2gl->parents_persist = parents_persist;
722 
723   return CreateRequest (E2Request_get_links, (Pointer) e2gl);
724 }
725 
726 NLM_EXTERN Entrez2RequestPtr EntrezCreateGetLinkedRequest (
727   const char* db,
728   Int4 uid,
729   Int4 num,
730   const Int4 uids[],
731   ByteStorePtr bs,
732   const char* linktype,
733   Int4 max_uids,
734   Boolean count_only,
735   Boolean parents_persist
736 )
737 
738 {
739   Entrez2GetLinksPtr  e2gl;
740   Entrez2IdListPtr    e2il;
741 
742   e2il = EntrezCreateEntrezIdList (db, uid, num, uids, bs);
743   if (e2il == NULL) return NULL;
744 
745   e2gl = Entrez2GetLinksNew ();
746   if (e2gl == NULL) return NULL;
747 
748   e2gl->uids = e2il;
749   e2gl->linktype = StringSaveNoNull (linktype);
750   e2gl->max_UIDS = max_uids;
751   e2gl->count_only = count_only;
752   e2gl->parents_persist = parents_persist;
753 
754   return CreateRequest (E2Request_get_linked, (Pointer) e2gl);
755 }
756 
757 NLM_EXTERN Entrez2RequestPtr EntrezCreateGetLinkCountsRequest (
758   const char* db,
759   Int4 uid
760 )
761 
762 {
763   Entrez2IdPtr  e2id;
764 
765   e2id = Entrez2IdNew ();
766   if (e2id == NULL) return NULL;
767 
768   e2id->db = StringSaveNoNull (db);
769   e2id->uid = uid;
770 
771   return CreateRequest (E2Request_get_link_counts, (Pointer) e2id);
772 }
773 
774 /* reply extraction functions */
775 
776 static Pointer GeneralEntrezExtractReply (
777   Entrez2ReplyPtr e2ry,
778   Uint1 choice,
779   Int4Ptr termpos
780 )
781 
782 {
783   E2ReplyPtr  reply;
784   Pointer     result = NULL;
785 
786   if (e2ry == NULL) return NULL;
787   reply = e2ry->reply;
788   if (reply == NULL) return NULL;
789 
790   if (reply->choice == choice) {
791     if (termpos != NULL) {
792       *termpos = reply->data.intvalue;
793     } else {
794       result = (Pointer) reply->data.ptrvalue;
795       reply->data.ptrvalue = NULL;
796     }
797   }
798   Entrez2ReplyFree (e2ry);
799 
800   return result;
801 }
802 
803 NLM_EXTERN char* EntrezExtractErrorReply (
804   Entrez2ReplyPtr e2ry
805 )
806 
807 {
808   return (char*) GeneralEntrezExtractReply (e2ry, E2Reply_error, NULL);
809 }
810 
811 NLM_EXTERN Entrez2InfoPtr EntrezExtractInfoReply (
812   Entrez2ReplyPtr e2ry
813 )
814 
815 {
816   return (Entrez2InfoPtr) GeneralEntrezExtractReply (e2ry, E2Reply_get_info, NULL);
817 }
818 
819 NLM_EXTERN Entrez2BooleanReplyPtr EntrezExtractBooleanReply (
820   Entrez2ReplyPtr e2ry
821 )
822 
823 {
824   return (Entrez2BooleanReplyPtr) GeneralEntrezExtractReply (e2ry, E2Reply_eval_boolean, NULL);
825 }
826 
827 NLM_EXTERN Entrez2DocsumListPtr EntrezExtractDocsumReply (
828   Entrez2ReplyPtr e2ry
829 )
830 
831 {
832   return (Entrez2DocsumListPtr) GeneralEntrezExtractReply (e2ry, E2Reply_get_docsum, NULL);
833 }
834 
835 NLM_EXTERN Int4 EntrezExtractTermPosReply (
836   Entrez2ReplyPtr e2ry
837 )
838 
839 {
840   Int4  termpos = 0;
841 
842   GeneralEntrezExtractReply (e2ry, E2Reply_get_term_pos, &termpos);
843   return termpos;
844 }
845 
846 NLM_EXTERN Entrez2TermListPtr EntrezExtractTermListReply (
847   Entrez2ReplyPtr e2ry
848 )
849 
850 {
851   return (Entrez2TermListPtr) GeneralEntrezExtractReply (e2ry, E2Reply_get_term_list, NULL);
852 }
853 
854 NLM_EXTERN Entrez2HierNodePtr EntrezExtractHierNodeReply (
855   Entrez2ReplyPtr e2ry
856 )
857 
858 {
859   return (Entrez2HierNodePtr) GeneralEntrezExtractReply (e2ry, E2Reply_get_term_hierarchy, NULL);
860 }
861 
862 NLM_EXTERN Entrez2LinkSetPtr EntrezExtractLinksReply (
863   Entrez2ReplyPtr e2ry
864 )
865 
866 {
867   return (Entrez2LinkSetPtr) GeneralEntrezExtractReply (e2ry, E2Reply_get_links, NULL);
868 }
869 
870 NLM_EXTERN Entrez2IdListPtr EntrezExtractLinkedReply (
871   Entrez2ReplyPtr e2ry
872 )
873 
874 {
875   return (Entrez2IdListPtr) GeneralEntrezExtractReply (e2ry, E2Reply_get_linked, NULL);
876 }
877 NLM_EXTERN Entrez2LinkCountListPtr EntrezExtractLinkCountReply (
878   Entrez2ReplyPtr e2ry
879 )
880 
881 {
882   return (Entrez2LinkCountListPtr) GeneralEntrezExtractReply (e2ry, E2Reply_get_link_counts, NULL);
883 }
884 
885 /* special SeqIdString to UID convenience function */
886 
887 NLM_EXTERN Uint4 EntrezGetUIDforSeqIdString (
888   const char* db,
889   const char* seq_id_string
890 )
891 
892 {
893   char                    ch;
894   Entrez2BooleanReplyPtr  e2br;
895   Entrez2IdListPtr        e2id;
896   Entrez2RequestPtr       e2rq;
897   Entrez2ReplyPtr         e2ry;
898   char*                   ptr;
899   char                    str [61];
900   Uint4                   uid = 0;
901 
902   if (StringHasNoText (db) || StringHasNoText (seq_id_string)) return 0;
903 
904   StringNCpy_0 (str, seq_id_string, sizeof (str) - 1);
905   ptr = str;
906   ch = *ptr;
907   while (ch != '\0') {
908     if (ch == '|' || ch == '.') {
909       *ptr = ' ';
910     }
911     ptr++;
912     ch = *ptr;
913   }
914   TrimSpacesAroundString (str);
915   if (StringStr (str, "[SQID]") == NULL) {
916     StringCat (str, " [SQID]");
917   }
918 
919   e2rq = EntrezCreateBooleanRequest (TRUE, FALSE, db, str,
920                                      0, 0, NULL, 1, 0);
921   if (e2rq == NULL) return 0;
922   e2ry = EntrezSynchronousQuery (e2rq);
923   e2rq = Entrez2RequestFree (e2rq);
924   if (e2ry == NULL) return 0;
925   e2br = EntrezExtractBooleanReply (e2ry);
926   if (e2br == NULL) return 0;
927 
928   if (e2br->count > 0) {
929     e2id = e2br->uids;
930     if (e2id != NULL && e2id->num > 0 && e2id->uids != NULL) {
931       BSSeek (e2id->uids, 0, SEEK_SET);
932       uid = Nlm_BSGetUint4 (e2id->uids);
933     }
934   }
935 
936   Entrez2BooleanReplyFree (e2br);
937 
938   return uid;
939 }
940 
941 /* result validation function */
942 
943 static int LIBCALLBACK SortVnpByStr (VoidPtr ptr1, VoidPtr ptr2)
944 
945 {
946   const char*  str1;
947   const char*  str2;
948   ValNodePtr   vnp1;
949   ValNodePtr   vnp2;
950 
951   if (ptr1 != NULL && ptr2 != NULL) {
952     vnp1 = *((ValNodePtr PNTR) ptr1);
953     vnp2 = *((ValNodePtr PNTR) ptr2);
954     if (vnp1 != NULL && vnp2 != NULL) {
955       str1 = (const char*) vnp1->data.ptrvalue;
956       str2 = (const char*) vnp2->data.ptrvalue;
957       if (str1 != NULL && str2 != NULL) {
958         return StringICmp (str1, str2);
959       }
960     }
961   }
962   return 0;
963 }
964 
965 NLM_EXTERN Boolean ValidateEntrez2InfoPtrEx (
966   Entrez2InfoPtr e2ip,
967   ValNodePtr PNTR head,
968   Boolean checkMenuNameVariants
969 )
970 
971 {
972   Char                       buf [128];
973   Char                       ch;
974   CharPtr                    db;
975   Int2                       dbcount;
976   CharPtr                    dbnames [256];
977   CharPtr                    dsf;
978   Int2                       dsfcount;
979   Entrez2DbInfoPtr           e2db;
980   Entrez2DocsumFieldInfoPtr  e2dsp;
981   Entrez2FieldInfoPtr        e2fip;
982   Entrez2LinkInfoPtr         e2lip;
983   CharPtr                    fld;
984   Int2                       fldcount;
985   Boolean                    hasLowCase;
986   Int2                       i;
987   CharPtr                    last;
988   ValNodePtr                 lastvnp;
989   size_t                     len1;
990   size_t                     len2;
991   CharPtr                    lnk;
992   Int2                       lnkcount;
993   ValNodePtr                 menuhead = NULL;
994   Boolean                    notAlphNum;
995   Boolean                    rsult = TRUE;
996   CharPtr                    str;
997   Char                       tmpdb [32];
998   Char                       tmpdsf [32];
999   Char                       tmpfld [32];
1000   Char                       tmplnk [32];
1001   ValNodePtr                 vnp;
1002 
1003   if (head != NULL) {
1004     *head = NULL;
1005   }
1006   if (e2ip == NULL) return FALSE;
1007 
1008   if (e2ip->db_count < 1 || e2ip->db_info == NULL) {
1009     sprintf (buf, "Entrez2 has no databases");
1010     ValNodeCopyStr (head, 0, buf);
1011     return FALSE;
1012   }
1013 
1014   for (i = 0; i < sizeof (dbnames) / sizeof (CharPtr); i++) {
1015     dbnames [i] = "?";
1016   }
1017   i = 0;
1018   for (e2db = e2ip->db_info; e2db != NULL; e2db = e2db->next) {
1019     i++;
1020     if (! StringHasNoText (e2db->db_name)) {
1021       dbnames [i] = e2db->db_name;
1022     } else if (! StringHasNoText (e2db->db_menu)) {
1023       dbnames [i] = e2db->db_menu;
1024     }
1025   }
1026 
1027   dbcount = 0;
1028   for (e2db = e2ip->db_info; e2db != NULL; e2db = e2db->next) {
1029     dbcount++;
1030 
1031     db = e2db->db_name;
1032     if (StringHasNoText (db)) {
1033       rsult = FALSE;
1034       if (StringHasNoText (e2db->db_menu)) {
1035         sprintf (tmpdb, "%d", (int) dbcount);
1036         db = tmpdb;
1037         sprintf (buf, "Database %d has no name", (int) dbcount);
1038         ValNodeCopyStr (head, 0, buf);
1039       } else {
1040         db = e2db->db_menu;
1041         sprintf (buf, "Database %s (%d) has no name", db, (int) dbcount);
1042         ValNodeCopyStr (head, 0, buf);
1043       }
1044     }
1045 
1046     if (StringHasNoText (e2db->db_menu)) {
1047       sprintf (buf, "Database %s has no menu name", db);
1048       ValNodeCopyStr (head, 0, buf);
1049       rsult = FALSE;
1050     }
1051     if (StringHasNoText (e2db->db_descr)) {
1052       sprintf (buf, "Database %s has no description", db);
1053       ValNodeCopyStr (head, 0, buf);
1054       rsult = FALSE;
1055     }
1056 
1057     if (e2db->doc_count < 1) {
1058       if (StringICmp (db, "Nucleotide") == 0) {
1059         /* now a virtual database consolidating NucCore, NucEst, NucGss */
1060       } else {
1061         sprintf (buf, "Database %s has no documents", db);
1062         ValNodeCopyStr (head, 0, buf);
1063         rsult = FALSE;
1064       }
1065     }
1066     if (e2db->field_count < 1 || e2db->fields == NULL) {
1067       sprintf (buf, "Database %s has no fields", db);
1068       ValNodeCopyStr (head, 0, buf);
1069       rsult = FALSE;
1070     }
1071     if (e2db->link_count < 1 || e2db->links == NULL) {
1072       if (StringICmp (db, "books") != 0 &&
1073           StringICmp (db, "gap") != 0 &&
1074           StringICmp (db, "gensat") != 0 &&
1075           StringICmp (db, "mesh") != 0 &&
1076           StringICmp (db, "ncbisearch") != 0 &&
1077           StringICmp (db, "nlmcatalog") != 0 &&
1078           StringICmp (db, "nucleotide") != 0 &&
1079           StringICmp (db, "nuccore") != 0 &&
1080           StringICmp (db, "nucgss") != 0 &&
1081           StringICmp (db, "nucest") != 0 &&
1082           StringICmp (db, "seqannot") != 0 &&
1083           StringICmp (db, "toolkit") != 0 &&
1084           StringICmp (db, "blastdbinfo") != 0 &&
1085           StringICmp (db, "virus") != 0) {
1086         sprintf (buf, "Database %s has no links", db);
1087         ValNodeCopyStr (head, 0, buf);
1088         rsult = FALSE;
1089       }
1090     }
1091     if (e2db->docsum_field_count < 1 || e2db->docsum_fields == NULL) {
1092       sprintf (buf, "Database %s has no docsum fields", db);
1093       ValNodeCopyStr (head, 0, buf);
1094       rsult = FALSE;
1095     }
1096 
1097     fldcount = 0;
1098     for (e2fip = e2db->fields; e2fip != NULL; e2fip = e2fip->next) {
1099       fldcount++;
1100 
1101       fld = e2fip->field_name;
1102       if (StringHasNoText (fld)) {
1103         rsult = FALSE;
1104         if (StringHasNoText (e2fip->field_menu)) {
1105           sprintf (tmpfld, "%d", (int) dbcount);
1106           fld = tmpfld;
1107           sprintf (buf, "Database %s field %d has no name", db, (int) fldcount);
1108           ValNodeCopyStr (head, 0, buf);
1109         } else {
1110           fld = e2fip->field_menu;
1111           sprintf (buf, "Database %s field %s (%d) has no name", db, fld, (int) fldcount);
1112           ValNodeCopyStr (head, 0, buf);
1113         }
1114       } else if (StringCmp (fld, "SLEN") == 0 ||
1115           StringCmp (fld, "MLWT") == 0 ||
1116           StringCmp (fld, "PMID") == 0 ||
1117           StringCmp (fld, "LLID") == 0 ||
1118           StringCmp (fld, "UID") == 0) {
1119         if (! e2fip->is_numerical) {
1120           sprintf (buf, "Database %s field %s does not have is_numerical set", db, fld);
1121           ValNodeCopyStr (head, 0, buf);
1122           rsult = FALSE;
1123         }
1124       } else if (StringCmp (fld, "TEXT") == 0) {
1125         sprintf (buf, "Database %s field %s should be WORD", db, fld);
1126         ValNodeCopyStr (head, 0, buf);
1127         rsult = FALSE;
1128       } else if (StringCmp (fld, "ORGN") == 0) {
1129         if (e2fip->term_count == 0) {
1130           if (StringICmp (db, "Nucleotide") == 0) {
1131             /* now a virtual database consolidating NucCore, NucEst, NucGss */
1132           } else {
1133             sprintf (buf, "Database %s field %s term count is 0", db, fld);
1134             ValNodeCopyStr (head, 0, buf);
1135             rsult = FALSE;
1136            }
1137        }
1138       }
1139       if (StringLen (fld) > 4) {
1140         sprintf (buf, "Database %s field %s name is > 4 characters long", db, fld);
1141         ValNodeCopyStr (head, 0, buf);
1142         rsult = FALSE;
1143       }
1144 
1145       hasLowCase = FALSE;
1146       notAlphNum = FALSE;
1147       str = fld;
1148       ch = *str;
1149       while (ch != '\0') {
1150         if (IS_LOWER (ch)) {
1151           hasLowCase = TRUE;
1152         } else if (! (IS_ALPHANUM (ch))) {
1153           notAlphNum = TRUE;
1154         }
1155         str++;
1156         ch = *str;
1157       }
1158       if (hasLowCase) {
1159         sprintf (buf, "Database %s field %s has lower case letters", db, fld);
1160         ValNodeCopyStr (head, 0, buf);
1161         rsult = FALSE;
1162       }
1163       if (notAlphNum) {
1164         sprintf (buf, "Database %s field %s has non-alphanumeric characters", db, fld);
1165         ValNodeCopyStr (head, 0, buf);
1166         rsult = FALSE;
1167       }
1168 
1169       if (StringHasNoText (e2fip->field_menu)) {
1170         sprintf (buf, "Database %s field %s has no menu name", db, fld);
1171         ValNodeCopyStr (head, 0, buf);
1172         rsult = FALSE;
1173       } else {
1174         ValNodeCopyStr (&menuhead, (Int2) dbcount, e2fip->field_menu);
1175         if (StringStr (e2fip->field_menu, "Date") != NULL) {
1176           if (! e2fip->is_date) {
1177             sprintf (buf, "Database %s field %s does not have is_date set", db, fld);
1178             ValNodeCopyStr (head, 0, buf);
1179             rsult = FALSE;
1180           }
1181         } else if (StringICmp (e2fip->field_menu, "Mesh") == 0) {
1182           sprintf (buf, "Database %s field-menu %s should be MeSH Terms", db, e2fip->field_menu);
1183           ValNodeCopyStr (head, 0, buf);
1184           rsult = FALSE;
1185         }
1186       }
1187       if (StringHasNoText (e2fip->field_descr)) {
1188         sprintf (buf, "Database %s field %s has no description", db, fld);
1189         ValNodeCopyStr (head, 0, buf);
1190         rsult = FALSE;
1191       }
1192     }
1193     if (e2db->field_count != fldcount) {
1194       sprintf (buf, "Database %s field count %ld does not match fldcount %d", db, (long) e2db->field_count, (int) fldcount);
1195       ValNodeCopyStr (head, 0, buf);
1196       rsult = FALSE;
1197     }
1198 
1199     lnkcount = 0;
1200     for (e2lip = e2db->links; e2lip != NULL; e2lip = e2lip->next) {
1201       lnkcount++;
1202 
1203       lnk = e2lip->link_name;
1204       if (StringHasNoText (lnk)) {
1205         rsult = FALSE;
1206         if (StringHasNoText (e2lip->link_menu)) {
1207           sprintf (tmplnk, "%d", (int) lnkcount);
1208           lnk = tmplnk;
1209           sprintf (buf, "Database %s link %d has no name", db, (int) lnkcount);
1210           ValNodeCopyStr (head, 0, buf);
1211         } else {
1212           lnk = e2lip->link_menu;
1213           sprintf (buf, "Database %s link %s (%d) has no name", db, lnk, (int) lnkcount);
1214           ValNodeCopyStr (head, 0, buf);
1215         }
1216       }
1217 
1218       /*
1219       if (StringHasNoText (e2lip->link_menu)) {
1220         sprintf (buf, "Database %s link %s has no menu name", db, lnk);
1221         ValNodeCopyStr (head, 0, buf);
1222         rsult = FALSE;
1223       }
1224       */
1225       if (StringHasNoText (e2lip->link_descr)) {
1226         if (StringICmp (db, "nucest") == 0 && StringICmp (lnk, "nucest_gene_clust") == 0) {
1227         } else if (StringICmp (db, "gene") == 0 && StringICmp (lnk, "gene_nucest_clust") == 0) {
1228         } else {
1229           sprintf (buf, "Database %s link %s has no description", db, lnk);
1230           ValNodeCopyStr (head, 0, buf);
1231           rsult = FALSE;
1232         }
1233       }
1234       if (StringHasNoText (e2lip->db_to)) {
1235         sprintf (buf, "Database %s link %s has no target database", db, lnk);
1236         ValNodeCopyStr (head, 0, buf);
1237         rsult = FALSE;
1238       }
1239     }
1240     if (e2db->link_count != lnkcount) {
1241       sprintf (buf, "Database %s link count %ld does not match lnkcount %d", db, (long) e2db->link_count, (int) lnkcount);
1242       ValNodeCopyStr (head, 0, buf);
1243       rsult = FALSE;
1244     }
1245 
1246     dsfcount = 0;
1247     for (e2dsp = e2db->docsum_fields; e2dsp != NULL; e2dsp = e2dsp->next) {
1248       dsfcount++;
1249 
1250       dsf = e2dsp->field_name;
1251       if (StringHasNoText (dsf)) {
1252         rsult = FALSE;
1253         if (StringHasNoText (e2dsp->field_description)) {
1254           sprintf (tmpdsf, "%d", (int) dsfcount);
1255           dsf = tmpdsf;
1256           sprintf (buf, "Database %s link %d has no name", db, (int) dsfcount);
1257           ValNodeCopyStr (head, 0, buf);
1258         } else {
1259           dsf = e2dsp->field_description;
1260           sprintf (buf, "Database %s link %s (%d) has no name", db, dsf, (int) dsfcount);
1261           ValNodeCopyStr (head, 0, buf);
1262         }
1263       }
1264 
1265       if (StringHasNoText (e2dsp->field_description)) {
1266         sprintf (buf, "Database %s docsum %s has no description", db, dsf);
1267         ValNodeCopyStr (head, 0, buf);
1268         rsult = FALSE;
1269       }
1270       if (e2dsp->field_type < 0) {
1271         sprintf (buf, "Database %s docsum %s field type not indicated", db, dsf);
1272         ValNodeCopyStr (head, 0, buf);
1273         rsult = FALSE;
1274       }
1275 
1276     }
1277     if (e2db->docsum_field_count != dsfcount) {
1278       sprintf (buf, "Database %s docsum count %ld does not match lnkcount %d", db, (long) e2db->docsum_field_count, (int) dsfcount);
1279       ValNodeCopyStr (head, 0, buf);
1280       rsult = FALSE;
1281     }
1282   }
1283 
1284   if (e2ip->db_count != dbcount) {
1285     sprintf (buf, "Database count %ld does not match dbcount %d", (long) e2ip->db_count, (int) dbcount);
1286     ValNodeCopyStr (head, 0, buf);
1287     rsult = FALSE;
1288   }
1289 
1290   menuhead = ValNodeSort (menuhead, SortVnpByStr);
1291   last = NULL;
1292   lastvnp = NULL;
1293   for (vnp = menuhead; vnp != NULL; vnp = vnp->next) {
1294     str = (CharPtr) vnp->data.ptrvalue;
1295     if (StringHasNoText (str)) continue;
1296     if (last != NULL && lastvnp != NULL) {
1297       if (StringICmp (last, str) == 0 && StringCmp (last, str) != 0) {
1298         sprintf (buf, "Menu names %s [%s] and %s [%s] differ in capitalization", last, dbnames [lastvnp->choice], str, dbnames [vnp->choice]);
1299         ValNodeCopyStr (head, 0, buf);
1300         rsult = FALSE;
1301       } else if (checkMenuNameVariants) {
1302         len1 = StringLen (last);
1303         len2 = StringLen (str);
1304         if (len1 < len2) {
1305           if (StringNICmp (last, str, len1) == 0) {
1306             if (StringICmp (last, "Gene Map") == 0 && StringICmp (str, "Gene Map Disorder") == 0) {
1307             } else if (StringICmp (last, "Organism") == 0 && StringICmp (str, "Organism unsynonymized") == 0) {
1308             } else if (StringICmp (last, "Reference") == 0 && StringICmp (str, "Reference Author") == 0) {
1309             } else if (StringICmp (last, "Reference") == 0 && StringICmp (str, "Reference SNP ID") == 0) {
1310             } else if (StringICmp (last, "Title") == 0 && StringICmp (str, "Title/Abstract") == 0) {
1311             } else if (StringICmp (last, "Rank") == 0 && StringICmp (str, "Ranked standard deviation") == 0) {
1312             } else if (StringICmp (last, "Book") == 0 && StringICmp (str, "Book's Topic") == 0) {
1313             } else if (StringICmp (last, "Gene Name") == 0 && StringICmp (str, "Gene Name or Description") == 0) {
1314             } else if (StringICmp (last, "Submitter") == 0 && StringICmp (str, "Submitter Handle") == 0) {
1315             } else if (StringICmp (last, "Abstract") == 0 && StringICmp (str, "Abstract/Index Tags") == 0) {
1316             } else if (StringICmp (last, "Author") == 0 && StringICmp (str, "Author Full Name") == 0) {
1317             } else if (StringICmp (last, "Expression") == 0 && StringICmp (str, "Expression Level") == 0) {
1318             } else if (StringICmp (last, "Chromosome") == 0 && StringICmp (str, "Chromosome GI") == 0) {
1319             } else if (StringICmp (last, "Disease") == 0 && StringICmp (str, "Disease or phenotype") == 0) {
1320             } else if (StringICmp (last, "GC") == 0 && StringICmp (str, "GC Content") == 0) {
1321             } else if (StringICmp (last, "Organism") == 0 && StringICmp (str, "Organism Motility") == 0) {
1322             } else if (StringICmp (last, "Publisher") == 0 && StringICmp (str, "Publisher ID") == 0) {
1323             } else if (StringICmp (last, "Disease") == 0 && StringICmp (str, "Disease-Stage") == 0) {
1324             } else if (StringICmp (last, "ActiveAid") == 0 && StringICmp (str, "ActiveAidCount") == 0) {
1325             } else if (StringICmp (last, "InactiveAid") == 0 && StringICmp (str, "InactiveAidCount") == 0) {
1326             } else if (StringICmp (last, "Phenotype") == 0 && StringICmp (str, "Phenotype Ontology ID") == 0) {
1327             } else if (StringICmp (last, "Title") == 0 && StringICmp (str, "Title Abbreviation") == 0) {
1328             } else if (StringICmp (last, "Library") == 0 && StringICmp (str, "Library Class") == 0) {
1329             } else if (StringICmp (last, "Sequence") == 0 && StringICmp (str, "Sequence Count") == 0) {
1330             } else if (StringICmp (last, "Journal") == 0 && StringICmp (str, "Journal List Identifier") == 0) {
1331             } else if (StringICmp (last, "CompoundID") == 0 && StringICmp (str, "CompoundIDActive") == 0) {
1332             } else if (StringICmp (last, "MeSHDescription") == 0 && StringICmp (str, "MeSHDescriptionActive") == 0) {
1333             } else if (StringICmp (last, "MeSHTerm") == 0 && StringICmp (str, "MeSHTermActive") == 0) {
1334             } else if (StringICmp (last, "PharmAction") == 0 && StringICmp (str, "PharmActionActive") == 0) {
1335             } else if (StringICmp (last, "SubstanceID") == 0 && StringICmp (str, "SubstanceIDActive") == 0) {
1336             } else if (StringICmp (last, "Synonym") == 0 && StringICmp (str, "SynonymActive") == 0) {
1337             } else if (StringICmp (last, "Definition") == 0 && StringICmp (str, "Definition Type") == 0) {
1338             } else if (StringICmp (last, "Reference") == 0 && StringICmp (str, "Reference Amino Acid") == 0) {
1339             } else if (StringICmp (last, "Reference SNP") == 0 && StringICmp (str, "Reference SNP ID") == 0) {
1340             } else if (StringICmp (last, "Analysis") == 0 && StringICmp (str, "Analysis ID") == 0) {
1341             } else if (StringICmp (last, "Document") == 0 && StringICmp (str, "Document ID") == 0) {
1342             } else if (StringICmp (last, "Study") == 0 && StringICmp (str, "Study ID") == 0) {
1343             } else if (StringICmp (last, "Variable") == 0 && StringICmp (str, "Variable ID") == 0) {
1344             } else if (StringICmp (last, "COG") == 0 && StringICmp (str, "COG group") == 0) {
1345             } else if (StringICmp (last, "Locus Tag") == 0 && StringICmp (str, "Locus Tag Prefix") == 0) {
1346             } else if (StringICmp (last, "Attribute") == 0 && StringICmp (str, "Attributes") == 0) {
1347             } else if (StringICmp (last, "Genotype") == 0 && StringICmp (str, "Genotype Platform") == 0) {
1348             } else if (StringICmp (last, "Group") == 0 && StringICmp (str, "Group ID") == 0) {
1349             } else if (StringICmp (last, "Clinical Synopsis") == 0 && StringICmp (str, "Clinical Synopsis Date") == 0) {
1350             } else if (StringICmp (last, "Volume") == 0 && StringICmp (str, "Volume3D") == 0) {
1351             } else if (StringICmp (last, "InChI") == 0 && StringICmp (str, "InChIKey") == 0) {
1352             } else if (StringICmp (last, "Dataset") == 0 && StringICmp (str, "Dataset ID") == 0) {
1353             } else if (StringICmp (last, "Comment") == 0 && StringICmp (str, "Comments") == 0) {
1354             } else if (StringICmp (last, "SID") == 0 && StringICmp (str, "SidExternalID") == 0) {
1355             } else if (StringICmp (last, "Platform") == 0 && StringICmp (str, "Platform Reporter Type") == 0) {
1356             } else if (StringICmp (last, "Database") == 0 && StringICmp (str, "Database Name") == 0) {
1357             } else if (StringICmp (last, "Date") == 0 && StringICmp (str, "Date Discontinued") == 0) {
1358             } else {
1359               sprintf (buf, "Menu names %s [%s] and %s [%s] may be unintended variants", last, dbnames [lastvnp->choice], str, dbnames [vnp->choice]);
1360               ValNodeCopyStr (head, 0, buf);
1361               rsult = FALSE;
1362             }
1363           }
1364         }
1365       }
1366     } else if (StringICmp (str, "Title Word") == 0) {
1367       sprintf (buf, "Menu name Title Word should be replaced by Title");
1368       ValNodeCopyStr (head, 0, buf);
1369       rsult = FALSE;
1370     }
1371     last = str;
1372     lastvnp = vnp;
1373   }
1374   ValNodeFreeData (menuhead);
1375 
1376   return rsult;
1377 }
1378 
1379 
1380 NLM_EXTERN Boolean ValidateEntrez2InfoPtr (
1381   Entrez2InfoPtr e2ip,
1382   ValNodePtr PNTR head
1383 )
1384 
1385 {
1386   return ValidateEntrez2InfoPtrEx (e2ip, head, FALSE);
1387 }
1388 
1389 /* network connection test functions */
1390 
1391 static CONN NetTestOpenConnection (void)
1392 
1393 {
1394   char        buffer [64];
1395   CONN        conn;
1396   size_t      n_written;
1397   EIO_Status  status;
1398 
1399   conn = QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 80, "/Service/bounce.cgi",
1400                              NULL, "Entrez2Tool", 0, eMIME_T_Text,
1401                              eMIME_Plain, eENCOD_None, 0);
1402   if (conn == NULL) return NULL;
1403 
1404   sprintf (buffer, "test\n");
1405   buffer [4] = '\012';
1406   status = CONN_Write (conn, (const void *) buffer, StringLen (buffer),
1407                        &n_written, eIO_WritePersist);
1408   if (status != eIO_Success) {
1409     CONN_Close (conn);
1410     return NULL;
1411   }
1412 
1413   return conn;
1414 }
1415 
1416 NLM_EXTERN Boolean NetTestAsynchronousQuery (
1417   QUEUE* queue,
1418   QueryResultProc resultproc,
1419   VoidPtr userdata
1420 )
1421 
1422 {
1423   CONN  conn;
1424 
1425   conn = NetTestOpenConnection ();
1426 
1427   if (conn == NULL) return FALSE;
1428 
1429   QUERY_SendQuery (conn);
1430 
1431   QUERY_AddToQueue (queue, conn, resultproc, userdata, TRUE);
1432 
1433   return TRUE;
1434 }
1435 
1436 NLM_EXTERN Boolean NetTestReadReply (
1437   CONN conn,
1438   EIO_Status status
1439 )
1440 
1441 {
1442   char         buffer [64];
1443   size_t       n_read;
1444   ErrSev       oldsev;
1445   Boolean      res = FALSE;
1446 
1447   if (conn != NULL && status == eIO_Success) {
1448     oldsev = ErrSetMessageLevel (SEV_MAX);
1449     status = CONN_Read (conn, buffer, sizeof (buffer), &n_read, eIO_ReadPlain);
1450     if (status == eIO_Success) {
1451       if (StringNCmp (buffer, "test", 4) == 0) {
1452         res = TRUE;
1453       }
1454     }
1455     ErrSetMessageLevel (oldsev);
1456   }
1457   return res;
1458 }
1459 
1460 NLM_EXTERN Int4 NetTestCheckQueue (
1461   QUEUE* queue
1462 )
1463 
1464 {
1465   return QUERY_CheckQueue (queue);
1466 }
1467 
1468 

source navigation ]   [ diff markup ]   [ identifier search ]   [ freetext search ]   [ file search ]  

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.