/*************************************************************************\ * Copyright (c) 2002 The University of Chicago, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. * This file is distributed subject to a Software License Agreement found * in the file LICENSE that is included with this distribution. \*************************************************************************/ /* program: sddsmselect * purpose: creates a SDDS data set from another data set based * on matching to data in a third data set. * * For example, one can select all of the rows from file1 that * have a match in file2, or that have no match in file2. * Similar to sddsxref, but doesn't transfer any data. * * Michael Borland, 1995 $Log: sddsmselect.c,v $ Revision 1.10 2002/08/14 17:12:49 soliday Added Open License Revision 1.9 2001/05/03 20:55:33 soliday Standardized usage messages. Revision 1.8 2001/01/23 19:47:28 soliday Fixed Solaris compiler warnings. Revision 1.7 1999/09/28 15:38:51 soliday Added SDDS_Terminate at the end. Revision 1.6 1999/05/25 19:12:05 soliday Removed compiler warning on linux. Revision 1.5 1999/01/06 19:54:48 borland Fixed the version number in the usage message. * Revision 1.4 1996/03/11 02:46:08 borland * Handles empty pages in input2 properly. If invert is on, copies remainder * of input1. Otherwise, deletes remainder of input1. * * Revision 1.3 1995/09/06 14:56:47 saunders * First test release of SDDS1.5 * */ #include "mdb.h" #include "SDDS.h" /*#include "SDDSaps.h"*/ #include "scan.h" #define SET_MATCH_COLUMNS 0 #define SET_EQUATE_COLUMNS 1 #define SET_NOWARNINGS 2 #define SET_INVERT 3 #define SET_REUSE 4 #define SET_PIPE 5 #define N_OPTIONS 6 typedef char *STRING_PAIR[2]; long rows_equate(SDDS_DATASET *SDDS1, long row1, SDDS_DATASET *SDDS2, long row2, long equate_columns, STRING_PAIR *equate_column); char *option[N_OPTIONS] = { "match", "equate", "nowarnings", "invert", "reuse", "pipe", } ; char *USAGE = "sddsmselect [-pipe[=input][,output]] [] [] \n\ [-match=[=][,...]]\n\ [-equate=[=][,...]] [-invert]\n\ [-reuse[=rows][,page]]\n\n\ sddsmselect selects data from for writing to \n\ based on the presence or absence of matching data in .\n\ If is not given, is replaced.\n\ match specifies names of columns to match between and\n\ for selection and placement of data taken from\n\ .\n\ equate specifies names of columns to equate between and\n\ for selection and placement of data taken from\n\ .\n\ reuse specifies that rows of may be reused, i.e., matched\n\ with more than one row of . Also, -reuse=page specifies\n\n\ that only the first page of is used.\n\ invert specifies that only nomatched rows are to be kept.\n\ nowarnings specifies that no warnings should be printed.\n\n\ Program by Michael Borland. (This is version 3, March 1996.)\n"; int main(int argc, char **argv) { SDDS_DATASET SDDS_1, SDDS_2, SDDS_output; long outputRow, i, j, k, i_arg, rows1, rows2, reuse, reusePage; SCANNED_ARG *s_arg; char s[200], *ptr; STRING_PAIR *match_column, *equate_column; long match_columns, equate_columns; char *input1, *input2, *output, *match_value; long tmpfile_used, retval1, retval2; long *row_used, n, warnings, invert; unsigned long pipeFlags; SDDS_RegisterProgramName(argv[0]); argc = scanargs(&s_arg, argc, argv); if (argc<3) bomb(NULL, USAGE); input1 = input2 = output = NULL; match_column = equate_column = NULL; match_columns = equate_columns = reuse = reusePage = invert = 0; tmpfile_used = 0; warnings = 1; pipeFlags = 0; for (i_arg=1; i_arg0) { if (!reusePage) { if ((retval2=SDDS_ReadPage(&SDDS_2))<=0) { if (warnings) fprintf(stderr, "warning: ends before \n"); if (invert) { /* nothing to match, so everything would normally be thrown out */ if (!SDDS_CopyPage(&SDDS_output, &SDDS_1) || !SDDS_WritePage(&SDDS_output)) SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); continue; } else /* nothing to match, so everything thrown out */ break; } } else { if (retval1==1 && (retval2=SDDS_ReadPage(&SDDS_2))<=0) SDDS_Bomb(" has no data"); SDDS_SetRowFlags(&SDDS_2, 1); } SDDS_SetRowFlags(&SDDS_1, 1); rows1 = SDDS_CountRowsOfInterest(&SDDS_1); if ((rows2 = SDDS_CountRowsOfInterest(&SDDS_2))) { row_used = SDDS_Realloc(row_used, sizeof(*row_used)*rows2); SDDS_ZeroMemory(row_used, rows2*sizeof(*row_used)); } if (!SDDS_StartPage(&SDDS_output, rows1)) { SDDS_SetError("Problem starting output page"); SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); } if (!SDDS_CopyParameters(&SDDS_output, &SDDS_1) || !SDDS_CopyArrays(&SDDS_output, &SDDS_1)) { SDDS_SetError("Problem copying parameter or array data from first input file"); SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); } outputRow = 0; for (j=0; jdata[index1]+size*row1; data2 = (char*)SDDS2->data[index2]+size*row2; if (memcmp(data1, data2, size)!=0) return(0); } return(1); }