diff options
Diffstat (limited to 'Build/source/utils/mtx/mtx-0.60d/mtxline.c')
-rw-r--r-- | Build/source/utils/mtx/mtx-0.60d/mtxline.c | 844 |
1 files changed, 844 insertions, 0 deletions
diff --git a/Build/source/utils/mtx/mtx-0.60d/mtxline.c b/Build/source/utils/mtx/mtx-0.60d/mtxline.c new file mode 100644 index 00000000000..f61cee0e24d --- /dev/null +++ b/Build/source/utils/mtx/mtx-0.60d/mtxline.c @@ -0,0 +1,844 @@ +/* Output from p2c 1.21alpha-07.Dec.93, the Pascal-to-C translator */ +/* From input file "mtxline.pas" */ + + +#include "p2c.h" + + +#define MTXLINE_G +#include "mtxline.h" + + +boolean bind_left[22] = { + false, false, true, false, false, true, true, false, true, true, true, + false, true, false, true, false, true, false, false, false, false, false +}; + +#ifndef STRINGS_H +#include "strings.h" +#endif + +#ifndef CONTROL_H +#include "control.h" +#endif + +#ifndef NOTES_H +#include "notes.h" +#endif + +#ifndef UTILITY_H +#include "utility.h" +#endif + + +typedef music_word word_scan[max_words]; + +typedef struct line_info { + word_index0 here, nword; + bar_index0 nbar; + paragraph_index0 voice_pos, voice_stave, mus, chord; + short extra; + boolean vocal; + word_index0 bar_bound[max_bars + 1]; + short word_bound[max_words + 1]; + word_scan scan; +} line_info; + + +Static Char name[22][10] = { + "?", "note", "znote", "lyricsTag", "(", ")", ")(", "[", "]", "_", "PMX<", + "macro", "endMacro", "meter", "ornament", "rest", "//", "BAR", "TeX", "@", + "firstonly", "ERROR" +}; + +Static line_info info[maxvoices]; + + +/* ------------------------------------------------------------- */ + +short beatsPerLine(void) +{ + short Result; + voice_index voice, FORLIM; + line_info *WITH; + + FORLIM = nvoices; + for (voice = 1; voice <= FORLIM; voice++) { + WITH = &info[voice-1]; + if (WITH->nbar > 0 || WITH->extra > 0) { + if (WITH->extra % one_beat > 0) { +/* p2c: mtxline.pas, line 99: + * Note: Using % for possibly-negative arguments [317] */ + error3(voice, "Line length not an integer number of beats"); + } + Result = WITH->nbar * meternum + WITH->extra / one_beat; + } + } + return Result; +} + + +void skipChordBar(voice_index voice) +{ + line_info *WITH; + Char STR1[256]; + + WITH = &info[voice-1]; + if (WITH->chord > 0) { + sprintf(STR1, "%c", barsym); + if (!strcmp(P[WITH->chord - 1], STR1)) + predelete(P[WITH->chord - 1], 1); + } +} + + +Char *getBar(Char *Result, voice_index voice, short bar) +{ + line_info *WITH; + + WITH = &info[voice-1]; + return (substr_(Result, P[WITH->mus - 1], + WITH->word_bound[WITH->bar_bound[bar-1]] + 1, + WITH->word_bound[WITH->bar_bound[bar]] - + WITH->word_bound[WITH->bar_bound[bar-1]])); +} + + +Char *musicLine(Char *Result, voice_index voice) +{ + return strcpy(Result, P[musicLineNo(voice) - 1]); +} + + +paragraph_index0 musicLineNo(voice_index voice) +{ + return (info[voice-1].mus); +} + + +void setMusicLineNo(voice_index voice, paragraph_index lno) +{ + info[voice-1].mus = lno; +} + + +paragraph_index0 chordLineNo(voice_index voice) +{ + return (info[voice-1].chord); +} + + +void setChordLineNo(voice_index voice, paragraph_index lno) +{ + info[voice-1].chord = lno; +} + + +void setVocal(voice_index voice, boolean voc) +{ + info[voice-1].vocal = voc; +} + + +boolean isVocal(voice_index voice) +{ + return (info[voice-1].vocal); +} + + +void setStavePos(voice_index voice, stave_index stave, stave_index pos) +{ + line_info *WITH; + + WITH = &info[voice-1]; + WITH->voice_pos = pos; + WITH->voice_stave = stave; +} + + +stave_index voiceStave(voice_index voice) +{ + return (info[voice-1].voice_stave); +} + + +stave_index voicePos(voice_index voice) +{ + return (info[voice-1].voice_pos); +} + + +voice_index companion(voice_index voice) +{ + short s; + + s = info[voice-1].voice_stave; + if (number_on_stave[s-1] == 1) + return voice; + else if (info[voice-1].voice_pos == 1) + return (voice + 1); + else + return (voice - 1); +} + + +void regroup(voice_index voice) +{ + word_index0 i, j; + word_index0 j2 = 0; + line_info *WITH; + word_index0 FORLIM; + + WITH = &info[voice-1]; + if (debugMode()) + printf("Voice %d has %d bars at ", voice, WITH->nbar); + if (debugMode()) { + FORLIM = WITH->nbar + 1; + for (i = 1; i <= FORLIM; i++) + printf("%d ", WITH->bar_bound[i]); + } + FORLIM = WITH->nbar; + for (i = 1; i <= FORLIM; i++) { + j2 = WITH->bar_bound[i]; + j = j2 + 1; + while (j <= WITH->here && + (bind_left[(long)WITH->scan[j-1]] || WITH->scan[j-1] == barword)) { + WITH->bar_bound[i]++; + j++; + } + } + if (WITH->extra > 0) + WITH->bar_bound[WITH->nbar + 1] = WITH->here; + if (debugMode()) { + printf(" regrouped to "); + FORLIM = WITH->nbar + 1; + for (i = 1; i <= FORLIM; i++) + printf("%d ", WITH->bar_bound[i]); + } + if (debugMode()) + putchar('\n'); + WITH->nword = WITH->here; +} + + +void resetInfo(voice_index voice, Char *buf) +{ + line_info *WITH; + + WITH = &info[voice-1]; + strcpy(buf, P[WITH->mus - 1]); + *P[WITH->mus - 1] = '\0'; + WITH->bar_bound[0] = 0; + WITH->word_bound[0] = 0; + WITH->nbar = 0; + WITH->here = 0; +} + + +void clearLabels(void) +{ + voice_index voice, FORLIM; + line_info *WITH; + + FORLIM = nvoices; + for (voice = 0; voice <= FORLIM - 1; voice++) { + WITH = &info[voice]; + WITH->chord = 0; + WITH->mus = 0; + } +} + + +void appendNote(voice_index voice, music_word nscan) +{ + line_info *WITH; + + WITH = &info[voice-1]; + WITH->here++; + if (WITH->here > max_words) + error3(voice, "Words per line limit exceeded"); + WITH->scan[WITH->here - 1] = nscan; +} + + +void appendToLine(voice_index voice, Char *note) +{ + line_info *WITH; + + if (*note == '\0') + return; + WITH = &info[voice-1]; + sprintf(P[WITH->mus - 1] + strlen(P[WITH->mus - 1]), "%s%c", note, blank); + WITH->word_bound[WITH->here] = strlen(P[WITH->mus - 1]); +} + + +void markBar(voice_index voice) +{ + line_info *WITH; + + WITH = &info[voice-1]; + if (WITH->nbar == 0) + error3(voice, "Empty bar"); + else + WITH->bar_bound[WITH->nbar] = WITH->here; +} + + +short numberOfBars(voice_index voice) +{ + return (info[voice-1].nbar); +} + + +void barForward(voice_index voice, short nbars) +{ + line_info *WITH; + + WITH = &info[voice-1]; + if (WITH->nbar + nbars < 0) + error3(voice, "Next voice before bar is full"); + WITH->nbar += nbars; + if (WITH->nbar > max_bars) + error3(voice, "Bars per line limit exceeded"); + if (nbars > 0) + WITH->bar_bound[WITH->nbar] = WITH->here; +} + + +void setExtraLength(voice_index voice, short ext) +{ + line_info *WITH; + + WITH = &info[voice-1]; + WITH->extra = ext; + WITH->scan[WITH->here] = other; +} + + +short ExtraLength(voice_index voice) +{ + return (info[voice-1].extra); +} + + +voice_index0 findVoice(Char *w_) +{ + voice_index0 Result = 0; + Char w[256]; + short i, FORLIM; + + strcpy(w, w_); + curtail(w, ':'); + FORLIM = nvoices; + for (i = 1; i <= FORLIM; i++) { + if (!strcmp(w, voice_label[i-1])) + return i; + } + getNum(w, &i); + if (i == 0) + return Result; + if (i > 0 && i <= nvoices) + return i; + error("Numeric label outside range 1..nvoices", print); + return Result; +} + + +Static void info3(voice_index voice) +{ + line_info *WITH; + + WITH = &info[voice-1]; + printf("In voice \"%s\" near word %d:\n", voice_label[voice-1], WITH->here); + printf("%*cV\n", WITH->word_bound[WITH->here], ' '); +} + + +void error3(voice_index voice, Char *message) +{ + Char STR1[256]; + + info3(voice); + sprintf(STR1, " %s", message); + error(STR1, print); +} + + +void warning3(voice_index voice, Char *message) +{ + Char STR1[256]; + + info3(voice); + sprintf(STR1, " %s", message); + warning(STR1, print); +} + + +Char *nextMusicWord(Char *Result, voice_index voice) +{ + return (MusicWord(Result, voice, info[voice-1].here)); +} + + +Char *MusicWord(Char *Result, short voice, short n) +{ + line_info *WITH; + + WITH = &info[voice-1]; + if (n > 0 && n <= WITH->nword) + return (substr_(Result, P[WITH->mus - 1], WITH->word_bound[n-1] + 1, + WITH->word_bound[n] - WITH->word_bound[n-1] - 1)); + else + return strcpy(Result, ""); +} + + +music_word thisNote(voice_index voice) +{ + line_info *WITH; + + WITH = &info[voice-1]; + return (WITH->scan[WITH->here - 2]); +} + + +music_word nextNote(voice_index voice) +{ + line_info *WITH; + + WITH = &info[voice-1]; + return (WITH->scan[WITH->here - 1]); +} + + +boolean endOfBar(voice_index voice, short bar_no) +{ + line_info *WITH; + + WITH = &info[voice-1]; + return (WITH->here > WITH->bar_bound[bar_no]); +} + + +void gotoBar(voice_index voice, short bar_no) +{ + line_info *WITH; + + WITH = &info[voice-1]; + WITH->here = WITH->bar_bound[bar_no-1] + 1; +} + + +Char *getMusicWord(Char *Result, voice_index voice) +{ + line_info *WITH; + + WITH = &info[voice-1]; + line_no = orig_line_no[WITH->mus - 1]; + MusicWord(Result, voice, WITH->here); + WITH->here++; + return Result; +} + + +boolean maybeMusicLine(Char *l_) +{ + Char l[256]; + Char w[256]; + music_word nscan; + + strcpy(l, l_); + GetNextWord(w, l, blank, dummy); +/* p2c: mtxline.pas: Note: Eliminated unused assignment statement [338] */ + if (pos1(w[0], "abcdefgr()[]{}CMm") == 0) + return false; + if (pos1(':', w) == 0) + return true; + getNextMusWord(w, l, &nscan); + return (nscan == abcdefg); +} + + +#define nmacros 99 + + +Static boolean macro_initialized = false; +Static Char macro_text[nmacros][256]; + + +Static void macroInit(void) +{ + short i; + + if (macro_initialized) + return; + macro_initialized = true; + for (i = 0; i <= nmacros - 1; i++) + *macro_text[i] = '\0'; +} + + +Static short identifyMacro(Char *s_) +{ + Char s[256]; + short k; + + strcpy(s, s_); + predelete(s, 2); + getNum(s, &k); + return k; +} + + +/* Local variables for getNextMusWord: */ +struct LOC_getNextMusWord { + Char *buf, *note; +} ; + +Local void expandThisMacro(struct LOC_getNextMusWord *LINK) +{ + Char playtag[11]; + short playID; + Char w[256]; + Char STR1[72]; + Char STR2[42]; + Char STR3[68]; + Char STR4[54]; + Char STR5[256], STR7[256]; + + macroInit(); + if (strlen(LINK->note) == 1) + error("Can't terminate a macro that has not been started", print); + playID = identifyMacro(LINK->note); + toString(playtag, playID); +/* p2c: mtxline.pas, line 310: + * Note: Possible string truncation in assignment [145] */ + if (playID < 1 || playID > 99) { + sprintf(STR2, "Macro ID %s is not in range 1..99", playtag); + error(STR2, print); + } + if (LINK->note[1] == 'P') { + if (*macro_text[playID-1] == '\0') { + sprintf(STR3, + "Macro %s inserts empty text: did you define it before use?", + playtag); + warning(STR3, print); + } + if (strlen(macro_text[playID-1]) + strlen(LINK->buf) <= 255) { + if (debugMode()) + printf("Inserting macro %s text \"%s\"\n", + playtag, macro_text[playID-1]); + printf("Buffer before insert: %s\n", LINK->buf); + sprintf(LINK->buf, "%s%s", + macro_text[playID-1], strcpy(STR5, LINK->buf)); + return; + } + sprintf(STR4, "Expansion of macro %s causes buffer overflow", playtag); + error(STR4, print); + } + if (pos1(LINK->note[1], "SR") == 0) { + sprintf(STR4, "Second character %c of macro word should be in \"PRS\"", + LINK->note[1]); + error(STR4, print); + } + *macro_text[playID-1] = '\0'; + do { + GetNextWord(w, LINK->buf, blank, dummy); + if (*w == '\0') { + sprintf(STR1, + "Macro definition %s should be terminated on the same input line", + playtag); + error(STR1, print); + } + if (!strcmp(w, "M")) { + if (debugMode()) + printf("Macro %s is: %s\n", playtag, macro_text[playID-1]); + break; + } + if (w[0] == 'M' && strlen(w) > 1) { + if (w[1] != 'P' || identifyMacro(w) == playID) { + sprintf(STR7, "%s not allowed inside macro definition %s", w, playtag); + error(STR7, print); + } + } + sprintf(macro_text[playID-1] + strlen(macro_text[playID-1]), "%s ", w); + } while (true); + if (LINK->note[1] == 'R') { + LINK->note[1] = 'P'; + sprintf(LINK->buf, "%s %s", LINK->note, strcpy(STR7, LINK->buf)); + } +} + + +void getNextMusWord(Char *buf_, Char *note_, music_word *nscan) +{ + struct LOC_getNextMusWord V; + Char maybe_error[256]; + Char STR2[256]; + + V.buf = buf_; + V.note = note_; + GetNextWord(V.note, V.buf, blank, dummy); + if (*V.note == '\0') + return; + if (V.note[0] == 'M' && expandMacro()) { + expandThisMacro(&V); + getNextMusWord(V.buf, V.note, nscan); + return; + } + if (V.note[0] == '\\') { + *maybe_error = '\0'; + if (V.note[strlen(V.note) - 1] != '\\') + strcpy(maybe_error, V.note); + while (*V.buf != '\0' && V.note[strlen(V.note) - 1] != '\\') + sprintf(V.note + strlen(V.note), " %s", + GetNextWord(STR2, V.buf, blank, dummy)); + if (V.note[strlen(V.note) - 1] != '\\') + error("Unterminated TeX literal", print); + *nscan = texword; + if (*maybe_error != '\0') { + sprintf(STR2, "Possible unterminated TeX literal: %s", maybe_error); + warning(STR2, print); + } + return; + } + if (solfaNoteNames()) { + translateSolfa(V.note); + if (V.note[0] == '"') + predelete(V.note, 1); + } + switch (V.note[0]) { + + case '_': + *nscan = pmxprefix; + delete1(V.note, 1); + break; + + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + *nscan = abcdefg; + break; + + case 'z': + *nscan = zword; + break; + + case '(': + *nscan = lparen; + break; + + case '{': + if (V.note[strlen(V.note) - 1] == '}') + *nscan = lyrtag; + else + *nscan = lparen; + break; + + case ')': + if (pos1('(', V.note) == 0) + *nscan = rparen; + else + *nscan = rlparen; + break; + + case '}': + if (pos1('{', V.note) == 0) + *nscan = rparen; + else + *nscan = rlparen; + break; + + case '[': + *nscan = lbrac; + break; + + case ']': + *nscan = rbrac; + break; + + case '@': + *nscan = atword; + break; + + case 'm': + *nscan = mword; + break; + + case 'r': + *nscan = rword; + break; + + case '#': + case '-': + case 'n': + case 'x': + case '?': + case 's': + case 't': + case 'D': + *nscan = pmxl; + break; + + case 'M': + if (!strcmp(V.note, "M")) + *nscan = endmacro; + else + *nscan = macro; + break; + + case 'G': + if (pos1('A', V.note) > 0) + *nscan = pmxl; + else + *nscan = other; + break; + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (pos1('/', V.note) > 0) + *nscan = mword; + else + *nscan = pmxl; + break; + + case 'o': + *nscan = oword; + break; + + case 'A': + case 'V': + *nscan = FirstOnly; + break; + + case '/': + if (!strcmp(V.note, "//")) + *nscan = nextvoice; + else if (!strcmp(V.note, "/")) { + strcpy(V.note, "//"); + warning("/ changed to //", print); + *nscan = nextvoice; + } else { + error("Word starts with /: do you mean \\?", print); + *nscan = err; + } + break; + + default: + if (pos1('|', V.note) > 0) + *nscan = barword; + else + *nscan = other; + break; + } +} + + +boolean upper(voice_index voice) +{ + line_info *WITH; + + WITH = &info[voice-1]; + if (WITH->voice_pos == 1 && voice < nvoices) + return (WITH->voice_stave == info[voice].voice_stave); + else + return false; +} + + +void describeVoice(voice_index voice, Char *describe_lyr) +{ + short bar, w; + line_info *WITH; + Char STR1[256]; + line_info *WITH1; + short FORLIM; + + WITH = &info[voice-1]; + printf("Voice `%s' is on line %d", voice_label[voice-1], WITH->mus); + if (WITH->vocal) { + printf(", is vocal"); + puts(describe_lyr); + } else { + if (WITH->chord > 0) + printf(" and has chords on line %d", WITH->chord); + putchar('\n'); + } + if (!debugMode()) + return; + WITH1 = &info[voice-1]; + printf("Line has %d bars", WITH1->nbar); + if (WITH1->extra > 0) + printf(" + %d/64 notes\n", WITH1->extra); + else + putchar('\n'); + printf("Bars:"); + FORLIM = WITH1->nbar; + for (bar = 1; bar <= FORLIM; bar++) + printf(" %s ", getBar(STR1, voice, bar)); + printf("\nWord types:"); + FORLIM = WITH1->nword; + for (w = 0; w <= FORLIM - 1; w++) + printf(" %s", name[(long)WITH1->scan[w]]); + putchar('\n'); +} + + +boolean aloneOnStave(stave_index stave) +{ + voice_index v; + + if (number_on_stave[stave-1] != 2) + return true; + else { + v = first_on_stave[stave-1]; + return (info[v-1].mus == 0 || info[v].mus == 0); + } +} + + +void selectVoices(Char *line_) +{ + Char line[256]; + short i = 0; + short k; + Char word[256]; + short FORLIM; + + strcpy(line, line_); + FORLIM = nvoices; + for (k = 0; k <= FORLIM - 1; k++) + selected[k] = false; + printf("Voice change to: %s = ", line); + while (i < nvoices) { + GetNextWord(word, line, blank, dummy); + if (*word == '\0') { + putchar('\n'); + return; + } + i++; + printf("%s ", word); + k = findVoice(word); + if (k == 0) + error("This voice is not in the style", print); + selected[k-1] = true; + } + putchar('\n'); +} + + + + +/* End. */ |