//
// Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu>
// Creation Date: Mon Jul 18 11:23:42 PDT 2005
// Last Modified: Tue Sep 1 13:54:42 PDT 2009 Added -f, and -p options
// Last Modified: Wed Sep 2 13:26:58 PDT 2009 Added -t option
// Last Modified: Sat Sep 5 15:21:29 PDT 2009 Added sub-spine features
// Last Modified: Tue Sep 8 11:43:46 PDT 2009 Added co-spine extraction
// Last Modified: Sat Apr 6 00:48:21 PDT 2013 Enabled multiple segment input
// Filename: ...sig/examples/all/extractx.cpp
// Web Address: http://sig.sapp.org/examples/museinfo/humdrum/extractx.cpp
// Syntax: C++; museinfo
//
// Description: C++ implementation of the Humdrum Toolkit extract command.
//
#include "humdrum.h"
#include "PerlRegularExpression.h"
#include <stdlib.h>
#include <string.h>
#ifndef OLDCPP
#include <iostream>
#include <fstream>
#else
#include <iostream.h>
#include <fstream.h>
#endif
// function declarations
void checkOptions(Options& opts, int argc, char* argv[]);
void excludeFields(HumdrumFile& infile, Array<int>& field,
Array<int>& subfield, Array<int>& model);
void extractFields(HumdrumFile& infile, Array<int>& field,
Array<int>& subfield, Array<int>& model);
void extractTrace(HumdrumFile& infile, const char* tracefile);
void getInterpretationFields(Array<int>& field, Array<int>& subfield,
Array<int>& model, HumdrumFile& infile,
const char* interps, int state);
//void extractInterpretations (HumdrumFile& infile, const char* interps);
void example(void);
void usage(const char* command);
void fillFieldData(Array<int>& field, Array<int>& subfield,
Array<int>& model, const char* fieldstring,
HumdrumFile& infile);
void processFieldEntry(Array<int>& field, Array<int>& subfield,
Array<int>& model, const char* string,
HumdrumFile& infile);
void removeDollarsFromString(Array<char>& buffer, int maxtrack);
int isInList(int number, Array<int>& listofnum);
void getTraceData(Array<int>& startline,
Array<Array<int> >& fields,
const char* tracefile, HumdrumFile& infile);
void printTraceLine(HumdrumFile& infile, int line,
Array<int>& field);
void dealWithSpineManipulators(HumdrumFile& infile, int line,
Array<int>& field, Array<int>& subfield,
Array<int>& model);
void storeToken(Array<Array<char> >& storage,
const char* string);
void storeToken(Array<Array<char> >& storage, int index,
const char* string);
void printMultiLines(Array<int>& vsplit, Array<int>& vserial,
Array<Array<char> >& tempout);
void reverseSpines(Array<int>& field, Array<int>& subfield,
Array<int>& model, HumdrumFile& infile,
const char* exinterp);
void getSearchPat(Array<char>& spat, int target,
const char* modifier);
void expandSpines(Array<int>& field, Array<int>& subfield,
Array<int>& model, HumdrumFile& infile,
const char* interp);
void dealWithSecondarySubspine(Array<int>& field, Array<int>& subfield,
Array<int>& model, int targetindex,
HumdrumFile& infile, int line, int spine,
int submodel);
void dealWithCospine(Array<int>& field, Array<int>& subfield,
Array<int>& model, int targetindex,
HumdrumFile& infile, int line, int cospine,
int comodel, int submodel,
const char* cointerp);
void printCotokenInfo(int& start, HumdrumFile& infile, int line,
int spine, Array<Array<char> >& cotokens,
Array<int>& spineindex,
Array<int>& subspineindex);
void fillFieldDataByGrep(Array<int>& field, Array<int>& subfield,
Array<int>& model, const char* grepString,
HumdrumFile& infile, int state);
// global variables
Options options; // database for command-line arguments
int excludeQ = 0; // used with -x option
int expandQ = 0; // used with -e option
const char* expandInterp = ""; // used with -E option
int interpQ = 0; // used with -i option
const char* interps = ""; // used with -i option
int debugQ = 0; // used with --debug option
int fieldQ = 0; // used with -f or -p option
const char* fieldstring = ""; // used with -f or -p option
Array<int> field; // used with -f or -p option
Array<int> subfield; // used with -f or -p option
Array<int> model; // used with -p, or -e options and similar
int countQ = 0; // used with -C option
int traceQ = 0; // used with -t option
const char* tracefile = ""; // used with -t option
int reverseQ = 0; // used with -r option
const char* reverseInterp = "**kern"; // used with -r and -R options.
// sub-spine "b" expansion model: how to generate data for a secondary
// spine if the primary spine is not divided. Models are:
// 'd': duplicate primary spine (or "a" subspine) data (default)
// 'n': null = use a null token
// 'r': rest = use a rest instead of a primary spine note (in **kern)
// data. 'n' will be used for non-kern spines when 'r' is used.
int submodel = 'd'; // used with -m option
const char* editorialInterpretation = "yy";
const char* cointerp = "**kern"; // used with -c option
int comodel = 0; // used with -M option
const char* subtokenseparator = " "; // used with a future option
int interpstate = 0; // used -I or with -i
int grepQ = 0; // used with -g option
const char* grepString = ""; // used with -g option
///////////////////////////////////////////////////////////////////////////
int main(int argc, char* argv[]) {
HumdrumFileSet infiles;
// process the command-line options
checkOptions(options, argc, argv);
// figure out the number of input files to process
int numinputs = options.getArgCount();
int i;
if (numinputs < 1) {
infiles.read(cin);
} else {
for (i=0; i<numinputs; i++) {
infiles.readAppend(options.getArg(i+1));
}
}
for (int i=0; i<infiles.getCount(); i++) {
if (countQ) {
cout << infiles[i].getMaxTracks() << endl;
exit(0);
}
if (expandQ) {
expandSpines(field, subfield, model, infiles[i], expandInterp);
} else if (interpQ) {
getInterpretationFields(field, subfield, model, infiles[i], interps,
interpstate);
} else if (reverseQ) {
reverseSpines(field, subfield, model, infiles[i], reverseInterp);
} else if (fieldQ || excludeQ) {
fillFieldData(field, subfield, model, fieldstring, infiles[i]);
} else if (grepQ) {
fillFieldDataByGrep(field, subfield, model, grepString, infiles[i],
interpstate);
}
if (debugQ && !traceQ) {
cout << "!! Field Expansion List:";
for (int j=0; j<field.getSize(); j++) {
cout << " " << field[j];
if (subfield[j]) {
cout << (char)subfield[j];
}
if (model[j]) {
cout << (char)model[j];
}
}
cout << endl;
}
// preserve SEGMENT filename if present
infiles[i].printNonemptySegmentLabel(cout);
// analyze the input file according to command-line options
if (fieldQ || grepQ) {
extractFields(infiles[i], field, subfield, model);
} else if (excludeQ) {
excludeFields(infiles[i], field, subfield, model);
} else if (traceQ) {
extractTrace(infiles[i], tracefile);
} else {
cout << infiles[i];
}
}
return 0;
}
///////////////////////////////////////////////////////////////////////////
//////////////////////////////
//
// fillFieldDataByGrep --
//
void fillFieldDataByGrep(Array<int>& field, Array<int>& subfield,
Array<int>& model, const char* searchstring, HumdrumFile& infile,
int state) {
field.setSize(infile.getMaxTracks()+1);
subfield.setSize(infile.getMaxTracks()+1);
model.setSize(infile.getMaxTracks()+1);
field.setSize(0);
subfield.setSize(0);
model.setSize(0);
Array<int> tracks;
tracks.setSize(infile.getMaxTracks()+1);
tracks.setAll(0);
PerlRegularExpression pre;
int track;
int i, j;
for (i=0; i<infile.getNumLines(); i++) {
if (!infile[i].isSpineLine()) {
continue;
}
for (j=0; j<infile[i].getFieldCount(); j++) {
if (pre.search(infile[i][j], searchstring, "")) {
track = infile[i].getPrimaryTrack(j);
tracks[track] = 1;
}
}
}
int zero = 0;
for (i=1; i<tracks.getSize(); i++) {
if (state != 0) {
tracks[i] = !tracks[i];
}
if (tracks[i]) {
field.append(i);
subfield.append(zero);
model.append(zero);
}
}
}
//////////////////////////////
//
// getInterpretationFields --
//
void getInterpretationFields(Array<int>& field, Array<int>& subfield,
Array<int>& model, HumdrumFile& infile, const char* interps,
int state) {
Array<Array<char> > sstrings; // search strings
sstrings.setSize(100);
sstrings.setSize(0);
sstrings.setGrowth(1000);
int i, j, k;
Array<char> buffer;
buffer.setSize(strlen(interps)+1);
strcpy(buffer.getBase(), interps);
PerlRegularExpression pre;
pre.sar(buffer, "\\s+", "", "g"); // remove spaces from the search string.
int index;
while (pre.search(buffer, "^([^,]+)")) {
sstrings.setSize(sstrings.getSize()+1);
index = sstrings.getSize()-1;
sstrings[index].setSize(strlen(pre.getSubmatch(1))+1);
strcpy(sstrings[index].getBase(), pre.getSubmatch());
pre.sar(buffer, "^[^,]+,?", "", "");
}
if (debugQ) {
cout << "!! Interpretation strings to search for: " << endl;
for (i=0; i<sstrings.getSize(); i++) {
cout << "!!\t" << sstrings[i].getBase() << endl;
}
}
Array<int> tracks;
tracks.setSize(infile.getMaxTracks()+1);
tracks.setAll(0);
tracks.allowGrowth(0);
for (i=0; i<infile.getNumLines(); i++) {
if (!infile[i].isInterpretation()) {
continue;
}
for (j=0; j<infile[i].getFieldCount(); j++) {
for (k=0; k<sstrings.getSize(); k++) {
if (strcmp(sstrings[k].getBase(), infile[i][j]) == 0) {
tracks[infile[i].getPrimaryTrack(j)] = 1;
}
}
}
}
field.setSize(tracks.getSize());
field.setSize(0);
subfield.setSize(tracks.getSize());
subfield.setSize(0);
model.setSize(tracks.getSize());
model.setSize(0);
int zero = 0;
for (i=1; i<tracks.getSize(); i++) {
if (state == 0) {
tracks[i] = !tracks[i];
}
if (tracks[i]) {
field.append(i);
subfield.append(zero);
model.append(zero);
}
}
}
//////////////////////////////
//
// expandSpines --
//
void expandSpines(Array<int>& field, Array<int>& subfield, Array<int>& model,
HumdrumFile& infile, const char* interp) {
Array<int> splits;
splits.setSize(infile.getMaxTracks()+1);
splits.allowGrowth(0);
splits.setAll(0);
int i, j;
for (i=0; i<infile.getNumLines(); i++) {
if (!infile[i].isSpineManipulator()) {
continue;
}
for (j=0; j<infile[i].getFieldCount(); j++) {
if (strchr(infile[i].getSpineInfo(j), '(') != NULL) {
splits[infile[i].getPrimaryTrack(j)] = 1;
}
}
}
field.setSize(infile.getMaxTracks()*2);
field.setSize(0);
field.allowGrowth(1);
subfield.setSize(infile.getMaxTracks()*2);
subfield.setSize(0);
subfield.allowGrowth(1);
model.setSize(infile.getMaxTracks()*2);
model.setSize(0);
model.allowGrowth(1);
int allQ = 0;
if (strcmp(interp, "") == 0) {
allQ = 1;
}
// ggg
Array<int> dummyfield;
Array<int> dummysubfield;
Array<int> dummymodel;
getInterpretationFields(dummyfield, dummysubfield, model, infile, interp, 1);
Array<int> interptracks;
interptracks.setSize(infile.getMaxTracks()+1);
interptracks.allowGrowth(0);
interptracks.setAll(0);
for (i=0; i<dummyfield.getSize(); i++) {
interptracks[dummyfield[i]] = 1;
}
int aval = 'a';
int bval = 'b';
int zero = 0;
for (i=1; i<splits.getSize(); i++) {
if (splits[i] && (allQ || interptracks[i])) {
field.append(i);
subfield.append(aval);
model.append(zero);
field.append(i);
subfield.append(bval);
model.append(zero);
} else {
field.append(i);
subfield.append(zero);
model.append(zero);
}
}
field.allowGrowth(0);
subfield.allowGrowth(0);
model.allowGrowth(0);
if (debugQ) {
cout << "!!expand: ";
for (i=0; i<field.getSize(); i++) {
cout << field[i];
if (subfield[i]) {
cout << (char)subfield[i];
}
if (i < field.getSize()-1) {
cout << ",";
}
}
cout << endl;
}
}
//////////////////////////////
//
// reverseSpines -- reverse the order of spines, grouped by the
// given exclusive interpretation.
//
void reverseSpines(Array<int>& field, Array<int>& subfield, Array<int>& model,
HumdrumFile& infile, const char* exinterp) {
Array<int> target;
target.setSize(infile.getMaxTracks()+1);
target.allowGrowth(0);
target.setAll(0);
int t;
for (t=1; t<=infile.getMaxTracks(); t++) {
if (strcmp(infile.getTrackExInterp(t), exinterp) == 0) {
target[t] = 1;
}
}
field.setSize(infile.getMaxTracks()*2);
field.setSize(0);
int i, j;
int lasti = target.getSize();
for (i=target.getSize()-1; i>0; i--) {
if (target[i]) {
lasti = i;
field.append(i);
for (j=i+1; j<target.getSize(); j++) {
if (!target[j]) {
field.append(j);
} else {
break;
}
}
}
}
// if the grouping spine is not first, then preserve the
// locations of the pre-spines.
int extras = 0;
if (lasti != 1) {
extras = lasti - 1;
field.setSize(field.getSize()+extras);
for (i=0; i<field.getSize()-extras; i++) {
field[field.getSize()-1-i] = field[field.getSize()-1-extras-i];
}
for (i=0; i<extras; i++) {
field[i] = i+1;
}
}
if (debugQ) {
cout << "!!reverse: ";
for (i=0; i<field.getSize(); i++) {
cout << field[i] << " ";
}
cout << endl;
}
subfield.setSize(field.getSize());
subfield.allowGrowth(0);
subfield.setAll(0);
model.setSize(field.getSize());
model.allowGrowth(0);
model.setAll(0);
field.allowGrowth(0);
}
//////////////////////////////
//
// fillFieldData --
//
void fillFieldData(Array<int>& field, Array<int>& subfield, Array<int>& model,
const char* fieldstring, HumdrumFile& infile) {
int maxtrack = infile.getMaxTracks();
field.setSize(maxtrack);
field.setGrowth(maxtrack);
field.setSize(0);
subfield.setSize(maxtrack);
subfield.setGrowth(maxtrack);
subfield.setSize(0);
model.setSize(maxtrack);
model.setGrowth(maxtrack);
model.setSize(0);
PerlRegularExpression pre;
Array<char> buffer;
buffer.setSize(strlen(fieldstring)+1);
strcpy(buffer.getBase(), fieldstring);
pre.sar(buffer, "\\s", "", "gs");
int start = 0;
int value = 0;
value = pre.search(buffer.getBase(), "^([^,]+,?)");
while (value != 0) {
start += value - 1;
start += strlen(pre.getSubmatch(1));
processFieldEntry(field, subfield, model, pre.getSubmatch(), infile);
value = pre.search(buffer.getBase() + start, "^([^,]+,?)");
}
}
//////////////////////////////
//
// processFieldEntry --
// 3-6 expands to 3 4 5 6
// $ expands to maximum spine track
// $-1 expands to maximum spine track minus 1, etc.
//
void processFieldEntry(Array<int>& field, Array<int>& subfield,
Array<int>& model, const char* string, HumdrumFile& infile) {
int maxtrack = infile.getMaxTracks();
int modletter;
int subletter;
PerlRegularExpression pre;
Array<char> buffer;
buffer.setSize(strlen(string)+1);
strcpy(buffer.getBase(), string);
// remove any comma left at end of input string (or anywhere else)
pre.sar(buffer, ",", "", "g");
// first remove $ symbols and replace with the correct values
removeDollarsFromString(buffer, infile.getMaxTracks());
int zero = 0;
if (pre.search(buffer.getBase(), "^(\\d+)-(\\d+)$")) {
int firstone = strtol(pre.getSubmatch(1), NULL, 10);
int lastone = strtol(pre.getSubmatch(2), NULL, 10);
if ((firstone < 1) && (firstone != 0)) {
cerr << "Error: range token: \"" << string << "\""
<< " contains too small a number at start: " << firstone << endl;
cerr << "Minimum number allowed is " << 1 << endl;
exit(1);
}
if ((lastone < 1) && (lastone != 0)) {
cerr << "Error: range token: \"" << string << "\""
<< " contains too small a number at end: " << lastone << endl;
cerr << "Minimum number allowed is " << 1 << endl;
exit(1);
}
if (firstone > maxtrack) {
cerr << "Error: range token: \"" << string << "\""
<< " contains number too large at start: " << firstone << endl;
cerr << "Maximum number allowed is " << maxtrack << endl;
exit(1);
}
if (lastone > maxtrack) {
cerr << "Error: range token: \"" << string << "\""
<< " contains number too large at end: " << lastone << endl;
cerr << "Maximum number allowed is " << maxtrack << endl;
exit(1);
}
int i;
if (firstone > lastone) {
for (i=firstone; i>=lastone; i--) {
field.append(i);
subfield.append(zero);
model.append(zero);
}
} else {
for (i=firstone; i<=lastone; i++) {
field.append(i);
subfield.append(zero);
model.append(zero);
}
}
} else if (pre.search(buffer.getBase(), "^(\\d+)([a-z]*)")) {
int value = strtol(pre.getSubmatch(1), NULL, 10);
modletter = 0;
subletter = 0;
if (strchr(pre.getSubmatch(2), 'a') != NULL) {
subletter = 'a';
}
if (strchr(pre.getSubmatch(), 'b') != NULL) {
subletter = 'b';
}
if (strchr(pre.getSubmatch(), 'c') != NULL) {
subletter = 'c';
}
if (strchr(pre.getSubmatch(), 'd') != NULL) {
modletter = 'd';
}
if (strchr(pre.getSubmatch(), 'n') != NULL) {
modletter = 'n';
}
if (strchr(pre.getSubmatch(), 'r') != NULL) {
modletter = 'r';
}
if ((value < 1) && (value != 0)) {
cerr << "Error: range token: \"" << string << "\""
<< " contains too small a number at end: " << value << endl;
cerr << "Minimum number allowed is " << 1 << endl;
exit(1);
}
if (value > maxtrack) {
cerr << "Error: range token: \"" << string << "\""
<< " contains number too large at start: " << value << endl;
cerr << "Maximum number allowed is " << maxtrack << endl;
exit(1);
}
field.append(value);
if (value == 0) {
subfield.append(zero);
model.append(zero);
} else {
subfield.append(subletter);
model.append(modletter);
}
}
}
//////////////////////////////
//
// removeDollarsFromString -- substitute $ sign for maximum track count.
//
void removeDollarsFromString(Array& buffer, int maxtrack) {
PerlRegularExpression pre;
char buf2[128] = {0};
int value2;
if (pre.search(buffer.getBase(), "\\$$")) {
sprintf(buf2, "%d", maxtrack);
pre.sar(buffer, "\\$$", buf2);
}
if (pre.search(buffer.getBase(), "\\$(?![\\d-])")) {
// don't know how this case could happen, however...
sprintf(buf2, "%d", maxtrack);
pre.sar(buffer, "\\$(?![\\d-])", buf2, "g");
}
if (pre.search(buffer.getBase(), "\\$0")) {
// replace $0 with maxtrack (used for reverse orderings)
sprintf(buf2, "%d", maxtrack);
pre.sar(buffer, "\\$0", buf2, "g");
}
while (pre.search(buffer.getBase(), "\\$(-?\\d+)")) {
value2 = maxtrack - (int)fabs(strtol(pre.getSubmatch(1), NULL, 10));
sprintf(buf2, "%d", value2);
pre.sar(buffer, "\\$-?\\d+", buf2);
}
}
//////////////////////////////
//
// excludeFields -- print all spines except the ones in the list of fields.
//
void excludeFields(HumdrumFile& infile, Array<int>& field,
Array<int>& subfield, Array<int>& model) {
int i;
int j;
int start = 0;
for (i=0; i<infile.getNumLines(); i++) {
switch (infile[i].getType()) {
case E_humrec_none:
case E_humrec_empty:
case E_humrec_global_comment:
case E_humrec_bibliography:
cout << infile[i] << '\n';
break;
case E_humrec_data_comment:
case E_humrec_data_kern_measure:
case E_humrec_interpretation:
case E_humrec_data:
start = 0;
for (j=0; j<infile[i].getFieldCount(); j++) {
if (isInList(infile[i].getPrimaryTrack(j), field)) {
continue;
}
if (start != 0) {
cout << '\t';
}
start = 1;
cout << infile[i][j];
}
if (start != 0) {
cout << endl;
}
break;
default:
cout << "!!Line = UNKNOWN:" << infile[i] << endl;
break;
}
}
}
//////////////////////////////
//
// extractFields -- print all spines except the ones in the list of fields.
//
void extractFields(HumdrumFile& infile, Array<int>& field,
Array<int>& subfield, Array<int>& model) {
PerlRegularExpression pre;
int i;
int j;
int t;
int start = 0;
int target;
int subtarget;
int modeltarget;
Array<char> spat;
for (i=0; i<infile.getNumLines(); i++) {
switch (infile[i].getType()) {
case E_humrec_none:
case E_humrec_empty:
case E_humrec_global_comment:
case E_humrec_bibliography:
cout << infile[i] << '\n';
break;
case E_humrec_data_comment:
case E_humrec_data_kern_measure:
case E_humrec_interpretation:
case E_humrec_data:
if (infile[i].isSpineManipulator()) {
dealWithSpineManipulators(infile, i, field, subfield, model);
break;
}
start = 0;
for (t=0; t<field.getSize(); t++) {
target = field[t];
subtarget = subfield[t];
modeltarget = model[t];
if (modeltarget == 0) {
switch (subtarget) {
case 'a':
case 'b':
modeltarget = submodel;
break;
case 'c':
modeltarget = comodel;
}
}
if (target == 0) {
if (start != 0) {
cout << '\t';
}
start = 1;
switch (infile[i].getType()) {
case E_humrec_data_comment:
cout << "!"; break;
case E_humrec_data_kern_measure:
cout << infile[i][0]; break;
case E_humrec_data:
cout << "."; break;
// interpretations handled in dealwithSpineManipulators()
}
} else {
for (j=0; j<infile[i].getFieldCount(); j++) {
if (infile[i].getPrimaryTrack(j) != target) {
continue;
}
switch (subtarget) {
case 'a':
getSearchPat(spat, target, "a");
if (pre.search(infile[i].getSpineInfo(j),
spat.getBase()) ||
!pre.search(infile[i].getSpineInfo(j), "\\(")) {
if (start != 0) {
cout << '\t';
}
start = 1;
cout << infile[i][j];
}
break;
case 'b':
getSearchPat(spat, target, "b");
if (pre.search(infile[i].getSpineInfo(j),
spat.getBase())) {
if (start != 0) {
cout << '\t';
}
start = 1;
cout << infile[i][j];
} else if (!pre.search(infile[i].getSpineInfo(j),
"\\(")) {
if (start != 0) {
cout << '\t';
}
start = 1;
dealWithSecondarySubspine(field, subfield, model, t,
infile, i, j, modeltarget);
}
break;
case 'c':
if (start != 0) {
cout << '\t';
}
start = 1;
dealWithCospine(field, subfield, model, t, infile, i, j,
modeltarget, modeltarget, cointerp);
break;
default:
if (start != 0) {
cout << '\t';
}
start = 1;
cout << infile[i][j];
}
}
}
}
if (start != 0) {
cout << endl;
}
break;
default:
cout << "!!Line = UNKNOWN:" << infile[i] << endl;
break;
}
}
}
//////////////////////////////
//
// dealWithCospine -- extract the required token(s) from a co-spine.
//
void dealWithCospine(Array<int>& field, Array<int>& subfield, Array<int>& model,
int targetindex, HumdrumFile& infile, int line, int cospine,
int comodel, int submodel, const char* cointerp) {
Array<Array<char> > cotokens;
cotokens.setSize(50);
cotokens.setSize(0);
cotokens.setGrowth(200);
char buffer[1024];
int i, j, k;
int index;
if (infile[line].isInterpretation()) {
cout << infile[line][cospine];
return;
}
if (infile[line].isMeasure()) {
cout << infile[line][cospine];
return;
}
if (infile[line].isLocalComment()) {
cout << infile[line][cospine];
return;
}
int count = infile[line].getTokenCount(cospine);
for (k=0; k<count; k++) {
infile[line].getToken(buffer, cospine, k, 1000);
cotokens.setSize(cotokens.getSize()+1);
index = cotokens.getSize()-1;
cotokens[index].setSize(strlen(buffer)+1);
strcpy(cotokens[index].getBase(), buffer);
}
Array<int> spineindex;
Array<int> subspineindex;
spineindex.setSize(infile.getMaxTracks()*2);
subspineindex.setSize(infile.getMaxTracks()*2);
spineindex.setSize(0);
subspineindex.setSize(0);
spineindex.setGrowth(1000);
subspineindex.setGrowth(1000);
for (j=0; j<infile[line].getFieldCount(); j++) {
if (strcmp(infile[line].getExInterp(j), cointerp) != 0) {
continue;
}
if (strcmp(infile[line][j], ".") == 0) {
continue;
}
count = infile[line].getTokenCount(j);
for (k=0; k<count; k++) {
infile[line].getToken(buffer, j, k, 1000);
if (comodel == 'r') {
if (strchr(buffer, 'r') != NULL) {
continue;
}
}
spineindex.append(j);
subspineindex.append(k);
}
}
if (debugQ) {
cout << "\n!!codata:\n";
for (i=0; i<cotokens.getSize(); i++) {
cout << "!!\t" << i << "\t" << cotokens[i].getBase();
if (i < spineindex.getSize()) {
cout << "\tspine=" << spineindex[i];
cout << "\tsubspine=" << subspineindex[i];
} else {
cout << "\tspine=.";
cout << "\tsubspine=.";
}
cout << endl;
}
}
Array<char> buff;
int start = 0;
for (i=0; i<field.getSize(); i++) {
if (strcmp(infile.getTrackExInterp(field[i]), cointerp) != 0) {
continue;
}
for (j=0; j<infile[line].getFieldCount(); j++) {
if (infile[line].getPrimaryTrack(j) != field[i]) {
continue;
}
if (subfield[i] == 'a') {
getSearchPat(buff, field[i], "a");
if ((strchr(infile[line].getSpineInfo(j), '(') == NULL) ||
(strstr(infile[line].getSpineInfo(j), buff.getBase()) != NULL)) {
printCotokenInfo(start, infile, line, j, cotokens, spineindex,
subspineindex);
}
} else if (subfield[i] == 'b') {
// this section may need more work...
getSearchPat(buff, field[i], "b");
if ((strchr(infile[line].getSpineInfo(j), '(') == NULL) ||
(strstr(infile[line].getSpineInfo(j), buff.getBase()) != NULL)) {
printCotokenInfo(start, infile, line, j, cotokens, spineindex,
subspineindex);
}
} else {
printCotokenInfo(start, infile, line, j, cotokens, spineindex,
subspineindex);
}
}
}
}
//////////////////////////////
//
// printCotokenInfo --
//
void printCotokenInfo(int& start, HumdrumFile& infile, int line, int spine,
Array<Array<char> >& cotokens, Array<int>& spineindex,
Array<int>& subspineindex) {
int i;
int found = 0;
for (i=0; i<spineindex.getSize(); i++) {
if (spineindex[i] == spine) {
if (start == 0) {
start++;
} else {
cout << subtokenseparator;
}
if (i<cotokens.getSize()) {
cout << cotokens[i].getBase();
} else {
cout << ".";
}
found = 1;
}
}
if (!found) {
if (start == 0) {
start++;
} else {
cout << subtokenseparator;
}
cout << ".";
}
}
//////////////////////////////
//
// dealWithSecondarySubspine -- what to print if a secondary spine
// does not exist on a line.
//
void dealWithSecondarySubspine(Array<int>& field, Array<int>& subfield,
Array<int>& model, int targetindex, HumdrumFile& infile, int line,
int spine, int submodel) {
int& i = line;
int& j = spine;
PerlRegularExpression pre;
Array<char> buffer;
switch (infile[line].getType()) {
case E_humrec_data_comment:
if ((submodel == 'n') || (submodel == 'r')) {
cout << "!";
} else {
cout << infile[i][j];
}
break;
case E_humrec_data_kern_measure:
cout << infile[i][j];
break;
case E_humrec_interpretation:
if ((submodel == 'n') || (submodel == 'r')) {
cout << "*";
} else {
cout << infile[i][j];
}
break;
case E_humrec_data:
if (submodel == 'n') {
cout << ".";
} else if (submodel == 'r') {
if (strcmp(infile[i][j], ".") == 0) {
cout << ".";
} else if (strchr(infile[i][j], 'q') != NULL) {
cout << ".";
} else if (strchr(infile[i][j], 'Q') != NULL) {
cout << ".";
} else {
buffer.setSize(strlen(infile[i][j])+1);
strcpy(buffer.getBase(), infile[i][j]);
if (pre.search(buffer, "{")) {
cout << "{";
}
// remove secondary chord notes:
pre.sar(buffer, " .*", "", "");
// remove unnecessary characters (such as stem direction):
pre.sar(buffer, "[^}pPqQA-Ga-g0-9.;%#n-]", "", "g");
// change pitch to rest:
pre.sar(buffer, "[A-Ga-g#n-]+", "r", "");
// add editorial marking unless -Y option is given:
if (strcmp(editorialInterpretation, "") != 0) {
if (pre.search(buffer, "rr")) {
pre.sar(buffer, "(?<=rr)", editorialInterpretation, "");
} else {
pre.sar(buffer, "(?<=r)", editorialInterpretation, "");
}
}
cout << buffer.getBase();
}
} else {
cout << infile[i][j];
}
break;
default:
cerr << "Should not get to this line of code" << endl;
exit(1);
}
}
//////////////////////////////
//
// getSearchPat --
//
void getSearchPat(Array<char>& spat, int target, const char* modifier) {
if (strlen(modifier) > 20) {
cerr << "Error in GetSearchPat" << endl;
exit(1);
}
spat.setSize(32);
strcpy(spat.getBase(), "\\(");
char buffer[32] = {0};
sprintf(buffer, "%d", target);
strcat(spat.getBase(), buffer);
strcat(spat.getBase(), "\\)");
strcat(spat.getBase(), modifier);
spat.setSize(strlen(spat.getBase())+1);
}
//////////////////////////////
//
// dealWithSpineManipulators -- check for proper Humdrum syntax of
// spine manipulators (**, *-, *x, *v, *^) when creating the output.
//
void dealWithSpineManipulators(HumdrumFile& infile, int line,
Array<int>& field, Array<int>& subfield, Array<int>& model) {
Array<int> vmanip; // counter for *v records on line
vmanip.setSize(infile[line].getFieldCount());
vmanip.allowGrowth(0);
vmanip.setAll(0);
Array<int> xmanip; // counter for *x record on line
xmanip.setSize(infile[line].getFieldCount());
xmanip.allowGrowth(0);
xmanip.setAll(0);
int i = 0;
int j;
for (j=0; j<vmanip.getSize(); j++) {
if (strcmp(infile[line][j], "*v") == 0) {
vmanip[j] = 1;
}
if (strcmp(infile[line][j], "*x") == 0) {
xmanip[j] = 1;
}
}
int counter = 1;
for (i=1; i<xmanip.getSize(); i++) {
if ((xmanip[i] == 1) && (xmanip[i-1] == 1)) {
xmanip[i] = counter;
xmanip[i-1] = counter;
counter++;
}
}
counter = 1;
i = 0;
while (i < vmanip.getSize()) {
if (vmanip[i] == 1) {
while ((i < vmanip.getSize()) && (vmanip[i] == 1)) {
vmanip[i] = counter;
i++;
}
counter++;
}
i++;
}
Array<int> fieldoccur; // nth occurance of an input spine in the output
fieldoccur.setSize(field.getSize());
fieldoccur.allowGrowth(0);
fieldoccur.setAll(0);
Array<int> trackcounter; // counter of input spines occurances in output
trackcounter.setSize(infile.getMaxTracks()+1);
trackcounter.allowGrowth(0);
trackcounter.setAll(0);
for (i=0; i<field.getSize(); i++) {
if (field[i] != 0) {
trackcounter[field[i]]++;
fieldoccur[i] = trackcounter[field[i]];
}
}
Array<Array<char> > tempout;
Array<int> vserial;
Array<int> xserial;
Array<int> fpos; // input column of output spine
tempout.setSize(1000);
tempout.setGrowth(1000);
tempout.setSize(0);
vserial.setSize(1000);
vserial.setGrowth(1000);
vserial.setSize(0);
xserial.setSize(1000);
xserial.setGrowth(1000);
xserial.setSize(0);
fpos.setSize(1000);
fpos.setGrowth(1000);
fpos.setSize(0);
Array<char> spat;
Array<char> spinepat;
PerlRegularExpression pre;
int subtarget;
int modeltarget;
int xdebug = 0;
int vdebug = 0;
int suppress = 0;
int t;
int target;
int tval;
for (t=0; t<field.getSize(); t++) {
target = field[t];
subtarget = subfield[t];
modeltarget = model[t];
if (modeltarget == 0) {
switch (subtarget) {
case 'a':
case 'b':
modeltarget = submodel;
break;
case 'c':
modeltarget = comodel;
}
}
suppress = 0;
if (target == 0) {
if (strncmp(infile[line][0], "**", 2) == 0) {
storeToken(tempout, "**blank");
tval = 0;
vserial.append(tval);
xserial.append(tval);
fpos.append(tval);
} else if (strcmp(infile[line][0], "*-") == 0) {
storeToken(tempout, "*-");
tval = 0;
vserial.append(tval);
xserial.append(tval);
fpos.append(tval);
} else {
storeToken(tempout, "*");
tval = 0;
vserial.append(tval);
xserial.append(tval);
fpos.append(tval);
}
} else {
for (j=0; j<infile[line].getFieldCount(); j++) {
if (infile[line].getPrimaryTrack(j) != target) {
continue;
}
// filter by subfield
if (subtarget == 'a') {
getSearchPat(spat, target, "b");
if (pre.search(infile[line].getSpineInfo(j), spat.getBase())) {
continue;
}
} else if (subtarget == 'b') {
getSearchPat(spat, target, "a");
if (pre.search(infile[line].getSpineInfo(j), spat.getBase())) {
continue;
}
}
switch (subtarget) {
case 'a':
if (!pre.search(infile[line].getSpineInfo(j), "\\(")) {
if (strcmp(infile[line][j], "*^") == 0) {
storeToken(tempout, "*");
} else {
storeToken(tempout, infile[line][j]);
}
} else {
getSearchPat(spat, target, "a");
spinepat.setSize(strlen(infile[line].getSpineInfo(j))+1);
strcpy(spinepat.getBase(), infile[line].getSpineInfo(j));
pre.sar(spinepat, "\\(", "\\(", "g");
pre.sar(spinepat, "\\)", "\\)", "g");
if ((strcmp(infile[line][j], "*v") == 0) &&
(strcmp(spinepat.getBase(), spat.getBase()) == 0)) {
storeToken(tempout, "*");
} else {
getSearchPat(spat, target, "b");
if ((strcmp(spinepat.getBase(), spat.getBase())==0) &&
(strcmp(infile[line][j], "*v") == 0)) {
// do nothing
suppress = 1;
} else {
storeToken(tempout, infile[line][j]);
}
}
}
break;
case 'b':
if (!pre.search(infile[line].getSpineInfo(j), "\\(")) {
if (strcmp(infile[line][j], "*^") == 0) {
storeToken(tempout, "*");
} else {
storeToken(tempout, infile[line][j]);
}
} else {
getSearchPat(spat, target, "b");
spinepat.setSize(strlen(infile[line].getSpineInfo(j))+1);
strcpy(spinepat.getBase(), infile[line].getSpineInfo(j));
pre.sar(spinepat, "\\(", "\\(", "g");
pre.sar(spinepat, "\\)", "\\)", "g");
if ((strcmp(infile[line][j], "*v") == 0) &&
(strcmp(spinepat.getBase(), spat.getBase()) == 0)) {
storeToken(tempout, "*");
} else {
getSearchPat(spat, target, "a");
if ((strcmp(spinepat.getBase(), spat.getBase())==0) &&
(strcmp(infile[line][j], "*v") == 0)) {
// do nothing
suppress = 1;
} else {
storeToken(tempout, infile[line][j]);
}
}
}
break;
case 'c':
// work on later
storeToken(tempout, infile[line][j]);
break;
default:
storeToken(tempout, infile[line][j]);
}
if (suppress) {
continue;
}
if (strcmp(tempout[tempout.getSize()-1].getBase(), "*x") == 0) {
tval = fieldoccur[t] * 1000 + xmanip[j];
xserial.append(tval);
xdebug = 1;
} else {
tval = 0;
xserial.append(tval);
}
if (strcmp(tempout[tempout.getSize()-1].getBase(), "*v") == 0) {
tval = fieldoccur[t] * 1000 + vmanip[j];
vserial.append(tval);
vdebug = 1;
} else {
tval = 0;
vserial.append(tval);
}
fpos.append(j);
}
}
}
vserial.allowGrowth(0);
xserial.allowGrowth(0);
if (debugQ && xdebug) {
cout << "!! *x serials = ";
for (int ii=0; ii<xserial.getSize(); ii++) {
cout << xserial[ii] << " ";
}
cout << "\n";
}
if (debugQ && vdebug) {
cout << "!!LINE: " << infile[line].getLine() << endl;
cout << "!! *v serials = ";
for (int ii=0; ii<vserial.getSize(); ii++) {
cout << vserial[ii] << " ";
}
cout << "\n";
}
// check for proper *x syntax /////////////////////////////////
for (i=0; i<xserial.getSize()-1; i++) {
if (!xserial[i]) {
continue;
}
if (xserial[i] != xserial[i+1]) {
if (strcmp(tempout[i].getBase(), "*x") == 0) {
xserial[i] = 0;
tempout[i].setSize(tempout[i].getSize()-1);
strcpy(tempout[i].getBase(), "*");
}
} else {
i++;
}
}
if ((tempout.getSize() == 1) || (xserial.getSize() == 1)) {
// get rid of *x if there is only one spine in output
if (xserial[0]) {
xserial[0] = 0;
tempout[0].setSize(tempout[0].getSize()-1);
strcpy(tempout[0].getBase(), "*");
}
} else if (xserial.getSize() > 1) {
// check the last item in the list
int index = xserial.getSize()-1;
if (strcmp(tempout[index].getBase(), "*x") == 0) {
if (xserial[index] != xserial[index-1]) {
xserial[index] = 0;
tempout[index].setSize(tempout[index].getSize()-1);
strcpy(tempout[index].getBase(), "*");
}
}
}
// check for proper *v syntax /////////////////////////////////
Array<int> vsplit;
vsplit.setSize(vserial.getSize());
vsplit.allowGrowth(0);
vsplit.setAll(0);
// identify necessary line splits
for (i=0; i<vserial.getSize()-1; i++) {
if (!vserial[i]) {
continue;
}
while ((i<vserial.getSize()-1) && (vserial[i]==vserial[i+1])) {
i++;
}
if ((i<vserial.getSize()-1) && vserial[i]) {
if (vserial.getSize() > 1) {
if (vserial[i+1]) {
vsplit[i+1] = 1;
}
}
}
}
// remove single *v spines:
for (i=0; i<vsplit.getSize()-1; i++) {
if (vsplit[i] && vsplit[i+1]) {
if (strcmp(tempout[i].getBase(), "*v") == 0) {
tempout[i].setSize(2);
strcpy(tempout[i].getBase(), "*");
vsplit[i] = 0;
}
}
}
if (debugQ) {
cout << "!!vsplit array: ";
for (i=0; i<vsplit.getSize(); i++) {
cout << " " << vsplit[i];
}
cout << endl;
}
if (vsplit.getSize() > 0) {
if (vsplit[vsplit.getSize()-1]) {
if (strcmp(tempout[tempout.getSize()-1].getBase(), "*v") == 0) {
tempout[tempout.getSize()-1].setSize(2);
strcpy(tempout[tempout.getSize()-1].getBase(), "*");
vsplit[vsplit.getSize()-1] = 0;
}
}
}
int vcount = 0;
for (i=0; i<vsplit.getSize(); i++) {
vcount += vsplit[i];
}
if (vcount) {
printMultiLines(vsplit, vserial, tempout);
}
int start = 0;
for (i=0; i<tempout.getSize(); i++) {
if (strcmp(tempout[i].getBase(), "") != 0) {
if (start != 0) {
cout << "\t";
}
cout << tempout[i].getBase();
start++;
}
}
if (start) {
cout << '\n';
}
}
//////////////////////////////
//
// printMultiLines -- print separate *v lines.
//
void printMultiLines(Array<int>& vsplit, Array<int>& vserial,
Array<Array<char> >& tempout) {
int i;
int splitpoint = -1;
for (i=0; i<vsplit.getSize(); i++) {
if (vsplit[i]) {
splitpoint = i;
break;
}
}
if (debugQ) {
cout << "!!tempout: ";
for (i=0; i<tempout.getSize(); i++) {
cout << tempout[i].getBase() << " ";
}
cout << endl;
}
if (splitpoint == -1) {
return;
}
int start = 0;
int printv = 0;
for (i=0; i<splitpoint; i++) {
if (strcmp(tempout[i].getBase(), "") != 0) {
if (start) {
cout << "\t";
}
cout << tempout[i].getBase();
start = 1;
if (strcmp(tempout[i].getBase(), "*v") == 0) {
if (printv) {
tempout[i].setSize(1);
tempout[i][0] = '\0';
} else {
tempout[i].setSize(2);
strcpy(tempout[i].getBase(), "*");
printv = 1;
}
} else {
tempout[i].setSize(2);
strcpy(tempout[i].getBase(), "*");
}
}
}
for (i=splitpoint; i<vsplit.getSize(); i++) {
if (strcmp(tempout[i].getBase(), "") != 0) {
if (start) {
cout << "\t";
}
cout << "*";
}
}
if (start) {
cout << "\n";
}
vsplit[splitpoint] = 0;
printMultiLines(vsplit, vserial, tempout);
}
//////////////////////////////
//
// storeToken --
//
void storeToken(Array<Array<char> >& storage, const char* string) {
storage.setSize(storage.getSize()+1);
int index = storage.getSize()-1;
storeToken(storage, index, string);
}
void storeToken(Array<Array<char> >& storage, int index, const char* string) {
storage[index].setSize(strlen(string)+1);
strcpy(storage[index].getBase(), string);
}
//////////////////////////////
//
// isInList -- returns true if first number found in list of numbers.
// returns the matching index plus one.
//
int isInList(int number, Array<int>& listofnum) {
int i;
for (i=0; i<listofnum.getSize(); i++) {
if (listofnum[i] == number) {
return i+1;
}
}
return 0;
}
//////////////////////////////
//
// getTraceData --
//
void getTraceData(Array<int>& startline, Array<Array<int> >& fields,
const char* tracefile, HumdrumFile& infile) {
char buffer[1024] = {0};
PerlRegularExpression pre;
int linenum;
startline.setSize(10000);
startline.setGrowth(10000);
startline.setSize(0);
fields.setSize(10000);
fields.setGrowth(10000);
fields.setSize(0);
ifstream input;
input.open(tracefile);
if (!input.is_open()) {
cerr << "Error: cannot open file for reading: " << tracefile << endl;
exit(1);
}
Array<char> temps;
Array<int> field;
Array<int> subfield;
Array<int> model;
input.getline(buffer, 1024);
while (!input.eof()) {
if (pre.search(buffer, "^\\s*$")) {
continue;
}
if (!pre.search(buffer, "(\\d+)")) {
continue;
}
linenum = strtol(pre.getSubmatch(1), NULL, 10);
linenum--; // adjust so that line 0 is the first line in the file
temps.setSize(strlen(buffer)+1);
strcpy(temps.getBase(), buffer);
pre.sar(temps, "\\d+", "", "");
pre.sar(temps, "[^,\\s\\d\\$\\-].*", ""); // remove any possible comments
pre.sar(temps, "\\s", "", "g");
if (pre.search(temps.getBase(), "^\\s*$")) {
// no field data to process online
continue;
}
startline.append(linenum);
fillFieldData(field, subfield, model, temps.getBase(), infile);
fields.append(field);
input.getline(buffer, 1024);
}
}
//////////////////////////////
//
// extractTrace --
//
void extractTrace(HumdrumFile& infile, const char* tracefile) {
Array<int> startline;
Array<Array<int> > fields;
getTraceData(startline, fields, tracefile, infile);
int i, j;
if (debugQ) {
for (i=0; i<startline.getSize(); i++) {
cout << "!!TRACE " << startline[i]+1 << ":\t";
for (j=0; j<fields[i].getSize(); j++) {
cout << fields[i][j] << " ";
}
cout << "\n";
}
}
if (startline.getSize() == 0) {
for (i=0; i<infile.getNumLines(); i++) {
switch (infile[i].getType()) {
case E_humrec_none:
case E_humrec_empty:
case E_humrec_global_comment:
case E_humrec_bibliography:
cout << infile[i] << '\n';
}
}
return;
}
for (i=0; i<startline[0]; i++) {
switch (infile[i].getType()) {
case E_humrec_none:
case E_humrec_empty:
case E_humrec_global_comment:
case E_humrec_bibliography:
cout << infile[i] << '\n';
}
}
int endline;
for (j=0; j<startline.getSize(); j++) {
if (j == startline.getSize()-1) {
endline = infile.getNumLines()-1;
} else {
endline = startline[j+1]-1;
}
for (i=startline[j]; i<endline; i++) {
switch (infile[i].getType()) {
case E_humrec_none:
case E_humrec_empty:
case E_humrec_global_comment:
case E_humrec_bibliography:
cout << infile[i] << '\n';
default:
printTraceLine(infile, i, fields[j]);
}
}
}
}
//////////////////////////////
//
// printTraceLine --
//
void printTraceLine(HumdrumFile& infile, int line, Array<int>& field) {
int j;
int t;
int start = 0;
int target;
start = 0;
for (t=0; t<field.getSize(); t++) {
target = field[t];
for (j=0; j<infile[line].getFieldCount(); j++) {
if (infile[line].getPrimaryTrack(j) != target) {
continue;
}
if (start != 0) {
cout << '\t';
}
start = 1;
cout << infile[line][j];
}
}
if (start != 0) {
cout << endl;
}
}
/*
//////////////////////////////
//
// extractInterpretation -- extract interpretations which match the
// given list. Not used any more: generalized to allow for
// other interpretation matching other than exclusive interpretations.
//
void extractInterpretations(HumdrumFile& infile, const char* interps) {
int i;
int j;
int column = 0;
PerlRegularExpression pre;
Array<char> buffer;
buffer.setSize(1024);
buffer.setSize(1);
strcpy(buffer.getBase(), "");
for (i=0; i<infile.getNumLines(); i++) {
if (debugQ) {
cout << "!!Processing line " << i+1 << ": " << infile[i] << endl;
}
switch (infile[i].getType()) {
case E_humrec_none:
case E_humrec_empty:
case E_humrec_global_comment:
case E_humrec_bibliography:
cout << infile[i] << '\n';
break;
case E_humrec_data_comment:
case E_humrec_data_kern_measure:
case E_humrec_interpretation:
case E_humrec_data:
column = 0;
for (j=0; j<infile[i].getFieldCount(); j++) {
buffer.setSize(strlen(infile[i].getExInterp(j))+1);
strcpy(buffer.getBase(), infile[i].getExInterp(j));
buffer.setSize(buffer.getSize()+strlen("\\b"));
strcat(buffer.getBase(), "\\b"); // word boundary marker
pre.sar(buffer, "\\*", "\\\\*", "g");
if (pre.search(interps, buffer.getBase()) == 0) {
// if (strstr(interps, infile[i].getExInterp(j)) == NULL) {
continue;
}
if (column != 0) {
cout << '\t';
}
column++;
cout << infile[i][j];
}
if (column != 0) {
cout << endl;
}
break;
default:
cout << "!!Line is UNKNOWN:" << infile[i] << endl;
break;
}
}
}
*/
//////////////////////////////
//
// checkOptions -- validate and process command-line options.
//
void checkOptions(Options& opts, int argc, char* argv[]) {
opts.define("P|F|S|x|exclude=s:", "Remove listed spines from output");
opts.define("i=s:", "Exclusive interpretation list to extract from input");
opts.define("I=s:", "Exclusive interpretation exclusion list");
opts.define("f|p|s|field|path|spine=s:",
"for extraction of particular spines");
opts.define("C|count=b", "print a count of the number of spines in file");
opts.define("c|cointerp=s:**kern", "Exclusive interpretation for cospines");
opts.define("g|grep=s:", "Extract spines which match a given regex.");
opts.define("r|reverse=b", "reverse order of spines by **kern group");
opts.define("R=s:**kern", "reverse order of spine by exinterp group");
opts.define("t|trace=s:", "use a trace file to extract data");
opts.define("e|expand=b", "expand spines with subspines");
opts.define("E|expand-interp=s:", "expand subspines limited to exinterp");
opts.define("m|model|method=s:d", "method for extracting secondary spines");
opts.define("M|cospine-model=s:d", "method for extracting cospines");
opts.define("Y|no-editoral-rests=b",
"do not display yy marks on interpreted rests");
opts.define("debug=b", "print debugging information");
opts.define("author=b"); // author of program
opts.define("version=b"); // compilation info
opts.define("example=b"); // example usages
opts.define("h|help=b"); // short description
opts.process(argc, argv);
// handle basic options:
if (opts.getBoolean("author")) {
cout << "Written by Craig Stuart Sapp, "
<< "craig@ccrma.stanford.edu, Feb 2008" << endl;
exit(0);
} else if (opts.getBoolean("version")) {
cout << argv[0] << ", version: Feb 2008" << endl;
cout << "compiled: " << __DATE__ << endl;
cout << MUSEINFO_VERSION << endl;
exit(0);
} else if (opts.getBoolean("help")) {
usage(opts.getCommand());
exit(0);
} else if (opts.getBoolean("example")) {
example();
exit(0);
}
excludeQ = opts.getBoolean("x");
interpQ = opts.getBoolean("i");
interps = opts.getString("i");
interpstate = 1;
if (!interpQ) {
interpQ = opts.getBoolean("I");
interpstate = 0;
interps = opts.getString("I");
}
fieldQ = opts.getBoolean("f");
debugQ = opts.getBoolean("debug");
countQ = opts.getBoolean("count");
traceQ = opts.getBoolean("trace");
tracefile = opts.getString("trace");
reverseQ = opts.getBoolean("reverse");
expandQ = opts.getBoolean("expand") || opts.getBoolean("E");
submodel = opts.getString("model")[0];
cointerp = opts.getString("cointerp");
comodel = opts.getString("cospine-model")[0];
if (opts.getBoolean("no-editoral-rests")) {
editorialInterpretation = "";
}
if (interpQ) {
fieldQ = 1;
}
if (expandQ) {
fieldQ = 1;
expandInterp = opts.getString("expand-interp");
}
if (!reverseQ) {
reverseQ = opts.getBoolean("R");
if (reverseQ) {
reverseInterp = opts.getString("R");
}
}
if (reverseQ) {
fieldQ = 1;
}
if (excludeQ) {
fieldstring = opts.getString("x");
} else if (fieldQ) {
fieldstring = opts.getString("f");
}
grepQ = opts.getBoolean("grep");
grepString = opts.getString("grep");
}
//////////////////////////////
//
// example -- example usage of the sonority program
//
void example(void) {
cout <<
" \n"
<< endl;
}
//////////////////////////////
//
// usage -- gives the usage statement for the sonority program
//
void usage(const char* command) {
cout <<
" \n"
<< endl;
}
// md5sum: 6f70bbbab298b6a2f516314973790a1a extractx.cpp [20130420]