arguments* parse_args(int argc, char* argv[]) { /* Parse the command line argument array into a convienent structure. */ FILE* csv; arguments* args = calloc(1, sizeof(arguments)); args->delim = *argv[2]; args->quo = *argv[3]; // Parse sequence of integers passed as command line arguments into an // integer array. args->n_fields = argc - 4; if(args->n_fields > MAX_N_FIELDS) { raise_too_many_fields_error(); } for(int i = 4; i < argc; i++) { args->field_idxs[i-4] = atoi(argv[i]); } if(!check_increasing(args->field_idxs, args->n_fields)) { raise_not_increasing_error(); } // Open a connection to the delimited file. if(strcmp(argv[1], "stdin") == 0) { csv = stdin; } else { csv = fopen(argv[1], "r"); } if(csv == NULL) { raise_file_error(); } args->csv = csv; return args; }
/* BIN * --- * Input parameters: * dataCol - the column with the channel data * numChans - number of channels in groupCol and qualCol * binLow - array of lower group boundaries * binHigh - array of higher group boundaries * numBins - number of binLow-binHigh group pairs * groupCol - the GROUPING column * qualCol - the QUALITY column * tabStops - array giving channels with tabs or stops */ int grp_do_bin(double *dataCol, long numChans, double *binLow, double *binHigh, long numBins, short *groupCol, short *qualCol, short *tabStops, dsErrList *errList, short partialBin, int isColReal){ long ii, jj, binLength, counter, tempLow, tempHigh, chanHigh; short isComplete; double maxVal, dataHigh; int tmpVar = 0; int isAscending = 0; /* Check for obviously bad inputs */ if(!dataCol || (numChans <= 0) || !binLow || !binHigh || (numBins < 0) || !groupCol || !qualCol || !tabStops){ if(errList) dsErrAdd(errList, dsDMGROUPBADPARAMERR, Accumulation, Generic); else err_msg("ERROR: At least one input parameter has an " "invalid value.\n"); return(GRP_ERROR); } /* Check for monotonically increasing or decreasing data */ if (check_increasing(dataCol, numChans) == 0) { isAscending = 1; } else { if ( check_decreasing(dataCol, numChans) != 0 ) { if(errList) dsErrAdd(errList, dsDMGROUPBADDATAORDERERR, Accumulation, Generic); else err_msg("ERROR: Data column is not increasing/decreasing.\n"); return(GRP_ERROR); } } if (isAscending) { dataHigh = dataCol[numChans - 1]; maxVal = binHigh[numBins - 1]; } else { dataHigh = dataCol[0]; maxVal = binLow[0]; } chanHigh = upper_bound(maxVal, dataCol, numChans, isAscending, isColReal, errList); /* Check if any bins overlap */ if(check_overlap(binLow, binHigh, numBins)){ if(errList) dsErrAdd(errList, dsDMGROUPOVERLAPBINSPECERR, Accumulation, Generic); else err_msg("ERROR: At least two bins in binspec overlap.\n"); return(GRP_ERROR); } /* Go through all binLow-binHigh pairs */ for(ii = 0; ii < numBins; ii++){ tempLow = lower_bound(binLow[ii], dataCol, numChans, isAscending, errList); tempHigh = upper_bound(binHigh[ii], dataCol, numChans, isAscending, isColReal, errList); if (!isAscending) { tmpVar = tempLow; tempLow = tempHigh; tempHigh = tmpVar; } if((tempLow == GRP_ERROR) || (tempHigh == GRP_ERROR)) continue; /* return(GRP_ERROR); */ /* If there are no data within the pair, skip to next pair */ if((tempHigh - tempLow) < 0) continue; binLength = tempHigh - tempLow; if(binLow[ii] > dataHigh){ if(errList) dsErrAdd(errList, dsDMGROUPINVALIDBINERR, Accumulation, Generic); else err_msg("ERROR: A bin boundary is invalid.\nMake " "sure the binspec fits within the bounds " "of the data.\n"); return(GRP_ERROR); } isComplete = GRP_TRUE; /* Check for a complete group */ for(jj = tempLow; jj <= tempHigh; jj++){ if ( (jj > chanHigh) || tabStops[jj] ) { isComplete = GRP_FALSE; break; } } /* If it's the last group, and partialBin is TRUE, then it's not complete. */ if( (partialBin && (ii == (numBins - 1))) || ((!isAscending) && (binLength < (numBins-1))) ) isComplete = GRP_FALSE; counter = 0; /* Create group - good or bad */ for(jj = tempLow; jj <= tempHigh; jj++){ /* Are we in a tab or stop? */ if(tabStops[jj]){ counter = 0; } /* Are we at the end of the table? */ else if(jj == (numChans - 1)){ /* Is this a single-element group? */ if(counter == 0){ if(isComplete){ groupCol[jj] = GRP_BEGIN; qualCol[jj] = GRP_GOOD; break; } else{ groupCol[jj] = GRP_BEGIN; qualCol[jj] = GRP_POOR; break; } } /* Does this complete the group? */ if(isComplete){ groupCol[jj] = GRP_MIDDLE; qualCol[jj] = GRP_GOOD; break; } else{ groupCol[jj] = GRP_MIDDLE; qualCol[jj] = GRP_POOR; break; } } /* Are we at the beginning of a group? */ else if(counter == 0){ if(isComplete){ groupCol[jj] = GRP_BEGIN; qualCol[jj] = GRP_GOOD; counter++; } else{ groupCol[jj] = GRP_BEGIN; qualCol[jj] = GRP_POOR; counter++; } } /* We must be in the middle of a group */ else{ if(isComplete){ groupCol[jj] = GRP_MIDDLE; qualCol[jj] = GRP_GOOD; counter++; } else{ groupCol[jj] = GRP_MIDDLE; qualCol[jj] = GRP_POOR; counter++; } } } /* end for(jj) */ } /* end for(ii) */ return(GRP_SUCCESS); }