/*
 * BRLTTY - A background process providing access to the console screen (when in
 *          text mode) for a blind person using a refreshable braille display.
 *
 * Copyright (C) 1995-2023 by The BRLTTY Developers.
 *
 * BRLTTY comes with ABSOLUTELY NO WARRANTY.
 *
 * This is free software, placed under the terms of the
 * GNU Lesser General Public License, as published by the Free Software
 * Foundation; either version 2.1 of the License, or (at your option) any
 * later version. Please see the file LICENSE-LGPL for details.
 *
 * Web Page: http://brltty.app/
 *
 * This software is maintained by Dave Mielke <dave@mielke.cc>.
 */

#include "prologue.h"

#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>

#include "log.h"
#include "strfmt.h"
#include "file.h"
#include "queue.h"
#include "datafile.h"
#include "variables.h"
#include "utf8.h"
#include "unicode.h"
#include "brl_dots.h"

struct DataFileStruct {
  const char *const name;
  const DataFileParameters *const parameters;
  DataFile *const includer;
  int line;

  struct {
    dev_t device;
    ino_t file;
  } identity;

  Queue *conditions;
  VariableNestingLevel *variables;

  const wchar_t *start;
  const wchar_t *end;
};

const wchar_t brlDotNumbers[BRL_DOT_COUNT] = {
  WC_C('1'), WC_C('2'), WC_C('3'), WC_C('4'),
  WC_C('5'), WC_C('6'), WC_C('7'), WC_C('8')
};
const unsigned char brlDotBits[BRL_DOT_COUNT] = {
  BRL_DOT_1, BRL_DOT_2, BRL_DOT_3, BRL_DOT_4,
  BRL_DOT_5, BRL_DOT_6, BRL_DOT_7, BRL_DOT_8
};

int
brlDotNumberToIndex (wchar_t number, int *index) {
  const wchar_t *character = wmemchr(brlDotNumbers, number, ARRAY_COUNT(brlDotNumbers));
  if (!character) return 0;
  *index = character - brlDotNumbers;
  return 1;
}

int
brlDotBitToIndex (unsigned char bit, int *index) {
  const unsigned char *cell = memchr(brlDotBits, bit, ARRAY_COUNT(brlDotBits));
  if (!cell) return 0;
  *index = cell - brlDotBits;
  return 1;
}

void
reportDataError (DataFile *file, const char *format, ...) {
  char message[0X200];

  {
    const char *name = NULL;
    const int *line = NULL;
    va_list args;

    if (file) {
      name = file->name;
      if (file->line) line = &file->line;
    }

    va_start(args, format);
    formatInputError(message, sizeof(message), name, line, format, args);
    va_end(args);
  }

  logMessage(LOG_WARNING, "%s", message);
}

int
compareKeyword (const wchar_t *keyword, const wchar_t *characters, size_t count) {
  while (count > 0) {
    wchar_t character1;
    wchar_t character2;

    if (!(character1 = *keyword)) return -1;
    keyword += 1;

    character1 = towlower(character1);
    character2 = towlower(*characters++);

    if (character1 < character2) return -1;
    if (character1 > character2) return 1;

    count -= 1;
  }

  return *keyword? 1: 0;
}

int
compareKeywords (const wchar_t *keyword1, const wchar_t *keyword2) {
  return compareKeyword(keyword1, keyword2, wcslen(keyword2));
}

int
isKeyword (const wchar_t *keyword, const wchar_t *characters, size_t count) {
  return compareKeyword(keyword, characters, count) == 0;
}

int
isHexadecimalDigit (wchar_t character, int *value, int *shift) {
  if ((character >= WC_C('0')) && (character <= WC_C('9'))) {
    *value = character - WC_C('0');
  } else if ((character >= WC_C('a')) && (character <= WC_C('f'))) {
    *value = character - WC_C('a') + 10;
  } else if ((character >= WC_C('A')) && (character <= WC_C('F'))) {
    *value = character - WC_C('A') + 10;
  } else {
    return 0;
  }

  *shift = 4;
  return 1;
}

int
isOctalDigit (wchar_t character, int *value, int *shift) {
  if ((character < WC_C('0')) || (character > WC_C('7'))) return 0;
  *value = character - WC_C('0');
  *shift = 3;
  return 1;
}

int
isNumber (int *number, const wchar_t *characters, int length) {
  if (length > 0) {
    char string[length + 1];
    string[length] = 0;

    {
      int index;

      for (index=0; index<length; index+=1) {
        wchar_t wc = characters[index];
        if (!iswLatin1(wc)) return 0;
        string[index] = wc;
      }
    }

    {
      char *end;
      long value = strtol(string, &end, 0);

      if (!*end) {
        *number = value;
        return 1;
      }
    }
  }

  return 0;
}

static VariableNestingLevel *baseDataVariables = NULL;
static VariableNestingLevel *currentDataVariables = NULL;

static VariableNestingLevel *
getBaseDataVariables (void) {
  if (baseDataVariables) {
    releaseVariableNestingLevel(currentDataVariables);
    deleteVariables(baseDataVariables);
  } else {
    VariableNestingLevel *globalVariables = getGlobalVariables(1);
    if (!globalVariables) return NULL;

    VariableNestingLevel *baseVariables = newVariableNestingLevel(globalVariables, "base");
    if (!baseVariables) return NULL;

    baseDataVariables = claimVariableNestingLevel(baseVariables);
  }

  currentDataVariables = claimVariableNestingLevel(baseDataVariables);
  return baseDataVariables;
}

int
setBaseDataVariables (const VariableInitializer *initializers) {
  VariableNestingLevel *variables = getBaseDataVariables();
  if (!variables) return 0;
  return setStringVariables(variables, initializers);
}

int
setTableDataVariables (const char *tableExtension, const char *subtableExtension) {
  const VariableInitializer initializers[] = {
    { .name = "tableExtension", .value = tableExtension },
    { .name = "subtableExtension", .value = subtableExtension },
    { .name = NULL }
  };

  return setBaseDataVariables(initializers);
}

static int
pushDataVariableNestingLevel (void) {
  VariableNestingLevel *variables = newVariableNestingLevel(currentDataVariables, NULL);
  if (!variables) return 0;

  releaseVariableNestingLevel(currentDataVariables);
  currentDataVariables = claimVariableNestingLevel(variables);

  return 1;
}

int
findDataOperand (DataFile *file, const char *description) {
  file->start = file->end;

  while (iswspace(file->start[0])) file->start += 1;
  if (*(file->end = file->start)) return 1;
  if (description) reportDataError(file, "%s not specified", description);
  return 0;
}

int
getDataCharacter (DataFile *file, wchar_t *character) {
  if (!*file->end) return 0;
  *character = *file->end++;
  return 1;
}

int
ungetDataCharacters (DataFile *file, unsigned int count) {
  unsigned int maximum = file->end - file->start;

  if (count > maximum) {
    reportDataError(file, "unget character count out of range: %u > %u",
                    count, maximum);
    return 0;
  }

  file->end -= count;
  return 1;
}

void
getTextRemaining (DataFile *file, DataOperand *text) {
  file->end = file->start + wcslen(file->start);
  text->characters = file->start;
  text->length = file->end - file->start;
}

int
getTextOperand (DataFile *file, DataOperand *text, const char *description) {
  if (!findDataOperand(file, description)) return 0;
  getTextRemaining(file, text);

  while (text->length) {
    unsigned int newLength = text->length - 1;
    if (!iswspace(text->characters[newLength])) break;
    text->length = newLength;
  }

  return 1;
}

int
getDataOperand (DataFile *file, DataOperand *operand, const char *description) {
  if (!findDataOperand(file, description)) return 0;

  do {
    file->end += 1;
  } while (file->end[0] && !iswspace(file->end[0]));

  operand->characters = file->start;
  operand->length = file->end - file->start;
  return 1;
}

int
parseDataString (DataFile *file, DataString *string, const wchar_t *characters, int length, int noUnicode) {
  int index = 0;

  string->length = 0;

  while (index < length) {
    wchar_t character = characters[index];
    DataOperand substitution = {
      .characters = &character,
      .length = 1
    };

    if (character == WC_C('\\')) {
      int start = index;
      const char *problem = strtext("invalid escape sequence");
      int ok = 0;

      if (++index < length) {
        switch ((character = characters[index])) {
          case WC_C('#'):
          case WC_C('\\'):
            ok = 1;
            break;

          case WC_C('b'):
            character = WC_C('\b');
            ok = 1;
            break;

          case WC_C('f'):
            character = WC_C('\f');
            ok = 1;
            break;

          case WC_C('n'):
            character = WC_C('\n');
            ok = 1;
            break;

          case WC_C('r'):
            character = WC_C('\r');
            ok = 1;
            break;

          case WC_C('R'):
            character = UNICODE_REPLACEMENT_CHARACTER;
            ok = 1;
            break;

          case WC_C('s'):
            character = WC_C(' ');
            ok = 1;
            break;

          case WC_C('t'):
            character = WC_C('\t');
            ok = 1;
            break;

          case WC_C('v'):
            character = WC_C('\v');
            ok = 1;
            break;

          {
            uint32_t result;
            int count;
            int (*isDigit) (wchar_t character, int *value, int *shift);

          case WC_C('o'):
            count = 3;
            isDigit = isOctalDigit;
            goto doNumber;

          case WC_C('U'):
            if (noUnicode) break;
            count = 8;
            goto doHexadecimal;

          case WC_C('u'):
            if (noUnicode) break;
            count = 4;
            goto doHexadecimal;

          case WC_C('X'):
          case WC_C('x'):
            count = 2;
            goto doHexadecimal;

          doHexadecimal:
            isDigit = isHexadecimalDigit;
            goto doNumber;

          doNumber:
            result = 0;

            while (++index < length) {
              {
                int value;
                int shift;

                if (!isDigit(characters[index], &value, &shift)) break;
                result = (result << shift) | value;
              }

              if (!--count) {
                if (result > WCHAR_MAX) {
                  problem = NULL;
                } else {
                  character = result;
                  ok = 1;
                }

                break;
              }
            }

            break;
          }

          case WC_C('{'): {
            const wchar_t *first = &characters[++index];
            const wchar_t *end = wmemchr(first, WC_C('}'), length-index);

            if (end) {
              int count = end - first;
              index += count;

              const Variable *variable = findReadableVariable(currentDataVariables, first, count);

              if (variable) {
                getVariableValue(variable, &substitution.characters, &substitution.length);
                ok = 1;
              }
            } else {
              index = length - 1;
            }

            break;
          }

          case WC_C('<'): {
            const wchar_t *first = &characters[++index];
            const wchar_t *end = wmemchr(first, WC_C('>'), length-index);

            if (noUnicode) break;

            if (end) {
              int count = end - first;
              index += count;

              {
                char name[count+1];

                {
                  unsigned int i;

                  for (i=0; i<count; i+=1) {
                    wchar_t wc = first[i];

                    if (wc == WC_C('_')) wc = WC_C(' ');
                    if (!iswLatin1(wc)) break;
                    name[i] = wc;
                  }

                  if (i < count) break;
                  name[i] = 0;
                }

                if (getCharacterByName(&character, name)) ok = 1;
              }
            } else {
              index = length - 1;
            }

            break;
          }
        }
      }

      if (!ok) {
        if (index < length) index += 1;

        if (problem) {
          reportDataError(file, "%s: %.*" PRIws,
                          gettext(problem),
                          index-start, &characters[start]);
        }

        return 0;
      }
    }
    index += 1;

    {
      unsigned int newLength = string->length + substitution.length;

      /* there needs to be room for a trailing NUL */
      if (newLength >= ARRAY_COUNT(string->characters)) {
        reportDataError(file, "string operand too long");
        return 0;
      }

      wmemcpy(&string->characters[string->length], substitution.characters, substitution.length);
      string->length = newLength;
    }
  }
  string->characters[string->length] = 0;

  return 1;
}

int
getDataString (DataFile *file, DataString *string, int noUnicode, const char *description) {
  DataOperand operand;

  if (getDataOperand(file, &operand, description))
    if (parseDataString(file, string, operand.characters, operand.length, noUnicode))
      return 1;

  return 0;
}

int
writeHexadecimalCharacter (FILE *stream, wchar_t character) {
  uint32_t value = character;

  if (value < 0X100) {
    return fprintf(stream, "\\x%02" PRIX32, value) != EOF;
  } else if (value < 0X10000) {
    return fprintf(stream, "\\u%04" PRIX32, value) != EOF;
  } else {
    return fprintf(stream, "\\U%08" PRIX32, value) != EOF;
  }
}

int
writeEscapedCharacter (FILE *stream, wchar_t character) {
  {
    static const char escapes[] = {
      [' ']  = 's',
      ['\\'] = '\\'
    };

    if (character < ARRAY_COUNT(escapes)) {
      char escape = escapes[character];

      if (escape) {
        return fprintf(stream, "\\%c", escape) != EOF;
      }
    }
  }

  if (iswspace(character) || iswcntrl(character)) return writeHexadecimalCharacter(stream, character);
  return writeUtf8Character(stream, character);
}

int
writeEscapedCharacters (FILE *stream, const wchar_t *characters, size_t count) {
  const wchar_t *end = characters + count;

  while (characters < end)
    if (!writeEscapedCharacter(stream, *characters++))
      return 0;

  return 1;
}

static int
parseDotOperand (DataFile *file, int *index, const wchar_t *characters, int length) {
  if (length == 1)
    if (brlDotNumberToIndex(characters[0], index))
      return 1;

  reportDataError(file, "invalid braille dot number: %.*" PRIws, length, characters);
  return 0;
}

int
getDotOperand (DataFile *file, int *index) {
  DataOperand number;

  if (getDataOperand(file, &number, "dot number"))
    if (parseDotOperand(file, index, number.characters, number.length))
      return 1;

  return 0;
}

int
parseCellsOperand (DataFile *file, ByteOperand *cells, const wchar_t *characters, int length) {
  unsigned char cell = 0;
  int start = 0;
  int index;

  cells->length = 0;

  for (index=0; index<length; index+=1) {
    int started = index != start;
    wchar_t character = characters[index];

    switch (character) {
      {
        int dot;

      case WC_C('1'):
        dot = BRL_DOT_1;
        goto doDot;

      case WC_C('2'):
        dot = BRL_DOT_2;
        goto doDot;

      case WC_C('3'):
        dot = BRL_DOT_3;
        goto doDot;

      case WC_C('4'):
        dot = BRL_DOT_4;
        goto doDot;

      case WC_C('5'):
        dot = BRL_DOT_5;
        goto doDot;

      case WC_C('6'):
        dot = BRL_DOT_6;
        goto doDot;

      case WC_C('7'):
        dot = BRL_DOT_7;
        goto doDot;

      case WC_C('8'):
        dot = BRL_DOT_8;
        goto doDot;

      doDot:
        if (started && !cell) goto invalid;

        if (cell & dot) {
          reportDataError(file, "dot specified more than once: %.1" PRIws, &character);
          return 0;
        }

        cell |= dot;
        break;
      }

      case CELLS_OPERAND_SPACE:
        if (started) goto invalid;
        break;

      case CELLS_OPERAND_DELIMITER:
        if (!started) {
          reportDataError(file, "missing cell specification: %.*" PRIws,
                          length-index, &characters[index]);
          return 0;
        }

        cells->bytes[cells->length++] = cell;

        if (cells->length == ARRAY_COUNT(cells->bytes)) {
          reportDataError(file, "cells operand too long");
          return 0;
        }

        cell = 0;
        start = index + 1;
        break;

      default:
      invalid:
        reportDataError(file, "invalid dot number: %.1" PRIws, &character);
        return 0;
    }
  }

  if (index == start) {
    reportDataError(file, "missing cell specification");
    return 0;
  }

  cells->bytes[cells->length++] = cell;		/*last cell */
  return 1;
}

int
getCellsOperand (DataFile *file, ByteOperand *cells, const char *description) {
  DataOperand operand;

  if (getDataOperand(file, &operand, description))
    if (parseCellsOperand(file, cells, operand.characters, operand.length))
      return 1;

  return 0;
}

int
writeDots (FILE *stream, unsigned char cell) {
  unsigned int dot;

  for (dot=1; dot<=BRL_DOT_COUNT; dot+=1) {
    if (cell & BRL_DOT(dot)) {
      if (fprintf(stream, "%u", dot) == EOF) return 0;
    }
  }

  return 1;
}

int
writeDotsCell (FILE *stream, unsigned char cell) {
  if (!cell) return fputc('0', stream) != EOF;
  return writeDots(stream, cell);
}

int
writeDotsCells (FILE *stream, const unsigned char *cells, size_t count) {
  const unsigned char *cell = cells;
  const unsigned char *end = cells + count;

  while (cell < end) {
    if (cell != cells)
      if (fputc('-', stream) == EOF)
        return 0;

    if (!writeDotsCell(stream, *cell++)) return 0;
  }

  return 1;
}

int
writeUtf8Cell (FILE *stream, unsigned char cell) {
  return writeUtf8Character(stream, (UNICODE_BRAILLE_ROW | cell));
}

int
writeUtf8Cells (FILE *stream, const unsigned char *cells, size_t count) {
  const unsigned char *end = cells + count;

  while (cells < end)
    if (!writeUtf8Cell(stream, *cells++))
      return 0;

  return 1;
}

typedef struct {
  unsigned canInclude:1;
  unsigned isIncluding:1;
  unsigned inElse:1;
} DataCondition;

static inline int
shallInclude (const DataCondition *condition) {
  return condition->canInclude && condition->isIncluding;
}

static void
deallocateDataCondition (void *item, void *data UNUSED) {
  DataCondition *condition = item;

  free(condition);
}

static Element *
getInnermostDataCondition (DataFile *file) {
  return getStackHead(file->conditions);
}

static Element *
getCurrentDataCondition (DataFile *file) {
  {
    Element *element = getInnermostDataCondition(file);

    if (element) return element;
  }

  reportDataError(file, "no outstanding condition");
  return NULL;
}

static int
removeDataCondition (DataFile *file, Element *element, int identifier) {
  if (!(element && (identifier == getElementIdentifier(element)))) return 0;
  deleteElement(element);
  return 1;
}

static Element *
pushDataCondition (
  DataFile *file, const DataString *name,
  DataConditionTester *testCondition, int negateCondition
) {
  DataCondition *condition;

  if ((condition = malloc(sizeof(*condition)))) {
    memset(condition, 0, sizeof(*condition));
    condition->inElse = 0;

    {
      const DataOperand identifier = {
        .characters = name->characters,
        .length = name->length
      };

      condition->isIncluding = testCondition(file, &identifier, file->parameters->data);
      if (negateCondition) condition->isIncluding = !condition->isIncluding;
    }

    {
      Element *element = getInnermostDataCondition(file);

      if (element) {
        const DataCondition *parent = getElementItem(element);

        condition->canInclude = shallInclude(parent);
      } else {
        condition->canInclude = 1;
      }
    }

    {
      Element *element = enqueueItem(file->conditions, condition);

      if (element) return element;
    }

    free(condition);
  } else {
    logMallocError();
  }

  return NULL;
}

static int
testDataCondition (DataFile *file) {
  Element *element = getInnermostDataCondition(file);

  if (element) {
    const DataCondition *condition = getElementItem(element);

    if (!shallInclude(condition)) return 0;
  }

  return 1;
}

static int
compareDataDirectiveNames (const wchar_t *name1, const wchar_t *name2) {
  return compareKeywords(name1, name2);
}

static int
sortDataDirectivesByName (const void *element1, const void *element2) {
  const DataDirective *const *directive1 = element1;
  const DataDirective *const *directive2 = element2;

  return compareDataDirectiveNames((*directive1)->name, (*directive2)->name);
}

static int
searchDataDirectiveByName (const void *target, const void *element) {
  const wchar_t *name = target;
  const DataDirective *const *directive = element;

  return compareDataDirectiveNames(name, (*directive)->name);
}

static const DataDirective *
findDataDirectiveByName (const DataDirectives *directives, const wchar_t *name) {
  DataDirective **directive = bsearch(
    name, directives->sorted.table, directives->sorted.count,
    sizeof(*directives->sorted.table), searchDataDirectiveByName
  );

  return directive? *directive: NULL;
}

static int
prepareDataDirectives (DataDirectives *directives) {
  if (!directives->sorted.table) {
    static const DataDirective unnamed = {
      .name = NULL,
      .processor = NULL
    };

    directives->unnamed = &unnamed;
    directives->sorted.count = 0;

    if (!(directives->sorted.table = malloc(ARRAY_SIZE(directives->sorted.table, directives->unsorted.count)))) {
      logMallocError();
      return 0;
    }

    {
      const DataDirective *directive = directives->unsorted.table;
      const DataDirective *end = directive + directives->unsorted.count;

      while (directive < end) {
        if (directive->name) {
          directives->sorted.table[directives->sorted.count++] = directive;
        } else {
          directives->unnamed = directive;
        }

        directive += 1;
      }
    }

    qsort(directives->sorted.table, directives->sorted.count,
          sizeof(*directives->sorted.table), sortDataDirectivesByName);
  }

  return 1;
}

int
processDirectiveOperand (DataFile *file, DataDirectives *directives, const char *description, void *data) {
  DataOperand name;

  if (getDataOperand(file, &name, description)) {
    const DataDirective *directive;

    if (!prepareDataDirectives(directives)) return 0;

    {
      wchar_t string[name.length + 1];

      wmemcpy(string, name.characters, name.length);
      string[name.length] = 0;

      if (!(directive = findDataDirectiveByName(directives, string))) {
        directive = directives->unnamed;
        ungetDataCharacters(file, name.length);
      }
    }

    if (!(directive->unconditional || testDataCondition(file))) return 1;
    if (directive->processor) return directive->processor(file, data);

    reportDataError(file, "unknown %s: %.*" PRIws,
                    description, name.length, name.characters);
  }

  return 1;
}

static int
processDataOperands (DataFile *file) {
  return file->parameters->processOperands(file, file->parameters->data);
}

static int
processDataCharacters (DataFile *file, const wchar_t *line) {
  file->end = file->start = line;

  if (!(file->parameters->options & DFO_NO_COMMENTS)) {
    if (!findDataOperand(file, NULL)) return 1;
    if (file->start[0] == WC_C('#')) return 1;
  }

  return processDataOperands(file);
}

static int
processConditionSubdirective (DataFile *file, Element *element) {
  int identifier = getElementIdentifier(element);

  if (findDataOperand(file, NULL)) {
    int result = processDataOperands(file);
    removeDataCondition(file, element, identifier);
    return result;
  }

  return 1;
}

int
processConditionOperands (
  DataFile *file,
  DataConditionTester *testCondition, int negateCondition,
  const char *description, void *data
) {
  DataString name;

  if (getDataString(file, &name, 1, description)) {
    Element *element = pushDataCondition(file, &name, testCondition, negateCondition);

    if (!element) return 0;
    if (!processConditionSubdirective(file, element)) return 0;
  }

  return 1;
}

static DATA_CONDITION_TESTER(testVariableDefined) {
  return !!findReadableVariable(currentDataVariables, identifier->characters, identifier->length);
}

static int
processVariableTestOperands (DataFile *file, int not, void *data) {
  return processConditionOperands(file, testVariableDefined, not, "variable name", data);
}

DATA_OPERANDS_PROCESSOR(processIfVarOperands) {
  return processVariableTestOperands(file, 0, data);
}

DATA_OPERANDS_PROCESSOR(processIfNotVarOperands) {
  return processVariableTestOperands(file, 1, data);
}

DATA_OPERANDS_PROCESSOR(processBeginVariablesOperands) {
  return pushDataVariableNestingLevel();
}

DATA_OPERANDS_PROCESSOR(processEndVariablesOperands) {
  if (currentDataVariables == file->variables) {
    reportDataError(file, "no nested variables");
  } else {
    currentDataVariables = removeVariableNestingLevel(currentDataVariables);
  }

  return 1;
}

DATA_OPERANDS_PROCESSOR(processListVariablesOperands) {
  listVariables(currentDataVariables);
  return 1;
}

static int
processVariableAssignmentOperands (DataFile *file, int ifNotSet, void *data) {
  DataOperand name;

  if (getDataOperand(file, &name, "variable name")) {
    DataString value;

    if (!getDataString(file, &value, 0, NULL)) {
      value.length = 0;
    }

    if (ifNotSet) {
      const Variable *variable = findReadableVariable(currentDataVariables, name.characters, name.length);

      if (variable) return 1;
    }

    {
      Variable *variable = findWritableVariable(currentDataVariables, name.characters, name.length);

      if (variable) {
        if (setVariable(variable, value.characters, value.length)) return 1;
      }
    }
  }

  return 1;
}

DATA_OPERANDS_PROCESSOR(processAssignDefaultOperands) {
  return processVariableAssignmentOperands(file, 1, data);
}

DATA_OPERANDS_PROCESSOR(processAssignOperands) {
  return processVariableAssignmentOperands(file, 0, data);
}

DATA_OPERANDS_PROCESSOR(processElseOperands) {
  Element *element = getCurrentDataCondition(file);

  if (element) {
    DataCondition *condition = getElementItem(element);

    if (condition->inElse) {
      reportDataError(file, "already in else");
    } else {
      condition->inElse = 1;
      condition->isIncluding = !condition->isIncluding;
      if (!processConditionSubdirective(file, element)) return 0;
    }
  }

  return 1;
}

DATA_OPERANDS_PROCESSOR(processEndIfOperands) {
  Element *element = getCurrentDataCondition(file);

  if (element) {
    removeDataCondition(file, element, getElementIdentifier(element));
  }

  return 1;
}

static int
isDataFileIncluded (DataFile *file, const char *path) {
  struct stat info;

  if (stat(path, &info) != -1) {
    while (file) {
      if ((file->identity.device == info.st_dev) && (file->identity.file == info.st_ino)) return 1;
      file = file->includer;
    }
  }

  return 0;
}

static FILE *
openIncludedDataFile (DataFile *includer, const char *path, const char *mode, int optional) {
  const char *const *overrideDirectories = getAllOverrideDirectories();
  const char *overrideDirectory = NULL;
  char *overridePath = NULL;

  int writable = (*mode == 'w') || (*mode == 'a');
  const char *name = locatePathName(path);
  FILE *file;

  if (overrideDirectories) {
    const char *const *directory = overrideDirectories;

    while (*directory) {
      if (**directory) {
        char *path = makePath(*directory, name);

        if (path) {
          if (!isDataFileIncluded(includer, path)) {
            if (testFilePath(path)) {
              file = openFile(path, mode, optional);
              overrideDirectory = *directory;
              overridePath = path;
              goto done;
            }
          }

          free(path);
        }
      }

      directory += 1;
    }
  }

  if (isDataFileIncluded(includer, path)) {
    logMessage(LOG_WARNING, "data file include loop: %s", path);
    file = NULL;
    errno = ENOENT;
  } else if (!(file = openFile(path, mode, optional))) {
    if (writable) {
      if (errno == ENOENT) {
        char *directory = getPathDirectory(path);

        if (directory) {
          int exists = ensureDirectory(directory, 0);
          free(directory);

          if (exists) {
            file = openFile(path, mode, optional);
            goto done;
          }
        }
      }

      if ((errno == EACCES) || (errno == EROFS)) {
        if ((overrideDirectory = getPrimaryOverrideDirectory())) {
          if ((overridePath = makePath(overrideDirectory, name))) {
            if (ensureDirectory(overrideDirectory, 0)) {
              file = openFile(overridePath, mode, optional);
              goto done;
            }
          }
        }
      }
    }
  }

done:
  if (overridePath) free(overridePath);
  return file;
}

FILE *
openDataFile (const char *path, const char *mode, int optional) {
  return openIncludedDataFile(NULL, path, mode, optional);
}

int
includeDataFile (DataFile *file, const wchar_t *name, int length) {
  int ok = 0;

  const char *prefixAddress = file->name;
  size_t prefixLength = 0;

  size_t suffixLength;
  char *suffixAddress = getUtf8FromWchars(name, length, &suffixLength);

  if (suffixAddress) {
    if (!isAbsolutePath(suffixAddress)) {
      const char *prefixEnd = strrchr(prefixAddress, '/');
      if (prefixEnd) prefixLength = prefixEnd - prefixAddress + 1;
    }

    {
      char path[prefixLength + suffixLength + 1];
      FILE *stream;

      snprintf(path, sizeof(path), "%.*s%.*s",
               (int)prefixLength, prefixAddress,
               (int)suffixLength, suffixAddress);

      if ((stream = openIncludedDataFile(file, path, "r", 0))) {
        if (processDataStream(file, stream, path, file->parameters)) ok = 1;
        fclose(stream);
      }
    }

    free(suffixAddress);
  } else {
    logMallocError();
  }

  return ok;
}

DATA_OPERANDS_PROCESSOR(processIncludeOperands) {
  DataString path;

  if (getDataString(file, &path, 0, "include file path"))
    if (!includeDataFile(file, path.characters, path.length))
      return 0;

  return 1;
}

static int
processDataLine (const LineHandlerParameters *parameters) {
  DataFile *file = parameters->data;
  file->line += 1;

  const char *byte = parameters->line.text;
  size_t size = parameters->line.length + 1;
  wchar_t characters[size];
  wchar_t *character = characters;

  convertUtf8ToWchars(&byte, &character, size);
  character = characters;

  if (*byte) {
    unsigned int offset = byte - parameters->line.text;
    reportDataError(file, "illegal UTF-8 character at offset %u", offset);
    return 1;
  }

  if (file->line == 1) {
    if (*character == UNICODE_BYTE_ORDER_MARK) {
      character += 1;
    }
  }

  return processDataCharacters(file, character);
}

int
processDataStream (
  DataFile *includer,
  FILE *stream, const char *name,
  const DataFileParameters *parameters
) {
  int ok = 0;

  if (parameters->logFileName) {
    parameters->logFileName(name, parameters->data);
  } else {
    logMessage(LOG_DEBUG, "including data file: %s", name);
  }

  DataFile file = {
    .name = name,
    .parameters = parameters,
    .includer = includer,
    .line = 0,
  };

  {
    struct stat info;

    if (fstat(fileno(stream), &info) != -1) {
      file.identity.device = info.st_dev;
      file.identity.file = info.st_ino;
    }
  }

  VariableNestingLevel *oldVariables = currentDataVariables;

  if ((file.variables = newVariableNestingLevel(oldVariables, name))) {
    currentDataVariables = claimVariableNestingLevel(file.variables);

    if ((file.conditions = newQueue(deallocateDataCondition, NULL))) {
      if (processLines(stream, processDataLine, &file)) ok = 1;

      if (getInnermostDataCondition(&file)) {
        reportDataError(&file, "outstanding condition at end of file");
      }

      deallocateQueue(file.conditions);
    }

    releaseVariableNestingLevel(currentDataVariables);
    currentDataVariables = oldVariables;
  }

  return ok;
}

int
processDataFile (const char *name, const DataFileParameters *parameters) {
  int ok = 0;
  FILE *stream;

  if ((stream = openDataFile(name, "r", 0))) {
    if (processDataStream(NULL, stream, name, parameters)) ok = 1;
    fclose(stream);
  }

  return ok;
}
