~ubuntu-branches/ubuntu/saucy/numdiff/saucy

« back to all changes in this revision

Viewing changes to flags.c

  • Committer: Package Import Robot
  • Author(s): Paolo Greppi
  • Date: 2011-11-28 19:45:34 UTC
  • Revision ID: package-import@ubuntu.com-20111128194534-wp8a412l2rdf5s1u
Tags: upstream-5.2.1
ImportĀ upstreamĀ versionĀ 5.2.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    Numdiff - compare putatively similar files, 
 
3
    ignoring small numeric differences
 
4
    Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010  Ivano Primi  <ivprimi@libero.it>
 
5
 
 
6
    This program is free software: you can redistribute it and/or modify
 
7
    it under the terms of the GNU General Public License as published by
 
8
    the Free Software Foundation, either version 3 of the License, or
 
9
    (at your option) any later version.
 
10
 
 
11
    This program is distributed in the hope that it will be useful,
 
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
    GNU General Public License for more details.
 
15
 
 
16
    You should have received a copy of the GNU General Public License
 
17
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
18
*/
 
19
 
 
20
#include"numdiff.h"
 
21
#include<xalloc.h>
 
22
 
 
23
/* Constants and default values */
 
24
#define CHUNK_ALLOC  20480
 
25
 
 
26
static flg_array internal_table;
 
27
 
 
28
/*
 
29
  `table' must be the address of a `flg_array' structure.
 
30
*/
 
31
static int init_flg_array (flg_array* table)
 
32
{
 
33
  if ((table))
 
34
    {
 
35
      table->ptr = NULL;
 
36
      table->size = table->len = 0;
 
37
      return 0;
 
38
    }
 
39
  else
 
40
    return -1;
 
41
}
 
42
 
 
43
int init_flags (void)
 
44
{
 
45
  return init_flg_array (&internal_table);
 
46
}
 
47
 
 
48
/*
 
49
  `table' must be the address of a `flg_array' structure.
 
50
*/
 
51
static int print_flg_array (FILE* fp, const flg_array* table)
 
52
{
 
53
  size_t n;
 
54
  unsigned short i;
 
55
  unsigned char byte, elem;
 
56
 
 
57
  if (!table || !table->ptr)
 
58
    return (fputs (_("<The array is empty>\n"), fp) == EOF);
 
59
  else
 
60
    {
 
61
      int outerror = 0;
 
62
 
 
63
      for (n = 0; !outerror && n < table->len; n += 4U)
 
64
        {
 
65
          byte = table->ptr[n/4U];
 
66
          for (i = 0; i < 4U; i++)
 
67
            {
 
68
              if ( (elem = (byte & 0x03 << 2*i) >> 2 * i) )
 
69
                {
 
70
                  if ( fprintf (fp, "%u", elem) < 0 )
 
71
                    {
 
72
                      outerror = 1;
 
73
                      break;
 
74
                    }
 
75
                }
 
76
              else
 
77
                break;
 
78
            }
 
79
        }
 
80
      if (!outerror)
 
81
        outerror = (fputc ('\n', fp) == EOF);
 
82
      return outerror;
 
83
    }
 
84
}
 
85
 
 
86
int print_flags (FILE* fp)
 
87
{
 
88
  return print_flg_array (fp, &internal_table);
 
89
}
 
90
 
 
91
/*
 
92
  array must be the address of a `flg_array' structure.
 
93
*/
 
94
static void addnewelem (flg_array* array, unsigned char elem)
 
95
{
 
96
  if (!array)
 
97
    return;
 
98
  if ( !array->ptr )
 
99
    {
 
100
      array->ptr = xcalloc (CHUNK_ALLOC, sizeof (unsigned char));
 
101
      array->size = CHUNK_ALLOC;
 
102
      array->ptr[0] = elem;
 
103
      array->len = 1;
 
104
#ifdef __MEMDEBUG__
 
105
      fprintf (stderr, "size = %6zu, len = %6zu, string:",
 
106
               array->size, array->len);
 
107
      print_flg_array (stderr, array);
 
108
#endif
 
109
    }
 
110
  else
 
111
    {
 
112
      if (array->len == 4 * array->size - 1)
 
113
        {
 
114
          unsigned char* p;
 
115
 
 
116
          array->ptr = xrealloc (array->ptr, array->size + CHUNK_ALLOC);
 
117
          array->size += CHUNK_ALLOC;
 
118
          array->ptr[array->len / 4U] |= elem << 2 * (array->len % 4U);
 
119
          array->len++; /* Now array->len == 4 * array->"old"size */
 
120
          for (p = array->ptr + array->len / 4; p < array->ptr + array->size; *p = 0, p++);
 
121
#ifdef __MEMDEBUG__
 
122
          fprintf (stderr, "size = %6zu, len = %6zu, string:",
 
123
                   array->size, array->len);
 
124
          print_flg_array (stderr, array);
 
125
#endif
 
126
        }
 
127
      else
 
128
        {
 
129
          array->ptr[array->len / 4U] |= elem << 2 * (array->len % 4U);
 
130
          array->len++;
 
131
#ifdef __MEMDEBUG__
 
132
          fprintf (stderr, "size = %6zu, len = %6zu, string:",
 
133
                   array->size, array->len);
 
134
          print_flg_array (stderr, array);
 
135
#endif
 
136
        }
 
137
    }
 
138
}
 
139
 
 
140
flg_array copy_of_intflagtab (void)
 
141
{
 
142
  return internal_table;
 
143
}
 
144
 
 
145
/*
 
146
  array must be the address of a `flg_array' structure.
 
147
*/
 
148
static void destroy_flg_array (flg_array* array)
 
149
{
 
150
  if ((array) && (array->ptr))
 
151
    {
 
152
      free ((void*)array->ptr);
 
153
      array->ptr = NULL;
 
154
      array->size = array->len = 0;
 
155
    }
 
156
 
157
 
 
158
void erase_flags (void)
 
159
{
 
160
  destroy_flg_array (&internal_table);
 
161
}
 
162
 
 
163
static void notedown_sdiff_common_lines (lin, lin);
 
164
static void notedown_sdiff_hunk (struct change *);
 
165
 
 
166
/* Next line number to be printed in the two input files.  */
 
167
static lin next0, next1;
 
168
 
 
169
/* 
 
170
 * Note down the edit-script SCRIPT in the INTERNAL_TABLE.
 
171
 */
 
172
 
 
173
void
 
174
notedown_sdiff_script (struct change *script)
 
175
{
 
176
  next0 = next1 = - files[0].prefix_lines;
 
177
  print_script (script, notedown_sdiff_hunk);
 
178
 
 
179
  notedown_sdiff_common_lines (files[0].valid_lines, files[1].valid_lines);
 
180
}
 
181
 
 
182
/* Print lines common to both files in side-by-side format.  */
 
183
static void
 
184
notedown_sdiff_common_lines (lin limit0, lin limit1)
 
185
{
 
186
  lin i0 = next0, i1 = next1;
 
187
 
 
188
  if (i0 != limit0 || i1 != limit1)
 
189
    {
 
190
      for (; i0 != limit0 && i1 != limit1; i0++, i1++)
 
191
        addnewelem (&internal_table, 3);
 
192
 
 
193
      for (; i1 != limit1; i1++)
 
194
        addnewelem (&internal_table, 2);
 
195
 
 
196
      for (; i0 != limit0; i0++)
 
197
        addnewelem (&internal_table, 1);
 
198
    }
 
199
 
 
200
  next0 = limit0;
 
201
  next1 = limit1;
 
202
}
 
203
 
 
204
/* Note down a hunk of an sdiff diff.
 
205
   This is a contiguous portion of a complete edit script,
 
206
   describing changes in consecutive lines.  */
 
207
 
 
208
static void
 
209
notedown_sdiff_hunk (struct change *hunk)
 
210
{
 
211
  lin first0, last0, first1, last1;
 
212
  register lin i, j;
 
213
 
 
214
  /* Determine range of line numbers involved in each file.  */
 
215
  enum changes changes =
 
216
    analyze_hunk (hunk, &first0, &last0, &first1, &last1);
 
217
  if (!changes)
 
218
    return;
 
219
 
 
220
  /* Note down lines up to this change.  */
 
221
  notedown_sdiff_common_lines (first0, first1);
 
222
 
 
223
  /* Note down ``xxx  |  xxx '' lines */
 
224
  if (changes == CHANGED)
 
225
    {
 
226
      for (i = first0, j = first1;  i <= last0 && j <= last1;  i++, j++)
 
227
        addnewelem (&internal_table, 3);
 
228
      changes = (i <= last0 ? OLD : 0) + (j <= last1 ? NEW : 0);
 
229
      next0 = first0 = i;
 
230
      next1 = first1 = j;
 
231
    }
 
232
 
 
233
  /* Note down ``     >  xxx '' lines */
 
234
  if (changes & NEW)
 
235
    {
 
236
      for (j = first1; j <= last1; ++j)
 
237
        addnewelem (&internal_table, 2);
 
238
      next1 = j;
 
239
    }
 
240
 
 
241
  /* Note down ``xxx  <     '' lines */
 
242
  if (changes & OLD)
 
243
    {
 
244
      for (i = first0; i <= last0; ++i)
 
245
        addnewelem (&internal_table, 1);
 
246
      next0 = i;
 
247
    }
 
248
}