//
// Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu>
// Creation Date: Thu Dec 13 14:58:53 PST 2012
// Last Modified: Thu Dec 13 22:56:07 PST 2012
// Filename: ...sig/examples/all/humsplit.cpp
// Web Address: http://sig.sapp.org/examples/museinfo/humdrum/humsplit.cpp
// Syntax: C++; museinfo
//
// Description: Splits multiple-segment Humdrum streams into separate files.
//
#include "humdrum.h"
#include "PerlRegularExpression.h"
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h> /* for stat function in fileExists */
#ifndef OLDCPP
#include <iostream>
using namespace std;
#else
#include <iostream.h>
#endif
// function declarations
void checkOptions(Options& opts, int argc, char* argv[]);
void example(void);
void usage(const char* command);
int getHumdrumSegmentCount(HumdrumStream& streamer);
void extractSegment(HumdrumFile& infile, HumdrumStream& streamer,
int extractNum);
void saveToDisk(HumdrumFile& infile, int count);
int fileExists(Array<char>& filename);
// global variables
Options options; // database for command-line arguments
int countQ = 0; // used with -c option
int extractQ = 0; // used with -x option
int extractNum = 0; // used with -x option
int segmentLabelQ = 0; // used with -s option
int overwriteQ = 0; // used with -O option (capital O)
int directoryQ = 0; // used with -d option
Array<char> Directory; // used with -d option
int extensionQ = 0; // used with -e option
Array<char> Extension; // used with -e option
int prefixQ = 0; // used with -p option
Array<char> Prefix; // used with -p option
int Width = 5; // used with -w option
int Start = 1; // used with -n option
///////////////////////////////////////////////////////////////////////////
int main(int argc, char* argv[]) {
checkOptions(options, argc, argv);
HumdrumStream streamer(options.getArgList());
HumdrumFile infile;
if (countQ) {
int count = getHumdrumSegmentCount(streamer);
cout << count << endl;
exit(0);
}
if (extractQ) {
extractSegment(infile, streamer, extractNum);
if (segmentLabelQ) {
infile.printSegmentLabel(cout);
}
cout << infile;
exit(0);
}
int filecounter = Start;
while (streamer.read(infile)) {
saveToDisk(infile, filecounter++);
}
return 0;
}
///////////////////////////////////////////////////////////////////////////
//////////////////////////////
//
// saveToDisk --
//
void saveToDisk(HumdrumFile& infile, int count) {
Array<char> writename;
writename = infile.getFilename();
PerlRegularExpression pre;
pre.sar(writename, ".*/", ""); // remove old directory path (or URI)
if (strlen(writename.getBase()) == 0) {
// There is no file, so create a synthetic one: count.humsplit
char filename[1024] = {0};
char format[32] = {0};
sprintf(format, "%s0%d.humsplit", "%", Width);
sprintf(filename, format, count);
writename = filename;
}
if (extensionQ) {
// remove old filename extension and replace with new one
pre.sar(writename, "\\.[^.]*$", "");
pre.sar(writename, "$", Extension.getBase());
}
if (prefixQ) {
// prefix to give to filename (useful for auto-naming).
pre.sar(writename, "^", Prefix.getBase());
}
if (directoryQ) {
// place in new directory if requested
pre.sar(Directory, "/*$", "/"); pre.sar(writename, "^", Directory.getBase());
}
if (!overwriteQ && fileExists(writename)) {
// print warning if trying to overwrite an existing file
cerr << "Warning: " << writename
<< " already exists. Skipping..." << endl;
return;
}
ofstream output;
output.open(writename.getBase());
if (!output.is_open()) {
cerr << "Warning: " << writename
<< " could not be written. Skipping..." << endl;
}
if (segmentLabelQ) {
// preserve segment label
infile.printSegmentLabel(output);
}
int i;
int start = 0;
if (strncmp(infile[0][0], "!!!!SEGMENT", strlen("!!!!SEGMENT")) == 0) {
start = 1;
}
for (i=start; i<infile.getNumLines(); i++) {
output << infile[i] << '\n';
}
output.close();
}
//////////////////////////////
//
// fileExists -- see if the file exists.
//
int fileExists(Array& filename) {
struct stat buf;
return stat(filename.getBase(), &buf) == -1 ? 0 : 1;
}
//////////////////////////////
//
// extractSegment --
//
void extractSegment(HumdrumFile& infile, HumdrumStream& streamer,
int extractNum) {
int count = 0;
while (streamer.read(infile)) {
count++;
if (count == extractNum) {
return;
}
}
infile.clear();
}
//////////////////////////////
//
// getHumdrumSegmentCount --
//
int getHumdrumSegmentCount(HumdrumStream& streamer) {
int count = 0;
HumdrumFile infile;
while (streamer.read(infile)) {
count++;
}
return count;
}
//////////////////////////////
//
// checkOptions -- validate and process command-line options.
//
void checkOptions(Options& opts, int argc, char* argv[]) {
opts.define("c|count=b:", "Count number of segments in input stream");
opts.define("x|extract=i:1", "Extract the nth stream");
opts.define("s|segment=b", "Display segment line in output (with -x)");
opts.define("O|overwrite=b", "Overwrite any existing files");
opts.define("d|directory=s:.", "Directory to save files to");
opts.define("e|extension=s:.krn","File extension replacement");
opts.define("p|prefix=s:", "Filename prefix");
opts.define("w|width=i:5", "Number width for automatic names");
opts.define("n|number=i:1", "Starting number for automatic names");
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, 13 Dec 2012" << endl;
exit(0);
} else if (opts.getBoolean("version")) {
cout << argv[0] << ", version: Dec 2012" << 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");
extractQ = opts.getBoolean("extract");
extractNum = opts.getInteger("extract");
segmentLabelQ = opts.getBoolean("segment");
directoryQ = opts.getBoolean("directory");
Directory = opts.getString("directory");
overwriteQ = opts.getBoolean("overwrite");
extensionQ = opts.getBoolean("extension");
Extension = opts.getString("extension");
prefixQ = opts.getBoolean("prefix");
Prefix = opts.getString("prefix");
Width = opts.getInteger("width");
Start = opts.getInteger("number");
}
//////////////////////////////
//
// 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: 62d15a7377274b6a8746c9e466ebb575 humsplit.cpp [20130206]