Include <getcwd.h>.
[debian/tar] / src / arith.c
1 /* Arithmetic for numbers greater than a long int, for GNU tar.
2    Copyright (C) 1996, 1997 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify it
5    under the terms of the GNU General Public License as published by the
6    Free Software Foundation; either version 2, or (at your option) any later
7    version.
8
9    This program is distributed in the hope that it will be useful, but
10    WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
12    Public License for more details.
13
14    You should have received a copy of the GNU General Public License along
15    with this program; if not, write to the Free Software Foundation, Inc.,
16    59 Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
18 #include "system.h"
19
20 /* common.h is needed to define FATAL_ERROR.  It also includes arith.h.  */
21 #include "common.h"
22
23 /* GNU tar needs handling numbers exceeding 32 bits, which is the size of
24    unsigned long ints for many C compilers.  This module should provide
25    machinery for handling at least BITS_PER_TARLONG bits per number.  If
26    `long long' ints are available and are sufficient for the task, they will
27    be used preferrably.
28
29    Russell Cattelan reports 165 Gb single tapes (digital video D2 tapes on
30    Ampex drives), so requiring 38 bits for the tape length in bytes.  He
31    also reports breaking the terabyte limit with a single file (using SGI
32    xFS file system over 37 28GB disk arrays attached to a Power Challenge
33    XL; check out http://www.lcse.umn.edu/ for a picture), so requiring a
34    little more than 40 bits for the file size in bytes.  The POSIX header
35    structure allows for 12 octal digits to represent file lengths, that is,
36    up to 36 bits for the byte size of files.
37
38    If `long long' is not supported by the compiler, SIZEOF_LONG_LONG will be
39    set to zero by configure.  In this case, or if `long long' ints does not
40    have enough bits, then huge numbers are rather represented by an array of
41    longs, with the least significant super-digit at position 0.  For making
42    multiplication and decimal input/output easy, the base of a super-digit
43    is an exact exponent of 10, and is such that base*base fits in a long.  */
44
45 #if SUPERDIGIT
46
47 /*-------------------------------.
48 | Check if ACCUMULATOR is zero.  |
49 `-------------------------------*/
50
51 int
52 zerop_tarlong_helper (unsigned long *accumulator)
53 {
54   int counter;
55
56   for (counter = LONGS_PER_TARLONG - 1; counter >= 0; counter--)
57     if (accumulator[counter])
58       return 0;
59
60   return 1;
61 }
62
63 /*----------------------------------------------.
64 | Check if FIRST is strictly less than SECOND.  |
65 `----------------------------------------------*/
66
67 int
68 lessp_tarlong_helper (unsigned long *first, unsigned long *second)
69 {
70   int counter;
71
72   for (counter = LONGS_PER_TARLONG - 1; counter >= 0; counter--)
73     if (first[counter] != second[counter])
74       return first[counter] < second[counter];
75
76   return 0;
77 }
78
79 /*----------------------------.
80 | Reset ACCUMULATOR to zero.  |
81 `----------------------------*/
82
83 void
84 clear_tarlong_helper (unsigned long *accumulator)
85 {
86   int counter;
87
88   for (counter = 0; counter < LONGS_PER_TARLONG; counter++)
89     accumulator[counter] = 0;
90 }
91
92 /*----------------------------.
93 | To ACCUMULATOR, add VALUE.  |
94 `----------------------------*/
95
96 void
97 add_to_tarlong_helper (unsigned long *accumulator, int value)
98 {
99   int counter;
100
101   if (value < 0)
102     for (counter = 0; counter < LONGS_PER_TARLONG; counter++)
103       {
104         if (accumulator[counter] >= -value)
105           {
106             accumulator[counter] += value;
107             return;
108           }
109         accumulator[counter] += value + SUPERDIGIT;
110         value = -1;
111       }
112   else
113     for (counter = 0; counter < LONGS_PER_TARLONG; counter++)
114       {
115         if (accumulator[counter] + value < SUPERDIGIT)
116           {
117             accumulator[counter] += value;
118             return;
119           }
120         accumulator[counter] += value - SUPERDIGIT;
121         value = 1;
122       }
123   FATAL_ERROR ((0, 0, _("Arithmetic overflow")));
124 }
125
126 /*--------------------------------.
127 | Multiply ACCUMULATOR by VALUE.  |
128 `--------------------------------*/
129
130 void
131 mult_tarlong_helper (unsigned long *accumulator, int value)
132 {
133   int carry = 0;
134   int counter;
135
136   for (counter = 0; counter < LONGS_PER_TARLONG; counter++)
137     {
138       carry += accumulator[counter] * value;
139       accumulator[counter] = carry % SUPERDIGIT;
140       carry /= SUPERDIGIT;
141     }
142   if (carry)
143     FATAL_ERROR ((0, 0, _("Arithmetic overflow")));
144 }
145
146 /*----------------------------------------------------------.
147 | Print the decimal representation of ACCUMULATOR on FILE.  |
148 `----------------------------------------------------------*/
149
150 void
151 print_tarlong_helper (unsigned long *accumulator, FILE *file)
152 {
153   int counter = LONGS_PER_TARLONG - 1;
154
155   while (counter > 0 && accumulator[counter] == 0)
156     counter--;
157
158   fprintf (file, "%uld", accumulator[counter]);
159   while (counter > 0)
160     fprintf (file, TARLONG_FORMAT, accumulator[--counter]);
161 }
162
163 #endif /* SUPERDIGIT */