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