1 /* @source ajobo **************************************************************
2 **
3 ** AJAX OBO handling functions
4 **
5 ** @author Copyright (C) 2010 Peter Rice
6 ** @version $Revision: 1.28 $
7 ** @modified May 5 pmr 2010 First AJAX version
8 ** @modified Sep 8 2010 pmr Added query and reading functions
9 ** @modified $Date: 2012/07/02 17:19:18 $ by $Author: rice $
10 ** @@
11 **
12 ** This library is free software; you can redistribute it and/or
13 ** modify it under the terms of the GNU Lesser General Public
14 ** License as published by the Free Software Foundation; either
15 ** version 2.1 of the License, or (at your option) any later version.
16 **
17 ** This library is distributed in the hope that it will be useful,
18 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20 ** Lesser General Public License for more details.
21 **
22 ** You should have received a copy of the GNU Lesser General Public
23 ** License along with this library; if not, write to the Free Software
24 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 ** MA  02110-1301,  USA.
26 **
27 ******************************************************************************/
28 
29 #include "ajlib.h"
30 
31 #include "ajobo.h"
32 #include "ajlist.h"
33 #include "ajoboread.h"
34 #include "ajobowrite.h"
35 
36 
37 static AjPStr oboTempQry = NULL;
38 
39 
40 static void oboMakeQry(const AjPObo thys, AjPStr* qry);
41 
42 
43 
44 
45 /* @filesection ajobo ********************************************************
46 **
47 ** @nam1rule aj Function belongs to the AJAX library.
48 **
49 ******************************************************************************/
50 
51 
52 
53 
54 
55 /* @datasection [AjPObo] Obo Term ********************************************
56 **
57 ** Function is for manipulating obo term objects
58 **
59 ** @nam2rule Obo Obo term objects
60 **
61 ******************************************************************************/
62 
63 
64 
65 
66 /* @section constructors ******************************************************
67 **
68 ** Constructors
69 **
70 ** @fdata [AjPObo]
71 **
72 ** @nam3rule New Constructor
73 ** @nam4rule NewObo Copy constructor
74 ** @nam3rule Parse Read from a file
75 ** @nam4rule Oboterm Read term
76 **
77 ** @argrule NewObo obo [const AjPObo] Source obo term object
78 ** @argrule Parse obobuff [AjPFilebuff] Input buffered file
79 **
80 ** @valrule * [AjPObo] Obo term object
81 **
82 ** @fcategory new
83 **
84 ******************************************************************************/
85 
86 
87 
88 
89 /* @func ajOboNew *************************************************************
90 **
91 ** Term constructor
92 **
93 ** @return [AjPObo] New object
94 **
95 ** @release 6.3.0
96 ** @@
97 ******************************************************************************/
98 
ajOboNew(void)99 AjPObo ajOboNew(void)
100 {
101     AjPObo ret;
102 
103     AJNEW0(ret);
104 
105     ret->Taglist = ajListNew();
106 
107     return ret;
108 }
109 
110 
111 
112 
113 /* @func ajOboNewObo **********************************************************
114 **
115 ** Term copy constructor
116 **
117 ** @param [r] obo [const AjPObo] Obo term
118 ** @return [AjPObo] New object
119 **
120 ** @release 6.4.0
121 ** @@
122 ******************************************************************************/
123 
ajOboNewObo(const AjPObo obo)124 AjPObo ajOboNewObo(const AjPObo obo)
125 {
126     AjPObo ret;
127     AjIList iter;
128     AjPObotag tag = NULL;
129     AjPOboxref xref = NULL;
130 
131     AJNEW0(ret);
132 
133     ret->Obsolete = obo->Obsolete;
134     ret->Builtin = obo->Builtin;
135     ret->Fpos = obo->Fpos;
136     ret->Format = obo->Format;
137 
138     if(obo->Id)
139         ret->Id = ajStrNewS(obo->Id);
140     if(obo->Trueid)
141         ret->Trueid = ajStrNewS(obo->Trueid);
142     if(obo->Fullid)
143         ret->Fullid = ajStrNewS(obo->Fullid);
144     if(obo->Name)
145         ret->Name = ajStrNewS(obo->Name);
146     if(obo->Namespace)
147         ret->Namespace = ajStrNewS(obo->Namespace);
148     if(obo->Def)
149         ret->Def = ajStrNewS(obo->Def);
150     if(obo->Comment)
151         ret->Comment = ajStrNewS(obo->Comment);
152     if(obo->Replaced)
153         ret->Replaced = ajStrNewS(obo->Replaced);
154     if(obo->Db)
155         ret->Db = ajStrNewS(obo->Db);
156     if(obo->Setdb)
157         ret->Setdb = ajStrNewS(obo->Setdb);
158     if(obo->Full)
159         ret->Full = ajStrNewS(obo->Full);
160     if(obo->Qry)
161         ret->Qry = ajStrNewS(obo->Qry);
162     if(obo->Formatstr)
163         ret->Formatstr = ajStrNewS(obo->Formatstr);
164     if(obo->Filename)
165         ret->Filename = ajStrNewS(obo->Filename);
166     if(obo->TextPtr)
167         ret->TextPtr = ajStrNewS(obo->TextPtr);
168 
169     if(obo->Taglist)
170     {
171         ret->Taglist = ajListNew();
172         iter = ajListIterNewread(obo->Taglist);
173         while(!ajListIterDone(iter))
174         {
175             tag = ajListIterGet(iter);
176             ajListPushAppend(ret->Taglist, ajObotagNewTag(tag));
177         }
178         ajListIterDel(&iter);
179     }
180 
181     if(obo->Dbxrefs)
182     {
183         ret->Dbxrefs = ajListNew();
184         iter = ajListIterNewread(obo->Dbxrefs);
185         while(!ajListIterDone(iter))
186         {
187             xref = ajListIterGet(iter);
188             ajListPushAppend(ret->Dbxrefs, ajOboxrefNewXref(xref));
189         }
190         ajListIterDel(&iter);
191     }
192 
193     return ret;
194 }
195 
196 
197 
198 
199 /* @section OBO term destructors **********************************************
200 **
201 ** Destruction destroys all internal data structures and frees the
202 ** memory allocated for the obo term object.
203 **
204 ** @fdata [AjPObo]
205 **
206 ** @nam3rule Del Destructor
207 **
208 ** @argrule Del Pobo [AjPObo*] Obo term
209 **
210 ** @valrule * [void]
211 **
212 ** @fcategory delete
213 **
214 ******************************************************************************/
215 
216 
217 
218 
219 /* @func ajOboDel *************************************************************
220 **
221 ** Term destructor
222 **
223 ** @param [d] Pobo       [AjPObo*]  Obo term object to delete
224 ** @return [void]
225 **
226 ** @release 6.4.0
227 ** @@
228 ******************************************************************************/
229 
ajOboDel(AjPObo * Pobo)230 void ajOboDel(AjPObo *Pobo)
231 {
232     AjPObo     term = NULL;
233     AjPObotag  tag  = NULL;
234     AjPOboxref xref = NULL;
235 
236     if(!Pobo) return;
237     if(!(*Pobo)) return;
238 
239     term = *Pobo;
240 
241     ajStrDel(&term->Id);
242     ajStrDel(&term->Trueid);
243     ajStrDel(&term->Fullid);
244     ajStrDel(&term->Name);
245     ajStrDel(&term->Namespace);
246     ajStrDel(&term->Def);
247     ajStrDel(&term->Comment);
248     ajStrDel(&term->Replaced);
249 
250     while(ajListPop(term->Dbxrefs, (void**) &xref))
251         ajOboxrefDel(&xref);
252 
253     while(ajListPop(term->Taglist, (void**) &tag))
254         ajObotagDel(&tag);
255 
256     ajListFree(&term->Taglist);
257 
258     ajStrDel(&term->Db);
259     ajStrDel(&term->Setdb);
260     ajStrDel(&term->Full);
261     ajStrDel(&term->Qry);
262     ajStrDel(&term->Formatstr);
263     ajStrDel(&term->Filename);
264     ajStrDel(&term->TextPtr);
265 
266     AJFREE(*Pobo);
267     *Pobo = NULL;
268 
269     return;
270 }
271 
272 
273 
274 
275 /* @section Casts *************************************************************
276 **
277 ** Return values from an obo term object
278 **
279 ** @fdata [AjPObo]
280 **
281 ** @nam3rule Get Return a value
282 ** @nam3rule Is Test a condition
283 ** @nam4rule Replaced Replacement id for an obsolete term
284 ** @nam4rule Db Source database name
285 ** @nam4rule Def Definition string
286 ** @nam4rule Entry Return entry text
287 ** @nam4rule Id Identifier string
288 ** @nam4rule Name Name
289 ** @nam4rule Namespace Namespace
290 ** @nam4rule Parents Return a list of parent ids
291 ** @nam4rule Qry Return a query field
292 ** @nam4rule Obsolete Term is flagged as obsolete
293 ** @nam4rule Tree List of terms below in hierarchy
294 ** @suffix C Character string result
295 ** @suffix S String object result
296 **
297 ** @argrule * obo [const AjPObo] Obo term object.
298 ** @argrule Def Pdefstr [AjPStr*] Returned definition string
299 ** @argrule Def nrefs [ajuint*] Number of dbxrefs after the definition
300 ** @argrule Parents uplist [AjPList] List of parent ids
301 ** @argrule Tree obolist [AjPList] Child obo terms
302 **
303 ** @valrule *GetParents [ajuint] Number of new ids appended to list
304 ** @valrule *GetTree [ajuint] Number of new terms in list
305 ** @valrule *GetDef     [AjBool] True on success
306 ** @valrule *IsObsolete [AjBool] True if obsolete
307 ** @valrule *GetReplaced [const AjPStr] Replacement identifier for an
308 **                                      obsolete term
309 ** @valrule *GetDb [const AjPStr] Database name
310 ** @valrule *GetEntry [const AjPStr] Entry full text
311 ** @valrule *GetId [const AjPStr] Identifier string
312 ** @valrule *GetName [const AjPStr] Name
313 ** @valrule *GetNamespace [const AjPStr] Namespace name
314 ** @valrule *C [const char*] Query as a character string.
315 ** @valrule *S [const AjPStr] Query as a string object.
316 **
317 ** @fcategory cast
318 **
319 ******************************************************************************/
320 
321 
322 
323 
324 /* @func ajOboGetDb ***********************************************************
325 **
326 ** Return the database name
327 **
328 ** @param [r] obo [const AjPObo] OBO term
329 **
330 ** @return [const AjPStr] Database name
331 **
332 **
333 ** @release 6.4.0
334 ******************************************************************************/
335 
ajOboGetDb(const AjPObo obo)336 const AjPStr ajOboGetDb(const AjPObo obo)
337 {
338     return obo->Db;
339 }
340 
341 
342 
343 
344 /* @func ajOboGetDef **********************************************************
345 **
346 ** Return the definition string and the number of dbxrefs
347 **
348 ** @param [r] obo [const AjPObo] OBO term
349 ** @param [w] Pdefstr [AjPStr*] Returned definition string
350 ** @param [w] nrefs [ajuint*] Number of dbxrefs after the definition
351 **
352 ** @return [AjBool] True on success.
353 **
354 **
355 ** @release 6.4.0
356 ******************************************************************************/
357 
ajOboGetDef(const AjPObo obo,AjPStr * Pdefstr,ajuint * nrefs)358 AjBool ajOboGetDef(const AjPObo obo, AjPStr *Pdefstr, ajuint *nrefs)
359 {
360     const char* cp;
361     ajuint i = 0;
362 
363     if(!obo) return ajFalse;
364 
365     cp = ajStrGetPtr(obo->Def);
366 
367     if(*cp == '"')
368     {
369         cp++;
370         i = 1;
371         while(*cp && *cp != '"')
372         {
373             i++;
374             cp++;
375         }
376         cp++;
377         ajStrAssignSubS(Pdefstr, obo->Def, 1, i);
378     }
379     else
380     {
381         i = 0;
382         while(*cp && *cp != '[')
383         {
384             i++;
385             cp++;
386         }
387         ajStrAssignSubS(Pdefstr, obo->Def, 0, i);
388     }
389 
390     while(*cp && *cp != '[')
391         cp++;
392 
393     *nrefs = 0;
394 
395     while (*cp)
396     {
397 
398     }
399 
400 
401     return ajTrue;
402 
403 }
404 
405 
406 
407 
408 /* @func ajOboGetEntry ********************************************************
409 **
410 ** Return the full text
411 **
412 ** @param [r] obo [const AjPObo] OBO term
413 **
414 ** @return [const AjPStr] Returned full text
415 **
416 **
417 ** @release 6.4.0
418 ******************************************************************************/
419 
ajOboGetEntry(const AjPObo obo)420 const AjPStr ajOboGetEntry(const AjPObo obo)
421 {
422     if(!obo)
423         return NULL;
424 
425     if(obo->TextPtr)
426         return obo->TextPtr;
427 
428     return ajStrConstEmpty();
429 }
430 
431 
432 
433 
434 /* @func ajOboGetId ***********************************************************
435 **
436 ** Return the identifier
437 **
438 ** @param [r] obo [const AjPObo] OBO term
439 **
440 ** @return [const AjPStr] Returned id
441 **
442 **
443 ** @release 6.4.0
444 ******************************************************************************/
445 
ajOboGetId(const AjPObo obo)446 const AjPStr ajOboGetId(const AjPObo obo)
447 {
448     if(!obo)
449         return NULL;
450 
451     return obo->Id;
452 }
453 
454 
455 
456 
457 /* @func ajOboGetName *********************************************************
458 **
459 ** Return the name
460 **
461 ** @param [r] obo [const AjPObo] OBO term
462 **
463 ** @return [const AjPStr] Returned name
464 **
465 **
466 ** @release 6.5.0
467 ******************************************************************************/
468 
ajOboGetName(const AjPObo obo)469 const AjPStr ajOboGetName(const AjPObo obo)
470 {
471     if(!obo)
472         return NULL;
473 
474     return obo->Name;
475 }
476 
477 
478 
479 
480 /* @func ajOboGetNamespace ****************************************************
481 **
482 ** Return the namespace name
483 **
484 ** @param [r] obo [const AjPObo] OBO term
485 **
486 ** @return [const AjPStr] Returned namespace
487 **
488 **
489 ** @release 6.4.0
490 ******************************************************************************/
491 
ajOboGetNamespace(const AjPObo obo)492 const AjPStr ajOboGetNamespace(const AjPObo obo)
493 {
494     if(!obo)
495         return NULL;
496 
497     return obo->Namespace;
498 }
499 
500 
501 
502 
503 /* @func ajOboGetParents ******************************************************
504 **
505 ** Return a list of all parent terms derived from is_a tags in the current
506 ** obo term
507 **
508 ** @param [r] obo [const AjPObo] OBO term
509 ** @param [u] uplist [AjPList] List of parent terms
510 **
511 ** @return [ajuint] Number of new terms added to list
512 **
513 **
514 ** @release 6.4.0
515 ******************************************************************************/
516 
ajOboGetParents(const AjPObo obo,AjPList uplist)517 ajuint ajOboGetParents(const AjPObo obo, AjPList uplist)
518 {
519     AjIList iter;
520     AjPObotag tag = NULL;
521     AjPStr up = NULL;
522     ajlong colpos = 0;
523 
524     ajulong oldlen;
525 
526     if(!obo)
527         return 0;
528 
529     oldlen = ajListGetLength(uplist);
530 
531     iter = ajListIterNewread(obo->Taglist);
532 
533     while(!ajListIterDone(iter))
534     {
535         tag = (AjPObotag) ajListIterGet(iter);
536 
537         if(!ajStrMatchC(tag->Name, "is_a"))
538             continue;
539 
540         colpos = 1 + ajStrFindAnyK(tag->Value, ':');
541         ajStrAssignSubS(&up, tag->Value, colpos, -1);
542 
543         ajListPushAppend(uplist, up);
544         up = NULL;
545     }
546 
547     if(obo->Obsolete && ajStrGetLen(obo->Replaced))
548     {
549         colpos = 1 + ajStrFindAnyK(obo->Replaced, ':');
550         ajStrAssignSubS(&up, obo->Replaced, colpos, -1);
551         ajDebug("ajOboGetParents obo id '%S' obsolete, consider '%S'\n",
552                 obo->Id, up);
553         ajListPushAppend(uplist, up);
554         up = NULL;
555     }
556 
557     ajListIterDel(&iter);
558 
559     return (ajuint) (ajListGetLength(uplist) - oldlen);
560 }
561 
562 
563 
564 
565 /* @func ajOboGetQryC *********************************************************
566 **
567 ** Returns the query string of an obo term.
568 ** Because this is a pointer to the real internal string
569 ** the caller must take care not to change the character string in any way.
570 ** If the string is to be changed (case for example) then it must first
571 ** be copied.
572 **
573 ** @param [r] obo [const AjPObo] Obo term object.
574 ** @return [const char*] Query as a character string.
575 **
576 ** @release 6.4.0
577 ** @@
578 ******************************************************************************/
579 
ajOboGetQryC(const AjPObo obo)580 const char* ajOboGetQryC(const AjPObo obo)
581 {
582     return MAJSTRGETPTR(ajOboGetQryS(obo));
583 }
584 
585 
586 
587 
588 /* @func ajOboGetQryS *********************************************************
589 **
590 ** Returns the query string of an obo term.
591 ** Because this is a pointer to the real internal string
592 ** the caller must take care not to change the character string in any way.
593 ** If the string is to be changed (case for example) then it must first
594 ** be copied.
595 **
596 ** @param [r] obo [const AjPObo] Obo term object.
597 ** @return [const AjPStr] Query as a string.
598 **
599 ** @release 6.4.0
600 ** @@
601 ******************************************************************************/
602 
ajOboGetQryS(const AjPObo obo)603 const AjPStr ajOboGetQryS(const AjPObo obo)
604 {
605     ajDebug("ajOboGetQryS '%S'\n", obo->Qry);
606 
607     if(ajStrGetLen(obo->Qry))
608 	return obo->Qry;
609 
610     oboMakeQry(obo, &oboTempQry);
611 
612     return oboTempQry;
613 }
614 
615 
616 
617 
618 /* @func ajOboGetReplaced *****************************************************
619 **
620 ** Return the recommended replacement for an obsolete term
621 **
622 ** @param [r] obo [const AjPObo] OBO term
623 **
624 ** @return [const AjPStr] Returned id
625 **
626 **
627 ** @release 6.4.0
628 ******************************************************************************/
629 
ajOboGetReplaced(const AjPObo obo)630 const AjPStr ajOboGetReplaced(const AjPObo obo)
631 {
632     return obo->Replaced;
633 }
634 
635 
636 
637 
638 /* @func ajOboGetTree *********************************************************
639 **
640 ** Return a list with all this term's descendants appended
641 **
642 ** @param [r] obo [const AjPObo] OBO term
643 ** @param [u] obolist [AjPList] List of obo terms
644 **
645 ** @return [ajuint] Number of terms returned
646 **
647 **
648 ** @release 6.4.0
649 ******************************************************************************/
650 
ajOboGetTree(const AjPObo obo,AjPList obolist)651 ajuint ajOboGetTree(const AjPObo obo, AjPList obolist)
652 {
653     AjPObo obonext = NULL;
654     AjPOboin oboin = NULL;
655     AjPStr oboqry = NULL;
656     static ajuint depth = 0;
657 
658     depth++;
659     oboin = ajOboinNew();
660     ajFmtPrintS(&oboqry, "%S-isa:%S", obo->Db, obo->Id);
661     ajOboinQryS(oboin, oboqry);
662 
663     if(ajStrGetLen(obo->TextPtr))
664         oboin->Input->Text = ajTrue;
665 
666     ajDebug("ajOboGetTree %u '%S'\n", depth, oboqry);
667     obonext = ajOboNew();
668     while(ajOboinRead(oboin, obonext))
669     {
670         ajDebug("ajOboGetTree push '%S'\n", obonext->Id);
671         ajListPushAppend(obolist, obonext);
672         ajOboGetTree(obonext, obolist);
673         obonext = ajOboNew();
674     }
675 
676     ajOboDel(&obonext);
677     ajOboinDel(&oboin);
678     ajStrDel(&oboqry);
679 
680     depth--;
681 
682     return (ajuint) ajListGetLength(obolist);
683 }
684 
685 
686 
687 
688 
689 /* @func ajOboIsObsolete ******************************************************
690 **
691 ** Test whether an obo term is obsolete
692 **
693 ** @param [r] obo [const AjPObo] OBO term
694 **
695 ** @return [AjBool] True if term is obsolete
696 **
697 **
698 ** @release 6.4.0
699 ******************************************************************************/
700 
ajOboIsObsolete(const AjPObo obo)701 AjBool ajOboIsObsolete(const AjPObo obo)
702 {
703     return obo->Obsolete;
704 }
705 
706 
707 
708 
709 /* @funcstatic oboMakeQry *****************************************************
710 **
711 ** Sets the query for an obo term
712 **
713 ** @param [r] thys [const AjPObo] Obo term object
714 ** @param [w] qry [AjPStr*] Query string in full
715 ** @return [void]
716 **
717 ** @release 6.4.0
718 ** @@
719 ******************************************************************************/
720 
oboMakeQry(const AjPObo thys,AjPStr * qry)721 static void oboMakeQry(const AjPObo thys, AjPStr* qry)
722 {
723     ajDebug("oboMakeQry (Name <%S> Formatstr <%S> Db <%S> "
724 	    "Filename <%S>)\n",
725 	    thys->Name, thys->Formatstr, thys->Db,
726 	    thys->Filename);
727 
728     /* ajOboTrace(thys); */
729 
730     if(ajStrGetLen(thys->Db))
731 	ajFmtPrintS(qry, "%S-id:%S", thys->Db, thys->Id);
732     else
733     {
734 	ajFmtPrintS(qry, "%S::%S:%S", thys->Formatstr,
735                     thys->Filename,thys->Id);
736     }
737 
738     ajDebug("      result: <%S>\n",
739 	    *qry);
740 
741     return;
742 }
743 
744 
745 
746 
747 /* @section obo term modifiers ************************************************
748 **
749 ** Obo term modifiers
750 **
751 ** @fdata [AjPObo]
752 **
753 ** @nam3rule Clear clear internal values
754 **
755 ** @argrule * obo [AjPObo] obo term object
756 **
757 ** @valrule * [void]
758 **
759 ** @fcategory modify
760 **
761 ******************************************************************************/
762 
763 
764 
765 
766 /* @func ajOboClear ***********************************************************
767 **
768 ** Resets all data for an obo term object so that it can be reused.
769 **
770 ** @param [u] obo [AjPObo] Obo term
771 ** @return [void]
772 **
773 ** @release 6.4.0
774 ** @@
775 ******************************************************************************/
776 
ajOboClear(AjPObo obo)777 void ajOboClear(AjPObo obo)
778 {
779     AjPObotag  tag  = NULL;
780     AjPOboxref xref = NULL;
781 
782     if(MAJSTRGETLEN(obo->Id))
783        ajStrSetClear(&obo->Id);
784     if(MAJSTRGETLEN(obo->Trueid))
785        ajStrSetClear(&obo->Trueid);
786     if(MAJSTRGETLEN(obo->Fullid))
787         ajStrSetClear(&obo->Fullid);
788     if(MAJSTRGETLEN(obo->Name))
789        ajStrSetClear(&obo->Name);
790     if(MAJSTRGETLEN(obo->Namespace))
791        ajStrSetClear(&obo->Namespace);
792     if(MAJSTRGETLEN(obo->Def))
793        ajStrSetClear(&obo->Def);
794     if(MAJSTRGETLEN(obo->Comment))
795        ajStrSetClear(&obo->Comment);
796     if(MAJSTRGETLEN(obo->Replaced))
797        ajStrSetClear(&obo->Replaced);
798 
799     if(MAJSTRGETLEN(obo->Db))
800        ajStrSetClear(&obo->Db);
801     if(MAJSTRGETLEN(obo->Setdb))
802        ajStrSetClear(&obo->Setdb);
803     if(MAJSTRGETLEN(obo->Full))
804        ajStrSetClear(&obo->Full);
805     if(MAJSTRGETLEN(obo->Qry))
806        ajStrSetClear(&obo->Qry);
807     if(MAJSTRGETLEN(obo->Formatstr))
808        ajStrSetClear(&obo->Formatstr);
809     if(MAJSTRGETLEN(obo->Filename))
810        ajStrSetClear(&obo->Filename);
811     if(MAJSTRGETLEN(obo->TextPtr))
812        ajStrSetClear(&obo->TextPtr);
813 
814     if(obo->Taglist)
815         while(ajListPop(obo->Taglist,(void**)&tag))
816             ajObotagDel(&tag);
817 
818     if(obo->Dbxrefs)
819         while(ajListPop(obo->Dbxrefs,(void**)&xref))
820             ajOboxrefDel(&xref);
821 
822     obo->Obsolete = ajFalse;
823     obo->Builtin = ajFalse;
824     obo->Fpos = 0L;
825     obo->Format = 0;
826 
827     return;
828 }
829 
830 
831 
832 
833 /* @datasection [AjPObotag] Obo tags *****************************************
834 **
835 ** Function is for manipulating obo tag objects
836 **
837 ** @nam2rule Obotag Obo tags
838 **
839 ******************************************************************************/
840 
841 
842 
843 
844 /* @section constructors ******************************************************
845 **
846 ** Constructors
847 **
848 ** @fdata [AjPObotag]
849 **
850 ** @nam3rule New Constructor
851 ** @nam4rule NewData Constructor using initial data values
852 ** @nam4rule NewTag Copy constructor
853 **
854 ** @argrule NewData name [const AjPStr] Name
855 ** @argrule NewData value [const AjPStr] Value
856 ** @argrule NewData  modifier [const AjPStr] Modifier
857 ** @argrule NewData comment [const AjPStr] Comment
858 ** @argrule NewData linenum [ajuint] OBO file line number
859 ** @argrule NewTag tag [const AjPObotag] Name
860 **
861 ** @valrule * [AjPObotag] Obo tag object
862 **
863 ** @fcategory new
864 **
865 ******************************************************************************/
866 
867 
868 
869 
870 /* @func ajObotagNewData ******************************************************
871 **
872 ** Tag constructor
873 **
874 ** @param [r] name [const AjPStr] Name
875 ** @param [r] value [const AjPStr] Value
876 ** @param [r] modifier [const AjPStr] Modifier
877 ** @param [r] comment [const AjPStr] Comment
878 ** @param [r] linenum [ajuint] OBO file line number
879 ** @return [AjPObotag] New object
880 **
881 ** @release 6.4.0
882 ** @@
883 ******************************************************************************/
884 
ajObotagNewData(const AjPStr name,const AjPStr value,const AjPStr modifier,const AjPStr comment,ajuint linenum)885 AjPObotag ajObotagNewData(const AjPStr name, const AjPStr value,
886                           const AjPStr modifier, const AjPStr comment,
887                           ajuint linenum)
888 {
889     AjPObotag ret;
890 
891     AJNEW0(ret);
892     ret->Name  = ajStrNewS(name);
893     ret->Value    = ajStrNewS(value);
894     ret->Modifier  = ajStrNewS(modifier);
895     ret->Comment  = ajStrNewS(comment);
896     ret->Linenumber = linenum;
897 
898     return ret;
899 }
900 
901 
902 
903 
904 
905 /* @func ajObotagNewTag *******************************************************
906 **
907 ** Tag copy constructor
908 **
909 ** @param [r] tag [const AjPObotag] Obo tag
910 ** @return [AjPObotag] New object
911 **
912 ** @release 6.4.0
913 ** @@
914 ******************************************************************************/
915 
ajObotagNewTag(const AjPObotag tag)916 AjPObotag ajObotagNewTag(const AjPObotag tag)
917 {
918     AjPObotag ret;
919 
920     AJNEW0(ret);
921 
922     if(tag->Name)
923         ret->Name  = ajStrNewS(tag->Name);
924     if(tag->Value)
925         ret->Value    = ajStrNewS(tag->Value);
926     if(tag->Modifier)
927         ret->Modifier  = ajStrNewS(tag->Modifier);
928     if(tag->Comment)
929         ret->Comment  = ajStrNewS(tag->Comment);
930 
931     ret->Linenumber = tag->Linenumber;
932 
933     return ret;
934 }
935 
936 
937 
938 
939 
940 /* @section obo tag destructors ***********************************************
941 **
942 ** Destruction destroys all internal data structures and frees the
943 ** memory allocated for the obo tag object.
944 **
945 ** @fdata [AjPObotag]
946 **
947 ** @nam3rule Del destructor
948 **
949 ** @argrule Del Ptag [AjPObotag*] Obo tag
950 **
951 ** @valrule * [void]
952 **
953 ** @fcategory delete
954 **
955 ******************************************************************************/
956 
957 
958 
959 
960 /* @func ajObotagDel **********************************************************
961 **
962 ** Tag destructor
963 **
964 ** @param [d] Ptag       [AjPObotag*]  Tag object to delete
965 ** @return [void]
966 **
967 ** @release 6.4.0
968 ** @@
969 ******************************************************************************/
970 
ajObotagDel(AjPObotag * Ptag)971 void ajObotagDel(AjPObotag *Ptag)
972 {
973     if(!Ptag) return;
974     if(!(*Ptag)) return;
975 
976     ajStrDel(&(*Ptag)->Name);
977     ajStrDel(&(*Ptag)->Value);
978     ajStrDel(&(*Ptag)->Modifier);
979     ajStrDel(&(*Ptag)->Comment);
980 
981     AJFREE(*Ptag);
982     *Ptag = NULL;
983 
984     return;
985 }
986 
987 
988 
989 
990 
991 /* @datasection [AjPOboxref] Obo dbxrefs ***************************************
992 **
993 ** Function is for manipulating obo dbxref objects
994 **
995 ** @nam2rule Oboxref Obo dbxrefs
996 **
997 ******************************************************************************/
998 
999 
1000 
1001 
1002 /* @section constructors ******************************************************
1003 **
1004 ** Constructors
1005 **
1006 ** @fdata [AjPOboxref]
1007 **
1008 ** @nam3rule New Constructor
1009 ** @nam4rule NewData Constructor with initial values
1010 ** @nam4rule NewXref Copy constructor
1011 **
1012 ** @argrule NewData name [const AjPStr] Name
1013 ** @argrule NewData desc [const AjPStr] Description
1014 ** @argrule NewXref xref [const AjPOboxref] Source dbxref object
1015 **
1016 ** @valrule * [AjPOboxref] Obo dbxref object
1017 **
1018 ** @fcategory new
1019 **
1020 ******************************************************************************/
1021 
1022 
1023 
1024 
1025 /* @func ajOboxrefNewData *****************************************************
1026 **
1027 ** Dbxref constructor
1028 **
1029 ** @param [r] name [const AjPStr] Name
1030 ** @param [r] desc [const AjPStr] Description
1031 ** @return [AjPOboxref] New object
1032 **
1033 ** @release 6.4.0
1034 ** @@
1035 ******************************************************************************/
1036 
ajOboxrefNewData(const AjPStr name,const AjPStr desc)1037 AjPOboxref ajOboxrefNewData(const AjPStr name, const AjPStr desc)
1038 {
1039     AjPOboxref ret;
1040 
1041     AJNEW0(ret);
1042     ret->Name = ajStrNewS(name);
1043     ret->Desc = ajStrNewS(desc);
1044 
1045     return ret;
1046 }
1047 
1048 
1049 
1050 
1051 
1052 /* @func ajOboxrefNewXref *****************************************************
1053 **
1054 ** Dbxref copy constructor
1055 **
1056 ** @param [r] xref [const AjPOboxref] Dbxref
1057 ** @return [AjPOboxref] New object
1058 **
1059 ** @release 6.4.0
1060 ** @@
1061 ******************************************************************************/
1062 
ajOboxrefNewXref(const AjPOboxref xref)1063 AjPOboxref ajOboxrefNewXref(const AjPOboxref xref)
1064 {
1065     AjPOboxref ret;
1066 
1067     AJNEW0(ret);
1068 
1069     ret->Name = ajStrNewS(xref->Name);
1070     ret->Desc = ajStrNewS(xref->Desc);
1071 
1072     return ret;
1073 }
1074 
1075 
1076 
1077 
1078 
1079 /* @section obo dbxref destructors ********************************************
1080 **
1081 ** Destruction destroys all internal data structures and frees the
1082 ** memory allocated for the obo dbxref object.
1083 **
1084 ** @fdata [AjPOboxref]
1085 **
1086 ** @nam3rule Del destructor
1087 **
1088 ** @argrule Del Pxref [AjPOboxref*] Obo dbxref
1089 **
1090 ** @valrule * [void]
1091 **
1092 ** @fcategory delete
1093 **
1094 ******************************************************************************/
1095 
1096 
1097 
1098 
1099 /* @func ajOboxrefDel *********************************************************
1100 **
1101 ** Dbxref destructor
1102 **
1103 ** @param [d] Pxref      [AjPOboxref*]  Dbxref object to delete
1104 ** @return [void]
1105 **
1106 ** @release 6.4.0
1107 ** @@
1108 ******************************************************************************/
1109 
ajOboxrefDel(AjPOboxref * Pxref)1110 void ajOboxrefDel(AjPOboxref *Pxref)
1111 {
1112     if(!Pxref) return;
1113     if(!(*Pxref)) return;
1114 
1115     ajStrDel(&(*Pxref)->Name);
1116     ajStrDel(&(*Pxref)->Desc);
1117 
1118     AJFREE(*Pxref);
1119     *Pxref = NULL;
1120 
1121     return;
1122 }
1123 
1124 
1125 
1126 
1127 
1128 /* @datasection [none] Miscellaneous functions ********************************
1129 **
1130 ** Functions to initialise and clean up internals
1131 **
1132 ** @nam2rule Obo Obo internals
1133 **
1134 ******************************************************************************/
1135 
1136 
1137 
1138 
1139 /* @section Miscellaneous *****************************************************
1140 **
1141 ** Functions to initialise and clean up internals
1142 **
1143 ** @fdata [none]
1144 **
1145 ** @nam3rule Exit Clean up and exit
1146 **
1147 ** @valrule * [void]
1148 **
1149 ** @fcategory misc
1150 **
1151 ******************************************************************************/
1152 
1153 
1154 
1155 
1156 /* @func ajOboExit ************************************************************
1157 **
1158 ** Cleans up obo term internal memory
1159 **
1160 ** @return [void]
1161 **
1162 ** @release 6.4.0
1163 ** @@
1164 ******************************************************************************/
1165 
ajOboExit(void)1166 void ajOboExit(void)
1167 {
1168     /* Query processing regular expressions */
1169 
1170     ajOboinExit();
1171     ajObooutExit();
1172 
1173     return;
1174 }
1175 
1176 
1177 
1178 
1179