cog/Frameworks/libsidplay/sidplay-residfp-code/.svn/pristine/71/71c86211eb323e868117d64afd9...

714 lines
21 KiB
Plaintext

/*
* This file is part of sidplayfp, a console SID player.
*
* Copyright 2012 Leandro Nini
* Copyright 1998, 2002 LaLa <LaLa@C64.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//
// STILView - command line version
//
#include <fstream>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stilview/stil.h>
STIL myStil;
char *hvscLoc = NULL;
char *entryStr = NULL;
int tuneNo = 0;
STIL::STILField field = STIL::all;
bool showBug = true;
bool showEntry = true;
bool showSection = true;
bool showVersion = false;
bool interactive = false;
bool demo = false;
char STIL_DEMO_ENTRY[]="/Galway_Martin/Green_Beret.sid";
// This is used for testing setBaseDir() when switching between different
// HVSC base directories. Ideally, it should point to a valid HVSC dir.
char OTHER_HVSC_BASE_DIR[]="E:\\MUSIC\\SID\\C64music\\";
#define STIL_MAX_PATH_SIZE 1024
using namespace std;
char toLowerAscii(char c)
{
return (c < 'A' || c > 'Z') ? c : c + ('a' - 'A');
}
bool strEquals(const char* s1, const char* s2)
{
while (*s1 && *s2)
{
if (toLowerAscii(*s1) != toLowerAscii(*s2))
return false;
s1++;
s2++;
}
return !(*s1 || *s2);
}
void printUsageStr(void)
{
cout << endl;
cout << myStil.getVersion();
cout << "USAGE: STILView [-e=<entry>] [-l=<HVSC loc>] [-t=<tuneNo>] [-f=<field>]" << endl;
cout << " [-d] [-i] [-s] [-b] [-o] [-v] [-h] [-m]" << endl;
}
void printUsage(void)
{
printUsageStr();
exit(1);
}
void printHelp(void)
{
printUsageStr();
cout << "Arguments can be specified in any order." << endl;
cout << endl;
cout << "-e=<entry> - Specifies the desired STIL entry with an HVSC-relative path." << endl;
cout << "-l=<HVSC loc> - Specifies the location of the HVSC base directory. If not" << endl;
cout << " specified, the value of the HVSC_BASE env. variable will be" << endl;
cout << " used. Specifying this option will override HVSC_BASE." << endl;
cout << "-t=<tuneNo> - If specified, only the STIL entry for the given tune number is" << endl;
cout << " printed. (Default: 0)" << endl;
cout << "-f=<field> - If specified, only the STIL entry for the given field is" << endl;
cout << " printed. (Default: all)" << endl;
cout << " Valid values for <field> are:" << endl;
cout << " all, name, author, title, artist, comment" << endl;
cout << "-d - Turns on debug mode for STILView." << endl;
cout << "-i - Enter interactive mode." << endl;
cout << "-m - Demo mode (tests STILView and shows its capabilities)." << endl;
cout << "-s - If specified, section-global (per dir/per composer) comments" << endl;
cout << " will NOT be printed." << endl;
cout << "-b - If specified, BUG entries will NOT be printed." << endl;
cout << "-o - If specified, STIL entries will NOT be printed." << endl;
cout << "-v - Print STILView's and STIL's version number." << endl;
cout << "-h - Print this help screen (all other options are ignored)." << endl;
cout << endl;
cout << "See user manual for further details and for examples." << endl;
cout << endl;
exit(0);
}
char *getArgValue(char *argStr)
{
char *temp = (char *)strchr(argStr, '=');
if (temp == NULL)
{
return NULL;
}
if (*(temp+1) == '\0')
{
return NULL;
}
return (temp+1);
}
void processArguments(int argc, char **argv)
{
for (int i=1; i<argc; i++)
{
if (argv[i][0] == '-')
{
switch (argv[i][1])
{
case 'd':
case 'D':
myStil.STIL_DEBUG = true;
break;
case 'e':
case 'E':
entryStr = getArgValue(argv[i]);
if (entryStr == NULL) {
cerr << "ERROR: STIL entry was not specified correctly!" << endl;
printUsage();
}
break;
case 'i':
case 'I':
interactive = true;
break;
case 'm':
case 'M':
demo = true;
break;
case 'l':
case 'L':
{
char *tempLoc = getArgValue(argv[i]);
if (tempLoc != NULL) {
hvscLoc = tempLoc;
}
}
break;
case 't':
case 'T':
{
char *tuneStr = getArgValue(argv[i]);
if (tuneStr == NULL) {
cerr << "ERROR: tune number was not specified correctly!" << endl;
printUsage();
}
sscanf(tuneStr, "%d", &tuneNo);
}
break;
case 's':
case 'S':
showSection = false;
break;
case 'b':
case 'B':
showBug = false;
break;
case 'o':
case 'O':
showEntry = false;
break;
case 'v':
case 'V':
showVersion = true;
break;
case 'f':
case 'F':
{
char *fieldStr = getArgValue(argv[i]);
if (fieldStr == NULL) {
cerr << "ERROR: field was not specified correctly!" << endl;
printUsage();
}
if (strEquals(fieldStr, "all")) {
field = STIL::all;
}
else if (strEquals(fieldStr, "name")) {
field = STIL::name;
}
else if (strEquals(fieldStr, "author")) {
field = STIL::author;
}
else if (strEquals(fieldStr, "title")) {
field = STIL::title;
}
else if (strEquals(fieldStr, "artist")) {
field = STIL::artist;
}
else if (strEquals(fieldStr, "comment")) {
field = STIL::comment;
}
else {
cerr << "ERROR: Unknown STIL field specified: '" << fieldStr << "' !" << endl;
cerr << "Valid values for <field> are:" << endl;
cerr << "all, name, author, title, artist, comment." << endl;
printUsage();
}
}
break;
case 'h':
case 'H':
printHelp();
break;
default:
cerr << "ERROR: Unknown argument: '" << argv[i] << "' !" << endl;
printUsage();
break;
}
}
else
{
cerr << "ERROR: Unknown argument: '" << argv[i] << "' !" << endl;
printUsage();
}
}
}
void checkArguments(void)
{
if (hvscLoc == NULL)
{
if (interactive || demo)
{
hvscLoc = new char[STIL_MAX_PATH_SIZE];
cout << "Enter HVSC base directory: ";
cin >> hvscLoc;
}
else
{
if (showVersion)
{
showBug = false;
showEntry = false;
showSection = false;
}
else
{
cerr << "ERROR: HVSC base dir was not specified and HVSC_BASE is not set, either!" << endl;
printUsage();
}
}
}
if (entryStr == NULL)
{
if ((!interactive) && (!demo))
{
if (showVersion) {
showBug = false;
showEntry = false;
showSection = false;
}
else
{
cerr << "ERROR: STIL entry was not specified!" << endl;
printUsage();
}
}
else
{
entryStr = STIL_DEMO_ENTRY;
}
}
}
int main(int argc, char **argv)
{
char temp[STIL_MAX_PATH_SIZE];
const char *tmpptr, *sectionPtr, *entryPtr, *bugPtr;
const char *versionPtr;
float tempval;
if (argc < 2)
{
printHelp();
}
hvscLoc = getenv("HVSC_BASE");
processArguments(argc, argv);
checkArguments();
if (interactive || demo) {
cout << "Reading STIL..." << endl;
}
else
{
if (showVersion && (hvscLoc == NULL))
{
versionPtr = myStil.getVersion();
if (versionPtr == NULL)
{
cerr << "ERROR: No STIL version string was found!" << endl;
}
else
{
cout << versionPtr;
}
exit(0);
}
}
if (myStil.setBaseDir(hvscLoc) != true)
{
cerr << "STIL error #" << myStil.getError() << ": " << myStil.getErrorStr() << endl;
exit(1);
}
if ((!interactive) && (!demo))
{
// Pure command-line version.
if (showVersion)
{
versionPtr = myStil.getVersion();
}
else
{
versionPtr = NULL;
}
if (showSection) {
sectionPtr = myStil.getGlobalComment(entryStr);
}
else
{
sectionPtr = NULL;
}
if (showEntry)
{
entryPtr = myStil.getEntry(entryStr, tuneNo, field);
}
else {
entryPtr = NULL;
}
if (showBug)
{
bugPtr = myStil.getBug(entryStr, tuneNo);
}
else {
bugPtr = NULL;
}
if (versionPtr != NULL)
{
if ((sectionPtr != NULL) || (entryPtr != NULL) || (bugPtr != NULL))
{
cout << "--- STILView VERSION ---" << endl;
}
cout << versionPtr;
}
if (sectionPtr != NULL)
{
if ((versionPtr != NULL) || (entryPtr != NULL) || (bugPtr != NULL))
{
cout << "---- GLOBAL COMMENT ----" << endl;
}
cout << sectionPtr;
}
if (entryPtr != NULL)
{
if ((versionPtr != NULL) || (sectionPtr != NULL) || (bugPtr != NULL))
{
cout << "------ STIL ENTRY ------" << endl;
}
cout << entryPtr;
}
if (bugPtr != NULL) {
if ((versionPtr != NULL) || (sectionPtr != NULL) || (entryPtr != NULL))
{
cout << "---------- BUG ----------" << endl;
}
cout << bugPtr;
}
}
else {
// We are either in interactive or demo mode here.
if (demo)
{
cout << "==== STILVIEW DEMO MODE ====" << endl;
cout << endl << "---- STIL VERSION ----" << endl;
cout << "---- ONE STRING ----" << endl;
}
// This gets printed regardless.
versionPtr = myStil.getVersion();
if (versionPtr == NULL)
{
cerr << "ERROR: No STIL version string was found!" << endl;
}
else
{
cout << versionPtr;
}
if (demo)
{
// Demo mode.
cout << "---- STIL CLASS VERSION # ----" << endl;
tempval = myStil.getVersionNo();
if (tempval == 0)
{
cerr << "ERROR: STILView version number was not found!" << endl;
}
else
{
cout << "STILView v" << tempval << endl;
}
cout << "---- STIL.txt VERSION # ----" << endl;
tempval = myStil.getSTILVersionNo();
if (tempval == 0)
{
cerr << "ERROR: STIL version number was not found!" << endl;
}
else
{
cout << "STIL v" << tempval << endl;
}
// For testing setBaseDir().
if (myStil.STIL_DEBUG == true)
{
if (myStil.setBaseDir(OTHER_HVSC_BASE_DIR) != true)
{
cerr << "STIL error #" << myStil.getError() << ": " << myStil.getErrorStr() << endl;
cerr << "Couldn't switch to new dir: '" << OTHER_HVSC_BASE_DIR << "'" << endl;
cerr << "Reverting back to '" << hvscLoc << "'" << endl;
}
else
{
hvscLoc = OTHER_HVSC_BASE_DIR;
cout << "Switch to new dir '" << hvscLoc << "' was successful!" << endl;
cout << "---- ONE STRING ----" << endl;
versionPtr = myStil.getVersion();
if (versionPtr == NULL)
{
cerr << "ERROR: No STIL version string was found!" << endl;
}
else
{
cout << versionPtr;
}
cout << "---- STIL CLASS VERSION # ----" << endl;
tempval = myStil.getVersionNo();
if (tempval == 0)
{
cerr << "ERROR: STILView version number was not found!" << endl;
}
else
{
cout << "STILView v" << tempval << endl;
}
cout << "---- STIL.txt VERSION # ----" << endl;
tempval = myStil.getSTILVersionNo();
if (tempval == 0)
{
cerr << "ERROR: STIL version number was not found!" << endl;
}
else
{
cout << "STIL v" << tempval << endl;
}
}
}
cout << endl << "==== STIL ABSOLUTE PATH TO " << entryStr << ", Tune #" << tuneNo << " ====" << endl << endl;
strcpy(temp, hvscLoc);
// Chop the trailing slash
char *tmp = temp+strlen(temp)-1;
if (*tmp == SLASH)
{
*tmp = '\0';
}
strcat(temp, entryStr);
cout << "---- GLOBAL COMMENT ----" << endl;
tmpptr = myStil.getAbsGlobalComment(temp);
if (tmpptr == NULL)
{
cerr << "STIL error #" << myStil.getError() << ": " << myStil.getErrorStr() << endl;
}
else
{
cout << tmpptr;
}
cout << "-- TUNE GLOBAL COMMENT --" << endl;
tmpptr = myStil.getAbsEntry(temp, 0, STIL::comment);
if (tmpptr == NULL)
{
cerr << "STIL error #" << myStil.getError() << ": " << myStil.getErrorStr() << endl;
}
else
{
cout << tmpptr;
}
cout << "------ STIL ENTRY ------" << endl;
cout << "(For tune #1)" << endl;
tmpptr = myStil.getAbsEntry(temp, 1, STIL::all);
if (tmpptr == NULL)
{
cerr << "STIL error #" << myStil.getError() << ": " << myStil.getErrorStr() << endl;
}
else
{
cout << tmpptr;
}
cout << "---------- BUG ----------" << endl;
tmpptr = myStil.getAbsBug(temp, tuneNo);
if (tmpptr == NULL)
{
cerr << "STIL error #" << myStil.getError() << ": " << myStil.getErrorStr() << endl;
}
else
{
cout << tmpptr;
}
cout << "==== END OF ENTRY ====" << endl;
cout << endl << "Trying to do setBaseDir() to wrong location..." << endl;
if (myStil.setBaseDir("This_should_not_work") != true)
{
cout << "setBaseDir() failed!" << endl;
cout << "But it should't have an impact on private data!" << endl;
cout << "You should see the same entry below:" << endl;
cout << endl << "------ STIL ENTRY ------" << endl;
tmpptr = myStil.getAbsEntry(temp, tuneNo, STIL::all);
if (tmpptr == NULL)
{
cerr << "STIL error #" << myStil.getError() << ": " << myStil.getErrorStr() << endl;
}
else
{
cout << tmpptr;
}
}
else
{
cout << "Oops, it should've failed!" << endl;
}
}
if (interactive)
{
// Interactive mode.
cout << endl << "==== ENTERING INTERACTIVE MODE ====" << endl << endl;
do
{
cout << "Enter desired entry (relative path) or 'q' to exit." << endl;
cout << "Entry: ";
cin >> temp;
if (*temp == '/')
{
cout << "Enter tune number (can enter 0, too): ";
cin >> tuneNo;
cout << "Field [(A)ll, (N)ame, A(U)thor (T)itle, A(R)tist,(C)omment]: ";
char fieldchar;
cin >> fieldchar;
switch (fieldchar)
{
case 'a':
case 'A':
field = STIL::all;
break;
case 'n':
case 'N':
field = STIL::name;
break;
case 'u':
case 'U':
field = STIL::author;
break;
case 't':
case 'T':
field = STIL::title;
break;
case 'r':
case 'R':
field = STIL::artist;
break;
case 'c':
case 'C':
field = STIL::comment;
break;
default:
cout << "Wrong field. Assuming (A)ll." << endl;
field = STIL::all;
break;
}
cout << endl << "==== " << temp << ", Tune #" << tuneNo << " ====" << endl << endl;
cout << "---- GLOBAL COMMENT ----" << endl;
tmpptr = myStil.getGlobalComment(temp);
if (tmpptr)
{
cout << tmpptr;
}
else
{
cout << "NONE!" << endl;
}
cout << "------ STIL ENTRY ------" << endl;
tmpptr = myStil.getEntry(temp, tuneNo, field);
if (tmpptr)
{
cout << tmpptr;
}
else
{
cout << "NONE!" << endl;
}
cout << "---------- BUG ----------" << endl;
tmpptr = myStil.getBug(temp, tuneNo);
if (tmpptr)
{
cout << tmpptr;
}
else
{
cout << "NONE!" << endl;
}
cout << "==== END OF ENTRY ====" << endl << endl;
}
} while (*temp == '/');
cout << "BYE!" << endl;
}
}
return 0;
}