SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
table.c
Go to the documentation of this file.
1/**
2 * @file table.c
3 * @brief DPL/MPL format input/output functions.
4 * @details Contains functions: get_table(), put_table(), float_array_from_double(),
5 * get_table_float(), put_table_float(), double_array_from_float(),
6 * delete_trailing_blanks(), fgets_skip().
7 * @author Michael Borland
8 * @date 1988
9 */
10
11#include "mdb.h"
12#include <ctype.h>
13#include "table.h"
14
15#define SDDS_SUPPORT 1
16
17#if SDDS_SUPPORT
18# include "SDDS.h"
19
20int32_t SDDS_ReadIntoMplTable(TABLE *mpl_data, char *file, int64_t sample_interval, int32_t mpl_flags, char *SDDS_tags);
21int32_t SDDS_WriteMplTable(TABLE *mpl_data, char *file);
22long SDDS_AddMplDefinition(SDDS_TABLE *SDDS_table, char *label, char *suffix, char *default_name, char *filename);
23void SDDS_ExtractNameAndUnit(char **name, char **unit, char *label);
24void SDDS_FixMplName(char *name);
25
26#endif
27
28extern void delete_trailing_blanks(char *s);
29extern int32_t SDDS_ReadIntoMplTable(TABLE *mpl_data, char *file, int64_t sample_interval, int32_t mpl_flags, char *SDDS_tags);
30
31/* routine: get_table()
32 * purpose: get a table from a file (dpl format)
33 */
34#define OAGBUFSIZ 1024
35
36/**
37 * @brief Gets a table from a file in DPL format.
38 *
39 * @param tab Pointer to a TABLE structure to store the data.
40 * @param file Name of the file to read.
41 * @param sample_interval Sampling interval for reading data points.
42 * @param flags Flags to control the reading behavior.
43 * @return Returns 1 on success, 0 on failure.
44 */
45long get_table(TABLE *tab, char *file, int64_t sample_interval, long flags) {
46 long i, n, m;
47 long sigma_y_present, sigma_x_and_y_present;
48 char s[OAGBUFSIZ];
49 double tmp;
50 FILE *fp;
51 char *ptr, *sdds_tags=NULL, *orig_tag = NULL;
52 long sdds_expected = 0, sdds_data = 0;
53
54 sigma_y_present = sigma_x_and_y_present = 0;
55 tab->c1 = tab->c2 = tab->s1 = tab->s2 = NULL;
56 tab->xlab = tab->ylab = tab->topline = tab->title = NULL;
57 tab->flags = 0;
58 tab->n_data = 0;
59
60#if defined(SDDS_SUPPORT)
61
62 if ((orig_tag = strchr(file, '='))) {
63 sdds_tags = orig_tag;
64 *sdds_tags = 0;
65 if (!fexists(file))
66 *sdds_tags = '=';
67 else {
68 sdds_expected = 1;
69 sdds_tags++;
70 }
71 }
72
73 if (!(fp = fopen_e(file, "r", FOPEN_RETURN_ON_ERROR))) {
74 fprintf(stderr, "error: unable to open file %s in mode r (get_table)\n", file);
75 exit(1);
76 }
77
78 if (!fgets_skip(s, OAGBUFSIZ, fp, '!', 1))
79 return (0);
80 fclose(fp);
81 if (strncmp(s, "SDDS", 4) == 0) {
82 if (!SDDS_ReadIntoMplTable(tab, file, sample_interval, flags, sdds_tags)) {
83 fprintf(stderr, "error: unable to read requested data from SDDS file %s\n", file);
84 exit(1);
85 }
86 sdds_data = 1;
87 sigma_x_and_y_present = (sigma_y_present = tab->flags & SIGMA_Y_PRESENT) && (tab->flags & SIGMA_X_PRESENT);
88 }
89 if (sdds_expected && !sdds_data)
90 *orig_tag = '=';
91
92#endif /* SDDS_SUPPORT */
93
94 if (!sdds_data) {
95 fp = fopen_e(file, "r", 0);
96#ifdef DEBUG
97 fprintf(stderr, "file %s opened: sample_interval=%ld flags=%x\n", file, sample_interval, flags);
98#endif
99
100 /* read in plot labels, skipping comment lines (! lines) */
101 fgets_skip(s, OAGBUFSIZ, fp, '!', 1);
102 delete_trailing_blanks(s);
103 cp_str(&(tab->xlab), s);
104 fgets_skip(s, OAGBUFSIZ, fp, '!', 1);
105 delete_trailing_blanks(s);
106 cp_str(&(tab->ylab), s);
107 fgets_skip(s, OAGBUFSIZ, fp, '!', 1);
108 delete_trailing_blanks(s);
109 cp_str(&(tab->title), s);
110 fgets_skip(s, OAGBUFSIZ, fp, '!', 1);
111 delete_trailing_blanks(s);
112 cp_str(&(tab->topline), s);
113#ifdef DEBUG
114 fprintf(stderr, "labels:\n<%s>\n<%s>\n<%s>\n<%s>\n", tab->xlab, tab->ylab, tab->title, tab->topline);
115#endif
116 }
117
118 if (flags & SWAP) {
119 ptr = tab->xlab;
120 tab->xlab = tab->ylab;
121 tab->ylab = ptr;
122 }
123
124 if (flags & READ_LABELS_ONLY) {
125 if (!sdds_data)
126 fclose(fp);
127 return (1);
128 }
129
130 if (!sdds_data) {
131 /* read in the number of data points */
132 fgets_skip(s, OAGBUFSIZ, fp, '!', 1);
133 if (!*s || 1 != sscanf(s, "%lf", &tmp)) {
134 fprintf(stderr, "error in format of file %s--couldn't scan number of points\n", file);
135 exit(1);
136 }
137 n = tmp + 0.5;
138#ifdef DEBUG
139 fprintf(stderr, "n_pts = %ld\n", n);
140#endif
141
142 /* adjust the number of data points for the sampling interval */
143 if (sample_interval <= 0)
144 sample_interval = 1;
145 n = n / sample_interval;
146
147 /* allocate memory for column 1 and 2 data and sigmas */
148 tab->c1 = tmalloc(sizeof(*(tab->c1)) * n);
149 tab->c2 = tmalloc(sizeof(*(tab->c2)) * n);
150 tab->s1 = tmalloc(sizeof(*(tab->s1)) * n);
151 tab->s2 = tmalloc(sizeof(*(tab->s2)) * n);
152 tab->flags = 0;
153
154#ifdef DEBUG
155 fprintf(stderr, "data pointers are: %x, %x, %x, %x\n", (unsigned long)tab->c1, (unsigned long)tab->c2, (unsigned long)tab->s1, (unsigned long)tab->s2);
156#endif
157
158 /* read in the data points, one by one */
159 for (i = 0; i < n; i++) {
160 if (fgets_skip(s, OAGBUFSIZ, fp, '!', (i == 0 ? 1 : sample_interval))) {
161#ifdef DEBUG
162 fprintf(stderr, "string: <%s>\n", s);
163#endif
164 if ((ptr = strchr(s, '!')))
165 *ptr = 0;
166 if (!get_double(tab->c1 + i, s) || !get_double(tab->c2 + i, s)) {
167 fprintf(stderr, "warning: error in format of file %s\n", file);
168 n = i - 1;
169 tab->c1 = trealloc((void *)tab->c1, sizeof(*(tab->c1)) * n);
170 tab->c2 = trealloc((void *)tab->c2, sizeof(*(tab->c2)) * n);
171 tab->s1 = trealloc((void *)tab->s1, sizeof(*(tab->s1)) * n);
172 tab->s2 = trealloc((void *)tab->s2, sizeof(*(tab->s2)) * n);
173 break;
174 }
175 tab->s1[i] = tab->s2[i] = 0;
176 if (i == 0) {
177 /* First point--establish the number of sigma values in the
178 * data. If there's only one sigma, interpret it as sigma_y,
179 * otherwise, the sigmas are sigma_x and sigma_y, in that
180 * order.
181 */
182 if (get_double(tab->s1 + i, s)) {
183 if (get_double(tab->s2 + i, s)) {
184 sigma_x_and_y_present = 1;
185 tab->flags |= SIGMA_X_PRESENT + SIGMA_Y_PRESENT;
186 } else {
187 tab->s2[i] = tab->s1[i];
188 tab->s1[i] = 0;
189 tab->flags |= SIGMA_Y_PRESENT;
190 sigma_y_present = 1;
191 }
192 }
193#ifdef DEBUG
194 fprintf(stderr, "tab->flags = %x\n", tab->flags);
195#endif
196 } else {
197 /* Scan sigma_y or (sigma_x, sigma_y) values, according
198 * to what the first line indicated is supposed to be present.
199 */
200 if (sigma_y_present && !get_double(tab->s2 + i, s)) {
201 fprintf(stderr, "error in format of file %s--expected sigma is missing\n", file);
202 exit(1);
203 } else if (sigma_x_and_y_present && (!get_double(tab->s1 + i, s) || !get_double(tab->s2 + i, s))) {
204 fprintf(stderr, "error in format of file %s--expected sigma is missing\n", file);
205 exit(1);
206 }
207 }
208 if (flags & SWAP) {
209 /* exchange x and y data points */
210 tmp = tab->c1[i];
211 tab->c1[i] = tab->c2[i];
212 tab->c2[i] = tmp;
213 /* exchange the sigmas, too */
214 tmp = tab->s1[i];
215 tab->s1[i] = tab->s2[i];
216 tab->s2[i] = tmp;
217 }
218 } else {
219 fprintf(stderr, "Warning: file %s contains only %ld of %ld expected points.\n", file, i, n);
220 n = i;
221 tab->c1 = trealloc((void *)tab->c1, sizeof(*(tab->c1)) * n);
222 tab->c2 = trealloc((void *)tab->c2, sizeof(*(tab->c2)) * n);
223 tab->s1 = trealloc((void *)tab->s1, sizeof(*(tab->s1)) * n);
224 tab->s2 = trealloc((void *)tab->s2, sizeof(*(tab->s2)) * n);
225 break;
226 }
227 }
228 tab->n_data = n;
229 }
230 n = tab->n_data;
231
232 /* Check to see if the data needs to be reverse in order, i.e.,
233 * if the first point should be the last and the last first.
234 */
235 if (flags & REVERSE || ((flags & REORDER_ASCENDING) && tab->c1[0] > tab->c1[n - 1]) || ((flags & REORDER_DESCENDING) && tab->c1[0] < tab->c1[n - 1])) {
236 /* Reverse the order of the data. */
237 m = n - 1;
238 for (i = 0; i < n / 2; i++) {
239 if (m - i > n - 1)
240 bomb("something impossible happened in get_table()", NULL);
241 tmp = tab->c1[i];
242 tab->c1[i] = tab->c1[m - i];
243 tab->c1[m - i] = tmp;
244 tmp = tab->c2[i];
245 tab->c2[i] = tab->c2[m - i];
246 tab->c2[m - i] = tmp;
247 tmp = tab->s1[i];
248 tab->s1[i] = tab->s1[m - i];
249 tab->s1[m - i] = tmp;
250 tmp = tab->s2[i];
251 tab->s2[i] = tab->s2[m - i];
252 tab->s2[m - i] = tmp;
253 }
254 }
255
256 if (!sdds_data) {
257 /* Check file for extra data. */
258 if (fgets_skip(s, OAGBUFSIZ, fp, '!', sample_interval))
259 fprintf(stderr, "Warning: file %s contains excess data (which is ignored).\n", file);
260 fclose(fp);
261 }
262
263 /* If there were no sigmas, free the arrays. */
264 if (!(tab->flags & SIGMA_X_PRESENT || tab->flags & SIGMA_Y_PRESENT) && !(flags & SAVE_SIGMA_ARRAYS)) {
265 if (tab->s1) {
266 tfree(tab->s1);
267 tab->s1 = NULL;
268 }
269 if (tab->s2) {
270 tfree(tab->s2);
271 tab->s2 = NULL;
272 }
273 }
274
275#ifdef DEBUG
276 for (i = 0; i < n; i++) {
277 fprintf(stderr, "%ldth point: c1=%le c2=%le", i, tab->c1[i], tab->c2[i]);
278 if (tab->s1)
279 fprintf(stderr, " s1=%le s2=%le\n", tab->s1[i], tab->s2[i]);
280 else
281 fputc('\n', stderr);
282 }
283#endif
284
285 return (1);
286}
287
288/* routine: put_table()
289 * purpose: write a table of numbers to a file in dpl format
290 *
291 * Michael Borland, 1987.
292 */
293
294void put_table(char *file, TABLE *tab, char *format) {
295 register long i;
296 FILE *fp;
297
298 if (SDDS_WriteMplTable(tab, file))
299 return;
300
301 fp = fopen_e(file, "w", FOPEN_SAVE_IF_EXISTS);
302
303 fprintf(fp, "%s\n%s\n%s\n%s\n%-10ld\n", tab->xlab, tab->ylab, tab->title, tab->topline, tab->n_data);
304
305 if (tab->flags & SIGMA_X_PRESENT && tab->flags & SIGMA_Y_PRESENT) {
306 if (format == NULL)
307 format = "%le %le %le %le\n";
308 for (i = 0; i < tab->n_data; i++)
309 fprintf(fp, format, tab->c1[i], tab->c2[i], tab->s1[i], tab->s2[i]);
310 } else if (tab->flags & SIGMA_X_PRESENT) {
311 if (format == NULL)
312 format = "%le %le %le 0.0\n";
313 for (i = 0; i < tab->n_data; i++)
314 fprintf(fp, format, tab->c1[i], tab->c2[i], tab->s1[i]);
315 } else if (tab->flags & SIGMA_Y_PRESENT) {
316 if (format == NULL)
317 format = "%le %le %le\n";
318 for (i = 0; i < tab->n_data; i++)
319 fprintf(fp, format, tab->c1[i], tab->c2[i], tab->s2[i]);
320 } else {
321 if (format == NULL)
322 format = "%le %le\n";
323 for (i = 0; i < tab->n_data; i++)
324 fprintf(fp, format, tab->c1[i], tab->c2[i]);
325 }
326
327 fclose(fp);
328}
329
330/* routine: get_table_float()
331 * purpose: get a table from a file (dpl format) and use float arrays
332 */
333
334long get_table_float(TABLE_FLOAT *tab, char *file, long sample_interval, long flags) {
335 long i, n, m;
336 long sigma_y_present, sigma_x_and_y_present;
337 char s[OAGBUFSIZ];
338 float tmp;
339 FILE *fp;
340 char *ptr;
341
342 fp = fopen_e(file, "r", 0);
343#ifdef DEBUG
344 fprintf(stderr, "file %s opened: sample_interval=%ld flags=%x\n", file, sample_interval, flags);
345#endif
346
347 sigma_y_present = sigma_x_and_y_present = 0;
348
349 /* read in plot labels, skipping comment lines (! lines) */
350 fgets_skip(s, OAGBUFSIZ, fp, '!', 1);
351 delete_trailing_blanks(s);
352 cp_str(&(tab->xlab), s);
353 fgets_skip(s, OAGBUFSIZ, fp, '!', 1);
354 delete_trailing_blanks(s);
355 cp_str(&(tab->ylab), s);
356 fgets_skip(s, OAGBUFSIZ, fp, '!', 1);
357 delete_trailing_blanks(s);
358 cp_str(&(tab->title), s);
359 fgets_skip(s, OAGBUFSIZ, fp, '!', 1);
360 delete_trailing_blanks(s);
361 cp_str(&(tab->topline), s);
362 if (flags & SWAP) {
363 ptr = tab->xlab;
364 tab->xlab = tab->ylab;
365 tab->ylab = ptr;
366 }
367#ifdef DEBUG
368 fprintf(stderr, "labels:\n<%s>\n<%s>\n<%s>\n<%s>\n", tab->xlab, tab->ylab, tab->title, tab->topline);
369#endif
370
371 if (flags & READ_LABELS_ONLY) {
372 fclose(fp);
373 return (1);
374 }
375
376 /* read in the number of data points */
377 fgets_skip(s, OAGBUFSIZ, fp, '!', 1);
378 if (!*s || 1 != sscanf(s, "%f", &tmp)) {
379 fprintf(stderr, "error in format of file %s--couldn't scan number of points\n", file);
380 exit(1);
381 }
382 n = tmp + 0.5;
383#ifdef DEBUG
384 fprintf(stderr, "n_pts = %ld\n", n);
385#endif
386
387 /* adjust the number of data points for the sampling interval */
388 if (sample_interval <= 0)
389 sample_interval = 1;
390 n = n / sample_interval;
391
392 /* allocate memory for column 1 and 2 data and sigmas */
393 tab->c1 = tmalloc(sizeof(*(tab->c1)) * n);
394 tab->c2 = tmalloc(sizeof(*(tab->c2)) * n);
395 tab->s1 = tmalloc(sizeof(*(tab->s1)) * n);
396 tab->s2 = tmalloc(sizeof(*(tab->s2)) * n);
397 tab->flags = 0;
398
399#ifdef DEBUG
400 fprintf(stderr, "data pointers are: %x, %x, %x, %x\n", (unsigned long)tab->c1, (unsigned long)tab->c2, (unsigned long)tab->s1, (unsigned long)tab->s2);
401#endif
402
403 /* read in the data points, one by one */
404 for (i = 0; i < n; i++) {
405 if (fgets_skip(s, OAGBUFSIZ, fp, '!', (i == 0 ? 1 : sample_interval))) {
406#ifdef DEBUG
407 fprintf(stderr, "string: <%s>\n", s);
408#endif
409 if ((ptr = strchr(s, '!')))
410 *ptr = 0;
411 if (!get_float(tab->c1 + i, s) || !get_float(tab->c2 + i, s)) {
412 fprintf(stderr, "warning: error in format of file %s--point %ld\n", file, n);
413 n = i - 1;
414 tab->c1 = trealloc((void *)tab->c1, sizeof(*(tab->c1)) * n);
415 tab->c2 = trealloc((void *)tab->c2, sizeof(*(tab->c2)) * n);
416 tab->s1 = trealloc((void *)tab->s1, sizeof(*(tab->s1)) * n);
417 tab->s2 = trealloc((void *)tab->s2, sizeof(*(tab->s2)) * n);
418 break;
419 }
420 tab->s1[i] = tab->s2[i] = 0;
421 if (i == 0) {
422 /* First point--establish the number of sigma values in the
423 * data. If there's only one sigma, interpret it as sigma_y,
424 * otherwise, the sigmas are sigma_x and sigma_y, in that
425 * order.
426 */
427 if (get_float(tab->s1 + i, s)) {
428 if (get_float(tab->s2 + i, s)) {
429 sigma_x_and_y_present = 1;
430 tab->flags |= SIGMA_X_PRESENT + SIGMA_Y_PRESENT;
431 } else {
432 tab->s2[i] = tab->s1[i];
433 tab->s1[i] = 0;
434 tab->flags |= SIGMA_Y_PRESENT;
435 sigma_y_present = 1;
436 }
437 }
438#ifdef DEBUG
439 fprintf(stderr, "tab->flags = %x\n", tab->flags);
440#endif
441 } else {
442 /* Scan sigma_y or (sigma_x, sigma_y) values, according
443 * to what the first line indicated is supposed to be present.
444 */
445 if (sigma_y_present && !get_float(tab->s2 + i, s)) {
446 fprintf(stderr, "error in format of file %s--expected sigma is missing\n", file);
447 exit(1);
448 } else if (sigma_x_and_y_present && (!get_float(tab->s1 + i, s) || !get_float(tab->s2 + i, s))) {
449 fprintf(stderr, "error in format of file %s--expected sigma is missing\n", file);
450 exit(1);
451 }
452 }
453 if (flags & SWAP) {
454 /* exchange x and y data points */
455 tmp = tab->c1[i];
456 tab->c1[i] = tab->c2[i];
457 tab->c2[i] = tmp;
458 /* exchange the sigmas, too */
459 tmp = tab->s1[i];
460 tab->s1[i] = tab->s2[i];
461 tab->s2[i] = tmp;
462 }
463 } else {
464 fprintf(stderr, "Warning: file %s contains only %ld of %ld expected points.\n", file, i, n);
465 n = i;
466 tab->c1 = trealloc((void *)tab->c1, sizeof(*(tab->c1)) * n);
467 tab->c2 = trealloc((void *)tab->c2, sizeof(*(tab->c2)) * n);
468 tab->s1 = trealloc((void *)tab->s1, sizeof(*(tab->s1)) * n);
469 tab->s2 = trealloc((void *)tab->s2, sizeof(*(tab->s2)) * n);
470 break;
471 }
472 }
473 tab->n_data = n;
474
475 /* Check to see if the data needs to be reverse in order, i.e.,
476 * if the first point should be the last and the last first.
477 */
478 if (flags & REVERSE || ((flags & REORDER_ASCENDING) && tab->c1[0] > tab->c1[n - 1]) || ((flags & REORDER_DESCENDING) && tab->c1[0] < tab->c1[n - 1])) {
479 /* Reverse the order of the data. */
480 m = n - 1;
481 for (i = 0; i < n / 2; i++) {
482 tmp = tab->c1[i];
483 tab->c1[i] = tab->c1[m - i];
484 tab->c1[m - i] = tmp;
485 tmp = tab->c2[i];
486 tab->c2[i] = tab->c2[m - i];
487 tab->c2[m - i] = tmp;
488 tmp = tab->s1[i];
489 tab->s1[i] = tab->s1[m - i];
490 tab->s1[m - i] = tmp;
491 tmp = tab->s2[i];
492 tab->s2[i] = tab->s2[m - i];
493 tab->s2[m - i] = tmp;
494 }
495 }
496
497 /* Check file for extra data. */
498 if (fgets_skip(s, OAGBUFSIZ, fp, '!', sample_interval))
499 fprintf(stderr, "Warning: file %s contains excess data (which is ignored).\n", file);
500
501 /* If there were no sigmas, free the arrays. */
502 if (!(tab->flags & SIGMA_X_PRESENT || tab->flags & SIGMA_Y_PRESENT) && !(flags & SAVE_SIGMA_ARRAYS)) {
503 tfree(tab->s1);
504 tab->s1 = NULL;
505 tfree(tab->s2);
506 tab->s2 = NULL;
507 }
508
509#ifdef DEBUG
510 for (i = 0; i < n; i++) {
511 fprintf(stderr, "%ldth point: c1=%le c2=%le", i, tab->c1[i], tab->c2[i]);
512 if (tab->s1)
513 fprintf(stderr, " s1=%le s2=%le\n", tab->s1[i], tab->s2[i]);
514 else
515 fputc('\n', stderr);
516 }
517#endif
518
519 fclose(fp);
520 return (1);
521}
522
523/* routine: put_table_float()
524 * purpose: write a table of numbers to a file in dpl format, using
525 * float table
526 *
527 * Michael Borland, 1987.
528 */
529
530void put_table_float(char *file, TABLE_FLOAT *tab, char *format) {
531 register long i;
532 FILE *fp;
533
534 fp = fopen_e(file, "w", FOPEN_SAVE_IF_EXISTS);
535
536 fprintf(fp, "%s\n%s\n%s\n%s\n%-10ld\n", tab->xlab, tab->ylab, tab->title, tab->topline, tab->n_data);
537
538 if (tab->flags & SIGMA_X_PRESENT && tab->flags & SIGMA_Y_PRESENT) {
539 if (format == NULL)
540 format = "%e %e %e %e\n";
541 for (i = 0; i < tab->n_data; i++)
542 fprintf(fp, format, tab->c1[i], tab->c2[i], tab->s1[i], tab->s2[i]);
543 } else if (tab->flags & SIGMA_X_PRESENT) {
544 if (format == NULL)
545 format = "%e %e %e 0.0\n";
546 for (i = 0; i < tab->n_data; i++)
547 fprintf(fp, format, tab->c1[i], tab->c2[i], tab->s1[i]);
548 } else if (tab->flags & SIGMA_Y_PRESENT) {
549 if (format == NULL)
550 format = "%e %e %e\n";
551 for (i = 0; i < tab->n_data; i++)
552 fprintf(fp, format, tab->c1[i], tab->c2[i], tab->s2[i]);
553 } else {
554 if (format == NULL)
555 format = "%e %e\n";
556 for (i = 0; i < tab->n_data; i++)
557 fprintf(fp, format, tab->c1[i], tab->c2[i]);
558 }
559
560 fclose(fp);
561}
562
563/* routine: float_array_from_double()
564 * purpose: copy an array of doubles into a newly-allocated array of floats
565 */
566
567float *float_array_from_double(double *x, long n) {
568 register float *ptr;
569 register long i;
570
571 if (!(ptr = tmalloc(n * sizeof(*ptr))))
572 return (ptr);
573
574 for (i = 0; i < n; i++)
575 ptr[i] = x[i];
576 return (ptr);
577}
578
579/* routine: double_array_from_float()
580 * purpose: copy an array of floats into a newly-allocated array of doubles
581 */
582
583double *double_array_from_float(float *x, long n) {
584 register double *ptr;
585 register long i;
586
587 if (!(ptr = tmalloc(n * sizeof(*ptr))))
588 return (ptr);
589
590 for (i = 0; i < n; i++)
591 ptr[i] = x[i];
592 return (ptr);
593}
594
595/* routine: delete_trailing_blanks
596 * purpose: delete trailing blanks in a string
597 */
598
599void delete_trailing_blanks(char *s) {
600 register char *ptr;
601
602 ptr = strlen(s) - 1 + s;
603 while (ptr >= s && isspace(*ptr))
604 *ptr-- = 0;
605}
606
607/* routine: fgets_skip()
608 * purpose: fgets() with skipping of lines according to a comment character
609 * and a sampling interval
610 */
611
612char *fgets_skip(char *s, /* buffer for lines */
613 long slen, /* length of lines to read */
614 FILE *fp, /* file to read from */
615 char skip_char, /* ignore lines that begin with this character */
616 long skip_lines /* skip this many (non-ignored) lines before returning a line */
617) {
618 register long i;
619 char c;
620
621 i = 0;
622 do {
623 if (!fgets(s, slen, fp))
624 return (NULL);
625 if (s[0] != skip_char)
626 i++;
627 } while (i < skip_lines);
628 if ((long)strlen(s) >= slen - 1) {
629 while ((c = getc(fp)))
630 if (c == '\n')
631 break;
632 }
633 return (s);
634}
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
void * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
Definition array.c:181
int tfree(void *ptr)
Frees a memory block and records the deallocation if tracking is enabled.
Definition array.c:230
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
Definition cp_str.c:28
int get_double(double *dptr, char *s)
Parses a double value from the given string.
Definition data_scan.c:40
int get_float(float *fptr, char *s)
Parses a float value from the given string.
Definition data_scan.c:208
long fexists(const char *filename)
Checks if a file exists.
Definition fexists.c:27
FILE * fopen_e(char *file, char *open_mode, long mode)
Opens a file with error checking, messages, and aborts.
Definition fopen_e.c:30
int32_t SDDS_ReadIntoMplTable(TABLE *mpl_data, char *file, int64_t sample_interval, int32_t mpl_flags, char *SDDS_tags)
Reads SDDS data into an MPL-compatible table structure.
long SDDS_AddMplDefinition(SDDS_TABLE *SDDS_table, char *label, char *suffix, char *default_name, char *filename)
Adds an MPL-compatible column definition to an SDDS dataset.
int32_t SDDS_WriteMplTable(TABLE *mpl_data, char *file)
Writes an MPL-compatible table to an SDDS file.
void SDDS_FixMplName(char *name)
Cleans and fixes an MPL-compatible name by removing specific sequences and extra spaces.
long get_table(TABLE *tab, char *file, int64_t sample_interval, long flags)
Gets a table from a file in DPL format.
Definition table.c:45
void SDDS_ExtractNameAndUnit(char **name, char **unit, char *label)
Extracts the name and unit from a labeled string.