SDDSlib
Loading...
Searching...
No Matches
mcTable.c File Reference

Read and write routines for Multi-Column Tables. More...

#include "mdb.h"
#include "column.h"
#include <ctype.h>

Go to the source code of this file.

Macros

#define DEBUG   0
 

Functions

char * fgets_mc_skip (char *s, long slen, FILE *fp, char skip_char)
 
void get_name_unit_descrip_format (char **name, char **unit, char **descrip, char **format, char *_buffer)
 
long get_mc_table (MC_TABLE *table, char *file, long flags)
 Reads a multi-column table from a file.
 
long put_mc_table (char *file, MC_TABLE *table)
 
long put_mc_table_header (FILE *fpo, MC_TABLE *table)
 

Variables

static char buffer [1024]
 
static char buffer1 [1024]
 

Detailed Description

Read and write routines for Multi-Column Tables.

This file contains functions to handle multi-column table operations, including reading from and writing to table files. It provides mechanisms to parse table headers, handle auxiliary quantities, and manage table data.

License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
M. Borland, C. Saunders, R. Soliday

Definition in file mcTable.c.

Macro Definition Documentation

◆ DEBUG

#define DEBUG   0

Definition at line 24 of file mcTable.c.

Function Documentation

◆ fgets_mc_skip()

char * fgets_mc_skip ( char * s,
long slen,
FILE * fp,
char skip_char )

Definition at line 197 of file mcTable.c.

202 {
203 do {
204 if (!fgets(s, slen, fp))
205 return (NULL);
206 chop_nl(s);
207 if (s[0] != skip_char)
208 break;
209 } while (1);
210 return (s);
211}

◆ get_mc_table()

long get_mc_table ( MC_TABLE * table,
char * file,
long flags )

Reads a multi-column table from a file.

Parses the specified file to populate the MC_TABLE structure with column information, auxiliary quantities, and table data.

Parameters
tablePointer to the MC_TABLE structure to populate.
filePath to the table file to read.
flagsFlags to control warning messages and behavior.
Returns
Returns 1 on success, 0 on failure.

Definition at line 42 of file mcTable.c.

42 {
43 FILE *fpi;
44 long i, j, i_col;
45 char *ptr;
46
47 if (!(fpi = fopen_e(file, "r", 1)))
48 return (0);
49
50 if (!fgets_mc_skip(buffer, 1024, fpi, '!'))
51 bomb("unable to read first line of table file", NULL);
52 if (!(get_long(&table->n_cols, buffer)))
53 bomb("unable to scan number of columns in table file", NULL);
54 if (table->n_cols <= 0)
55 bomb("number of columns is invalid in table file", NULL);
56 table->n_lines_per_row = 1;
57 table->n_auxiliaries = 0;
58 if (get_long(&table->n_lines_per_row, buffer)) {
59 if (table->n_lines_per_row <= 0)
60 bomb("number of lines per row is invalid in table file", NULL);
61 if (get_long(&table->n_auxiliaries, buffer) &&
62 table->n_auxiliaries < 0)
63 bomb("number of auxiliary quantities is invalid in table file", NULL);
64 }
65
66#if DEBUG
67 printf("file %s\nn_cols = %ld n_lines_per_row = %ld n_auxiliaries = %ld\n",
68 file, table->n_cols, table->n_lines_per_row, table->n_auxiliaries);
69#endif
70
71 table->name = tmalloc(sizeof(char *) * table->n_cols);
72 table->unit = tmalloc(sizeof(char *) * table->n_cols);
73 table->description = tmalloc(sizeof(char *) * table->n_cols);
74 table->format = tmalloc(sizeof(char *) * table->n_cols);
75
76 for (i = 0; i < table->n_cols; i++) {
77 if (!fgets_mc_skip(buffer, 1024, fpi, '!'))
78 bomb("missing quantity name and units line in table file", NULL);
79 get_name_unit_descrip_format(table->name + i, table->unit + i,
80 table->description + i, table->format + i, buffer);
81 if (table->format[i] && !strchr(table->format[i], '%'))
82 table->format[i] = NULL;
83 }
84
85#if DEBUG
86 for (i = 0; i < table->n_cols; i++)
87 printf("column %ld: %s in %s--%s in format %s\n",
88 i, table->name[i], table->unit[i], table->description[i],
89 (table->format[i] ? table->format[i] : "{null}"));
90#endif
91
92 if (!fgets_mc_skip(buffer, 1024, fpi, '!'))
93 bomb("missing title string in table file", NULL);
94 cp_str(&table->title, buffer);
95
96 if (!fgets_mc_skip(buffer, 1024, fpi, '!'))
97 bomb("missing label string in table file", NULL);
98 cp_str(&table->label, buffer);
99
100#if DEBUG
101 printf("title: %s\nlabel: %s\n", table->title, table->label);
102#endif
103
104 if (table->n_auxiliaries) {
105#if DEBUG
106 printf("%ld auxuliary quantities are expected\n", table->n_auxiliaries);
107#endif
108 /* get auxiliary quantity names\units... */
109 table->aux_name = tmalloc(sizeof(char *) * table->n_auxiliaries);
110 table->aux_unit = tmalloc(sizeof(char *) * table->n_auxiliaries);
111 table->aux_description = tmalloc(sizeof(char *) * table->n_auxiliaries);
112 table->aux_value = tmalloc(sizeof(*(table->aux_value)) * table->n_auxiliaries);
113 for (i = 0; i < table->n_auxiliaries; i++) {
114 if (!fgets_mc_skip(buffer, 1024, fpi, '!'))
115 bomb("missing quantity name and units line in table file", NULL);
116 get_name_unit_descrip_format(table->aux_name + i, table->aux_unit + i,
117 table->aux_description + i, &ptr, buffer);
118 if ((!ptr || 1 != sscanf(ptr, "%lf", table->aux_value + i)) && flags & GMCT_WARN_MISSING_AUXVAL)
119 printf("warning: missing value for auxiliary quantity %s---zero assumed\n", table->aux_name[i]);
120 }
121 }
122
123#if DEBUG
124 for (i = 0; i < table->n_auxiliaries; i++) {
125 printf("auxiliary %ld: %s = %le %s---%s\n",
126 i, table->aux_name[i], table->aux_value[i], table->aux_unit[i],
127 table->aux_description[i]);
128 }
129#endif
130
131 if (!fgets_mc_skip(buffer, 1024, fpi, '!'))
132 bomb("missing number of data rows in table file", NULL);
133 if (!get_long(&table->n_rows, buffer) || table->n_rows < 0)
134 bomb("invalid number of data rows specified in table file", NULL);
135 if (table->n_rows == 0)
136 return (1);
137
138#if DEBUG
139 printf("n_rows = %ld\n", table->n_rows);
140#endif
141
142 table->value = (double **)zarray_2d(sizeof(double), table->n_cols, table->n_rows);
143 table->row_label = (char **)tmalloc(sizeof(char *) * table->n_rows);
144
145 for (i = 0; i < table->n_rows; i++) {
146 i_col = 0;
147 table->row_label[i] = NULL;
148 for (j = 0; j < table->n_lines_per_row && i_col < table->n_cols; j++) {
149 if (!fgets_mc_skip(buffer, 1024, fpi, '!'))
150 break;
151 strcpy(buffer1, buffer);
152#if DEBUG
153 printf("row %ld, line %ld:\n%s\n", i, j, buffer);
154#endif
155 while (i_col < table->n_cols && get_double(table->value[i_col] + i, buffer))
156 i_col++;
157 }
158
159 if (!is_blank(buffer)) {
160 cp_str(table->row_label + i, buffer);
161 while (isspace(*table->row_label[i]))
162 table->row_label[i]++;
163 } else
164 cp_str(table->row_label + i, "");
165
166 if (i_col == 0) {
167 if (flags & GMCT_WARN_WRONG_COUNT)
168 printf("warning: fewer data rows than expected in file %s\n", file);
169 break;
170 } else if (i_col != table->n_cols) {
171 if (flags & GMCT_WARN_INCOMPLETE_ROW) {
172 printf("warning: incomplete data row in file %s\n", file);
173 printf("line in question is:\n%s\n", buffer1);
174 printf("skipping to next line\n");
175 }
176 i--;
177 continue;
178 }
179#if DEBUG
180 printf("%ld: ", i);
181 for (i_col = 0; i_col < table->n_cols; i_col++)
182 printf("%.4le ", table->value[i_col][i]);
183 putchar('\n');
184#endif
185 }
186 if (i == table->n_rows && fgets_mc_skip(buffer, 1024, fpi, '!') && flags & GMCT_WARN_EXTRA_ROWS)
187 printf("warning: file %s contains extra rows, which are ignored\n",
188 file);
189 table->n_rows = i;
190 return (1);
191}
void ** zarray_2d(uint64_t size, uint64_t n1, uint64_t n2)
Allocates a 2D array with specified dimensions.
Definition array.c:93
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_long(long *iptr, char *s)
Parses a long integer value from the given string.
Definition data_scan.c:255
int get_double(double *dptr, char *s)
Parses a double value from the given string.
Definition data_scan.c:40
FILE * fopen_e(char *file, char *open_mode, long mode)
Opens a file with error checking, messages, and aborts.
Definition fopen_e.c:30
long is_blank(char *s)
Determine whether a string is composed entirely of whitespace characters.
Definition is_blank.c:27

◆ get_name_unit_descrip_format()

void get_name_unit_descrip_format ( char ** name,
char ** unit,
char ** descrip,
char ** format,
char * _buffer )

Definition at line 269 of file mcTable.c.

269 {
270 char *ptr, *ptrn, *ptru, *ptrd, *ptrf;
271 char *blank_string;
272
273 cp_str(&blank_string, " ");
274
275 ptr = ptrn = buf;
276 ptru = ptrd = ptrf = NULL;
277 while ((ptr = strchr(ptr, '\\'))) {
278 if (ptr[1] == '\\')
279 ptr += 2;
280 else {
281 if (!ptru) {
282 *ptr = 0;
283 ptru = ++ptr;
284 } else if (!ptrd) {
285 *ptr = 0;
286 ptrd = ++ptr;
287 } else {
288 *ptr = 0;
289 ptrf = ++ptr;
290 break;
291 }
292 }
293 }
294 cp_str(name, ptrn);
295 trim_spaces(*name);
296 if (ptru) {
297 cp_str(unit, ptru);
298 trim_spaces(*unit);
299 } else
300 *unit = blank_string;
301 if (ptrd && !is_blank(ptrd)) {
302 cp_str(descrip, ptrd);
303 trim_spaces(*descrip);
304 } else
305 cp_str(descrip, *name);
306 if (ptrf) {
307 cp_str(format, ptrf);
308 trim_spaces(*format);
309 } else
310 *format = NULL;
311}
char * trim_spaces(char *s)
Trims leading and trailing spaces from a string.
Definition trim_spaces.c:28

◆ put_mc_table()

long put_mc_table ( char * file,
MC_TABLE * table )

Definition at line 213 of file mcTable.c.

213 {
214 FILE *fpo;
215 long i, j, wrap;
216
217 if (!(fpo = fopen(file, "w"))) {
218 printf("unable to write to file %s\n", file);
219 return (0);
220 }
221
222 if (table->n_lines_per_row < 1)
223 table->n_lines_per_row = 1;
224
225 put_mc_table_header(fpo, table);
226
227 wrap = table->n_cols / table->n_lines_per_row;
228 for (i = 0; i < table->n_rows; i++) {
229 j = 0;
230 while (j < table->n_cols) {
231 fprintf(fpo, (table->format && table->format[j] ? table->format[j] : "%le"),
232 table->value[j][i]);
233 if (j == table->n_cols - 1 && table->row_label && table->row_label[j])
234 fprintf(fpo, " %s", table->row_label[j]);
235 if (++j % wrap == 0)
236 fputc('\n', fpo);
237 else
238 fputs(" ", fpo);
239 }
240 }
241 fclose(fpo);
242 return (1);
243}

◆ put_mc_table_header()

long put_mc_table_header ( FILE * fpo,
MC_TABLE * table )

Definition at line 245 of file mcTable.c.

245 {
246 long i;
247
248 fprintf(fpo, "%ld %ld %ld\n", table->n_cols, table->n_lines_per_row, table->n_auxiliaries);
249
250 for (i = 0; i < table->n_cols; i++)
251 fprintf(fpo, "%s\\%s\\%s\\%s\n",
252 table->name[i],
253 (table->unit[i] && (long)strlen(table->unit[i]) > 1) ? table->unit[i] : " ",
254 (table->description[i] && (long)strlen(table->description[i]) > 1) ? table->description[i] : " ",
255 (table->format[i] ? table->format[i] : ""));
256
257 fprintf(fpo, "%s\n%s\n",
258 (table->title && (long)strlen(table->title) > 1) ? table->title : " ",
259 (table->label && (long)strlen(table->label) > 1) ? table->label : " ");
260
261 for (i = 0; i < table->n_auxiliaries; i++)
262 fprintf(fpo, "%s\\%s\\%s\\%.16e\n", table->aux_name[i], table->aux_unit[i],
263 table->aux_description[i], table->aux_value[i]);
264
265 fprintf(fpo, "%ld\n", table->n_rows);
266 return (1);
267}

Variable Documentation

◆ buffer

char buffer[1024]
static

Definition at line 26 of file mcTable.c.

◆ buffer1

char buffer1[1024]
static

Definition at line 27 of file mcTable.c.