SDDSlib
Loading...
Searching...
No Matches
sddsbreak.c
Go to the documentation of this file.
1/**
2 * @file sddsbreak.c
3 * @brief Breaks up pages of an SDDS (Self Describing Data Sets) file into subpages based on various criteria.
4 *
5 * This program processes an SDDS file and splits its pages into subpages according to user-specified options.
6 * Supported options allow for breaking based on gaps in data, increases or decreases of column values,
7 * changes of specified amounts or bases, matching string patterns, row limits with optional overlaps,
8 * and specifying the major order of data (row or column).
9 *
10 * ## Usage
11 * ```
12 * sddsbreak [OPTIONS] [<inputfile>] [<outputfile>]
13 * ```
14 *
15 * ### Options:
16 * - `-pipe=[input][,output]`
17 * - Use pipes for input and/or output.
18 *
19 * - `-gapin=<column-name>[,{amount=<value> | factor=<value>}]`
20 * - Break pages when the gap in the specified column exceeds a certain amount or factor.
21 *
22 * - `-increaseof=<column-name>[,amount=<value>[,cumulative][,reset]]`
23 * - Break pages when the specified column increases by a certain amount. Options allow for cumulative tracking and resetting.
24 *
25 * - `-decreaseof=<column-name>[,amount=<value>[,cumulative][,reset]]`
26 * - Break pages when the specified column decreases by a certain amount. Options allow for cumulative tracking and resetting.
27 *
28 * - `-changeof=<column-name>[,amount=<value>,base=<value>]`
29 * - Break pages based on changes in the specified column relative to a base value and by a specified amount.
30 *
31 * - `-matchto=<column-name>,<pattern>[,after]`
32 * - Break pages when a pattern is matched in the specified column. The `after` option determines if the break occurs after the match.
33 *
34 * - `-rowlimit=<integer>[,overlap=<integer>]`
35 * - Limit the number of rows per subpage with an optional overlap between consecutive subpages.
36 *
37 * - `-majorOrder=row|column`
38 * - Specify the major order of data as row-major or column-major.
39 *
40 * @copyright
41 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
42 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
43 *
44 * @license
45 * This file is distributed under the terms of the Software License Agreement
46 * found in the file LICENSE included with this distribution.
47 *
48 * @author M. Borland, C. Saunders, R. Soliday, H. Shang
49 */
50
51#include "mdb.h"
52#include "SDDS.h"
53#include "scan.h"
54
55/* Enumeration for option types */
56enum option_type {
57 SET_GAPIN,
58 SET_INCREASEOF,
59 SET_DECREASEOF,
60 SET_CHANGEOF,
61 SET_ROWLIMIT,
62 SET_PIPE,
63 SET_MATCHTO,
64 SET_MAJOR_ORDER,
65 N_OPTIONS
66};
67
68char *option[N_OPTIONS] = {
69 "gapin",
70 "increaseof",
71 "decreaseof",
72 "changeof",
73 "rowlimit",
74 "pipe",
75 "matchto",
76 "majorOrder",
77};
78
79char *USAGE =
80 "Usage: sddsbreak [OPTIONS] [<inputfile>] [<outputfile>]\n"
81 "\n"
82 "Options:\n"
83 " -pipe=[input][,output]\n"
84 " Use pipes for input and/or output.\n"
85 " -gapin=<column-name>[,{amount=<value> | factor=<value>}]\n"
86 " Break pages based on gaps in the specified column.\n"
87 " -increaseof=<column-name>[,amount=<value>[,cumulative][,reset]]\n"
88 " Break pages when the specified column increases by a certain amount.\n"
89 " -decreaseof=<column-name>[,amount=<value>[,cumulative][,reset]]\n"
90 " Break pages when the specified column decreases by a certain amount.\n"
91 " -changeof=<column-name>[,amount=<value>,base=<value>]\n"
92 " Break pages based on changes in the specified column relative to a base value.\n"
93 " -matchto=<column-name>,<pattern>[,after]\n"
94 " Break pages when a pattern is matched in the specified column.\n"
95 " -rowlimit=<integer>[,overlap=<integer>]\n"
96 " Limit the number of rows per subpage with an optional overlap.\n"
97 " -majorOrder=row|column\n"
98 " Specify the major order of data as row-major or column-major.\n"
99 "\n"
100 "Program by Michael Borland. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n";
101
102#define GAPIN_AMOUNT 0x0001U
103#define GAPIN_FACTOR 0x0002U
104char *gapinUsage = "-gapin=<column-name>[,{amount=<value> | factor=<value>}]";
105
106#define CHANGEOF_AMOUNT 0x0001U
107#define CHANGEOF_BASE 0x0002U
108char *changeofUsage = "-changeof=<column-name>[,amount=<value>,base=<value>]";
109
110#define INCREASEOF_AMOUNT 0x0001UL
111#define INCREASEOF_CUMULATIVE 0x0002UL
112#define INCREASEOF_RESET 0x0004UL
113char *increaseOfUsage = "-increaseOf=<column-name>[,amount=<value>[,cumulative][,reset]]";
114
115#define DECREASEOF_AMOUNT 0x0001UL
116#define DECREASEOF_CUMULATIVE 0x0002UL
117#define DECREASEOF_RESET 0x0004UL
118char *decreaseOfUsage = "-decreaseOf=<column-name>[,amount=<value>[,cumulative[,reset]]]";
119
120#define ROWLIMIT_OVERLAP 0x0001U
121
122int main(int argc, char **argv) {
123 SDDS_DATASET SDDSnew, SDDSold;
124 long iArg;
125 SCANNED_ARG *scArg;
126 char *input = NULL, *output = NULL, *columnName = NULL;
127 long mode = -1, matchCode, tmpfile_used;
128 int64_t i, j, rows, rowLimit;
129 long breakNext;
130 double gapAmount = 0, gapFactor = 0, changeAmount, changeBase, *columnData = NULL;
131 char *matchPattern = NULL;
132 long matchPatternAfter = 0;
133 double increaseOfAmount = -1, decreaseOfAmount = -1;
134 long retval;
135 int32_t dataType;
136 long overlap = 0;
137 unsigned long flags = 0, pipeFlags = 0, changeFlags = 0, decreaseOfFlags = 0, increaseOfFlags = 0;
138 unsigned long majorOrderFlag;
139 char **stringData = NULL;
140 short columnMajorOrder = -1;
141
143 argc = scanargs(&scArg, argc, argv);
144 if (argc < 2) {
145 fprintf(stderr, "%s", USAGE);
146 return EXIT_FAILURE;
147 }
148
149 for (iArg = 1; iArg < argc; iArg++) {
150 if (scArg[iArg].arg_type == OPTION) {
151 switch (matchCode = match_string(scArg[iArg].list[0], option, N_OPTIONS, 0)) {
152 case SET_MAJOR_ORDER:
153 majorOrderFlag = 0;
154 scArg[iArg].n_items -= 1;
155 if (scArg[iArg].n_items > 0 &&
156 !scanItemList(&majorOrderFlag, scArg[iArg].list + 1, &scArg[iArg].n_items, 0,
157 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
158 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)) {
159 SDDS_Bomb("invalid -majorOrder syntax/values");
160 }
161 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
162 columnMajorOrder = 1;
163 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
164 columnMajorOrder = 0;
165 break;
166
167 case SET_GAPIN:
168 if ((scArg[iArg].n_items -= 2) < 0 ||
169 !scanItemList(&flags, scArg[iArg].list + 2, &scArg[iArg].n_items, 0,
170 "amount", SDDS_DOUBLE, &gapAmount, 1, GAPIN_AMOUNT,
171 "factor", SDDS_DOUBLE, &gapFactor, 1, GAPIN_FACTOR, NULL) ||
172 (flags & GAPIN_AMOUNT && gapAmount <= 0) ||
173 (flags & GAPIN_FACTOR && gapFactor <= 0)) {
174 fprintf(stderr, "Error: invalid -gapin syntax/values\n");
175 return EXIT_FAILURE;
176 }
177 columnName = scArg[iArg].list[1];
178 mode = matchCode;
179 break;
180
181 case SET_INCREASEOF:
182 increaseOfFlags = 0;
183 if (scArg[iArg].n_items < 2) {
184 fprintf(stderr, "Error: invalid -increaseOf syntax\n");
185 return EXIT_FAILURE;
186 }
187 scArg[iArg].n_items -= 2;
188 if (!scanItemList(&increaseOfFlags, scArg[iArg].list + 2, &scArg[iArg].n_items, 0,
189 "amount", SDDS_DOUBLE, &increaseOfAmount, 1, INCREASEOF_AMOUNT,
190 "cumulative", -1, NULL, 0, INCREASEOF_CUMULATIVE,
191 "reset", -1, NULL, 0, INCREASEOF_RESET, NULL) ||
192 ((flags & INCREASEOF_AMOUNT) && increaseOfAmount <= 0)) {
193 fprintf(stderr, "Error: invalid -increaseOf syntax\n");
194 return EXIT_FAILURE;
195 }
196 columnName = scArg[iArg].list[1];
197 mode = matchCode;
198 break;
199
200 case SET_DECREASEOF:
201 decreaseOfFlags = 0;
202 if (scArg[iArg].n_items < 2) {
203 fprintf(stderr, "Error: invalid -decreaseOf syntax\n");
204 return EXIT_FAILURE;
205 }
206 scArg[iArg].n_items -= 2;
207 if (!scanItemList(&decreaseOfFlags, scArg[iArg].list + 2, &scArg[iArg].n_items, 0,
208 "amount", SDDS_DOUBLE, &decreaseOfAmount, 1, DECREASEOF_AMOUNT,
209 "cumulative", -1, NULL, 0, DECREASEOF_CUMULATIVE,
210 "reset", -1, NULL, 0, DECREASEOF_RESET, NULL) ||
211 ((flags & DECREASEOF_AMOUNT) && decreaseOfAmount <= 0)) {
212 fprintf(stderr, "Error: invalid -decreaseOf syntax\n");
213 return EXIT_FAILURE;
214 }
215 columnName = scArg[iArg].list[1];
216 mode = matchCode;
217 break;
218
219 case SET_CHANGEOF:
220 if ((scArg[iArg].n_items -= 2) < 0 ||
221 !scanItemList(&changeFlags, scArg[iArg].list + 2, &scArg[iArg].n_items, 0,
222 "amount", SDDS_DOUBLE, &changeAmount, 1, CHANGEOF_AMOUNT,
223 "base", SDDS_DOUBLE, &changeBase, 1, CHANGEOF_BASE, NULL) ||
224 (changeFlags & CHANGEOF_AMOUNT && changeAmount <= 0)) {
225 fprintf(stderr, "Error: invalid -changeof syntax/values\n");
226 return EXIT_FAILURE;
227 }
228 columnName = scArg[iArg].list[1];
229 mode = matchCode;
230 break;
231
232 case SET_ROWLIMIT:
233 if (scArg[iArg].n_items < 2) {
234 fprintf(stderr, "Error: invalid -rowlimit syntax\n");
235 return EXIT_FAILURE;
236 }
237 if (sscanf(scArg[iArg].list[1], "%" SCNd64, &rowLimit) != 1 || rowLimit <= 0) {
238 fprintf(stderr, "Error: invalid -rowlimit syntax\n");
239 return EXIT_FAILURE;
240 }
241 if (scArg[iArg].n_items > 2) {
242 scArg[iArg].n_items -= 2;
243 if (!scanItemList(&flags, scArg[iArg].list + 2, &scArg[iArg].n_items, 0,
244 "overlap", SDDS_LONG, &overlap, 1, ROWLIMIT_OVERLAP, NULL) ||
245 overlap < 0) {
246 fprintf(stderr, "Error: invalid overlap given in -rowlimit syntax\n");
247 return EXIT_FAILURE;
248 }
249 }
250 mode = matchCode;
251 break;
252
253 case SET_PIPE:
254 if (!processPipeOption(scArg[iArg].list + 1, scArg[iArg].n_items - 1, &pipeFlags)) {
255 fprintf(stderr, "Error: invalid -pipe syntax\n");
256 return EXIT_FAILURE;
257 }
258 break;
259
260 case SET_MATCHTO:
261 if ((scArg[iArg].n_items != 3 && scArg[iArg].n_items != 4) ||
262 strlen(columnName = scArg[iArg].list[1]) == 0 ||
263 strlen(matchPattern = scArg[iArg].list[2]) == 0) {
264 fprintf(stderr, "Error: invalid -matchTo syntax\n");
265 return EXIT_FAILURE;
266 }
267 if (scArg[iArg].n_items == 4) {
268 if (strncmp(scArg[iArg].list[3], "after", strlen(scArg[iArg].list[3])) == 0)
269 matchPatternAfter = 1;
270 else {
271 fprintf(stderr, "Error: invalid -matchTo syntax\n");
272 return EXIT_FAILURE;
273 }
274 }
275 mode = matchCode;
276 break;
277
278 default:
279 fprintf(stderr, "Error: unknown switch: %s\n", scArg[iArg].list[0]);
280 fprintf(stderr, "%s", USAGE);
281 return EXIT_FAILURE;
282 }
283 } else {
284 if (input == NULL)
285 input = scArg[iArg].list[0];
286 else if (output == NULL)
287 output = scArg[iArg].list[0];
288 else {
289 fprintf(stderr, "Error: too many filenames given\n");
290 return EXIT_FAILURE;
291 }
292 }
293 }
294
295 processFilenames("sddsbreak", &input, &output, pipeFlags, 0, &tmpfile_used);
296
297 if (mode == -1) {
298 fprintf(stderr, "Error: no break mode specified\n");
299 return EXIT_FAILURE;
300 }
301
302 if (!SDDS_InitializeInput(&SDDSold, input) ||
303 !SDDS_InitializeCopy(&SDDSnew, &SDDSold, output, "w")) {
304 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
305 return EXIT_FAILURE;
306 }
307
308 SDDSnew.layout.data_mode.no_row_counts = 0;
309 if (columnMajorOrder != -1)
310 SDDSnew.layout.data_mode.column_major = columnMajorOrder;
311 else
312 SDDSnew.layout.data_mode.column_major = SDDSold.layout.data_mode.column_major;
313
314 if (!SDDS_WriteLayout(&SDDSnew)) {
315 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
316 return EXIT_FAILURE;
317 }
318
319 if (mode != SET_ROWLIMIT) {
320 if (SDDS_GetColumnInformation(&SDDSold, "type", &dataType, SDDS_BY_NAME, columnName) != SDDS_LONG) {
321 SDDS_SetError("Problem getting type information on given column");
322 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
323 return EXIT_FAILURE;
324 }
325 if (mode == SET_MATCHTO) {
326 if (!(dataType == SDDS_STRING)) {
327 fprintf(stderr, "Error: given column does not contain string data\n");
328 return EXIT_FAILURE;
329 }
330 } else if (!SDDS_NUMERIC_TYPE(dataType)) {
331 if (!(mode == SET_CHANGEOF && !(changeFlags & CHANGEOF_AMOUNT) && !(changeFlags & CHANGEOF_BASE))) {
332 fprintf(stderr, "Error: given column does not contain numeric data\n");
333 return EXIT_FAILURE;
334 }
335 }
336 }
337
338 while ((retval = SDDS_ReadPage(&SDDSold)) > 0) {
339 if ((rows = SDDS_CountRowsOfInterest(&SDDSold)) < 0) {
340 SDDS_SetError("Problem getting number of rows of tabular data");
341 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
342 return EXIT_FAILURE;
343 }
344 if (!SDDS_StartPage(&SDDSnew, rows) ||
345 !SDDS_CopyParameters(&SDDSnew, &SDDSold) ||
346 !SDDS_CopyArrays(&SDDSnew, &SDDSold)) {
347 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
348 return EXIT_FAILURE;
349 }
350 if (rows == 0) {
351 if (!SDDS_WritePage(&SDDSnew)) {
352 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
353 return EXIT_FAILURE;
354 }
355 continue;
356 }
357
358 switch (mode) {
359 case SET_GAPIN:
360 columnData = SDDS_GetColumnInDoubles(&SDDSold, columnName);
361 if (!columnData) {
362 SDDS_SetError("Unable to read specified column");
363 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
364 return EXIT_FAILURE;
365 }
366 if (!gapAmount && rows > 1) {
367 double *gap = tmalloc(sizeof(*gap) * rows);
368 for (i = 1; i < rows; i++)
369 gap[i - 1] = fabs(columnData[i] - columnData[i - 1]);
370 if (!compute_average(&gapAmount, gap, rows - 1)) {
371 fprintf(stderr, "Error: unable to determine default gap amount--couldn't find median gap\n");
372 free(gap);
373 return EXIT_FAILURE;
374 }
375 gapAmount *= (gapFactor ? gapFactor : 2);
376 free(gap);
377 }
378 {
379 int64_t newStart = 0;
380 for (i = 1; i <= rows; i++) {
381 if (i != rows && fabs(columnData[i] - columnData[i - 1]) < gapAmount)
382 continue;
383 if (!SDDS_CopyRows(&SDDSnew, &SDDSold, newStart, i - 1) ||
384 !SDDS_WritePage(&SDDSnew)) {
385 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
386 free(columnData);
387 return EXIT_FAILURE;
388 }
389 newStart = i;
390 }
391 }
392 free(columnData);
393 break;
394
395 case SET_INCREASEOF:
396 columnData = SDDS_GetColumnInDoubles(&SDDSold, columnName);
397 if (!columnData) {
398 SDDS_SetError("Unable to read specified column");
399 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
400 return EXIT_FAILURE;
401 }
402 {
403 int64_t newStart = 0;
404 if (increaseOfAmount <= 0) {
405 for (i = 1; i <= rows; i++) {
406 if (i != rows && columnData[i] <= columnData[i - 1])
407 continue;
408 if (!SDDS_CopyRows(&SDDSnew, &SDDSold, newStart, i - 1) ||
409 !SDDS_WritePage(&SDDSnew)) {
410 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
411 free(columnData);
412 return EXIT_FAILURE;
413 }
414 newStart = i;
415 }
416 } else {
417 if (increaseOfFlags & INCREASEOF_CUMULATIVE) {
418 long iref = 0;
419 for (i = 1; i <= rows; i++) {
420 if ((increaseOfFlags & INCREASEOF_RESET) && columnData[i] < columnData[iref])
421 iref = i;
422 if (i != rows && (columnData[i] - columnData[iref]) < increaseOfAmount)
423 continue;
424 if (!SDDS_CopyRows(&SDDSnew, &SDDSold, newStart, i - 1) ||
425 !SDDS_WritePage(&SDDSnew)) {
426 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
427 free(columnData);
428 return EXIT_FAILURE;
429 }
430 newStart = i;
431 if (increaseOfFlags & INCREASEOF_CUMULATIVE)
432 iref = i;
433 }
434 } else {
435 for (i = 1; i <= rows; i++) {
436 if (i != rows && (columnData[i] - columnData[i - 1]) < increaseOfAmount)
437 continue;
438 if (!SDDS_CopyRows(&SDDSnew, &SDDSold, newStart, i - 1) ||
439 !SDDS_WritePage(&SDDSnew)) {
440 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
441 free(columnData);
442 return EXIT_FAILURE;
443 }
444 newStart = i;
445 }
446 }
447 }
448 }
449 free(columnData);
450 break;
451
452 case SET_DECREASEOF:
453 columnData = SDDS_GetColumnInDoubles(&SDDSold, columnName);
454 if (!columnData) {
455 SDDS_SetError("Unable to read specified column");
456 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
457 return EXIT_FAILURE;
458 }
459 {
460 int64_t newStart = 0;
461 if (decreaseOfAmount <= 0) {
462 for (i = 1; i <= rows; i++) {
463 if (i != rows && columnData[i] >= columnData[i - 1])
464 continue;
465 if (!SDDS_CopyRows(&SDDSnew, &SDDSold, newStart, i - 1) ||
466 !SDDS_WritePage(&SDDSnew)) {
467 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
468 free(columnData);
469 return EXIT_FAILURE;
470 }
471 newStart = i;
472 }
473 } else {
474 if (decreaseOfFlags & DECREASEOF_CUMULATIVE) {
475 long iref = 0;
476 for (i = 1; i <= rows; i++) {
477 if ((decreaseOfFlags & DECREASEOF_RESET) && columnData[i] > columnData[iref])
478 iref = i;
479 if (i != rows && (columnData[iref] - columnData[i]) < decreaseOfAmount)
480 continue;
481 if (!SDDS_CopyRows(&SDDSnew, &SDDSold, newStart, i - 1) ||
482 !SDDS_WritePage(&SDDSnew)) {
483 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
484 free(columnData);
485 return EXIT_FAILURE;
486 }
487 newStart = i;
488 if (decreaseOfFlags & DECREASEOF_CUMULATIVE)
489 iref = i;
490 }
491 } else {
492 for (i = 1; i <= rows; i++) {
493 if (i != rows && (columnData[i - 1] - columnData[i]) < decreaseOfAmount)
494 continue;
495 if (!SDDS_CopyRows(&SDDSnew, &SDDSold, newStart, i - 1) ||
496 !SDDS_WritePage(&SDDSnew)) {
497 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
498 free(columnData);
499 return EXIT_FAILURE;
500 }
501 newStart = i;
502 }
503 }
504 }
505 }
506 free(columnData);
507 break;
508
509 case SET_CHANGEOF:
510 if (dataType != SDDS_STRING) {
511 columnData = SDDS_GetColumnInDoubles(&SDDSold, columnName);
512 if (!columnData) {
513 SDDS_SetError("Unable to read specified column");
514 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
515 return EXIT_FAILURE;
516 }
517 } else {
518 stringData = SDDS_GetColumn(&SDDSold, columnName);
519 if (!stringData) {
520 SDDS_SetError("Unable to read specified column");
521 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
522 return EXIT_FAILURE;
523 }
524 }
525 {
526 int64_t newStart = 0;
527 if (dataType == SDDS_STRING || !changeAmount) {
528 for (i = 1; i <= rows; i++) {
529 if (i != rows &&
530 ((dataType == SDDS_STRING && strcmp(stringData[i], stringData[i - 1]) == 0) ||
531 (dataType != SDDS_STRING && columnData[i] == columnData[i - 1])))
532 continue;
533 if (!SDDS_CopyRows(&SDDSnew, &SDDSold, newStart, i - 1) ||
534 !SDDS_WritePage(&SDDSnew)) {
535 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
536 if (dataType != SDDS_STRING)
537 free(columnData);
538 else
539 SDDS_FreeStringArray(stringData, rows);
540 return EXIT_FAILURE;
541 }
542 newStart = i;
543 }
544 } else {
545 long region = 0, lastRegion = 0;
546 if (!(changeFlags & CHANGEOF_BASE) && rows >= 1)
547 changeBase = columnData[0];
548 if (rows > 1)
549 lastRegion = (columnData[0] - changeBase) / changeAmount;
550
551 newStart = 0;
552 for (i = 1; i <= rows; i++) {
553 if (i != rows)
554 region = (columnData[i] - changeBase) / changeAmount;
555 if (i != rows && region == lastRegion)
556 continue;
557 if (!SDDS_CopyRows(&SDDSnew, &SDDSold, newStart, i - 1) ||
558 !SDDS_WritePage(&SDDSnew)) {
559 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
560 if (dataType != SDDS_STRING)
561 free(columnData);
562 else
563 SDDS_FreeStringArray(stringData, rows);
564 return EXIT_FAILURE;
565 }
566 newStart = i;
567 lastRegion = region;
568 }
569 }
570 }
571 if (dataType != SDDS_STRING)
572 free(columnData);
573 else
574 SDDS_FreeStringArray(stringData, rows);
575 break;
576
577 case SET_MATCHTO:
578 stringData = SDDS_GetColumn(&SDDSold, columnName);
579 if (!stringData) {
580 SDDS_SetError("Unable to read specified column");
581 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
582 return EXIT_FAILURE;
583 }
584 {
585 int64_t newStart = 0;
586 breakNext = 0;
587 for (i = 1; i <= rows; i++) {
588 if (i != rows && !breakNext) {
589 if (wild_match(stringData[i], matchPattern)) {
590 if (matchPatternAfter) {
591 breakNext = 1;
592 continue;
593 }
594 } else {
595 continue;
596 }
597 }
598 if (!SDDS_CopyRows(&SDDSnew, &SDDSold, newStart, i - 1) ||
599 !SDDS_WritePage(&SDDSnew)) {
600 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
601 SDDS_FreeStringArray(stringData, rows);
602 return EXIT_FAILURE;
603 }
604 breakNext = 0;
605 newStart = i;
606 }
607 }
608 SDDS_FreeStringArray(stringData, rows);
609 break;
610
611 case SET_ROWLIMIT:
612 for (i = 0; i < rows; i += rowLimit - overlap) {
613 if ((j = i + rowLimit - 1) >= rows)
614 j = rows - 1;
615 if (!SDDS_CopyRows(&SDDSnew, &SDDSold, i, j)) {
616 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
617 return EXIT_FAILURE;
618 }
619 if (!SDDS_WritePage(&SDDSnew)) {
620 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
621 return EXIT_FAILURE;
622 }
623 if (j == rows - 1)
624 break;
625 }
626 break;
627
628 default:
629 fprintf(stderr, "Error: unknown break mode code seen---this can't happen\n");
630 return EXIT_FAILURE;
631 }
632 }
633
634 if (retval == 0) {
635 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
636 return EXIT_FAILURE;
637 }
638
639 if (!SDDS_Terminate(&SDDSold)) {
640 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
641 return EXIT_FAILURE;
642 }
643
644 if (!SDDS_Terminate(&SDDSnew)) {
645 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
646 return EXIT_FAILURE;
647 }
648
649 if (tmpfile_used && !replaceFileAndBackUp(input, output)) {
650 return EXIT_FAILURE;
651 }
652
653 return EXIT_SUCCESS;
654}
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_CopyParameters(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:286
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
Definition SDDS_copy.c:40
int32_t SDDS_CopyArrays(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:334
int32_t SDDS_CopyRows(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, int64_t firstRow, int64_t lastRow)
Definition SDDS_copy.c:882
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
void * SDDS_GetColumn(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves a copy of the data for a specified column, including only rows marked as "of interest".
int64_t SDDS_CountRowsOfInterest(SDDS_DATASET *SDDS_dataset)
Counts the number of rows marked as "of interest" in the current data table.
double * SDDS_GetColumnInDoubles(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves the data of a specified numerical column as an array of doubles, considering only rows mark...
int32_t SDDS_GetColumnInformation(SDDS_DATASET *SDDS_dataset, char *field_name, void *memory, int32_t mode,...)
Retrieves information about a specified column in the SDDS dataset.
Definition SDDS_info.c:41
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.
int32_t SDDS_FreeStringArray(char **string, int64_t strings)
Frees an array of strings by deallocating each individual string.
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:379
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
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
#define SDDS_NUMERIC_TYPE(type)
Checks if the given type identifier corresponds to any numeric type.
Definition SDDStypes.h:138
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59
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.
long compute_average(double *value, double *data, int64_t n)
Computes the average of an array of doubles.
Definition median.c:144
long replaceFileAndBackUp(char *file, char *replacement)
Replaces a file with a replacement file and creates a backup of the original.
Definition replacefile.c:75
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
Definition scanargs.c:36
long processPipeOption(char **item, long items, unsigned long *flags)
Definition scanargs.c:356
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:390
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.
int wild_match(char *string, char *template)
Determine whether one string is a wildcard match for another.
Definition wild_match.c:49