doc_ref.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /**
  2. * @file doc_ref.h
  3. */
  4. #ifndef DOC_REF_H
  5. #define DOC_REF_H
  6. #include <stdlib.h>
  7. #include "gl_list.h"
  8. #include "doc_stream.h"
  9. //#include "doc_elt.h"
  10. /* #include "doc_elt.h" */
  11. struct doc_elt;
  12. typedef struct doc_elt doc_elt;
  13. typedef struct merge_ctxt merge_ctxt;
  14. typedef struct doc_ref doc_ref;
  15. /**
  16. * Indicates an input document (ancestor, local, or source). Used to
  17. * indicate the document from which a doc_* object originates.
  18. */
  19. typedef enum doc_src
  20. {
  21. ANC_SRC = 1,
  22. REM_SRC = 2,
  23. LOC_SRC = 4
  24. } doc_src;
  25. /**
  26. * A reference to a doc_elt. It is used to keep track of what files a
  27. * merged document represents.
  28. */
  29. typedef struct doc_ref
  30. {
  31. doc_src src;
  32. doc_elt *elt;
  33. doc_ref *parent;
  34. bool circular_conflict;
  35. } doc_ref;
  36. /* Constructor and destructor */
  37. static inline doc_ref *doc_ref_create_empty ();
  38. static inline void doc_ref_free (doc_ref *ref);
  39. /* Set the doc_elt reference */
  40. static inline doc_elt * doc_ref_get_elt (doc_ref *ref);
  41. static inline void doc_ref_set_elt (doc_ref *ref, doc_elt *elt);
  42. /* Set the doc_src this file represents */
  43. static inline doc_src doc_ref_get_src (doc_ref *ref);
  44. static inline void doc_ref_set_src (doc_ref *ref, doc_src src);
  45. static inline void doc_ref_add_src (doc_ref *ref, doc_src src);
  46. static inline bool doc_ref_isexactly (doc_ref *ref, doc_src src);
  47. static inline bool doc_ref_contains (doc_ref *ref, doc_src src);
  48. static inline doc_ref *doc_ref_get_parent (doc_ref *ref);
  49. static inline void doc_ref_set_paraent (doc_ref *ref, doc_ref* parent);
  50. /* circular conflict */
  51. static inline bool doc_ref_is_circular_conflict (doc_ref *ref);
  52. static inline void doc_ref_set_circular_conflict (doc_ref *ref, bool conflict);
  53. /* check for a circulor conflic, and mark it in all doc_refs */
  54. static inline bool dec_ref_check_for_circular_conflict (doc_ref *ref);
  55. /*
  56. * doc_reflist
  57. */
  58. /**
  59. * @brief Check to see if any of the elemets in a list of doc_refs are
  60. * updated.
  61. * This depends on the element's implementation of this.
  62. * This function will stop early if it finds a response.
  63. */
  64. bool doc_reflist_isupdated (gl_list_t reflist);
  65. /**
  66. * @brief Merge two doc_ref lists together. This function changes ancestor.
  67. */
  68. void doc_reflist_merge (doc_ref *parent, gl_list_t ancestor, gl_list_t descendant, merge_ctxt *ctxt);
  69. /**
  70. * @brief print a list of ref_docs
  71. */
  72. void doc_reflist_print (gl_list_t reflist, void *context, doc_stream *out);
  73. /*
  74. * Implementation Details
  75. */
  76. static inline doc_ref *
  77. doc_ref_create_empty ()
  78. {
  79. doc_ref *d = malloc (sizeof (doc_ref));
  80. d->elt = NULL;
  81. d->src = 0;
  82. d->parent = NULL;
  83. d->circular_conflict = false;
  84. return d;
  85. }
  86. static inline void
  87. doc_ref_free (doc_ref *ref)
  88. {
  89. free (ref);
  90. }
  91. static inline doc_elt *
  92. doc_ref_get_elt (doc_ref *ref)
  93. {
  94. return ref->elt;
  95. }
  96. static inline void
  97. doc_ref_set_elt (doc_ref *ref, doc_elt *elt)
  98. {
  99. ref->elt = elt;
  100. return;
  101. }
  102. static inline doc_src
  103. doc_ref_get_src (doc_ref *ref)
  104. {
  105. return ref->src;
  106. }
  107. static inline void
  108. doc_ref_set_src (doc_ref *ref, doc_src src)
  109. {
  110. ref->src = src;
  111. return;
  112. }
  113. static inline void
  114. doc_ref_add_src (doc_ref *ref, doc_src src)
  115. {
  116. ref->src = ref->src | src;
  117. return;
  118. }
  119. static inline bool
  120. doc_ref_isexactly (doc_ref *ref, doc_src src)
  121. {
  122. return (ref->src == src);
  123. }
  124. static inline bool
  125. doc_ref_contains (doc_ref *ref, doc_src src)
  126. {
  127. return (ref->src & src);
  128. }
  129. static inline doc_ref *doc_ref_get_parent (doc_ref *ref)
  130. {
  131. return ref->parent;
  132. }
  133. static inline void doc_ref_set_parent (doc_ref *ref, doc_ref* parent)
  134. {
  135. ref->parent = parent;
  136. return;
  137. }
  138. static inline bool doc_ref_is_circular_conflict (doc_ref *ref)
  139. {
  140. return ref->circular_conflict;
  141. }
  142. static inline void doc_ref_set_circular_conflict (doc_ref *ref, bool conflict)
  143. {
  144. ref->circular_conflict = conflict;
  145. }
  146. /* check for a circulor conflict, and mark it in all doc_refs */
  147. static inline bool doc_ref_check_for_circular_conflict (doc_ref *ref)
  148. {
  149. bool exit = false;
  150. bool conflict = false;
  151. doc_ref *parent = doc_ref_get_parent (ref);
  152. while ((parent != NULL)
  153. && (!conflict)
  154. && !(doc_ref_is_circular_conflict(parent)))
  155. {
  156. printf ("checking parent par=%d, ref=%d\n",
  157. doc_ref_get_elt (parent), doc_ref_get_elt (ref));
  158. if (doc_ref_get_elt (parent) == doc_ref_get_elt (ref))
  159. {
  160. printf ("CIRCULAR CONFLICT\n");
  161. conflict = true;
  162. }
  163. parent = doc_ref_get_parent ( parent );
  164. }
  165. /* set the doc_refs as having a conflict, if there was one */
  166. exit = false;
  167. if (conflict)
  168. {
  169. doc_ref * parent = doc_ref_get_parent (ref);
  170. while ( (parent != NULL) && (!exit))
  171. {
  172. if (doc_ref_get_elt (parent) == doc_ref_get_elt (ref))
  173. {
  174. exit = true;
  175. }
  176. doc_ref_set_circular_conflict (parent, true);
  177. parent = doc_ref_get_parent (parent);
  178. }
  179. }
  180. printf ("conflict = %d\n", conflict);
  181. return conflict;
  182. }
  183. #endif /* DOC_REF_H */