Various fixes:
[SXSI/TextCollection.git] / swcsa / utils / basics.c
1 #ifdef __cplusplus
2 extern "C" {
3 #endif
4
5 // Basics
6
7 // #include "basics.h" included later to avoid macro recursion for malloc
8 #include <sys/types.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11
12                 // Memory management
13
14 static  void *Malloc (size_t n)
15
16            { void *p;
17              if (n == 0) return NULL;
18              p = (void*) malloc (n);
19              if (p == NULL)
20                 { fprintf (stderr,"Could not allocate %i bytes\n",n);
21                   exit(1);
22                 }
23              return p;
24            }
25
26 static  void Free (void *p)
27
28            { if (p) free (p);
29            }
30
31 static  void *Realloc (void *p, size_t n)
32
33            { if (p == NULL) return Malloc (n);
34              if (n == 0) { Free(p); return NULL; }
35              p = (void*) realloc (p,n);
36              if (p == NULL)
37                 { fprintf (stderr,"Could not allocate %i bytes\n",n);
38                   exit(1);
39                 }
40              return p;
41            }
42
43 #include "basics.h"
44
45         // bits needed to represent a number between 0 and n
46
47 uint _bits (uint n)
48
49    { uint b = 0;
50      while (n)
51         { b++; n >>= 1; }
52      return b;
53    }
54
55         // returns e[p..p+len-1], assuming len <= W
56
57 uint bitread (uint *e, uint p, uint len)
58
59    { uint answ;
60      e += p/W; p %= W;
61      answ = *e >> p;
62      if (len == W)
63           { if (p) answ |= (*(e+1)) << (W-p);
64           }
65      else { if (p+len > W) answ |= (*(e+1)) << (W-p);
66             answ &= (1<<len)-1;
67           }
68      return answ;
69    }
70
71
72         // writes e[p..p+len-1] = s, len <= W
73
74 void bitwrite (register uint *e, register uint p,
75                register uint len, register uint s)
76
77    { e += p/W; p %= W;
78      if (len == W)
79           { *e |= (*e & ((1<<p)-1)) | (s << p);
80             if (!p) return;
81             e++;
82             *e = (*e & ~((1<<p)-1)) | (s >> (W-p));
83           }
84      else { if (p+len <= W)
85                { *e = (*e & ~(((1<<len)-1)<<p)) | (s << p);
86                  return;
87                }
88             *e = (*e & ((1<<p)-1)) | (s << p);
89             e++; len -= W-p;
90             *e = (*e & ~((1<<len)-1)) | (s >> (W-p));
91           }
92    }
93         // writes e[p..p+len-1] = 0
94
95 void bitzero2 (register uint *e, register uint p,
96                register uint len)
97
98    { e += p/W; p %= W;
99      if (p+len >= W)
100         { *e &= ~((1<<p)-1);
101           len -= p;
102           e++; p = 0;
103         }
104      while (len >= W)
105         { *e++ = 0;
106           len -= W;
107         }
108      if (len > 0)
109         *e &= ~(((1<<len)-1)<<p);
110    }
111 #ifdef __cplusplus
112 }
113 #endif