#ifndef LANDMARK_HH #define LANDMARK_HH #include "string.hh" class LandmarkMap; class Landmark { LandmarkMap *_map; unsigned _cp; public: static const unsigned NO_LINE = ~0U; Landmark() : _map(0), _cp(0) { } Landmark(LandmarkMap *map, unsigned cp) : _map(map), _cp(cp) { } explicit Landmark(PermString); LandmarkMap *landmark_map() const { return _map; } unsigned cp() const { return _cp; } operator bool() const { return _map; } bool has_line() const { return line() != ~0U; } inline PermString file() const; inline unsigned line() const; inline unsigned column() const; operator String() const { return string(); } String string() const; Landmark &operator+=(int delta) { _cp += delta; return *this; } Landmark &operator-=(int delta) { _cp -= delta; return *this; } Landmark &operator++() { return *this += 1; } Landmark &operator--() { return *this -= 1; } inline Landmark operator+(int) const; inline Landmark operator+(unsigned) const; inline Landmark operator-(int) const; }; class LandmarkMap { class Landmass; Landmass *_head; Landmass *_tail; public: static const unsigned NO_LINE = Landmark::NO_LINE; static const unsigned LAST_CP = ~0U; LandmarkMap(PermString); ~LandmarkMap(); bool find(unsigned cp, Landmass *&, int &) const; PermString file(unsigned cp) const; unsigned line(unsigned cp) const; unsigned column(unsigned cp) const; void mark_tab(unsigned cp); inline void finish_line(unsigned cp); void change_lines(unsigned cp, PermString, unsigned); }; class LandmarkMap::Landmass { static const int MAX_LINES = 80; unsigned _first_cp; unsigned _last_cp; Landmass *_next; int _n; unsigned _cp[MAX_LINES + 1]; PermString _file[MAX_LINES]; unsigned _line[MAX_LINES]; short _tabs[MAX_LINES]; short *_complex_tabs; short _n_complex_tabs; public: Landmass(unsigned, PermString, unsigned); ~Landmass(); bool full() const { return _n >= MAX_LINES; } unsigned first_cp() const { return _first_cp; } unsigned last_cp() const { return _last_cp; } Landmass *next() const { return _next; } void set_next(Landmass *n) { _next = n; } int lineid(unsigned) const; int last_lineid() const { return _n - 1; } PermString file(int lineid) const { return _file[lineid]; } unsigned line(int lineid) const { return _line[lineid]; } unsigned left_cp(int lineid) const { return _cp[lineid]; } unsigned right_cp(int lineid) const { return _cp[lineid+1]; } void mark_tab(unsigned cp); int column(unsigned cp) const; Landmass *finish_line(unsigned cp); void change_lines(unsigned cp, PermString, unsigned); }; inline void LandmarkMap::finish_line(unsigned cp) { _tail = _tail->finish_line(cp); } inline PermString Landmark::file() const { return (_map ? _map->file(_cp) : PermString()); } inline unsigned Landmark::line() const { return (_map ? _map->line(_cp) : NO_LINE); } inline unsigned Landmark::column() const { return (_map ? _map->column(_cp) : NO_LINE); } inline Landmark Landmark::operator+(int delta) const { return Landmark(_map, _cp + delta); } inline Landmark Landmark::operator+(unsigned delta) const { return Landmark(_map, _cp + delta); } inline Landmark Landmark::operator-(int delta) const { return Landmark(_map, _cp - delta); } #endif