SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
sddssplit.c File Reference

Detailed Description

Splits an SDDS file into multiple files, each containing a single page.

This utility reads an SDDS (Self Describing Data Set) file and splits its contents into multiple output files, with each page stored in a separate file. The tool allows customization of output filenames, page selection, output format, and more.

Usage

sddssplit <inputFile>
[-pipe[=input]]
[-binary | -ascii]
[-digits=<number>]
[-rootname=<string>]
[-firstPage=<number>]
[-lastPage=<number>]
[-interval=<number>]
[-extension=<string>]
[-groupParameter=<parameterName>]
[-nameParameter=<filenameParameter>]
[-offset=<integer>]
[-majorOrder=row|column]

Options

Optional Description
-pipe Use standard input instead of an input file.
-binary Specify output format (binary).
-ascii Specify output format (ASCII).
-digits Specify number of digits for output file indices.
-rootname Rootname for output filenames. Defaults to input file name.
-firstPage First page to include in the output. Defaults to 1.
-lastPage Last page to include in the output. Defaults to the last page in the input file.
-interval Interval between included pages. Defaults to 1.
-extension Specify file extension for output files. Defaults to "sdds".
-groupParameter Group pages into output files based on the specified parameter.
-nameParameter Name output files based on the specified parameter.
-offset Offset for page numbering in output filenames.
-majorOrder Specify row- or column-major order for output.
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, H. Shang

Definition in file sddssplit.c.

#include "mdb.h"
#include "SDDS.h"
#include "scan.h"

Go to the source code of this file.

Functions

int main (int argc, char **argv)
 

Function Documentation

◆ main()

int main ( int argc,
char ** argv )

Definition at line 128 of file sddssplit.c.

128 {
129 SDDS_DATASET sdds_dataset, sdds_orig;
130 long i_arg, offset = 0;
131 SCANNED_ARG *s_arg;
132 char *input = NULL, *rootname = NULL, name[500], format[100], *extension = "sdds";
133 long ascii_output = 0, binary_output = 0, retval, digits = 3;
134 long first_page = 0, last_page = 0, interval = 0;
135 unsigned long pipe_flags = 0, major_order_flag = 0;
136 char *file_parameter = NULL, *name_from_parameter = NULL, *group_parameter_name = NULL;
137 char *last_group_parameter = NULL, *this_group_parameter = NULL;
138 short column_major_order = -1, file_active = 0;
139
141 argc = scanargs(&s_arg, argc, argv);
142 if (argc < 2) {
143 fprintf(stderr, "%s", USAGE);
144 return 1;
145 }
146
147 for (i_arg = 1; i_arg < argc; i_arg++) {
148 if (s_arg[i_arg].arg_type == OPTION) {
149 delete_chars(s_arg[i_arg].list[0], "_");
150 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
151 case SET_MAJOR_ORDER:
152 major_order_flag = 0;
153 s_arg[i_arg].n_items--;
154 if (s_arg[i_arg].n_items > 0 &&
155 !scanItemList(&major_order_flag, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
156 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
157 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)) {
158 fprintf(stderr, "Error: Invalid -majorOrder syntax/values\n");
159 return 1;
160 }
161 column_major_order = (major_order_flag & SDDS_COLUMN_MAJOR_ORDER) ? 1 : 0;
162 break;
163 case SET_BINARY:
164 binary_output = 1;
165 ascii_output = 0;
166 break;
167 case SET_ASCII:
168 ascii_output = 1;
169 binary_output = 0;
170 break;
171 case SET_DIGITS:
172 if (s_arg[i_arg].n_items != 2 || sscanf(s_arg[i_arg].list[1], "%ld", &digits) != 1 || digits <= 0) {
173 fprintf(stderr, "Error: Invalid -digits syntax\n");
174 return 1;
175 }
176 break;
177 case SET_ROOTNAME:
178 if (s_arg[i_arg].n_items != 2) {
179 fprintf(stderr, "Error: Invalid -rootname syntax\n");
180 return 1;
181 }
182 rootname = s_arg[i_arg].list[1];
183 break;
184 case SET_FIRST_PAGE:
185 if (s_arg[i_arg].n_items != 2 || sscanf(s_arg[i_arg].list[1], "%ld", &first_page) != 1 || first_page <= 0) {
186 fprintf(stderr, "Error: Invalid -firstPage syntax\n");
187 return 1;
188 }
189 break;
190 case SET_LAST_PAGE:
191 if (s_arg[i_arg].n_items != 2 || sscanf(s_arg[i_arg].list[1], "%ld", &last_page) != 1 || last_page <= 0) {
192 fprintf(stderr, "Error: Invalid -lastPage syntax\n");
193 return 1;
194 }
195 break;
196 case SET_INTERVAL:
197 if (s_arg[i_arg].n_items != 2 || sscanf(s_arg[i_arg].list[1], "%ld", &interval) != 1 || interval <= 0) {
198 fprintf(stderr, "Error: Invalid -interval syntax\n");
199 return 1;
200 }
201 break;
202 case SET_EXTENSION:
203 if (s_arg[i_arg].n_items != 2) {
204 fprintf(stderr, "Error: Invalid -extension syntax\n");
205 return 1;
206 }
207 extension = s_arg[i_arg].list[1];
208 break;
209 case SET_OFFSET:
210 if (s_arg[i_arg].n_items != 2 || sscanf(s_arg[i_arg].list[1], "%ld", &offset) != 1) {
211 fprintf(stderr, "Error: Invalid -offset syntax\n");
212 return 1;
213 }
214 break;
215 case SET_PIPE:
216 pipe_flags = USE_STDIN;
217 break;
218 case SET_NAMEPARAMETER:
219 if (s_arg[i_arg].n_items != 2) {
220 fprintf(stderr, "Error: Invalid -nameParameter syntax\n");
221 return 1;
222 }
223 file_parameter = s_arg[i_arg].list[1];
224 break;
225 case SET_GROUPPARAMETER:
226 if (s_arg[i_arg].n_items != 2) {
227 fprintf(stderr, "Error: Invalid -groupParameter syntax\n");
228 return 1;
229 }
230 group_parameter_name = s_arg[i_arg].list[1];
231 break;
232 default:
233 fprintf(stderr, "Error: Unknown switch: %s\n", s_arg[i_arg].list[0]);
234 fprintf(stderr, "%s", USAGE);
235 return 1;
236 }
237 } else {
238 if (!input) {
239 input = s_arg[i_arg].list[0];
240 } else {
241 fprintf(stderr, "Error: Too many filenames\n");
242 return 1;
243 }
244 }
245 }
246
247 if (!input && !(pipe_flags & USE_STDIN)) {
248 fprintf(stderr, "Error: Missing input filename\n");
249 return 1;
250 }
251
252 if (pipe_flags & USE_STDIN && !file_parameter && !rootname) {
253 fprintf(stderr, "Error: Provide -rootname or -nameParameter with -pipe\n");
254 return 1;
255 }
256
257 if (!rootname && !file_parameter) {
258 if ((rootname = strrchr(input, '.'))) {
259 *rootname = 0;
260 SDDS_CopyString(&rootname, input);
261 input[strlen(input)] = '.';
262 } else {
263 SDDS_CopyString(&rootname, input);
264 }
265 }
266
267 if (first_page && last_page && first_page > last_page) {
268 fprintf(stderr, "Error: firstPage > lastPage\n");
269 return 1;
270 }
271
272 if (!SDDS_InitializeInput(&sdds_orig, input)) {
273 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
274 return 1;
275 }
276
277 if (!extension || SDDS_StringIsBlank(extension)) {
278 extension = NULL;
279 snprintf(format, sizeof(format), "%%s%%0%ldld", digits);
280 } else {
281 snprintf(format, sizeof(format), "%%s%%0%ldld.%s", digits, extension);
282 }
283
284 if (file_parameter &&
285 SDDS_CheckParameter(&sdds_orig, file_parameter, NULL, SDDS_STRING, stderr) != SDDS_CHECK_OKAY) {
286 fprintf(stderr, "Error: Filename parameter not present or wrong type\n");
287 return 1;
288 }
289
290 last_group_parameter = NULL;
291 while ((retval = SDDS_ReadPage(&sdds_orig)) > 0) {
292 if (first_page && retval < first_page) {
293 continue;
294 }
295 if (last_page && retval > last_page) {
296 break;
297 }
298 if (interval) {
299 if (first_page) {
300 if ((retval - first_page) % interval != 0) {
301 continue;
302 }
303 } else if ((retval - 1) % interval != 0) {
304 continue;
305 }
306 }
307 if (file_parameter) {
308 if (!SDDS_GetParameter(&sdds_orig, file_parameter, &name_from_parameter)) {
309 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
310 return 1;
311 }
312 strncpy(name, name_from_parameter, sizeof(name) - 1);
313 name[sizeof(name) - 1] = '\0';
314 free(name_from_parameter);
315 } else {
316 snprintf(name, sizeof(name), format, rootname, retval - offset);
317 }
318 if (group_parameter_name) {
319 if (!SDDS_GetParameterAsString(&sdds_orig, group_parameter_name, &this_group_parameter)) {
320 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
321 return 1;
322 }
323 }
324 if (!group_parameter_name || !last_group_parameter ||
325 (group_parameter_name && strcmp(this_group_parameter, last_group_parameter))) {
326 if (file_active && !SDDS_Terminate(&sdds_dataset)) {
327 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
328 return 1;
329 }
330 file_active = 0;
331 if (!SDDS_InitializeCopy(&sdds_dataset, &sdds_orig, name, "w")) {
332 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
333 return 1;
334 }
335 if ((ascii_output && sdds_dataset.layout.data_mode.mode != SDDS_ASCII) ||
336 (binary_output && sdds_dataset.layout.data_mode.mode != SDDS_BINARY)) {
337 sdds_dataset.layout.data_mode.mode = ascii_output ? SDDS_ASCII : SDDS_BINARY;
338 }
339 sdds_dataset.layout.data_mode.column_major = (column_major_order != -1) ? column_major_order : sdds_orig.layout.data_mode.column_major;
340 if (!SDDS_WriteLayout(&sdds_dataset)) {
341 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
342 return 1;
343 }
344 file_active = 1;
345 }
346 if (group_parameter_name) {
347 free(last_group_parameter);
348 last_group_parameter = this_group_parameter;
349 this_group_parameter = NULL;
350 }
351 if (!SDDS_CopyPage(&sdds_dataset, &sdds_orig) || !SDDS_WritePage(&sdds_dataset)) {
352 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
353 return 1;
354 }
355 }
356 if (retval == 0) {
357 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
358 return 1;
359 }
360 if (!SDDS_Terminate(&sdds_orig)) {
361 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
362 return 1;
363 }
364 return 0;
365}
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
Definition SDDS_copy.c:40
int32_t SDDS_CopyPage(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:578
char * SDDS_GetParameterAsString(SDDS_DATASET *SDDS_dataset, char *parameter_name, char **memory)
Retrieves the value of a specified parameter as a string from the current data table of an SDDS datas...
void * SDDS_GetParameter(SDDS_DATASET *SDDS_dataset, char *parameter_name, void *memory)
Retrieves the value of a specified parameter from the current data table of a data set.
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:49
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_ReadPage(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
int32_t SDDS_StringIsBlank(char *s)
Checks if a string is blank (contains only whitespace characters).
int32_t SDDS_CheckParameter(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a parameter exists in the SDDS dataset with the specified name, units, and type.
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
Definition SDDS_utils.c:856
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
char * delete_chars(char *s, char *t)
Removes all occurrences of characters found in string t from string s.
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)
Definition scanargs.c:36
long scanItemList(unsigned long *flags, char **item, long *items, unsigned long mode,...)
Scans a list of items and assigns values based on provided keywords and types.