//
// Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu>
// Creation Date: Sat Sep 17 23:28:09 PDT 2011
// Last Modified: Sat Sep 17 23:28:15 PDT 2011
// Filename: ...sig/examples/all/pullout.cpp
// Web Address: http://sig.sapp.org/examples/museinfo/humdrum/pullout.cpp
// Syntax: C++; museinfo
//
// Description: Extract movements from a multi-movement Humdrum file.
//
#include "humdrum.h"
#include <string.h>
#include <ctype.h>
#ifndef OLDCPP
#include <iostream>
#include <fstream>
using namespace std;
#else
#include <iostream.h>
#include <fstream.h>
#endif
// function declarations
void checkOptions(Options& opts, int argc, char* argv[]);
void example(void);
void usage(const char* command);
int countSegments(istream& stream, int precount = 0, int nth = 0);
// global variables
Options options; // database for command-line arguments
int countQ = 0; // used with -c option
int nth = 0; // used with -n option
int rangeQ = 0; // used with -r option
///////////////////////////////////////////////////////////////////////////
int main(int argc, char* argv[]) {
// process the command-line options
checkOptions(options, argc, argv);
// figure out the number of input files to process
int numinputs = options.getArgCount();
ifstream input;
istream* stream;
int count = 0;
int ncount = 0;
int i;
for (i=0; i<numinputs || i==0; i++) {
// if no command-line arguments read data file from standard input
if (numinputs < 1) {
stream = &cin;
} else {
input.open(options.getArgument(i+1));
stream = &input;
}
if (countQ || rangeQ) {
count += countSegments(*stream);
} else if (nth) {
ncount += countSegments(*stream, ncount, nth);
if (ncount >= nth) {
break;
}
}
}
if (countQ) {
cout << count << endl;
} else if (rangeQ) {
if (count >= 1) {
for (i=1; i<=count; i++) {
cout << i;
if (i < count) {
cout << ' ';
}
}
cout << "\n";
}
}
return 0;
}
///////////////////////////////////////////////////////////////////////////
//////////////////////////////
//
// countSegments --
//
int countSegments(istream& stream, int precount, int nth) {
char ch;
int output = 0;
char lastlast = 0;
char last = 0;
int charcount = 0;
int printQ = 0;
int state = 0; // 0 = out of data, 1 = in data
while (!stream.eof()) {
if (state == 0) {
// out of data, waiting for an exclusive interpretation
if (((lastlast == 0x0a) || (charcount < 3)) && (last == '*')
&& (ch == '*')) {
state = 1;
if ((nth > 0) && (precount+output == nth-1)) {
cout << "**";
printQ =1;
}
}
} else {
if ((lastlast == 0x0a) && (last == '*') && (ch == '-')) {
// should also check that the next character
// is either a newline, a tab or an end of file.
output++;
state = 0;
if (printQ) {
// while not end of line or file, print characters
// then print an end of line.
stream.get(ch);
while ((!stream.eof()) && (ch != 0x0a) && (ch != 0x0d)) {
cout << ch;
stream.get(ch);
}
cout << endl;
printQ = 0;
// force a break in the main loop:
return 999999999;
}
}
}
lastlast = last;
last = ch;
stream.get(ch);
if (printQ) {
cout << ch;
}
if (ch == 0x0d) {
ch = 0x0a;
}
}
return output;
}
//////////////////////////////
//
// checkOptions -- validate and process command-line options.
//
void checkOptions(Options& opts, int argc, char* argv[]) {
opts.define("c|count=b", "count number of segments");
opts.define("r|range=b", "print a range for the count");
opts.define("n|nth=i:0", "print a particular segment");
opts.define("debug=b"); // determine bad input line num
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, Sept 2011" << endl;
exit(0);
} else if (opts.getBoolean("version")) {
cout << argv[0] << ", version: 18 Sept 2011" << 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);
}
countQ = opts.getBoolean("count");
rangeQ = opts.getBoolean("range");
nth = opts.getInteger("nth");
}
//////////////////////////////
//
// example -- example usage of the quality program
//
void example(void) {
cout <<
" \n"
<< endl;
}
//////////////////////////////
//
// usage -- gives the usage statement for the meter program
//
void usage(const char* command) {
cout <<
" \n"
<< endl;
}
// md5sum: 2e1571a60880800f2828e78de4b3df8f pullout.cpp [20111004]