/**************************************************************************** PROJECT: MusixTeX PreProcessor FILE : mpp.cc AUTHOR : J. C. Nieuwenhuizen copyright (c) FlowerSoft 1995 --*/ #include #include #include "score.h" #include "ifeature.h" #include "imacro.h" #include "inote.h" #include "init.h" #include "mpp.h" #include "version.h" static void extention( String& path, const char* extention ) { int p = path.lastPos( '.' ); if ( ( ( p < 2 ) || ( path.len() - p > 3 ) ) || ( ( p == 2 ) && ( path[ 0 ] == '.' ) ) ) { if ( extention ) path += extention; } else if ( !extention || !*extention ) path = (const char*)path.left( p - 1 ); } const char* const USAGE_STRING = "Usage: mpp [options] instrument1 [, staff2] [instrument2 [, ...] ...]"; const char* const OPTION_STRING = "Options:\n" #if 0 " - read from standard input -e extract mode \n" " -h print this message -oxxx output file; -o- standard output\n" " -s silent mode -v verbose mode \n"; #else " - read from standard input\n" " -e, --extract extract mode; \"\\startextract\" iso \"\\startpiece\"\n" " -h, --help print this message\n" " -o FILE, --outfile=FILE write output to FILE; stdout: FILE == \"-\"\n" " -s, --silent silent mode; don't echo to stdout\n" " -v, --verbose verbose mode\n" " --version print version number and exit"; #endif void displayVersion() { cout = _cout; // make sure cout == stdout cout << "mpp " << VERSION_STRING << endl; } void displayHelp() { displayVersion(); cout << USAGE_STRING << endl; cout << endl; cout << OPTION_STRING; #ifndef __MSDOS__ cout << endl; #endif error( 0, 0, 0 ); } void displayUsage() { // error( USAGE_STRING, 0, 0 ); cerr << USAGE_STRING; #ifndef __MSDOS__ cerr << endl; #endif error( 0, 0, 0 ); } void identify() { cout << "This is mpp " << VERSION_STRING << endl; } Mode mode = NORMAL; #if 0 #include "getoptin.h" #include "strlist.h" void parseCommandLine( int argc, char* argv[], StringList& fileList ) { opterr = 0; // do not print error message int c; #define LONG_OPTIONS #ifdef LONG_OPTIONS int option_index = 0; static struct option long_options[] = { { "extract", 0, 0, 0 }, { "help", 0, 0, 0 }, // { "output", 0, 0, 0 }, { "silent", 0, 0, 0 }, { "verbose", 0, 0, 0 }, { "version", 0, 0, 0 }, { 0, 0, 0, 0 } }; while ( ( c = gnuGetoptLong ( argc, argv, "ehsvo:", long_options, &option_index ) ) != EOF ) { if ( !c ) // long option?? { if ( String( long_options[ option_index ].name ) == "version" ) { displayVersion(); error( 0, 0, 0 ); } c = long_options[ option_index ].name[ 0 ]; } #else // not LONG_OPTIONS while ( ( c = gnuGetopt( argc, argv, "ehsvo:" ) ) != EOF ) { #endif // not LONG_OPTIONS // cerr << "option: " << quoteChar( "c: ", (char)c ) << endl; switch ( c ) { case 'e' : mode = Mode( mode | EXTRACT ); break; case 's' : cout = cnull; if ( mode & VERBOSE ) warning( "silent mode ignored", __FILE__, __LINE__ ); else mode = Mode( mode | SILENT ); break; case 'v' : warning( "verbose mode not implemented", __FILE__, __LINE__ ); if ( mode & SILENT ) warning( "verbose mode ignored", __FILE__, __LINE__ ); else mode = Mode( mode | VERBOSE ); break; case 'o' : if ( !fileList.empty() ) error( "too many output files specified", __FILE__, __LINE__ ); fileList.put( *new String( optarg ) ); break; case 'h' : displayHelp(); break; case '?' : case ':' : // no argument specified with -o // assume standard output // cerr << quoteChar( "c: ", (char)c ) << endl; // cerr << quoteChar( "optopt: ", (char)optopt ) << endl; if ( optopt == 'o' ) { if ( !fileList.empty() ) error( "too many output files specified", __FILE__, __LINE__ ); fileList.put( *new String( '-' ) ); break; } // error( 0, 0, 0 ); error( quoteString( "invalid option", argv[ optind - 1 ] ), __FILE__, __LINE__ ); break; default: error( quoteChar( "invalid option", c ), __FILE__, __LINE__ ); break; } } if ( optind < argc ) { // no output file specified; assume // base output file == base first input file if ( fileList.empty() ) fileList.put( *new String( argv[ optind ] ) ); while ( optind < argc ) { // cerr << quoteString( "argument: ", argv[ optind ] ) << endl; // every option "-x" is scanned by getopt // however, "--" forces `end of options' // therefore, command lines like // mpp (..) -- (..) -x (..) // are invalid if ( ( argv[ optind ][ 0 ] == '-' ) && argv[ optind ][ 1 ] ) error( quoteString( "invalid musicfile name", argv[ optind ] ), __FILE__, __LINE__ ); fileList.put( *new String( argv[ optind++ ] ) ); } } } int main( int argc, char* argv[] ) { StringList musicFiles; parseCommandLine( argc, argv, musicFiles ); if ( musicFiles.empty() ) displayHelp(); String& s = musicFiles.top(); if ( !s.len() || ( s[ 0 ] == '-' ) || isspace( s[ 0 ] ) ) s = "-"; // no input file specified; assume // base input file == base output file if ( musicFiles.count() == 1 ) musicFiles.put( *new String( musicFiles.top() ) ); String& outName = musicFiles.get(); if ( outName != "-" ) { extention( outName, "" ); extention( outName, ".tex" ); } Score score( outName ); delete &outName; identify(); initNoteNames(); // must be done first initFeatureList(); initMacroList(); cout << endl; int staffCount = 0; while ( !musicFiles.empty() ) { String& musicFile = musicFiles.get(); if ( musicFile == "," ) { staffCount++; if ( musicFiles.empty() ) error( "second staff expected", __FILE__, __LINE__ ); delete &musicFile; continue; } if ( musicFile.len() && ( musicFile[ 0 ] != '-' ) ) extention( musicFile, ".mpp" ); Staff& staff = *new Staff( musicFile, staffCount ); delete &musicFile; // reverse order score.insert( staff ); staffCount = 0; } if ( score.empty() ) error( "no input file specified", __FILE__, __LINE__ ); score.process(); return 0; } #else #include "loptions.h" #ifdef __unix__ const char pathSeparator = '/'; #else const char pathSeparator = '\\'; #endif char* execPrefix; int main( const int argc, char* const argv[] ) { execPrefix = argv[ 0 ]; String exec_prefix = execPrefix; execPrefix[ exec_prefix.lastPos( pathSeparator ) ] = 0; Long_option_list optionList; optionList.put( *new Long_switch_option( "help", 'h' ) ); optionList.put( *new Long_switch_option( "extract", 'e' ) ); optionList.put( *new Long_string_option( "outfile", 'o' ) ); optionList.put( *new Long_switch_option( "silent", 's' ) ); optionList.put( *new Long_switch_option( "verbose", 'v' ) ); optionList.put( *new Long_switch_option( "version" ) ); optionList.parse( argc, argv ); if ( optionList.get( "help" ) ) displayHelp(); if ( optionList.get( "version" ) ) { displayVersion(); error( 0, 0, 0 ); } String outName; if ( optionList.get( "outfile" ) ) outName = optionList.get( "outfile" ).argument(); if ( optionList.get( "extract" ) ) mode = Mode( mode | EXTRACT ); if ( optionList.get( "silent" ) ) { cout = cnull; mode = Mode( mode | SILENT ); } else if ( optionList.get( "verbose" ) ) { warning( "verbose mode not implemented", __FILE__, __LINE__ ); mode = Mode( mode | VERBOSE ); } String inName; if ( optionList ) { inName = optionList++; if ( !outName.len() ) outName = inName; } else if ( !inName.len() ) inName = outName; if ( !outName.len() ) displayUsage(); if ( !optionList && !inName.len() ) displayUsage(); if ( outName != "-" ) { extention( outName, "" ); extention( outName, ".tex" ); } Score score( outName ); identify(); // now that everything seems ok // init lists first; Staff uses lists initNoteNames(); // init noteNames first; Macros use noteNames initFeatureList(); initMacroList(); cout << endl; int staffCount = 0; if ( inName.len() ) { if( inName[ 0 ] != '-' ) extention( inName, ".mpp" ); score.insert( *new Staff( inName, 0 ) ); } while ( optionList ) { String musicFile = optionList++; if ( musicFile == "," ) { staffCount++; if ( !optionList ) error( "second staff expected", __FILE__, __LINE__ ); musicFile = optionList++; } if ( musicFile.len() && ( musicFile[ 0 ] != '-' ) ) extention( musicFile, ".mpp" ); Staff& staff = *new Staff( musicFile, staffCount ); // reverse order score.insert( staff ); staffCount = 0; } if ( score.empty() ) error( "no input file specified", __FILE__, __LINE__ ); score.process(); return 0; } #endif