view src/dil/SourceText.d @ 818:372fa4fbbb1d

Added error messages and applied fixes.
author Aziz K?ksal <aziz.koeksal@gmail.com>
date Thu, 13 Mar 2008 02:21:26 +0100
parents bcb74c9b895c
children
line wrap: on
line source

/++
  Author: Aziz Köksal
  License: GPL3
+/
module dil.SourceText;

import dil.Converter;
import dil.Information;
import dil.Location;
import dil.Messages;
import common;

import tango.io.File;
import tango.io.FilePath;

/// Represents D source code.
///
/// The source text may come from a file or from a memory buffer.
final class SourceText
{
  string filePath; /// The file path to the source text. Mainly used for error messages.
  char[] data; /// The UTF-8, zero-terminated source text.

  /// Constructs a SourceText object.
  /// Params:
  ///   filePath = file path to the source file.
  ///   loadFile = whether to load the file in the constructor.
  this(string filePath, bool loadFile = false)
  {
    this.filePath = filePath;
    loadFile && load();
  }

  /// Constructs a SourceText object.
  /// Params:
  ///   filePath = file path for error messages.
  ///   data = memory buffer.
  this(string filePath, char[] data)
  {
    this(filePath);
    this.data = data;
    addSentinelCharacter();
  }

  /// Loads the source text from a file.
  void load(InfoManager infoMan = null)
  {
    if (!infoMan)
      infoMan = new InfoManager;
    assert(filePath.length);

    scope(failure)
    {
      if (!(new FilePath(this.filePath)).exists())
        infoMan ~= new LexerError(new Location(filePath, 0),
                                  MSG.InexistantFile);
      else
        infoMan ~= new LexerError(new Location(filePath, 0),
                                  MSG.CantReadFile);
      data = "\0";
      return;
    }

    // Read the file.
    auto rawdata = cast(ubyte[]) (new File(filePath)).read();
    // Convert the data.
    auto converter = Converter(filePath, infoMan);
    data = converter.data2UTF8(rawdata);
    addSentinelCharacter();
  }

  /// Adds '\0' to the text (if not already there.)
  private void addSentinelCharacter()
  {
    if (data.length == 0 || data[$-1] != 0)
      data ~= 0;
  }
}