50#include "match_string.h"
60char *option[N_OPTIONS] = {
68 "mpl2sdds <mpl-filename> [<mpl-filename>...] \n"
69 " -output=<SDDS-filename>\n"
70 " [-erase] [-binary]\n\n"
72 " -output=<SDDS-filename> Specifies the output SDDS file. This option is mandatory.\n"
73 " -erase Erase existing data in the output SDDS file before adding new data.\n"
74 " -binary Output the SDDS file in binary format.\n\n"
75 "Program by Michael Borland. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
").";
77void extract_name_and_unit(
char **name,
char **unit,
char *label);
78long add_definition(
SDDS_DATASET *SDDS_dataset,
char *label,
char *filename);
79void fix_mpl_name(
char *name);
81int main(
int argc,
char **argv) {
86 long i, j, i_arg, inputs;
88 long erase, rows, new_columns, SDDS_rows;
94 argc =
scanargs(&scanned, argc, argv);
101 inputs = erase = binary = 0;
103 for (i_arg = 1; i_arg < argc; i_arg++) {
104 if (scanned[i_arg].arg_type == OPTION) {
106 switch (
match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
111 if (scanned[i_arg].n_items != 2) {
112 bomb(
"Invalid syntax for -output option.", USAGE);
114 output = scanned[i_arg].list[1];
117 if (scanned[i_arg].n_items != 1) {
118 bomb(
"Invalid syntax for -binary option.", USAGE);
123 bomb(
"Unknown option provided.", USAGE);
126 input =
trealloc(input, (inputs + 1) *
sizeof(*input));
127 input[inputs++] = scanned[i_arg].list[0];
132 bomb(
"The -output option must be specified.", USAGE);
135 bomb(
"No input MPL files provided.", USAGE);
138 if (!erase &&
fexists(output)) {
141 fprintf(stderr,
"Error: Unable to read SDDS layout from %s.\n", output);
146 fprintf(stderr,
"Error: Unable to read data table from %s.\n", output);
151 fclose(SDDS_dataset.layout.fp);
152 SDDS_dataset.layout.fp =
fopen_e(output,
"w", 0);
155 if (!
SDDS_InitializeOutput(&SDDS_dataset, binary ? SDDS_BINARY : SDDS_ASCII, 1, NULL, NULL, output)) {
156 fprintf(stderr,
"Error: Unable to initialize output SDDS structure for %s.\n", output);
164 mpl_data =
tmalloc(
sizeof(*mpl_data) * inputs);
165 data =
tmalloc(
sizeof(*data) * (2 * inputs));
166 index =
tmalloc(
sizeof(*index) * (2 * inputs));
169 for (i = 0; i < inputs; i++) {
170 if (!
get_table(&mpl_data[i], input[i], 1, 0)) {
171 fprintf(stderr,
"Warning: Unable to read data from %s. Continuing with other files.\n", input[i]);
176 if (!(rows = mpl_data[i].n_data)) {
177 fprintf(stderr,
"Warning: No data in file %s. Continuing with other files.\n", input[i]);
180 }
else if (rows != mpl_data[i].n_data) {
181 SDDS_Bomb(
"All MPL files must have the same number of data points.");
182 }
else if (SDDS_rows != -1 && rows != SDDS_rows) {
183 SDDS_Bomb(
"Number of data points in MPL files must match the number of rows in the SDDS file.");
186 if ((index[new_columns] = add_definition(&SDDS_dataset, mpl_data[i].xlab, input[i])) < 0) {
187 free(mpl_data[i].c1);
189 data[new_columns++] = mpl_data[i].c1;
192 if ((index[new_columns] = add_definition(&SDDS_dataset, mpl_data[i].ylab, input[i])) < 0) {
193 free(mpl_data[i].c2);
195 data[new_columns++] = mpl_data[i].c2;
199 if (!rows || !new_columns) {
200 SDDS_Bomb(
"All input files are empty or invalid.");
212 for (i = 0; i < new_columns; i++) {
213 for (j = 0; j < rows; j++) {
214 SDDS_SetRowValues(&SDDS_dataset, SDDS_SET_BY_INDEX | SDDS_PASS_BY_VALUE, j, index[i], data[i][j], -1);
226long add_definition(
SDDS_DATASET *SDDS_dataset,
char *label,
char *filename) {
227 char *symbol, *name, *unit;
230 extract_name_and_unit(&symbol, &unit, label);
235 fprintf(stderr,
"Warning: Column name '%s' from file '%s' already exists and will be ignored.\n", name, filename);
247void extract_name_and_unit(
char **name,
char **unit,
char *label) {
250 if ((uptr = strchr(label,
'('))) {
252 if ((ptr = strchr(uptr,
')'))) {
261 ptr = label + strlen(label) - 1;
262 while (ptr != label && *ptr ==
' ') {
268void fix_mpl_name(
char *name) {
272 while ((ptr = strchr(ptr,
'$'))) {
273 switch (*(ptr + 1)) {
290 while ((ptr = strchr(ptr,
' '))) {
292 while (*ptr1 ==
' ') {
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row,...)
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_InitializeOutput(SDDS_DATASET *SDDS_dataset, int32_t data_mode, int32_t lines_per_row, const char *description, const char *contents, const char *filename)
Initializes the SDDS output dataset.
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
int32_t SDDS_DefineColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, int32_t field_length)
Defines a data column within the SDDS dataset.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
#define SDDS_DOUBLE
Identifier for the double data type.
void * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
long fexists(const char *filename)
Checks if a file exists.
FILE * fopen_e(char *file, char *open_mode, long mode)
Opens a file with error checking, messages, and aborts.
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
char * strcpy_ss(char *dest, const char *src)
Safely copies a string, handling memory overlap.
long get_table(TABLE *tab, char *file, int64_t sample_interval, long flags)
Gets a table from a file in DPL format.