summaryrefslogtreecommitdiff
path: root/Build/source/texk/gregorio/gregorio-src/src/struct_iter.h
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/gregorio/gregorio-src/src/struct_iter.h')
-rw-r--r--Build/source/texk/gregorio/gregorio-src/src/struct_iter.h191
1 files changed, 191 insertions, 0 deletions
diff --git a/Build/source/texk/gregorio/gregorio-src/src/struct_iter.h b/Build/source/texk/gregorio/gregorio-src/src/struct_iter.h
new file mode 100644
index 00000000000..f0b19040655
--- /dev/null
+++ b/Build/source/texk/gregorio/gregorio-src/src/struct_iter.h
@@ -0,0 +1,191 @@
+/*
+ * Gregorio is a program that translates gabc files to GregorioTeX
+ * This header defines the Gregorio data structures and functions.
+ *
+ * Copyright (C) 2016-2019 The Gregorio Project (see CONTRIBUTORS.md)
+ *
+ * This file is part of Gregorio.
+ *
+ * Gregorio is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Gregorio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Gregorio. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file
+ * The file starts by the definition of all the structures used in
+ * gregorio. As it is certainly the most important file for
+ * understanding, read it carefully.
+ */
+
+#ifndef STRUCT_ITER_H
+#define STRUCT_ITER_H
+
+#include "struct.h"
+
+/* This enum defines bitfields selecting the node types that should be passed
+ * to end_item in gregorio_from_note_to_note */
+typedef enum {
+ GRESTRUCT_NONE = 0,
+ GRESTRUCT_NOTE = 1 << 0,
+ GRESTRUCT_GLYPH = 1 << 1,
+ GRESTRUCT_ELEMENT = 1 << 2,
+ GRESTRUCT_SYLLABLE = 1 << 3
+} gregorio_note_iter_item_type;
+
+typedef struct {
+ gregorio_syllable *syllable;
+ gregorio_element *element;
+ gregorio_glyph *glyph;
+ gregorio_note *note;
+} gregorio_note_iter_position;
+
+static __inline void gregorio_from_note_to_note(
+ const gregorio_note_iter_position *const start,
+ const gregorio_note_iter_position *const end, bool include_end,
+ void (*const visit)(const gregorio_note_iter_position *, void *),
+ void (*const end_item)(const gregorio_note_iter_position *,
+ gregorio_note_iter_item_type, void *),
+ const gregorio_note_iter_item_type desired_end_items, void *data)
+{
+ /* Note: include_end is effectively ignored if end is NULL */
+
+ gregorio_note_iter_position p = *start;
+
+ while (p.syllable) {
+ if (!p.element) {
+ p.element = p.syllable->elements[0];
+ }
+ while (p.element) {
+ if (p.element->type == GRE_ELEMENT) {
+ if (!p.glyph) {
+ p.glyph = p.element->u.first_glyph;
+ }
+ while (p.glyph) {
+ if (p.glyph->type == GRE_GLYPH) {
+ if (!p.note) {
+ p.note = p.glyph->u.notes.first_note;
+ }
+ while (p.note) {
+ bool at_end = (end && p.note == end->note);
+
+ if (p.note->type == GRE_NOTE
+ && (!at_end || include_end)) {
+ visit(&p, data);
+ }
+
+ if (at_end) {
+ if (end_item) {
+ gregorio_fail(gregorio_from_note_to_note,
+ "unused code path");
+ if (desired_end_items & GRESTRUCT_NOTE) {
+ /* currently unused */
+ /* LCOV_EXCL_START */
+ /* to enable the real code, delete this
+ * assertion: */
+ gregorio_fail(gregorio_from_note_to_note,
+ "unused code path");
+ end_item(&p, GRESTRUCT_NOTE, data);
+ }
+ /* LCOV_EXCL_END */
+ if (desired_end_items & GRESTRUCT_GLYPH) {
+ /* currently unused */
+ /* LCOV_EXCL_START */
+ /* to enable the real code, delete this
+ * assertion: */
+ gregorio_fail(gregorio_from_note_to_note,
+ "unused code path");
+ end_item(&p, GRESTRUCT_GLYPH, data);
+ }
+ /* LCOV_EXCL_END */
+ if (desired_end_items
+ & GRESTRUCT_ELEMENT) {
+ /* currently unused */
+ /* LCOV_EXCL_START */
+ /* to enable the real code, delete this
+ * assertion: */
+ gregorio_fail(gregorio_from_note_to_note,
+ "unused code path");
+ end_item(&p, GRESTRUCT_ELEMENT, data);
+ }
+ /* LCOV_EXCL_END */
+ if (desired_end_items
+ & GRESTRUCT_SYLLABLE) {
+ end_item(&p, GRESTRUCT_SYLLABLE, data);
+ }
+ }
+ return;
+ }
+
+ if (end_item
+ && (desired_end_items & GRESTRUCT_NOTE)) {
+ /* in 4.2.0, this code is never hit, as the only
+ * usage that gets through to here does not
+ * include GRESTRUCT_NOTE in desired_end_items */
+ /* LCOV_EXCL_START */
+ /* to enable the real code, delete this
+ * assertion: */
+ gregorio_fail(gregorio_from_note_to_note,
+ "unused code path");
+ end_item(&p, GRESTRUCT_NOTE, data);
+
+ }
+ /* LCOV_EXCL_STOP */
+ p.note = p.note->next;
+ } /* note */
+ }
+ if (end_item && (desired_end_items & GRESTRUCT_GLYPH)) {
+ /* in 4.2.0, this code is never hit, as the only usage
+ * that gets through to here does not include
+ * GRESTRUCT_GLYPH in desired_end_items */
+ /* LCOV_EXCL_START */
+ /* to enable the real code, delete this assertion: */
+ gregorio_fail(gregorio_from_note_to_note,
+ "unused code path");
+ end_item(&p, GRESTRUCT_GLYPH, data);
+ }
+ /* LCOV_EXCL_STOP */
+ p.glyph = p.glyph->next;
+ } /* glyph */
+ }
+ if (end_item && (desired_end_items & GRESTRUCT_ELEMENT)) {
+ end_item(&p, GRESTRUCT_ELEMENT, data);
+ }
+ p.element = p.element->next;
+ } /* element */
+ if (end_item && (desired_end_items & GRESTRUCT_SYLLABLE)) {
+ end_item(&p, GRESTRUCT_SYLLABLE, data);
+ }
+ p.syllable = p.syllable->next_syllable;
+ } /* syllable */
+}
+
+static __inline void gregorio_for_each_note(const gregorio_score *score,
+ void (*const visit)(const gregorio_note_iter_position *, void *),
+ void (*const end_item)(const gregorio_note_iter_position *,
+ gregorio_note_iter_item_type, void *),
+ const gregorio_note_iter_item_type desired_end_items, void *data)
+{
+ gregorio_note_iter_position p = {
+ /* .syllable = */ NULL,
+ /* .element = */ NULL,
+ /* .glyph = */ NULL,
+ /* .note = */ NULL
+ };
+
+ p.syllable = score->first_syllable;
+
+ gregorio_from_note_to_note(&p, NULL, true, visit, end_item,
+ desired_end_items, data);
+}
+
+#endif