int EOF_IMPORT_VIA_LC(EOF_VOCAL_TRACK *tp, struct Lyric_Format **lp, int format, char *inputfilename, char *string2) { char * returnedfn = NULL; //Return string from dialog window FILE *inf; //Used to open the input file struct Lyric_Format *detectionlist; unsigned long i; int jumpcode = 0; eof_log("EOF_IMPORT_VIA_LC() entered", 1); //Validate parameters if((tp == NULL) || (inputfilename == NULL)) return 0; //Return failure if((format == 0) && (lp == NULL)) return 0; //Return failure //Perform detection logic InitLyrics(); //Initialize all variables in the Lyrics structure InitMIDI(); //Initialize all variables in the MIDI structure if(format == 0) //Auto-detect lyric format { detectionlist=DetectLyricFormat(inputfilename); if(detectionlist == NULL) return 0; //Return invalid lyric file if(detectionlist->format == PITCHED_LYRIC_FORMAT) { //If the detection format is Pitched Lyrics, the user must specify the corresponding Vocal Rhythm MIDI *lp=detectionlist; //Return the detected lyric information via the lp pointer return -1; //Return prompt for user selection } if(detectionlist->next != NULL) { //If there was more MIDI track with lyrics, the user must specify which track to import *lp=detectionlist; //Return the detected lyric information via the lp pointer return -2; //Return prompt for user selection } Lyrics.in_format=detectionlist->format; //Format to import if(detectionlist->track != NULL) Lyrics.inputtrack=detectionlist->track; //Track to import from DestroyLyricFormatList(detectionlist); //Deallocate the linked list returned by DetectLyricFormat() detectionlist=NULL; } else //Import specific format { Lyrics.in_format=format; if(Lyrics.in_format == KAR_FORMAT) { //If this is a format for which string2 (pitched file or track name) must be specified if(string2 == NULL) //If the track name to import is not given return 0; //Return failure Lyrics.inputtrack=DuplicateString(string2); //Make a duplicate, so its de-allocation won't affect calling function } else if(Lyrics.in_format == PITCHED_LYRIC_FORMAT) { //If importing Pitched Lyrics, user must provide the Vocal Rhythm MIDI returnedfn = ncd_file_select(0, eof_filename, "Select Vocal Rhythm MIDI", eof_filter_midi_files); eof_clear_input(); if(!returnedfn) return 0; //Return error or user canceled } } Lyrics.infilename=DuplicateString(inputfilename); //Make a duplicate, so it's de-allocation won't affect calling function jumpcode=setjmp(jumpbuffer); //Store environment/stack/etc. info in the jmp_buf array if(jumpcode!=0) //if program control returned to the setjmp() call above returning any nonzero value { (void) puts("Assert() handled sucessfully!"); free(Lyrics.infilename); Lyrics.infilename = NULL; ReleaseMemory(1); //Release memory allocated during lyric import return 0; //Return error } //Import lyrics switch(Lyrics.in_format) { case SCRIPT_FORMAT: //Load script.txt format file as input inf=fopen_err(Lyrics.infilename,"rt"); //Script is a text format Script_Load(inf); break; case VL_FORMAT: //Load VL format file as input inf=fopen_err(Lyrics.infilename,"rb"); //VL is a binary format VL_Load(inf); break; case MIDI_FORMAT: //Load MIDI format file as input if(string2 == NULL) //If no track name was given Lyrics.inputtrack=DuplicateString("PART VOCALS"); //Default to PART VOCALS else Lyrics.inputtrack=DuplicateString(string2); //Make a duplicate, so its de-allocation won't affect calling function inf=fopen_err(Lyrics.infilename,"rb"); //MIDI is a binary format Parse_Song_Ini(Lyrics.infilename,1,1); //Load ALL tags from song.ini first, as the delay tag will affect timestamps MIDI_Load(inf,Lyric_handler,0); //Call MIDI_Load, specifying the new KAR-compatible Lyric Event handler break; case USTAR_FORMAT: //Load UltraStar format file as input inf=fopen_err(Lyrics.infilename,"rt"); //UltraStar is a text format UStar_Load(inf); break; case LRC_FORMAT: //Load LRC format file as input case ELRC_FORMAT: inf=fopen_err(Lyrics.infilename,"rt"); //LRC is a text format LRC_Load(inf); break; case VRHYTHM_FORMAT: //Load vocal rhythm (MIDI) and pitched lyrics inf=fopen_err(returnedfn,"rb"); //Vrhythm is a binary format VRhythm_Load(inputfilename,returnedfn,inf); break; case PITCHED_LYRIC_FORMAT: inf=fopen_err(returnedfn,"rb"); //Vrhythm is a binary format VRhythm_Load(eof_filename,returnedfn,inf); break; case KAR_FORMAT: //Load KAR MIDI file inf=fopen_err(Lyrics.infilename,"rb"); //KAR is a binary format MIDI_Load(inf,Lyric_handler,0); //Call MIDI_Load, specifying the new KAR-compatible Lyric Event handler break; case SKAR_FORMAT: //Load SKAR MIDI file inf=fopen_err(Lyrics.infilename,"rb"); //KAR is a binary format Lyrics.inputtrack=DuplicateString("Words"); MIDI_Load(inf,SKAR_handler,0); //Call MIDI_Load, specifying the Simple Karaoke Event handler EndLyricLine(); //KAR files do not mark the end of the last line of lyrics break; case ID3_FORMAT: //Load MP3 ID3 tag inf=fopen_err(Lyrics.infilename,"rb"); //MP3 is a binary format ID3_Load(inf); break; case SRT_FORMAT: //Load SRT file inf=fopen_err(Lyrics.infilename,"rt"); //SRT is a text format SRT_Load(inf); break; case XML_FORMAT: //Load XML file inf=fopen_err(Lyrics.infilename,"rt"); //XML is a text format XML_Load(inf); break; case C9C_FORMAT: //Load JamBand file inf=fopen_err(Lyrics.infilename,"rt"); //JamBand is a text format JB_Load(inf); break; case RS_FORMAT: //Load Rocksmith XML file case RS2_FORMAT: inf=fopen_err(Lyrics.infilename,"rt"); //Rocksmith XML is a text format RS_Load(inf); break; default: return 0; //Return failure }//switch(Lyrics.in_format) free(Lyrics.infilename); Lyrics.infilename = NULL; //Validate imported lyrics if((Lyrics.piececount == 0) || (MIDI_Lyrics.head != NULL)) //If the imported MIDI track had no valid lyrics or otherwise was incorrectly formatted { ReleaseMemory(1); //Release memory allocated during lyric import fclose_err(inf); return 0; //Return no EOF lyric structure } PostProcessLyrics(); //Perform validation of pointers, counters, etc. if(Lyrics.pitch_tracking) { //Only perform input pitch validation and remapping if the import lyrics had pitch information RemapPitches(); //Ensure pitches are within the correct range (except for pitchless lyrics) } //Delete any existing lyrics and lines for(i = 0; i < tp->lyrics; i++) { free(tp->lyric[i]); } tp->lyrics = 0; tp->lines = 0; fclose_err(inf); //Ensure this file gets closed inf=NULL; if(EOF_TRANSFER_FROM_LC(tp,&Lyrics) != 0) //Pass the Lyrics global variable by reference { ReleaseMemory(1); //Release memory allocated during lyric import return 0; //Return error (failed to import into EOF lyric structure) } ReleaseMemory(1); //Release memory allocated during lyric import return 1; //Return finished EOF lyric structure }
int main(int argc, char **argv) { XML test = NULL; int errors = 0; printf("Running series of tests on the xml library:\nchecking for regressions.\n\n"); // 1. Check invalid pointer errors... printf("\nChecking for invalid pointers.\t\t \t\t \n"); errors += check(test, NULL, NULL); errors += check(test, "anything", NULL); errors += check(test, "anything.anythingelse", NULL); errors += check(test, "anything#anythingelse", NULL); XML_Set(test, "anything", "test"); XML_Set(test, "anything.anythingelse", "test"); XML_Set(test, "anything#anythingelse", "test"); errors += check(test, "anything", NULL); errors += check(test, "anything.anythingelse", NULL); errors += check(test, "anything#anythingelse", NULL); // 2. Verify loading of static data... test = XML_ParseString(static_data); errors += serious_data_testing(test); // 5. Verify adding data to the loaded data... printf("\nChecking for adding data (nodes)\t\t \t\t \n"); XML_Set(test, "test.added", "added"); // Added nodes errors += check(test, "test.added", "added"); errors += check(test, "test.added[2]", NULL); XML_Set(test, "test.added", "added again"); errors += check(test, "test.added", "added again"); errors += check(test, "test.added[2]", NULL); XML_Set(test, "test.added[2]", "added after"); errors += check(test, "test.added", "added after"); errors += check(test, "test.added[1]", "added again"); errors += check(test, "test.added[2]", "added after"); printf("\nChecking for adding data (attributes)\t\t \t\t \n"); XML_Set(test, "test.added2#value", "added"); // Added attributes errors += check(test, "test.added2#value", "added"); errors += check(test, "test.added2[2]#value", NULL); XML_Set(test, "test.added2#value", "added again"); errors += check(test, "test.added2#value", "added again"); errors += check(test, "test.added2[2]#value", NULL); XML_Set(test, "test.added2[2]#value", "added after"); errors += check(test, "test.added2#value", "added after"); errors += check(test, "test.added2[1]#value", "added again"); errors += check(test, "test.added2[2]#value", "added after"); XML_Set(test, "test#added", "added"); errors += check(test, "test#added", "added"); XML_Set(test, "test.multi[3]", "another"); errors += check(test, "test.multi[3]", "another"); errors += check(test, "test.multi[4]", NULL); XML_Set(test, "test.multi[3]", "three"); XML_SetInt(test, "test.inttest", 1); errors += check(test, "test.inttest", "1"); XML_SetInt(test, "test.inttest%i", 2, 2); errors += check(test, "test.inttest2", "2"); XML_SetDouble(test, "test.doubletest", 1.0); errors += check(test, "test.doubletest", "1.000000"); XML_SetDouble(test, "test.doubletest%i", 2, 2); errors += check(test, "test.doubletest2", "2.000000"); // 6. Saving, and reading from a file... XML_Save(test, "regression_test.xml"); XML_Free(test); test = XML_Load("regression_test.xml"); errors += serious_data_testing(test); // 7. Brute force attack if(!errors) { printf("\nStarting brute force attack\t\t \t\t \n"); char str[1000]; char v[30]; int i; for(i=1;i<BRUTE_TEST_LENGTH;i++) { sprintf(str, "brute%i", i); sprintf(v, "%i", i); XML_Set(test, str, v); errors += check(test, str, v); } for(i=1;i<BRUTE_TEST_LENGTH;i++) { sprintf(str, "brute2#test%i", i); sprintf(v, "%i", i); XML_Set(test, str, v); errors += check(test, str, v); } // large memory block tests... char * a = malloc(MEMORY_TEST_SIZE+1); if(a) { memset(a, 'A', MEMORY_TEST_SIZE); *(a+MEMORY_TEST_SIZE) = 0; XML_Set(test, "test.long", a); errors += check(test, "test.long", a); XML_Set(test, "test.long2#long", a); errors += check(test, "test.long2#long", a); free(a); } } else printf("\nBrute force test skipped due to previous errors.\t\t \n"); // 8. Search printf("\nStarting search test...\n"); XML_S a; char *b; int cnt = 0; a = XML_Search_Init(test, "test.seven"); if(!a) {errors++; printf("Failed to start finding on line %i.\n", __LINE__);} b = XML_Search(a); if(strcmp(b, "eight")) {errors++; printf("Failed to find 'eight' on line %i.\n", __LINE__);} b = XML_Search(a); if(strcmp(b, "nine")) {errors++; printf("Failed to find 'nine' on line %i.\n", __LINE__);} b = XML_Search(a); if(strcmp(b, "ten")) {errors++; printf("Failed to find 'ten' on line %i.\n", __LINE__);} b = XML_Search(a); if(b) {errors++; printf("Failed to finish finding on line %i.\n", __LINE__);} XML_Search_Free(a); // 8. Done! XML_Free(test); printf("\nFinished!\t\t \t\t \n"); if(errors) { printf("\n\n%i errors were encountered.\nThere are regressions.\nThis library should NOT be distributed!\n", errors); return 1; } printf("\nNo regressions detected.\t\t \t\t \n"); return 0; }