154 {
156 char *input, *output;
157 long i_arg, non_dominate_sort = 0;
158 SCANNED_ARG *s_arg;
159
160 long tmpfile_used, sort_requests, noWarnings, uniqueRows, provideIdenticalCount, tmpfileForInternalPipe;
161 long sort_parameters;
163 unsigned long pipeFlags, majorOrderFlag;
164 short columnMajorOrder = -1;
165
167 argc =
scanargs(&s_arg, argc, argv);
168 if (argc < 2) {
170 }
171
172 input = output = NULL;
173 tmpfile_used = sort_requests = noWarnings = sort_parameters = tmpfileForInternalPipe = 0;
174 sort_request = sort_parameter = NULL;
175 pipeFlags = 0;
176 uniqueRows = provideIdenticalCount = 0;
177 for (i_arg = 1; i_arg < argc; i_arg++) {
178 if (s_arg[i_arg].arg_type == OPTION) {
179 switch (
match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
180 case SET_MAJOR_ORDER:
181 majorOrderFlag = 0;
182 s_arg[i_arg].n_items--;
183 if (s_arg[i_arg].n_items > 0 &&
184 (!
scanItemList(&majorOrderFlag, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
185 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
186 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
187 SDDS_Bomb(
"invalid -majorOrder syntax/values");
188 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
189 columnMajorOrder = 1;
190 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
191 columnMajorOrder = 0;
192 break;
193 case SET_NON_DOMINATE_SORT:
194 non_dominate_sort = 1;
195 break;
196 case SET_COLUMN:
197 if (s_arg[i_arg].n_items < 2 || s_arg[i_arg].n_items > 4)
199 sort_request =
trealloc(sort_request,
sizeof(*sort_request) * (sort_requests + 1));
200 sort_request[sort_requests].name = s_arg[i_arg].list[1];
201 sort_request[sort_requests].maximize_order = 0;
202 sort_request[sort_requests].decreasing_order = 0;
203 sort_request[sort_requests].absolute = 0;
204 if (s_arg[i_arg].n_items >= 3) {
205 int j;
206 for (j = 2; j < s_arg[i_arg].n_items; j++) {
207 switch (
match_string(s_arg[i_arg].list[j], order_mode, 5, 0)) {
208 case 0:
209 break;
210 case 1:
211 sort_request[sort_requests].decreasing_order = 1;
212 break;
213 case 2:
214 break;
215 case 3:
216 sort_request[sort_requests].maximize_order = 1;
217 break;
218 case 4:
219 sort_request[sort_requests].absolute = 1;
220 break;
221 default:
222 fprintf(stderr, "unknown sort order specified--give 'increasing' or 'decreasing' for dominated sorting\n or'maximize' or 'minimize' for non-dominated-sorting.\n");
223 exit(EXIT_FAILURE);
224 break;
225 }
226 }
227 }
228 sort_requests++;
229 break;
230 case SET_PARAMETER:
231 if (s_arg[i_arg].n_items < 2 || s_arg[i_arg].n_items > 3)
233 sort_parameter =
trealloc(sort_parameter,
sizeof(*sort_parameter) * (sort_parameters + 1));
234 sort_parameter[sort_parameters].name = s_arg[i_arg].list[1];
235 if (s_arg[i_arg].n_items == 3) {
236 if ((sort_parameter[sort_parameters].decreasing_order =
match_string(s_arg[i_arg].list[2], order_mode, 2, 0)) < 0)
237 SDDS_Bomb(
"unknown sort order specified--give 'increasing' or 'decreasing'");
238 } else
239 sort_parameter[sort_parameters].decreasing_order = 0;
240 sort_parameters++;
241 break;
242 case SET_NOWARNINGS:
243 noWarnings = 1;
244 break;
245 case SET_NUMERICHIGH:
246 numericHigh = 1;
247 break;
248 case SET_PIPE:
249 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
251 break;
252 case SET_UNIQUE:
253 uniqueRows = 1;
254 if (s_arg[i_arg].n_items > 1) {
256 if (s_arg[i_arg].n_items > 2 ||
257 strncmp("count", s_arg[i_arg].list[1], strlen(s_arg[i_arg].list[1])) != 0)
259 provideIdenticalCount = 1;
260 }
261 break;
262 default:
263 fprintf(stderr, "error: unknown switch: %s\n", s_arg[i_arg].list[0]);
264 exit(EXIT_FAILURE);
265 break;
266 }
267 } else {
268 if (input == NULL)
269 input = s_arg[i_arg].list[0];
270 else if (output == NULL)
271 output = s_arg[i_arg].list[0];
272 else
274 }
275 }
276
277 if (!sort_requests && !sort_parameters)
279 processFilenames(
"sddssort", &input, &output, pipeFlags, noWarnings, &tmpfile_used);
282 exit(EXIT_FAILURE);
283 }
284 if (sort_requests <= 1)
285 non_dominate_sort = 0;
286
287 if (SDDS_input.layout.popenUsed) {
288
289
290
291 pid_t pid;
292 char tmpfileName[1024];
293 pid = getpid();
294 sprintf(tmpfileName, "/tmp/sddssort.%ld", (long)pid);
295 tmpfileForInternalPipe = 1;
298 exit(EXIT_FAILURE);
299 }
300 if (columnMajorOrder != -1)
301 SDDS_tmp.layout.data_mode.column_major = columnMajorOrder;
302 else
303 SDDS_tmp.layout.data_mode.column_major = SDDS_input.layout.data_mode.column_major;
304 if (non_dominate_sort) {
308 exit(EXIT_FAILURE);
309 }
313 constDefined = 1;
314 }
315 }
316
319 exit(EXIT_FAILURE);
320 }
324 exit(EXIT_FAILURE);
325 }
326 }
329 exit(EXIT_FAILURE);
330 }
333 exit(EXIT_FAILURE);
334 }
335 }
338 exit(EXIT_FAILURE);
339 }
340 if (columnMajorOrder != -1)
341 SDDS_output.layout.data_mode.column_major = columnMajorOrder;
342 else
343 SDDS_output.layout.data_mode.column_major = SDDS_input.layout.data_mode.column_major;
344 if (provideIdenticalCount &&
347 exit(EXIT_FAILURE);
348 }
349 if (non_dominate_sort) {
353 exit(EXIT_FAILURE);
354 }
358 constDefined = 1;
359 }
360 }
363 if (!SDDS_SortAll(&SDDS_input, &SDDS_output, sort_request, sort_requests, sort_parameter, sort_parameters,
364 uniqueRows, provideIdenticalCount, pipeFlags, non_dominate_sort)) {
367 }
370 exit(EXIT_FAILURE);
371 }
373 exit(EXIT_FAILURE);
375
376
377 return EXIT_SUCCESS;
378}
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
int32_t SDDS_CopyPage(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
int32_t SDDS_DefineSimpleColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data column within the 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_SetError(char *error_text)
Records an error message in the SDDS error stack.
int32_t SDDS_CheckColumn(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a column exists in the SDDS dataset with the specified name, units, and type.
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.
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
#define SDDS_ANY_NUMERIC_TYPE
Special identifier used by SDDS_Check*() routines to accept any numeric type.
#define SDDS_DOUBLE
Identifier for the double data type.
#define SDDS_LONG64
Identifier for the signed 64-bit integer data type.
void * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
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.
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
long processPipeOption(char **item, long items, unsigned long *flags)
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
void free_scanargs(SCANNED_ARG **scanned, int argc)
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.
char * str_tolower(char *s)
Convert a string to lower case.