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

Detailed Description

Calculates the response matrix derivative with respect to correctors, BPMs, or quadrupoles.

This program processes an input SDDS response matrix file to compute its derivative with respect to selected elements such as correctors ("cor"), Beam Position Monitors (BPMs, "bpm"), or quadrupoles ("quad"). Additional options allow users to append zero rows before or after the main data. Supported modes and options are described below.

Usage

sddsrespmatrixderivative [<inputfile>] [<outputfile>]
[-pipe=[input][,output]]
-mode=<string>
[-addRowsBefore=<number>]
[-addRowsAfter=<number>]
[-verbose]

Options

Required Description
-mode=<string> Mode of derivative: cor, bpm or quad
Optional Description
-pipe=[input][,output] Read input from and/or write output to a pipe.
-addRowsBefore=<number> Add zero rows before meaningful rows. Default: 0.
-addRowsAfter=<number> Add zero rows after meaningful rows. Default: 0.
-verbose Enable detailed logging to stderr.

Incompatibilities

  • When -mode=quad is specified:
    • -addRowsBefore is treated as the starting column number for diagonal output.
    • -addRowsAfter specifies the number of rows of diagonal output.
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
R. Soliday

Definition in file sddsrespmatrixderivative.c.

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

Go to the source code of this file.

Functions

char ** TokenizeString (char *source, long n_items)
 
char * JoinStrings (char **source, long n_items, long buflen_increment)
 
int MakeDerivative (char *mode, int addRowsBefore, int addRowsAfter, int addColumnsBefore, MATRIX *B, MATRIX *A)
 
int MakeRootnameColumn (char *mode, long inputDoubleColumns, int64_t inputRows, long addRowsBefore, long addRowsAfter, char **inputDoubleColumnName, char **stringData, char **rootnameData)
 
int main (int argc, char **argv)
 

Function Documentation

◆ JoinStrings()

char * JoinStrings ( char ** source,
long n_items,
long buflen_increment )

Definition at line 720 of file sddstranspose.c.

720 {
721 char *buffer;
722 char *ptr;
723 long buffer_size, bufferLeft, bufferUsed;
724 long i, slen;
725 char *sptr;
726
727 buffer_size = buflen_increment;
728 buffer = (char *)malloc(sizeof(char) * buffer_size);
729 buffer[0] = '\0';
730 ptr = buffer;
731 bufferLeft = buffer_size - 2;
732 bufferUsed = 0;
733 for (i = 0; i < n_items; i++) {
734 sptr = source[i];
735 slen = strlen(sptr);
736 while ((slen + 5) > bufferLeft) {
737 buffer = trealloc(buffer, sizeof(char) * (buffer_size += buflen_increment));
738 bufferLeft += buflen_increment;
739 ptr = buffer + bufferUsed;
740 }
741 if (i) {
742 slen++;
743 *ptr++ = ' ';
744 }
745 *ptr++ = '"';
746 while (*sptr)
747 *ptr++ = *sptr++;
748 *ptr++ = '"';
749 *ptr = '\0';
750 bufferLeft -= slen + 2;
751 bufferUsed += slen + 2;
752 }
753
754 return buffer;
755}
void * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
Definition array.c:181

◆ main()

int main ( int argc,
char ** argv )

Definition at line 100 of file sddsrespmatrixderivative.c.

100 {
101 SCANNED_ARG *s_arg;
102 SDDS_DATASET inputPage, outputPage;
103
104 char *inputfile, *outputfile;
105 char **inputColumnName, **inputStringColumnName, **inputDoubleColumnName;
106 char **outputStringColumnName, **outputDoubleColumnName;
107 int64_t inputRows, outputRows;
108 long inputDoubleColumns, inputStringColumns;
109 long outputDoubleColumns, outputStringColumns;
110 char **inputParameterName;
111 int32_t inputParameters, inputColumns;
112 char *inputDescription, *inputContents;
113 long i, i_arg, col;
114#define BUFFER_SIZE_INCREMENT 16384
115 MATRIX *R, *Rderiv;
116 long OldStringColumnsDefined;
117 long verbose;
118 long ascii;
119 unsigned long pipeFlags;
120 long tmpfile_used, noWarnings;
121 long ipage, columnType;
122 long addRowsBefore, addRowsAfter, addColumnsBefore;
123 char *mode;
124 char **stringData = NULL;
125 char **rootnameData = NULL;
126
127 inputColumnName = outputStringColumnName = outputDoubleColumnName = inputParameterName = NULL;
128 outputRows = outputDoubleColumns = outputStringColumns = OldStringColumnsDefined = 0;
129
131
132 argc = scanargs(&s_arg, argc, argv);
133 if (argc == 1)
134 bomb(NULL, USAGE);
135
136 inputfile = outputfile = NULL;
137 verbose = 0;
138 ascii = 0;
139 pipeFlags = 0;
140 tmpfile_used = 0;
141 noWarnings = 0;
142 mode = NULL;
143 int modeDefined = 0;
144 addRowsBefore = 0;
145 addRowsAfter = 0;
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], commandline_option, N_OPTIONS, UNIQUE_MATCH)) {
151 case CLO_VERBOSE:
152 verbose = 1;
153 break;
154 case CLO_PIPE:
155 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
156 SDDS_Bomb("Invalid -pipe syntax");
157 break;
158 case CLO_MODE:
159 modeDefined = 1;
160 if (!(mode = s_arg[i_arg].list[1]))
161 SDDS_Bomb("No mode string provided");
162 break;
163 case CLO_ADDROWSBEFORE:
164 if (!(sscanf(s_arg[i_arg].list[1], "%ld", &addRowsBefore)) || (addRowsBefore < 0))
165 SDDS_Bomb("Invalid value for addRowsBefore: must be a non-negative number");
166 break;
167 case CLO_ADDROWSAFTER:
168 if (!(sscanf(s_arg[i_arg].list[1], "%ld", &addRowsAfter)) || (addRowsAfter < 0))
169 SDDS_Bomb("Invalid value for addRowsAfter: must be a non-negative number");
170 break;
171 default:
172 bomb("Unrecognized option provided", USAGE);
173 }
174 } else {
175 if (!inputfile)
176 inputfile = s_arg[i_arg].list[0];
177 else if (!outputfile)
178 outputfile = s_arg[i_arg].list[0];
179 else
180 bomb("Too many filenames provided", USAGE);
181 }
182 }
183
184 if (modeDefined) {
185 if (strcmp(mode, "cor") && strcmp(mode, "bpm") && strcmp(mode, "quad")) {
186 bomb("Invalid mode parameter", "Mode must be 'cor', 'bpm', or 'quad'");
187 }
188 } else {
189 bomb("Mode parameter is not defined.", "Mode must be 'cor', 'bpm', or 'quad'");
190 }
191
192 processFilenames("sddsrespmatrixderivative", &inputfile, &outputfile, pipeFlags, noWarnings, &tmpfile_used);
193
194 if (!SDDS_InitializeInput(&inputPage, inputfile) ||
195 !(inputColumnName = (char **)SDDS_GetColumnNames(&inputPage, &inputColumns)) ||
196 !(inputParameterName = (char **)SDDS_GetParameterNames(&inputPage, &inputParameters)) ||
197 !SDDS_GetDescription(&inputPage, &inputDescription, &inputContents)) {
198 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
199 exit(EXIT_FAILURE);
200 }
201
202 inputDoubleColumns = 0;
203 inputStringColumns = 0;
204 inputDoubleColumnName = (char **)malloc(inputColumns * sizeof(char *));
205 inputStringColumnName = (char **)malloc(inputColumns * sizeof(char *));
206 inputRows = 0;
207
208 if (strcmp(mode, "quad") == 0) {
209 addColumnsBefore = addRowsBefore;
210 addRowsBefore = 0;
211 } else {
212 addColumnsBefore = 0;
213 }
214
215 /* Read data */
216 while (0 < (ipage = SDDS_ReadTable(&inputPage))) {
217 if (ipage == 1) {
218 if (!SDDS_SetColumnFlags(&inputPage, 0))
219 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
220
221 /* Count the string and numerical columns in the input file */
222 for (i = 0; i < inputColumns; i++) {
223 if (SDDS_NUMERIC_TYPE(columnType = SDDS_GetColumnType(&inputPage, i))) {
224 inputDoubleColumnName[inputDoubleColumns] = inputColumnName[i];
225 inputDoubleColumns++;
226 } else if (columnType == SDDS_STRING) {
227 inputStringColumnName[inputStringColumns] = inputColumnName[i];
228 inputStringColumns++;
229 }
230 }
231
232 if (!(inputRows = SDDS_CountRowsOfInterest(&inputPage)))
233 SDDS_Bomb("No rows in dataset.");
234 } else {
235 SDDS_Bomb("Dataset must be one-page.");
236 }
237
238 if (inputDoubleColumns == 0)
239 SDDS_Bomb("No numerical columns in file.");
240
241 if ((ipage == 1) && verbose) {
242 fprintf(stderr, "Number of numerical columns: %ld.\n", inputDoubleColumns);
243 fprintf(stderr, "Number of string columns: %ld.\n", inputStringColumns);
244 fprintf(stderr, "Number of rows: %" PRId64 ".\n", inputRows);
245 }
246
247 /* Work on data */
248 if (inputDoubleColumns) {
249 m_alloc(&R, inputDoubleColumns, inputRows);
250 outputRows = inputDoubleColumns * inputRows + addRowsBefore + addRowsAfter;
251
252 if (strcmp(mode, "cor") == 0) {
253 m_alloc(&Rderiv, inputDoubleColumns, outputRows);
254 } else if (strcmp(mode, "bpm") == 0) {
255 m_alloc(&Rderiv, inputRows, outputRows);
256 } else {
257 outputRows = addRowsAfter;
258 m_alloc(&Rderiv, inputDoubleColumns, outputRows);
259 }
260
261 for (col = 0; col < inputDoubleColumns; col++) {
262 if (!(R->a[col] = (double *)SDDS_GetColumnInDoubles(&inputPage, inputDoubleColumnName[col]))) {
263 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
264 }
265 }
266
267 /* Read stringData only in non-quad mode */
268 if (strcmp(mode, "quad") != 0) {
269 if (!(stringData = SDDS_GetColumn(&inputPage, "BPMName"))) {
270 SDDS_SetError("Unable to read specified column: BPMName.");
271 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
272 return EXIT_FAILURE;
273 }
274 }
275 }
276
277 if ((ipage == 1) && verbose) {
278 fprintf(stderr, "Starting MakeDerivative...\n");
279 }
280
281 MakeDerivative(mode, addRowsBefore, addRowsAfter, addColumnsBefore, Rderiv, R);
282
283 rootnameData = (char **)malloc(outputRows * sizeof(char *));
284 if ((ipage == 1) && verbose) {
285 fprintf(stderr, "Starting MakeRootnameColumn...\n");
286 }
287
288 MakeRootnameColumn(mode, inputDoubleColumns, inputRows, addRowsBefore, addRowsAfter,
289 inputDoubleColumnName, stringData, rootnameData);
290
291 /* Define output page */
292 if ((ipage == 1) && verbose) {
293 fprintf(stderr, "Starting output...\n");
294 }
295
296 if (ipage == 1) {
297 if (strcmp(mode, "cor") == 0) {
298 outputDoubleColumns = inputDoubleColumns;
299 outputDoubleColumnName = inputDoubleColumnName;
300 } else if (strcmp(mode, "bpm") == 0) {
301 outputDoubleColumns = inputRows;
302 outputDoubleColumnName = stringData;
303 } else {
304 outputDoubleColumns = inputDoubleColumns;
305 outputDoubleColumnName = inputDoubleColumnName;
306 }
307
308 if (!SDDS_InitializeOutput(&outputPage, ascii ? SDDS_ASCII : SDDS_BINARY, 1, NULL, NULL, outputfile))
309 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
310
311 /* Define string columns */
312 outputStringColumns = 1;
313 outputStringColumnName = (char **)malloc(sizeof(char *));
314 outputStringColumnName[0] = "Rootname";
315 if (SDDS_DefineColumn(&outputPage, outputStringColumnName[0], NULL, NULL, NULL, NULL, SDDS_STRING, 0) < 0)
316 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
317
318 /* Define double columns */
319 for (i = 0; i < outputDoubleColumns; i++) {
320 if (SDDS_DefineColumn(&outputPage, outputDoubleColumnName[i], NULL, NULL, NULL, NULL, SDDS_DOUBLE, 0) < 0)
321 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
322 }
323
324 /* Write layout */
325 switch (SDDS_CheckParameter(&outputPage, "InputFile", NULL, SDDS_STRING, NULL)) {
326 case SDDS_CHECK_NONEXISTENT:
327 if (SDDS_DefineParameter(&outputPage, "InputFile", NULL, NULL, "Original matrix file", NULL, SDDS_STRING, NULL) < 0)
328 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
329 break;
330 default:
331 break;
332 }
333
334 if (!SDDS_WriteLayout(&outputPage))
335 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
336 }
337
338 if (!SDDS_StartTable(&outputPage, outputRows))
339 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
340
341 if (ipage == 1) {
342 if (!SDDS_SetParameters(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, "InputFile", inputfile ? inputfile : "pipe", NULL))
343 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
344 }
345
346 /* Assign data to output table part of data set */
347
348 /* Assign string column data */
349 if (!SDDS_SetColumn(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_REFERENCE, rootnameData, outputRows, outputStringColumnName[0]))
350 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
351
352 /* Assign double column data */
353 for (i = 0; i < outputDoubleColumns; i++) {
354 if (!SDDS_SetColumn(&outputPage, SDDS_SET_BY_NAME | SDDS_PASS_BY_REFERENCE, Rderiv->a[i], outputRows, outputDoubleColumnName[i]))
355 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
356 }
357 }
358
359 if (!SDDS_WriteTable(&outputPage))
360 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
361
362 if (outputDoubleColumns) {
363 m_free(&R);
364 m_free(&Rderiv);
365 free(rootnameData);
366 }
367
368 if (!SDDS_Terminate(&inputPage) || !SDDS_Terminate(&outputPage))
369 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
370
371 if (tmpfile_used && !replaceFileAndBackUp(inputfile, outputfile))
372 exit(EXIT_FAILURE);
373
374 return EXIT_SUCCESS;
375}
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_SetColumn(SDDS_DATASET *SDDS_dataset, int32_t mode, void *data, int64_t rows,...)
Sets the values for one data column in the current data table of an SDDS dataset.
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.
int32_t SDDS_SetColumnFlags(SDDS_DATASET *SDDS_dataset, int32_t column_flag_value)
Sets the acceptance flags for all columns in the current data table of a data set.
int32_t SDDS_GetDescription(SDDS_DATASET *SDDS_dataset, char **text, char **contents)
Retrieves the text and contents descriptions from an SDDS dataset.
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_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:49
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
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_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_DefineParameter(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, char *fixed_value)
Defines a data parameter with a fixed string value.
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:379
char ** SDDS_GetParameterNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all parameters in the SDDS dataset.
char ** SDDS_GetColumnNames(SDDS_DATASET *SDDS_dataset, int32_t *number)
Retrieves the names of all columns in the SDDS dataset.
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_GetColumnType(SDDS_DATASET *SDDS_dataset, int32_t index)
Retrieves the data type of a column in the SDDS dataset by its index.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
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.
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#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 bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
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.
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

◆ MakeDerivative()

int MakeDerivative ( char * mode,
int addRowsBefore,
int addRowsAfter,
int addColumnsBefore,
MATRIX * B,
MATRIX * A )

Definition at line 424 of file sddsrespmatrixderivative.c.

424 {
425 register long i, j;
426 long Ncols, Nrows;
427
428 Ncols = A->n;
429 Nrows = A->m;
430
431 /* Initialize matrix B to zero */
432 for (i = 0; i < B->n; i++) {
433 for (j = 0; j < B->m; j++) {
434 B->a[i][j] = 0.0;
435 }
436 }
437
438 if (strcmp(mode, "cor") == 0) {
439 for (i = 0; i < Ncols; i++) {
440 for (j = 0; j < Nrows; j++) {
441 B->a[i][i + j * Ncols + addRowsBefore] = A->a[i][j];
442 }
443 }
444 } else if (strcmp(mode, "bpm") == 0) {
445 for (i = 0; i < Nrows; i++) {
446 for (j = 0; j < Ncols; j++) {
447 B->a[i][i * Ncols + j + addRowsBefore] = A->a[j][i];
448 }
449 }
450 } else { /* mode == "quad" */
451 for (i = 0; i < addRowsAfter; i++) {
452 B->a[i + addColumnsBefore][i] = 1.0;
453 }
454 }
455
456 return EXIT_SUCCESS;
457}

◆ MakeRootnameColumn()

int MakeRootnameColumn ( char * mode,
long inputDoubleColumns,
int64_t inputRows,
long addRowsBefore,
long addRowsAfter,
char ** inputDoubleColumnName,
char ** stringData,
char ** rootnameData )

Definition at line 379 of file sddsrespmatrixderivative.c.

380 {
381 int64_t i, j, n;
382
383 n = 0;
384 for (i = 0; i < addRowsBefore; i++) {
385 rootnameData[n] = (char *)malloc(sizeof(char) * 1);
386 rootnameData[n][0] = '\0'; // Initialize to empty string
387 n++;
388 }
389
390 if (strcmp(mode, "quad") == 0) {
391 for (i = 0; i < addRowsAfter; i++) {
392 if (addRowsAfter > inputDoubleColumns) {
393 SDDS_SetError("Number of addRowsAfter is greater than number of input columns in quad mode.");
394 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
395 return EXIT_FAILURE;
396 }
397 rootnameData[n] = (char *)malloc(sizeof(char) * (strlen(inputDoubleColumnName[i]) + 1));
398 strcpy(rootnameData[n], inputDoubleColumnName[i]);
399 n++;
400 }
401 } else {
402 for (i = 0; i < inputRows; i++) {
403 for (j = 0; j < inputDoubleColumns; j++) {
404 size_t len = strlen(inputDoubleColumnName[j]) + strlen(stringData[i]) + 1;
405 rootnameData[n] = (char *)malloc(sizeof(char) * (len + 1));
406 strcpy(rootnameData[n], inputDoubleColumnName[j]);
407 strcat(rootnameData[n], stringData[i]);
408 n++;
409 }
410 }
411 /* Only in non-quad mode, add additional rows after */
412 for (i = 0; i < addRowsAfter; i++) {
413 rootnameData[n] = (char *)malloc(sizeof(char) * 1);
414 rootnameData[n][0] = '\0'; // Initialize to empty string
415 n++;
416 }
417 }
418
419 return EXIT_SUCCESS;
420}

◆ TokenizeString()

char ** TokenizeString ( char * source,
long n_items )

Definition at line 697 of file sddstranspose.c.

697 {
698 char *buffer;
699 long buflen;
700 char *ptr;
701 char **string_array;
702 long i;
703
704 if (!source)
705 return NULL;
706 ptr = source;
707 string_array = (char **)malloc(sizeof(char *) * n_items);
708 buflen = strlen(source) + 1;
709 buffer = (char *)malloc(sizeof(char) * buflen);
710 for (i = 0; i < n_items; i++) {
711 if (SDDS_GetToken(ptr, buffer, buflen) != -1)
712 SDDS_CopyString(&string_array[i], buffer);
713 else
714 SDDS_CopyString(&string_array[i], "");
715 }
716 free(buffer);
717 return string_array;
718}
int32_t SDDS_GetToken(char *s, char *buffer, int32_t buflen)
Extracts the next token from a string, handling quoted substrings and escape characters.
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