1 //
2 //      aegis - project change supervisor
3 //      Copyright (C) 2003-2009, 2012 Peter Miller
4 //
5 //      This program is free software; you can redistribute it and/or modify
6 //      it under the terms of the GNU General Public License as published by
7 //      the Free Software Foundation; either version 3 of the License, or
8 //      (at your option) any later version.
9 //
10 //      This program is distributed in the hope that it will be useful,
11 //      but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //      GNU General Public License for more details.
14 //
15 //      You should have received a copy of the GNU General Public License
16 //      along with this program. If not, see
17 //      <http://www.gnu.org/licenses/>.
18 //
19 
20 #include <common/ac/assert.h>
21 #include <common/ac/stdio.h>
22 
23 #include <libaegis/change.h>
24 #include <libaegis/change/branch.h>
25 #include <libaegis/emit/edit_number.h>
26 #include <libaegis/file/event.h>
27 #include <libaegis/file/event/list.h>
28 #include <libaegis/http.h>
29 #include <libaegis/project/file/roll_forward.h>
30 
31 
32 static file_event *
file_event_from_revision(string_ty * revision,const file_event_list::pointer & felp)33 file_event_from_revision(string_ty *revision,
34     const file_event_list::pointer &felp)
35 {
36     if (!felp)
37         return 0;
38     for (size_t j = 0; j < felp->size(); ++j)
39     {
40         file_event *fep = felp->get(j);
41         assert(fep);
42         if (!fep)
43             continue;
44         fstate_src_ty *src = fep->get_src();
45         assert(src);
46         if (!src)
47             continue;
48         assert(src->edit);
49         if (!src->edit)
50             continue;
51         assert(src->edit->revision);
52         if (!src->edit->revision)
53             continue;
54         if (str_equal(revision, src->edit->revision))
55             return fep;
56     }
57     return 0;
58 }
59 
60 
61 static void
emit_edit_number_inner(change::pointer cp,fstate_src_ty * src_data,const file_event_list::pointer & felp=file_event_list::pointer ())62 emit_edit_number_inner(change::pointer cp, fstate_src_ty *src_data,
63     const file_event_list::pointer &felp = file_event_list::pointer())
64 {
65     if (src_data->edit_origin && src_data->edit)
66     {
67         //
68         // We have both the original version copied, and the
69         // current head revision.  Print them both, with a
70         // notation implying "from the old one to the new one"
71         // if they differ.  Only print one if thay are the same.
72         //
73         assert(src_data->edit->revision);
74         assert(src_data->edit_origin->revision);
75         if
76         (
77             !str_equal
78             (
79                 src_data->edit->revision,
80                 src_data->edit_origin->revision
81             )
82         )
83         {
84             file_event *fep =
85                 file_event_from_revision
86                 (
87                     src_data->edit_origin->revision,
88                     felp
89                 );
90             if (fep)
91             {
92                 emit_file_href(fep->get_change(), fep->get_src()->file_name, 0);
93                 printf("%s</a>\n", src_data->edit_origin->revision->str_text);
94                 nstring mod =
95                     nstring::format
96                     (
97                         "diff+unified+rhs=%s",
98                         cp->version_get().c_str()
99                     );
100                 emit_file_href
101                 (
102                     fep->get_change(),
103                     fep->get_src()->file_name,
104                     mod.c_str()
105                 );
106                 printf("&rarr;</a>\n");
107             }
108             else
109             {
110                 printf
111                 (
112                     "%s\n&rarr;\n",
113                     src_data->edit_origin->revision->str_text
114                 );
115             }
116         }
117         emit_file_href(cp, src_data->file_name, 0);
118         printf("%s", src_data->edit->revision->str_text);
119         printf("</a>\n");
120         return;
121     }
122 
123     if (src_data->edit_origin)
124     {
125         //
126         // The "original version" copied.
127         //
128         assert(src_data->edit_origin->revision);
129         file_event *fep =
130             file_event_from_revision(src_data->edit_origin->revision, felp);
131         if (fep)
132         {
133             emit_file_href(fep->get_change(), fep->get_src()->file_name, 0);
134             printf("%s</a>\n", fep->get_src()->edit->revision->str_text);
135         }
136         else
137             printf("%s\n", src_data->edit_origin->revision->str_text);
138     }
139     if (src_data->edit)
140     {
141         //
142         // For active branches, the current
143         // head revision.  For completed changes
144         // and branches, the revision at aeipass.
145         //
146         assert(src_data->edit->revision);
147         file_event *fep =
148             file_event_from_revision(src_data->edit->revision, felp);
149         if (fep)
150         {
151             emit_file_href(fep->get_change(), fep->get_src()->file_name, 0);
152             printf("%s</a>\n", fep->get_src()->edit->revision->str_text);
153         }
154         else
155             printf("%4s\n", src_data->edit->revision->str_text);
156     }
157     if (!cp->bogus && src_data->edit_origin_new)
158     {
159         printf("<br>{cross ");
160 
161         assert(src_data->edit_origin_new->revision);
162         file_event *fep =
163             file_event_from_revision(src_data->edit_origin_new->revision, felp);
164         if (fep)
165         {
166             emit_file_href(fep->get_change(), fep->get_src()->file_name, 0);
167             printf("%s</a>", fep->get_src()->edit->revision->str_text);
168         }
169         else
170             printf("%4s", src_data->edit_origin_new->revision->str_text);
171         printf("}\n");
172     }
173 }
174 
175 
176 void
emit_edit_number(change::pointer cp,fstate_src_ty * src,project_file_roll_forward * hp)177 emit_edit_number(change::pointer cp, fstate_src_ty *src,
178     project_file_roll_forward * hp)
179 {
180     switch (src->action)
181     {
182     case file_action_remove:
183     case file_action_insulate:
184     case file_action_transparent:
185         emit_edit_number_inner(cp, src);
186         break;
187 
188     case file_action_create:
189     case file_action_modify:
190         if (hp && hp->is_set())
191             emit_edit_number_inner(cp, src, hp->get(src));
192         else
193             emit_edit_number_inner(cp, src);
194         break;
195     }
196 }
197 
198 
199 // vim: set ts=8 sw=4 et :
200