void HumdrumFileBasic::makeNewSpineInfo(SigCollection<char*>&spineinfo, HumdrumRecord& aRecord, int newsize, int& spineid, SigCollection<int>& ex) { SigCollection<char*> newinfo; newinfo.setSize(newsize); int i, j; for (i=0; i<newsize; i++) { newinfo[i] = new char[1024]; newinfo[i][0] = '\0'; } int spinecount = aRecord.getFieldCount(); int subcount; int inindex = 0; int outindex = 0; for (inindex=0; inindex<spinecount; inindex++) { if (strcmp("*^", aRecord[inindex]) == 0) { strcpy(newinfo[outindex], "("); strcat(newinfo[outindex], spineinfo[inindex]); strcat(newinfo[outindex], ")a"); outindex++; strcpy(newinfo[outindex], "("); strcat(newinfo[outindex], spineinfo[inindex]); strcat(newinfo[outindex], ")b"); outindex++; } else if (strcmp("*-", aRecord[inindex]) == 0) { // don't increment outindex } else if (strcmp("*+", aRecord[inindex]) == 0) { strcpy(newinfo[outindex], spineinfo[inindex]); outindex++; spineid++; sprintf(newinfo[outindex], "%d", spineid); outindex++; } else if (strcmp("*x", aRecord[inindex]) == 0) { strcpy(newinfo[outindex], spineinfo[inindex+1]); outindex++; strcpy(newinfo[outindex], spineinfo[inindex]); outindex++; inindex++; } else if (strcmp("*v", aRecord[inindex]) == 0) { subcount = 1; strcpy(newinfo[outindex], spineinfo[inindex]); for (j=inindex+1; j<spinecount; j++) { if (strcmp("*v", aRecord[j]) == 0) { subcount++; if (subcount > 1) { strcat(newinfo[outindex], " "); strcat(newinfo[outindex], spineinfo[inindex+subcount-1]); simplifySpineString(newinfo[outindex]); } } else { break; } } if (subcount == 1) { cout << "Error: single *v path indicator on line: " << aRecord.getLineNum() << "\n" << aRecord.getLine() << endl; exit(1); } else { inindex += subcount-1; } // check to see if the spine info can be simplified: simplifySpineInfo(newinfo, outindex); outindex++; } else if (strncmp("**", aRecord[inindex], 2) == 0) { int value; value = Convert::exint.getValue(aRecord[inindex]); if (spineid != ex.getSize()) { cout << "Error in exclusive interpretation allocation" << endl; exit(1); } if (value == E_unknown) { value = Convert::exint.add(aRecord[inindex]); ex.append(value); } else { ex.append(value); } strcpy(newinfo[outindex], spineinfo[inindex]); outindex++; } else { strcpy(newinfo[outindex], spineinfo[inindex]); outindex++; } } if (outindex != newinfo.getSize()) { cout << "Error in HumdrumFileBasic path parsing" << endl; exit(1); } if (inindex != spineinfo.getSize()) { cout << "Error in HumdrumFileBasic path parsing" << endl; exit(1); } // delete the old information: for (i=0; i<spineinfo.getSize(); i++) { if (spineinfo[i] != NULL) { delete [] spineinfo[i]; spineinfo[i] = NULL; } } spineinfo.setSize(newinfo.getSize()); // copy the new spine path indicators int length; for (i=0; i<spineinfo.getSize(); i++) { length = strlen(newinfo[i]); spineinfo[i] = new char[length + 1]; strcpy(spineinfo[i], newinfo[i]); delete [] newinfo[i]; newinfo[i] = NULL; } newinfo.setSize(0); }
void HumdrumFileBasic::privateSpineAnalysis(void) { int init = 0; int spineid = 0; SigCollection<char*> spineinfo; SigCollection<int> exinterps; exinterps.setSize(100); exinterps.setAllocSize(100); exinterps.setSize(1); exinterps[0] = 0; exinterps.allowGrowth(); spineinfo.setSize(1000); spineinfo.setAllocSize(1000); spineinfo.setSize(0); spineinfo.allowGrowth(); int currentwidth = 0; int prediction = 0; int length; int tlen = 0; int i, n; int type; char* tptr = NULL; char buffer[1024] = {0}; char* bp; for (i=0; i<trackexinterp.getSize(); i++) { if (trackexinterp[i] != NULL) { delete [] trackexinterp[i]; trackexinterp[i] = NULL; } } trackexinterp.setSize(100); trackexinterp.setGrowth(1000); trackexinterp.setSize(0); trackexinterp.allowGrowth(1); int linecount = getNumLines(); for (n=0; n<linecount; n++) { ((*this)[n]).setLineNum(n+1); type = ((*this)[n]).getType(); if (type == E_humrec_data || type == E_humrec_data_measure || type == E_humrec_data_comment) { if (init == 0) { cout << (*this); cout << "Error on line " << n+1 << "of data: no starting interpretation" << endl; exit(1); } ((*this)[n]).copySpineInfo(spineinfo, n+1); currentwidth = (*this)[n].getFieldCount(); (*this)[n].setSpineWidth(currentwidth); } else if (type == E_humrec_interpretation) { currentwidth = (*this)[n].getFieldCount(); if (!init) { init = 1; if (!((*this)[n]).hasExclusiveQ()) { cout << "Error on line " << n+1 << " of file: " << "No starting exclusive interpretation" << endl; cout << "The file contains: " << endl; cout << (*this) << endl; exit(1); } if (spineinfo.getSize() != 0) { cout << "Error on line " << n+1 << endl; exit(1); } for (i=0; i<getSpineCount(n); i++) { if (strncmp("**", getRecord(n)[i], 2) != 0) { cout << "Error on line " << n+1 << ": nonexclusive" << endl; } tlen = strlen(getRecord(n)[i]); tptr = new char[tlen + 1]; strcpy(tptr, getRecord(n)[i]); trackexinterp.append(tptr); spineid++; sprintf(buffer, "%d", spineid); length = strlen(buffer); bp = new char[length + 1]; strcpy(bp, buffer); spineinfo.append(bp); int value; value = Convert::exint.getValue(getRecord(n)[i]); if (spineid != exinterps.getSize()) { cout << "Error in exclusive interpretation allocation."; cout << "Line: " << n+1 << endl; exit(1); } if (value == E_unknown) { value = Convert::exint.add(getRecord(n)[i]); exinterps.append(value); } else { exinterps.append(value); } } ((*this)[n]).copySpineInfo(spineinfo, n+1); (*this)[n].setSpineWidth(currentwidth); } else if (((*this)[n]).hasExclusiveQ() || ((*this)[n]).hasPathQ()) { prediction = predictNewSpineCount(((*this)[n])); (*this)[n].setSpineWidth(currentwidth); currentwidth = prediction; int w; int ii; w = n+1; while (w < linecount && getSpineCount(w) == 0) { w++; } if ((w < linecount) && (prediction != getSpineCount(w))) { cerr << "Error on line " << w+1 << ": " << "spine count does not match:" << " prediction = " << prediction << " actual = " << getSpineCount(w) << endl; cerr << "Data up to error: " << endl; for (ii=0; ii<w+1; ii++) { cout << (*this)[ii] << endl; } exit(1); } else if ((w >= linecount) && prediction != 0) { cerr << "Error in termination of humdrum data" << endl; } ((*this)[n]).copySpineInfo(spineinfo, n+1); makeNewSpineInfo(spineinfo, ((*this)[n]), prediction, spineid, exinterps); if (prediction == 0) { init = 0; } } else { // plain tandem interpretation if (init == 0) { cerr << "Error on first line of data: no starting interpretation" << endl; exit(1); } ((*this)[n]).copySpineInfo(spineinfo, n+1); (*this)[n].setSpineWidth(currentwidth); } } else { // do nothing: global comment, bibliography information, or null line (*this)[n].setSpineWidth(currentwidth); } } // delete the contents of spineinfo for (i=0; i<spineinfo.getSize(); i++) { if (spineinfo[i] != NULL) { delete [] spineinfo[i]; spineinfo[i] = NULL; } } spineinfo.setSize(0); // provide Exclusive Interpretations ownerships to the record spines int spineindex; linecount = getNumLines(); int m; const char* ptr; for (n=0; n<linecount; n++) { type = ((*this)[n]).getType(); if ((type & E_humrec_data) == E_humrec_data) { for (m=0; m<getSpineCount(n); m++) { ptr = ((*this)[n]).getSpineInfo(m); while (ptr[0] != '\0' && !isdigit(ptr[0])) { ptr++; } sscanf(ptr, "%d", &spineindex); ((*this)[n]).setExInterp(m, exinterps[spineindex]); } } } maxtracks = spineid; trackexinterp.allowGrowth(0); }