1 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  *  Copyright (C) 2009-2010  Kouhei Sutou <kou@clear-code.com>
4  *
5  *  This library is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU Lesser 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 library 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 Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 #  include <config.h>
22 #endif /* HAVE_CONFIG_H */
23 
24 #include <stdlib.h>
25 #include <string.h>
26 #include <glib.h>
27 
28 #include "cut-sequence-matcher.h"
29 #include "cut-diff-writer.h"
30 #include "cut-utils.h"
31 
32 G_DEFINE_TYPE(CutDiffWriter, cut_diff_writer, G_TYPE_OBJECT)
33 
34 static void dispose        (GObject         *object);
35 
36 static void
cut_diff_writer_class_init(CutDiffWriterClass * klass)37 cut_diff_writer_class_init (CutDiffWriterClass *klass)
38 {
39     GObjectClass *gobject_class;
40 
41     gobject_class = G_OBJECT_CLASS(klass);
42 
43     gobject_class->dispose = dispose;
44 }
45 
46 static void
cut_diff_writer_init(CutDiffWriter * writer)47 cut_diff_writer_init (CutDiffWriter *writer)
48 {
49 }
50 
51 static void
dispose(GObject * object)52 dispose (GObject *object)
53 {
54     G_OBJECT_CLASS(cut_diff_writer_parent_class)->dispose(object);
55 }
56 
57 void
cut_diff_writer_write(CutDiffWriter * writer,const gchar * string,CutDiffWriterTag tag)58 cut_diff_writer_write (CutDiffWriter       *writer,
59                        const gchar         *string,
60                        CutDiffWriterTag     tag)
61 {
62     CUT_DIFF_WRITER_GET_CLASS(writer)->write(writer, string, tag);
63 }
64 
65 void
cut_diff_writer_write_segment(CutDiffWriter * writer,const gchar * string,guint begin,guint end,CutDiffWriterTag tag)66 cut_diff_writer_write_segment (CutDiffWriter       *writer,
67                                const gchar         *string,
68                                guint                begin,
69                                guint                end,
70                                CutDiffWriterTag     tag)
71 {
72     GString *segment;
73     const gchar *segment_begin, *segment_end;
74 
75     segment_begin = g_utf8_offset_to_pointer(string, begin);
76     segment_end = g_utf8_offset_to_pointer(string, end);
77     segment = g_string_new(NULL);
78     g_string_append_len(segment, segment_begin, segment_end - segment_begin);
79     cut_diff_writer_write(writer, segment->str, tag);
80     g_string_free(segment, TRUE);
81 }
82 
83 void
cut_diff_writer_write_mark(CutDiffWriter * writer,const gchar * mark,const gchar * separator,CutDiffWriterTag tag)84 cut_diff_writer_write_mark (CutDiffWriter       *writer,
85                             const gchar         *mark,
86                             const gchar         *separator,
87                             CutDiffWriterTag     tag)
88 {
89     cut_diff_writer_write(writer, mark, tag);
90     if (separator && separator[0])
91         cut_diff_writer_write(writer, separator, CUT_DIFF_WRITER_TAG_NONE);
92 }
93 
94 void
cut_diff_writer_write_line(CutDiffWriter * writer,const gchar * line,CutDiffWriterTag tag)95 cut_diff_writer_write_line (CutDiffWriter       *writer,
96                             const gchar         *line,
97                             CutDiffWriterTag     tag)
98 {
99     CUT_DIFF_WRITER_GET_CLASS(writer)->write_line(writer, line, tag);
100 }
101 
102 void
cut_diff_writer_write_lines(CutDiffWriter * writer,gchar ** lines,guint begin,guint end,CutDiffWriterTag tag)103 cut_diff_writer_write_lines (CutDiffWriter       *writer,
104                              gchar              **lines,
105                              guint                begin,
106                              guint                end,
107                              CutDiffWriterTag     tag)
108 {
109     guint i;
110 
111     for (i = begin; i < end; i++) {
112         cut_diff_writer_write_line(writer, lines[i], tag);
113     }
114 }
115 
116 void
cut_diff_writer_mark_line(CutDiffWriter * writer,const gchar * mark,const gchar * separator,const gchar * line,CutDiffWriterTag tag)117 cut_diff_writer_mark_line (CutDiffWriter       *writer,
118                            const gchar         *mark,
119                            const gchar         *separator,
120                            const gchar         *line,
121                            CutDiffWriterTag     tag)
122 {
123     cut_diff_writer_write_mark(writer, mark, separator, tag);
124     cut_diff_writer_write_line(writer, line, tag);
125 }
126 
127 void
cut_diff_writer_mark_lines(CutDiffWriter * writer,const gchar * mark,const gchar * separator,gchar ** lines,guint begin,guint end,CutDiffWriterTag tag)128 cut_diff_writer_mark_lines (CutDiffWriter       *writer,
129                             const gchar         *mark,
130                             const gchar         *separator,
131                             gchar              **lines,
132                             guint                begin,
133                             guint                end,
134                             CutDiffWriterTag     tag)
135 {
136     guint i;
137 
138     for (i = begin; i < end; i++) {
139         cut_diff_writer_mark_line(writer, mark, separator, lines[i], tag);
140     }
141 }
142 
143 void
cut_diff_writer_write_character_n_times(CutDiffWriter * writer,gchar character,guint n,CutDiffWriterTag tag)144 cut_diff_writer_write_character_n_times (CutDiffWriter    *writer,
145                                          gchar             character,
146                                          guint             n,
147                                          CutDiffWriterTag  tag)
148 {
149     GString *string;
150     guint i;
151 
152     string = g_string_new(NULL);
153 
154     for (i = 0; i < n; i++) {
155         g_string_append_c(string, character);
156     }
157 
158     cut_diff_writer_write(writer, string->str, tag);
159     g_string_free(string, TRUE);
160 }
161 
162 void
cut_diff_writer_write_spaces(CutDiffWriter * writer,const gchar * string,guint begin,guint end,CutDiffWriterTag tag)163 cut_diff_writer_write_spaces (CutDiffWriter *writer,
164                               const gchar *string, guint begin, guint end,
165                               CutDiffWriterTag tag)
166 {
167     GString *buffer;
168     const gchar *last;
169 
170     buffer = g_string_new(NULL);
171     last = g_utf8_offset_to_pointer(string, end);
172     for (string = g_utf8_offset_to_pointer(string, begin);
173          string < last;
174          string = g_utf8_next_char(string)) {
175         if (g_unichar_iswide_cjk(g_utf8_get_char(string))) {
176             g_string_append(buffer, "  ");
177         } else if (string[0] == '\t') {
178             g_string_append_c(buffer, '\t');
179         } else {
180             g_string_append_c(buffer, ' ');
181         }
182     }
183     cut_diff_writer_write(writer, buffer->str, tag);
184     g_string_free(buffer, TRUE);
185 }
186 
187 void
cut_diff_writer_finish(CutDiffWriter * writer)188 cut_diff_writer_finish (CutDiffWriter *writer)
189 {
190     CUT_DIFF_WRITER_GET_CLASS(writer)->finish(writer);
191 }
192 
193 /*
194 vi:ts=4:nowrap:ai:expandtab:sw=4
195 */
196