summaryrefslogtreecommitdiff
path: root/Build/source/utils/m-tx/mtx-src/mtxline.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/m-tx/mtx-src/mtxline.c')
-rw-r--r--Build/source/utils/m-tx/mtx-src/mtxline.c851
1 files changed, 851 insertions, 0 deletions
diff --git a/Build/source/utils/m-tx/mtx-src/mtxline.c b/Build/source/utils/m-tx/mtx-src/mtxline.c
new file mode 100644
index 00000000000..b08eef73777
--- /dev/null
+++ b/Build/source/utils/m-tx/mtx-src/mtxline.c
@@ -0,0 +1,851 @@
+/* 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], orig_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->orig_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]);
+ WITH->orig_word_bound[WITH->here] = nextWordBound(orig_P[WITH->mus - 1],
+ note[0], WITH->orig_word_bound[WITH->here - 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");
+ if (WITH->nbar + nbars > max_bars)
+ error3(voice, "Bars per line limit exceeded");
+ WITH->nbar += nbars;
+ 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)
+{
+ short p;
+ line_info *WITH;
+
+ WITH = &info[voice-1];
+ printf("In voice \"%s\" near word %d:\n", voice_label[voice-1], WITH->here);
+ p = WITH->orig_word_bound[WITH->here - 1] - 1;
+ if (p < 0)
+ p = 0;
+ printf("%*cV\n", p, ' ');
+}
+
+
+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 317:
+ * 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. */