diff options
author | Karl Berry <karl@freefriends.org> | 2021-02-25 19:22:25 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2021-02-25 19:22:25 +0000 |
commit | ad547a6b5986815fda458221149728d9d9ab1d87 (patch) | |
tree | 16296910eb3eca724371474ea9aea3994dc69614 /Build/source/utils/m-tx/mtx-src/notes.c | |
parent | 947b43de3dd21d58ccc2ffadefc4441ea1c2a813 (diff) |
restore Build,TODO from r57911
git-svn-id: svn://tug.org/texlive/trunk@57915 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/m-tx/mtx-src/notes.c')
-rw-r--r-- | Build/source/utils/m-tx/mtx-src/notes.c | 511 |
1 files changed, 511 insertions, 0 deletions
diff --git a/Build/source/utils/m-tx/mtx-src/notes.c b/Build/source/utils/m-tx/mtx-src/notes.c new file mode 100644 index 00000000000..3d4c445ba13 --- /dev/null +++ b/Build/source/utils/m-tx/mtx-src/notes.c @@ -0,0 +1,511 @@ +/* Output from p2c 1.21alpha-07.Dec.93, the Pascal-to-C translator */ +/* From input file "notes.pas" */ + + +#include "p2c.h" + + +#define NOTES_G +#include "notes.h" + + +short count64['9' + 1 - '0'] = { + 64, 4, 32, 2, 16, 0, 1, 0, 8, 128 +}; + +#ifndef STRINGS_H +#include "strings.h" +#endif + +#ifndef GLOBALS_H +#include "globals.h" +#endif + + +typedef struct parsedNote { + Char name; + Char duration[2]; + Char octave[9]; + Char accidental[17], whatever[17], dotgroup[17], xtuplet[17]; + Char shortcut[33]; +} parsedNote; + + +Static void printNote(parsedNote n) +{ + printf("%c|%s|%s|%s|%s|%s|%s|%s\n", + n.name, n.duration, n.octave, n.accidental, n.whatever, n.dotgroup, + n.xtuplet, n.shortcut); +} + + +/* If rearrangeNote is TRUE, translate original note to the following form: + 1. Note name. + 2. Duration. + 3. Octave adjustments. + 4. Everything except the other six items. + 5. Accidental with adjustments (rest: height adjustment) + 6. Dot with adjustments. + 7. Xtuplet group. +*/ + +void translateSolfa(Char *nt) +{ + short k; + + if (!solfaNoteNames()) + return; + k = pos1(*nt, solfa_names); + if (k > 0) + *nt = has_duration[k-1]; +} + + +Char durationCode(Char *note) +{ + Char Result = unspecified; + Char code; + + if (strlen(note) <= 1) + return Result; + code = note[1]; + if (pos1(code, durations) > 0) + return code; + return Result; +} + + +Static Char half(Char dur) +{ + Char Result; + short k; + Char STR1[20]; + Char STR2[24]; + + k = pos1(dur, durations); + Result = dur; + if (k == 0) { + sprintf(STR1, "Invalid duration %c", dur); + error(STR1, print); + return Result; + } + if (k <= ndurs) + return (durations[k]); + sprintf(STR2, "%c is too short to halve", dur); + error(STR2, print); + return Result; +} + + +Static void addDuration(Char *note, Char dur) +{ + if (insertDuration()) + insertChar(dur, note, 2); +} + + +/* Extract procedures. All of these remove part of "note" (sometimes + the part is empty) and put it somewhere else. The part may be anywhere + in "note", except when otherwise specified.*/ + +/* Unconditionally extracts the first character. */ + +Static void extractFirst(Char *note, Char *first) +{ + *first = note[0]; + predelete(note, 1); +} + + +/* Extracts at most one of the characters in "hits". */ + +Static void extractOneOf(Char *note, Char *hits, Char *hit) +{ + short i, l; + + l = strlen(note); + *hit = '\0'; + for (i = 1; i <= l; i++) { + if (pos1(note[i-1], hits) > 0) { + sprintf(hit, "%c", note[i-1]); + delete1(note, i); + return; + } + } +} + + +/* Extracts contiguous characters in "hits" until no more are found. + There may be more later. */ + +Static void extractContiguous(Char *note, Char *hits, Char *hit) +{ + short i, l, len; + + l = strlen(note); + len = l; + *hit = '\0'; + for (i = 1; i <= l; i++) { + if (pos1(note[i-1], hits) > 0) { + do { + if (pos1(note[i-1], hits) == 0) + return; + sprintf(hit + strlen(hit), "%c", note[i-1]); + delete1(note, i); + len--; + } while (len >= i); + return; + } + } +} + + +/* Extracts the specified character and everything after it. */ + +Static void extractAfter(Char *note, Char delim, Char *tail) +{ + short newlen; + + newlen = pos1(delim, note); + *tail = '\0'; + if (newlen == 0) + return; + newlen--; + strcpy(tail, note); + predelete(tail, newlen); + note[(long)((int)newlen)] = '\0'; +/* p2c: notes.pas, line 109: + * Note: Modification of string length may translate incorrectly [146] */ +} + + +/* Extracts the dot shortcut part of a note: comma shortcut is no problem + because a comma cannot be part of a number. */ + +Static void extractDotShortcut(Char *note, Char *tail) +{ + Char names[256], tail2[256]; + short l = 1; + short lt; + Char ch; + + extractAfter(note, '.', tail); + lt = strlen(tail); + if (l < lt && tail[1] == '.') + l = 2; + if (solfaNoteNames()) + strcpy(names, solfa_names); + else + strcpy(names, has_duration); + if (l < lt && pos1(tail[l], names) > 0) { + translateSolfa(&tail[l]); + return; + } + if (l == 2) + error("\"..\" followed by non-note", print); + if (l >= lt) { + strcat(note, tail); + *tail = '\0'; + return; + } + ch = tail[0]; + predelete(tail, 1); + extractDotShortcut(tail, tail2); + sprintf(note + strlen(note), "%c%s", ch, tail); + strcpy(tail, tail2); +} + + +/* Extracts a signed number. */ + +Static void extractSignedNumber(Char *note, Char *number) +{ + short k; + Char note0[256]; + + k = pos1('+', note); + if (k == 0) + k = pos1('-', note); + *number = '\0'; + if (k == 0) + return; + strcpy(note0, note); + do { + sprintf(number + strlen(number), "%c", note[k-1]); + delete1(note, k); + } while (k <= strlen(note) && + (note[k-1] == '0' || pos1(note[k-1], digits) != 0)); + if (strlen(number) == 1) { + strcpy(note, note0); + *number = '\0'; + } +} + + +/* Local variables for extractGroup: */ +struct LOC_extractGroup { + Char *group; + short gl, k; + boolean probe, nonumber; +} ; + +Local void tryMore(struct LOC_extractGroup *LINK) +{ + while (LINK->k <= LINK->gl && LINK->group[LINK->k-1] == LINK->group[0]) + LINK->k++; +} + +Local void try_(Char *s, struct LOC_extractGroup *LINK) +{ + LINK->probe = (LINK->k < LINK->gl && pos1(LINK->group[LINK->k-1], s) > 0); + if (LINK->probe) + LINK->k++; +} + +Local void tryNumber(struct LOC_extractGroup *LINK) +{ + boolean dot_ = false; + + LINK->nonumber = true; + while (LINK->k <= LINK->gl && pos1(LINK->group[LINK->k-1], digitsdot) > 0) { + LINK->k++; + if (LINK->group[LINK->k-1] == '.') { + if (dot_) + error("Extra dot in number", print); + else + dot_ = true; + } else + LINK->nonumber = false; + } +} + + +/* Extracts a symbol followed by optional +- or <> shift indicators */ + +Static void extractGroup(Char *note, Char delim, Char *group_) +{ + struct LOC_extractGroup V; + short k0; + Char tail[256]; + + V.group = group_; + extractAfter(note, delim, V.group); + if (*V.group == '\0') + return; + V.gl = strlen(V.group); + V.k = 2; + if (V.gl > 1 && V.group[1] == ':') + V.k = 3; + else { + tryMore(&V); + k0 = V.k; + try_("+-<>", &V); + if (V.probe) + tryNumber(&V); + if (V.nonumber) + V.k = k0; + k0 = V.k; + try_("+-<>", &V); + if (V.probe) + tryNumber(&V); + if (V.nonumber) + V.k = k0; + } + strcpy(tail, V.group); + V.k--; + V.group[(long)((int)V.k)] = '\0'; +/* p2c: notes.pas, line 170: + * Note: Modification of string length may translate incorrectly [146] */ + predelete(tail, V.k); + strcat(note, tail); +} + + +Static void parseNote(Char *note_, parsedNote *pnote) +{ + Char note[256]; + Char onlymidi[256]; + Char STR1[256]; + Char STR2[10]; + + strcpy(note, note_); + *pnote->shortcut = '\0'; + *pnote->xtuplet = '\0'; + *pnote->accidental = '\0'; + *pnote->dotgroup = '\0'; + *pnote->duration = '\0'; + *pnote->octave = '\0'; + *onlymidi = '\0'; + extractFirst(note, &pnote->name); + extractAfter(note, 'x', pnote->xtuplet); + extractAfter(note, ',', pnote->shortcut); + if (*pnote->shortcut == '\0') + extractDotShortcut(note, pnote->shortcut); + if (pnote->name != rest) { + extractGroup(note, 's', pnote->accidental); + if (*pnote->accidental == '\0') + extractGroup(note, 'f', pnote->accidental); + if (*pnote->accidental == '\0') + extractGroup(note, 'n', pnote->accidental); + } + /* Look for 'i' or 'c' anywhere in what is left of note.*/ + if (*pnote->accidental != '\0') { + extractOneOf(note, "ic", onlymidi); + strcat(pnote->accidental, onlymidi); +/* p2c: notes.pas, line 192: + * Note: Possible string truncation in assignment [145] */ + } + extractGroup(note, 'd', pnote->dotgroup); + if (pnote->name == rest) + extractSignedNumber(note, pnote->accidental); + extractOneOf(note, durations, pnote->duration); + sprintf(STR1, "%c", rest); + if (strcmp(note, STR1)) + extractContiguous(note, "=+-", pnote->octave); + if (*note != '\0' && isdigit(note[0])) { + sprintf(STR2, "%c%s", note[0], pnote->octave); + strcpy(pnote->octave, STR2); +/* p2c: notes.pas, line 198: + * Note: Possible string truncation in assignment [145] */ + delete1(note, 1); + } + strcpy(pnote->whatever, note); +/* p2c: notes.pas, line 200: + * Note: Possible string truncation in assignment [145] */ +} + + +/* On input: "note" is a note word; "dur1" is the default duration. + On output: "note" has possibly been modified; + possibly been split into two parts, the second being "shortcut"; + "dur" is the suggested new default duration; + "count" is the count of the total of "note" and "shortcut" */ +void processNote(Char *note, Char *xnote, Char dur1, Char *dur, short *count) +{ + Char sc[3], origdur[3]; + short multiplicity, l; + parsedNote pnote; + Char STR1[36]; + Char STR3[256]; + + *xnote = '\0'; + *dur = dur1; + if (*note == '\0' || !isNoteOrRest(note) || isPause(note)) + return; + parseNote(note, &pnote); + if (debugMode()) { + printf("%s => ", note); + printNote(pnote); + } + if (pos1('.', pnote.whatever) > 0) { + sprintf(STR3, "Suspicious dot in word %s", note); + warning(STR3, print); + } + strcpy(origdur, pnote.duration); + if (*pnote.duration == '\0') + *dur = dur1; + else + *dur = pnote.duration[0]; + *count = count64[*dur - '0']; + if (*pnote.dotgroup != '\0') { + *count += *count / 2; + if (startsWith(pnote.dotgroup, "dd")) + *count += *count / 6; + } + sprintf(pnote.duration, "%c", *dur); + if (*pnote.shortcut != '\0') { + if (*pnote.dotgroup != '\0') + error("You may not explicitly dot a note with a shortcut", print); + sprintf(sc, "%c", pnote.shortcut[0]); + predelete(pnote.shortcut, 1); + if (!strcmp(sc, ".")) { + multiplicity = 1; + if (pnote.shortcut[0] == '.') { + multiplicity++; + predelete(pnote.shortcut, 1); + strcat(sc, "."); +/* p2c: notes.pas, line 234: + * Note: Possible string truncation in assignment [145] */ + } + *count += *count; + dur1 = pnote.duration[0]; + for (l = 1; l <= multiplicity; l++) { + sprintf(pnote.dotgroup + strlen(pnote.dotgroup), "%c", dotcode); +/* p2c: notes.pas, line 237: + * Note: Possible string truncation in assignment [145] */ + dur1 = half(dur1); + } + addDuration(pnote.shortcut, dur1); + } else { + addDuration(pnote.shortcut, half(pnote.duration[0])); + *count += *count / 2; + } + } + if (!insertDuration()) { + strcpy(pnote.duration, origdur); +/* p2c: notes.pas, line 244: + * Note: Possible string truncation in assignment [145] */ + } + if (rearrangeNote()) + sprintf(note, "%c%s%s%s%s%s%s", + pnote.name, pnote.duration, pnote.octave, pnote.whatever, + pnote.accidental, pnote.dotgroup, pnote.xtuplet); + else + strcpy(pnote.shortcut, " "); + if (!insertDuration() && *pnote.shortcut != '\0') { + sprintf(STR1, "%s%s", sc, pnote.shortcut); + strcpy(pnote.shortcut, STR1); +/* p2c: notes.pas, line 249: + * Note: Possible string truncation in assignment [145] */ + } + strcpy(xnote, pnote.shortcut); +} + + +Char octaveCode(Char *note) +{ /*if debugMode then write('Octave code in note "',note,'" is ');*/ + parsedNote pnote; + + parseNote(note, &pnote); + /*if debugMode then writeln('"',octave,'"');*/ + if (*pnote.octave == '\0') + return ' '; + else + return (pnote.octave[0]); +} + + +void removeOctaveCode(Char code, Char *note) +{ /*if debugMode then writeln('remove ',code,' from ',note);*/ + short k, l; + + l = strlen(note); + for (k = 1; k <= l; k++) { + if (note[k-1] == code) { + if (k == l || note[k] < '0' || note[k] > '9') { + delete1(note, k); + return; + } + } + } + fatalerror("Code not found in note"); +} + + +void insertOctaveCode(Char code, Char *note) +{ /*if debugMode then writeln('insert ',code,' into ',note); */ + short l; + + l = strlen(note); + if (l < 2 || note[1] < '0' || note[1] > '9') + fatalerror("Trying to insert octave into note without duration"); + if (l <= 2 || note[2] < '0' || note[2] > '9') + insertChar(code, note, 3); + else + printf("Not inserting \"%c\", note already has octave code\"\n", code); +} + + + + +/* End. */ |