129 {
131 char *input, *output;
132 long i_arg, non_dominate_sort = 0;
133 SCANNED_ARG *s_arg;
134
135 long tmpfile_used, sort_requests, noWarnings, uniqueRows, provideIdenticalCount, tmpfileForInternalPipe;
136 long sort_parameters;
138 unsigned long pipeFlags, majorOrderFlag;
139 short columnMajorOrder = -1;
140
142 argc =
scanargs(&s_arg, argc, argv);
143 if (argc < 2) {
145 }
146
147 input = output = NULL;
148 tmpfile_used = sort_requests = noWarnings = sort_parameters = tmpfileForInternalPipe = 0;
149 sort_request = sort_parameter = NULL;
150 pipeFlags = 0;
151 uniqueRows = provideIdenticalCount = 0;
152 for (i_arg = 1; i_arg < argc; i_arg++) {
153 if (s_arg[i_arg].arg_type == OPTION) {
154 switch (
match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
155 case SET_MAJOR_ORDER:
156 majorOrderFlag = 0;
157 s_arg[i_arg].n_items--;
158 if (s_arg[i_arg].n_items > 0 &&
159 (!
scanItemList(&majorOrderFlag, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
160 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
161 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
162 SDDS_Bomb(
"invalid -majorOrder syntax/values");
163 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
164 columnMajorOrder = 1;
165 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
166 columnMajorOrder = 0;
167 break;
168 case SET_NON_DOMINATE_SORT:
169 non_dominate_sort = 1;
170 break;
171 case SET_COLUMN:
172 if (s_arg[i_arg].n_items < 2 || s_arg[i_arg].n_items > 4)
174 sort_request =
trealloc(sort_request,
sizeof(*sort_request) * (sort_requests + 1));
175 sort_request[sort_requests].name = s_arg[i_arg].list[1];
176 sort_request[sort_requests].maximize_order = 0;
177 sort_request[sort_requests].decreasing_order = 0;
178 sort_request[sort_requests].absolute = 0;
179 if (s_arg[i_arg].n_items >= 3) {
180 int j;
181 for (j = 2; j < s_arg[i_arg].n_items; j++) {
182 switch (
match_string(s_arg[i_arg].list[j], order_mode, 5, 0)) {
183 case 0:
184 break;
185 case 1:
186 sort_request[sort_requests].decreasing_order = 1;
187 break;
188 case 2:
189 break;
190 case 3:
191 sort_request[sort_requests].maximize_order = 1;
192 break;
193 case 4:
194 sort_request[sort_requests].absolute = 1;
195 break;
196 default:
197 fprintf(stderr, "unknown sort order specified--give 'increasing' or 'decreasing' for dominated sorting\n or'maximize' or 'minimize' for non-dominated-sorting.\n");
198 exit(EXIT_FAILURE);
199 break;
200 }
201 }
202 }
203 sort_requests++;
204 break;
205 case SET_PARAMETER:
206 if (s_arg[i_arg].n_items < 2 || s_arg[i_arg].n_items > 3)
208 sort_parameter =
trealloc(sort_parameter,
sizeof(*sort_parameter) * (sort_parameters + 1));
209 sort_parameter[sort_parameters].name = s_arg[i_arg].list[1];
210 if (s_arg[i_arg].n_items == 3) {
211 if ((sort_parameter[sort_parameters].decreasing_order =
match_string(s_arg[i_arg].list[2], order_mode, 2, 0)) < 0)
212 SDDS_Bomb(
"unknown sort order specified--give 'increasing' or 'decreasing'");
213 } else
214 sort_parameter[sort_parameters].decreasing_order = 0;
215 sort_parameters++;
216 break;
217 case SET_NOWARNINGS:
218 noWarnings = 1;
219 break;
220 case SET_NUMERICHIGH:
221 numericHigh = 1;
222 break;
223 case SET_PIPE:
224 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
226 break;
227 case SET_UNIQUE:
228 uniqueRows = 1;
229 if (s_arg[i_arg].n_items > 1) {
231 if (s_arg[i_arg].n_items > 2 ||
232 strncmp("count", s_arg[i_arg].list[1], strlen(s_arg[i_arg].list[1])) != 0)
234 provideIdenticalCount = 1;
235 }
236 break;
237 default:
238 fprintf(stderr, "error: unknown switch: %s\n", s_arg[i_arg].list[0]);
239 exit(EXIT_FAILURE);
240 break;
241 }
242 } else {
243 if (input == NULL)
244 input = s_arg[i_arg].list[0];
245 else if (output == NULL)
246 output = s_arg[i_arg].list[0];
247 else
249 }
250 }
251
252 if (!sort_requests && !sort_parameters)
254 processFilenames(
"sddssort", &input, &output, pipeFlags, noWarnings, &tmpfile_used);
257 exit(EXIT_FAILURE);
258 }
259 if (sort_requests <= 1)
260 non_dominate_sort = 0;
261
262 if (SDDS_input.layout.popenUsed) {
263
264
265
266 pid_t pid;
267 char tmpfileName[1024];
268 pid = getpid();
269 sprintf(tmpfileName, "/tmp/sddssort.%ld", (long)pid);
270 tmpfileForInternalPipe = 1;
273 exit(EXIT_FAILURE);
274 }
275 if (columnMajorOrder != -1)
276 SDDS_tmp.layout.data_mode.column_major = columnMajorOrder;
277 else
278 SDDS_tmp.layout.data_mode.column_major = SDDS_input.layout.data_mode.column_major;
279 if (non_dominate_sort) {
283 exit(EXIT_FAILURE);
284 }
288 constDefined = 1;
289 }
290 }
291
294 exit(EXIT_FAILURE);
295 }
299 exit(EXIT_FAILURE);
300 }
301 }
304 exit(EXIT_FAILURE);
305 }
308 exit(EXIT_FAILURE);
309 }
310 }
313 exit(EXIT_FAILURE);
314 }
315 if (columnMajorOrder != -1)
316 SDDS_output.layout.data_mode.column_major = columnMajorOrder;
317 else
318 SDDS_output.layout.data_mode.column_major = SDDS_input.layout.data_mode.column_major;
319 if (provideIdenticalCount &&
322 exit(EXIT_FAILURE);
323 }
324 if (non_dominate_sort) {
328 exit(EXIT_FAILURE);
329 }
333 constDefined = 1;
334 }
335 }
338 if (!SDDS_SortAll(&SDDS_input, &SDDS_output, sort_request, sort_requests, sort_parameter, sort_parameters,
339 uniqueRows, provideIdenticalCount, pipeFlags, non_dominate_sort)) {
342 }
345 exit(EXIT_FAILURE);
346 }
348 exit(EXIT_FAILURE);
350
351
352 return EXIT_SUCCESS;
353}
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.