Line data Source code
1 : /***************************************************************************//**
2 :
3 : @file util.c
4 :
5 : @author Stephen Brennan
6 :
7 : @date Created Sunday, 1 September 2013
8 :
9 : @brief Contains definitions for the general purpose items.
10 :
11 : @copyright Copyright (c) 2013-2016, Stephen Brennan. Released under the
12 : Revised BSD License. See the LICENSE.txt file for details.
13 :
14 : *******************************************************************************/
15 :
16 : #include <sys/time.h> /* gettimeofday */
17 : #include <stdio.h> /* fprintf, fopen */
18 : #include <stdlib.h> /* malloc, exit */
19 : #include <wchar.h> /* wchar_t */
20 : #include <stdbool.h> /* bool */
21 : #include <string.h> /* strcmp */
22 :
23 : #include "libstephen/base.h" /* SMB_* */
24 :
25 :
26 : /**
27 : @brief Utility function for macro smb_new(). Wrapper over malloc().
28 :
29 : Allocate a certain amount of memory. If allocation fails, EXIT with an error
30 : message.
31 :
32 : @param amt The number of bytes to allocate.
33 : @returns The pointer to the allocated memory (guaranteed).
34 : */
35 504453 : void *smb___new(size_t amt)
36 : {
37 504453 : void *result = malloc(amt);
38 504453 : if (!result) {
39 0 : fprintf(stderr, "smb_new: allocation error\n");
40 0 : exit(1);
41 : }
42 504453 : return result;
43 : }
44 :
45 : /**
46 : @brief Utility function for macro smb_renew(). Wrapper over realloc().
47 :
48 : Reallocate a certain amount of memory.
49 :
50 : @param ptr The memory to reallocate.
51 : @param newsize The new size of the memory.
52 : @returns The pointer to the new block.
53 : */
54 24536 : void *smb___renew(void *ptr, size_t newsize)
55 : {
56 24536 : void *result = realloc(ptr, newsize);
57 24536 : if (!result) {
58 0 : fprintf(stderr, "smb_renew: allocation error\n");
59 0 : exit(1);
60 : }
61 24536 : return result;
62 : }
63 :
64 : /**
65 : @brief Utility function for macro smb_free(). Wrapper over free().
66 :
67 : Free a pointer.
68 :
69 : @param ptr Memory to free.
70 : */
71 504461 : void smb___free(void *ptr)
72 : {
73 504461 : free(ptr);
74 504461 : }
75 :
76 0 : wchar_t *smb_read_linew(FILE *file, smb_status *status)
77 : {
78 : (void)status; // unused;
79 : #define SMBRL_BUFSIZE 256
80 0 : int bufsize = SMBRL_BUFSIZE;
81 0 : int position = 0;
82 0 : wchar_t *buffer = smb_new(wchar_t, bufsize);
83 : wint_t wc;
84 :
85 : while (true) {
86 : // Read a character
87 0 : wc = fgetwc(file);
88 :
89 : // If we hit EOF, replace it with a null character and return.
90 0 : if (wc == WEOF || wc == L'\n') {
91 0 : buffer[position++] = L'\0';
92 0 : return buffer;
93 : } else {
94 0 : buffer[position++] = wc;
95 : }
96 :
97 : // If we have exceeded the buffer, reallocate.
98 0 : if (position >= bufsize) {
99 0 : buffer = smb_renew(wchar_t, buffer, bufsize+SMBRL_BUFSIZE);
100 0 : bufsize += SMBRL_BUFSIZE;
101 : }
102 0 : }
103 : }
104 :
105 :
106 0 : char *smb_read_line(FILE *file, smb_status *status)
107 : {
108 : (void) status; // unused
109 0 : int bufsize = SMBRL_BUFSIZE;
110 0 : int position = 0;
111 0 : char *buffer = smb_new(char, bufsize);
112 : int c;
113 :
114 : while (true) {
115 : // Read a character
116 0 : c = fgetc(file);
117 :
118 : // If we hit EOF, replace it with a null character and return.
119 0 : if (c == EOF || c == '\n') {
120 0 : buffer[position++] = '\0';
121 0 : return buffer;
122 : } else {
123 0 : buffer[position++] = c;
124 : }
125 :
126 : // If we have exceeded the buffer, reallocate.
127 0 : if (position >= bufsize) {
128 0 : buffer = smb_renew(char, buffer, bufsize+SMBRL_BUFSIZE);
129 0 : bufsize += SMBRL_BUFSIZE;
130 : }
131 0 : }
132 : }
133 :
134 : /**
135 : @brief Print a DATA, treating it as a `char *`.
136 : @param f File to print to.
137 : @param d DATA to print.
138 : */
139 0 : void data_printer_string(FILE *f, DATA d)
140 : {
141 0 : fprintf(f, "\"%s\"", (char *)d.data_ptr);
142 0 : }
143 :
144 : /**
145 : @brief Print a DATA, treating it as an int.
146 : @param f File to print to.
147 : @param d DATA to print.
148 : */
149 0 : void data_printer_int(FILE *f, DATA d)
150 : {
151 0 : fprintf(f, "%lld", d.data_llint);
152 0 : }
153 :
154 : /**
155 : @brief Print a DATA, treating it as a float.
156 : @param f File to print to.
157 : @param d DATA to print.
158 : */
159 0 : void data_printer_float(FILE *f, DATA d)
160 : {
161 0 : fprintf(f, "%f", d.data_dbl);
162 0 : }
163 :
164 : /**
165 : @brief Print a DATA, treating it as a pointer.
166 : @param f File to print to.
167 : @param d DATA to print.
168 : */
169 0 : void data_printer_pointer(FILE *f, DATA d)
170 : {
171 0 : fprintf(f, "%p", d.data_ptr);
172 0 : }
173 :
174 : /**
175 : @brief Test whether two null terminated strings are equal.
176 : @param d1 First data.
177 : @param d2 Second data.
178 : @return An integer indicating whether the strings are equal, less than, or
179 : greater than.
180 : */
181 33 : int data_compare_string(DATA d1, DATA d2)
182 : {
183 : char *s1, *s2;
184 33 : s1 = (char *)d1.data_ptr;
185 33 : s2 = (char *)d2.data_ptr;
186 33 : return strcmp(s1, s2);
187 : }
188 :
189 : /**
190 : @brief Test whether two ints are equal.
191 : @param d1 First int.
192 : @param d2 Second int.
193 : @return An integer indicating whether the ints are equal, less than, or
194 : greater than.
195 : */
196 863 : int data_compare_int(DATA d1, DATA d2)
197 : {
198 : // Since the difference between two long long ints could be more than an int,
199 : // we need to store the difference and conditionally return.
200 863 : long long int diff = d1.data_llint - d2.data_llint;
201 863 : if (diff < 0) {
202 149 : return -1;
203 714 : } else if (diff > 0) {
204 677 : return 1;
205 : } else {
206 37 : return 0;
207 : }
208 : }
209 :
210 : /**
211 : @brief Test whether two doubles are equal.
212 :
213 : This function compares two doubles stored in DATA. However, it's NOT a smart
214 : comparison. It really just tests whether the binary representations
215 : themselves are equal. If you want a smart method for comparing floating
216 : point numbers, look elsewhere!
217 :
218 : @param d1 First double.
219 : @param d2 Second double.
220 : @return An integer indicating whether the doubles are equal, less than, or
221 : greater than.
222 : */
223 0 : int data_compare_float(DATA d1, DATA d2)
224 : {
225 0 : double diff = d1.data_llint - d2.data_llint;
226 0 : if (diff < 0) {
227 0 : return -1;
228 0 : } else if (diff > 0) {
229 0 : return 1;
230 : } else {
231 0 : return 0;
232 : }
233 : }
234 :
235 : /**
236 : @brief Test whether two pointers are equal. Does not order them.
237 : @param d1 First pointer.
238 : @param d2 Second pointer.
239 : @return 0 if equal, 1 if not.
240 : */
241 0 : int data_compare_pointer(DATA d1, DATA d2)
242 : {
243 0 : if (d1.data_ptr == d2.data_ptr) {
244 0 : return 0;
245 : } else {
246 0 : return 1;
247 : }
248 : }
|