131 {
132 int iArg;
133 unsigned long dummyFlags, pipeFlags, majorOrderFlag;
134 SCANNED_ARG *scanned;
136 char *input = NULL, *output = NULL, *distFile = NULL, **columnName = NULL, **sigmaName = NULL, **excludeName = NULL, *distFileIndep = NULL, *distFileDepen = NULL;
137 long testCode = 0, distCode = -1, code, degreesFree = -1, columnNames = 0, excludeNames = 0;
138 char *dofParameter = NULL;
139 short columnMajorOrder = -1;
140 int threads = 1;
141
143 argc =
scanargs(&scanned, argc, argv);
144 if (argc < 3)
146
147 pipeFlags = 0;
148
149 for (iArg = 1; iArg < argc; iArg++) {
150 if (scanned[iArg].arg_type == OPTION) {
151
152 code =
match_string(scanned[iArg].list[0], option, N_OPTIONS, 0);
153 switch (code) {
154 case CLO_MAJOR_ORDER:
155 majorOrderFlag = 0;
156 scanned[iArg].n_items--;
157 if (scanned[iArg].n_items > 0 &&
158 !
scanItemList(&majorOrderFlag, scanned[iArg].list + 1, &scanned[iArg].n_items, 0,
159 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
160 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)) {
161 SDDS_Bomb(
"invalid -majorOrder syntax/values");
162 }
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 CLO_PIPE:
169 if (!
processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags))
170 SDDS_Bomb(
"invalid -pipe syntax/values");
171 break;
172 case CLO_COLUMN:
173 if ((scanned[iArg].n_items != 2 && scanned[iArg].n_items != 3) ||
175 SDDS_Bomb(
"invalid -column syntax/values");
176 }
177 moveToStringArray(&columnName, &columnNames, scanned[iArg].list + 1, 1);
178 sigmaName =
SDDS_Realloc(sigmaName,
sizeof(*sigmaName) * columnNames);
179 if (scanned[iArg].n_items == 3) {
180 scanned[iArg].n_items -= 2;
181 if (!
scan_item_list(&dummyFlags, scanned[iArg].list + 2, &scanned[iArg].n_items,
"sigma",
182 SDDS_STRING, sigmaName + columnNames - 1, 1, 1, NULL) ||
183 dummyFlags != 1 ||
185 SDDS_Bomb(
"invalid -column syntax/values");
186 }
187 } else {
188 sigmaName[columnNames - 1] = NULL;
189 }
190 break;
191 case CLO_TEST:
192 if (scanned[iArg].n_items != 2 ||
193 (testCode =
match_string(scanned[iArg].list[1], testChoice, N_TESTS, 0)) < 0) {
194 SDDS_Bomb(
"invalid -test syntax/values");
195 }
196 break;
197 case CLO_FILEDIST:
198 if (scanned[iArg].n_items != 4) {
199 SDDS_Bomb(
"too few qualifiers for -fileDistribution");
200 }
204 SDDS_Bomb(
"invalid -fileDistribution values");
205 }
206 break;
207 case CLO_GAUSSIAN:
208 case CLO_POISSON:
209 case CLO_STUDENT:
210 case CLO_CHISQUARED:
211 distCode = code;
212 break;
213 case CLO_DOF:
214 if (scanned[iArg].n_items != 2) {
215 SDDS_Bomb(
"too few qualifiers for -degreesOfFreedom");
216 }
217 if (scanned[iArg].list[1][0] == '@') {
220 }
221 } else if (sscanf(scanned[iArg].list[1], "%ld", °reesFree) != 1 || degreesFree <= 1) {
222 SDDS_Bomb(
"invalid degrees-of-freedom given for -student/-chiSquared");
223 }
224 break;
225 case CLO_EXCLUDE:
227 SDDS_Bomb(
"invalid -exclude syntax/values");
228 }
229 moveToStringArray(&excludeName, &excludeNames, scanned[iArg].list + 1, scanned[iArg].n_items - 1);
230 break;
231 case CLO_THREADS:
232 if (scanned[iArg].n_items != 2 ||
233 !sscanf(scanned[iArg].list[1], "%d", &threads) ||
234 threads < 1) {
236 }
237 break;
238 default:
239 fprintf(stderr, "error: unknown/ambiguous option: %s (%s)\n", scanned[iArg].list[0], argv[0]);
240 exit(EXIT_FAILURE);
241 }
242 } else {
243 if (!input)
244 input = scanned[iArg].list[0];
245 else if (!output)
246 output = scanned[iArg].list[0];
247 else
249 }
250 }
251
253
256 if (!columnNames)
257 SDDS_Bomb(
"-column option must be supplied");
258 if (!(columnNames = expandColumnPairNames(&SDDSin, &columnName, &sigmaName, columnNames, excludeName, excludeNames, FIND_NUMERIC_TYPE, 0))) {
260 SDDS_Bomb(
"named columns nonexistent or nonnumerical");
261 }
263 SDDS_Bomb(
"degrees-of-freedom parameter not found");
264
265 if (distFile)
266 compareToFileDistribution(output, testCode, &SDDSin, columnName, columnNames, distFile, distFileIndep, distFileDepen);
267 else
268 compareToDistribution(output, testCode, &SDDSin, columnName, sigmaName, columnNames, distCode, degreesFree, dofParameter, columnMajorOrder, threads);
269
272 return EXIT_FAILURE;
273 }
274 return EXIT_SUCCESS;
275}
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
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.
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory 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.
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)
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.
long scan_item_list(unsigned long *flags, char **item, long *items,...)
Scans a list of items without flag extension and assigns values based on provided keywords and types.