NOUSERMACRO(nPending setPending)

manpagesection(17. THE CLASS INPUT)

    Flc() generates a file tt(Scannerbase.h) defining the scanner class's base
class, by default named tt(ScannerBase) (which is the name used in this
man-page). The base class tt(ScannerBase) contains a nested class tt(Input)
having this interface:
        verb(
class Input
{
    public:
        Input();
        Input(std::istream *iStream, size_t lineNr = 1);
        size_t get();
        size_t lineNr() const;          
        size_t nPending() const;          
        void setPending(size_t nPending);          
        void reRead(size_t ch);
        void reRead(std::string const &str, size_t fmIdx);
        void close();
};
        )        
    The members of this class are all required and offer an implementation
level between the operations of tt(ScannerBase) and flc()'s actual input
file that's being processed.

    By default, flc() provides the implementation of all of tt(Input)'s
required members. Therefore, in most situations this section of this man-page
can safely be ignored.

    However, users may define and extend their own tt(Input) class, providing
flc()'s base class with their own tt(Input) class. To do so flc()'s rules file
must contain the following two directives:
        verb(
       %input-inline         = "inline"
       %input-interface      = "interface"
       %input-implementation = "sourcefile"
        )
    Here, `tt(inline)' is the name of a file containing the inline
implementations of the class tt(Input)'s member functions; `tt(interface)' is
the name of a file containing the class tt(Input)'s interface, while the
non-inline implementations of the class tt(Input) is provided in
`tt(sourcefile)'. 

By default the class tt(Input) is defined in tt(ScannerBase's) private
section. When providing your own implementation the class tt(Input) is
declared and defined in tt(ScannerBase's) protected section so its members can
also be accessed by the derived class tt(Scanner). Moreover, in that situation
the (otherwise private) tt(ScannerBase) data member tt(Input *d_input) is also
declared in tt(ScannerBase's) protected section. 

In the default implementation of the class tt(Input) short, one-line
implementations of some of its members are defined tt(inline) below the
interface of the class tt(ScannerBase) in the generated tt(ScannerBase.h)
file. When providing your own implementation these members can also be defined
tt(inline) by providing their implementations in a file (e.g.,
tt("inputinline")) which is specified by the tt(%input-inline) directive.

When using the tt(%input-inline) directive make sure that the defined members
are specified as inline tt(Input::) class members inside the class
tt(ScannerBase) (using the actually used scanner class name). E.g., if the
default scanner class is used (see also the tt(%class-name) directive), then
the inline implementation of the member tt(Input::lineNr) could be
        verb(
    inline size_t ScannerBase::Line::lineNr() const
    {
        return d_lineNr;
    }
        )
If, when using your self-defined tt(Input) class, the default implementations
of those tt(inline) members are not modified then use the default
implementations by simply not specifying the tt(%input-inline) directive.

Avoid using standard extensions for the files specified at the
tt(input-implementation, input-inline,) and tt(input-interface) directives to
prevent confusing the compiler when using program maintenance utilities: the
interface specifies the interface of the class tt(Input), like the one shown
aboove, and that interface is then inserted in tt(ScannerBase's) class as a
nested class. Putting these file(s) in, e.g., a subdirectory tt(input) of
the scanner's directory, and then specifying, e.g.,
            verb(
       %input-interface      = "input/interface"
            ) nicely separates the interface and implementation of the
scanner-class from the user-defined input class.
    
The file tt(sourcefile) specified at the tt(%input-implementation) directive
contains the standard (non-inline) implementations of members of the
user-define tt(Input) class. 

All member functions of the self-defined class tt(Input) must be defined 
within the class tt(ScannerBase's) class scope. E.g., an implementation
of the member tt(Input::reRead(size_t ch)) would use the following mold:
         verb(
       void ScannerBase::Input::reRead(size_t ch)
       {
           .... your implementation here
       }
        )        

When your user-defined input class requires headers, which are not already
provided by the class tt(ScannerBase) (see the top lines of a generated
tt(scannerbase.h) file for an overview of the already included header files)
then provide the required tt(#include) specifications in the file specified at
the tt(%baseclass-preinclude) directive (or corresponding option). The
generated scanner itself is self-supporting and doesn't need additional
headers. 

As an advice: when implementing your own tt(Input) class start out with the
default class declaration and implementation as found in tt(ScannerBase.h) and
tt(lex.cc), and modify that default class to the class you need. Note that the
interface of your class tt(Input) must em(at least) offer the same members and
constructors of the default provided class tt(input), but it may define
additional data members and/or member functions if required by your
implementation (see also the following two section for descriptions of the
class tt(Input's) constructors and required members.

When the lexical scanner generated by flc() switches streams using the
tt(//include) directive (see also section bf(2. FILE SWITCHING)) in the
bf(flexc++input)(7) man page), then the input stream that's currently
processed is pushed on an tt(Input) stack maintained by tt(ScannerBase), and
processing continues at the file named at the tt(//include) directive. Once
the latter file has been processed, the previously pushed stream is popped off
the stack, and processing of the popped stream continues. This implies that
tt(Input) objects must be `stack-able'. Its interface must always be 
designed in such a way that it satisfies this requirement.


manpagesection(18. INPUT CONSTRUCTORS)

    itemization(
    itb(Input())
        The default constructor is used by bf(ScannerBase) to prepare the
stack for tt(Input) objects. It must make sure that a default (empty)
tt(Input) object is in a valid state and can be destroyed. It serves no
further purpose. tt(Input) objects, however, must support the default (or
overloaded) assignment operator.
    itb(Input(std::istream *iStream, size_t lineNr = 1))
        This constructor receives a pointer to a dynamically allocated
tt(istream) object. The tt(Input) constructor should preserve this pointer
when the tt(Input) object is pushed on and popped off the stack. A
tt(shared_ptr) probably comes in handy here. The tt(Input) object becomes the
owner of the tt(istream) object, albeit that its destructor is em(not)
supposed to destroy the tt(istream) object. Destruction remains the
responsibility of the tt(ScannerBase) object, which calls the tt(Input::close)
member (see below) when it's time to destroy (close) the stream.

        The new input stream's line counter is set to tt(lineNr), by default
1. 
    )

manpagesection(19. REQUIRED PUBLIC MEMBER FUNCTIONS)

    itemization(
    itb(size_t get())
        returns the next character to be processed by the lexical
scanner. Usually it will be the next character from the tt(istream) passed to
the tt(Input) class at construction time. It is never called by the
tt(ScannerBase) object for tt(Input) objects defined using tt(Input)'s default
constructor. It should return 0x100 once tt(istream)'s end-of-file has been
reached. 
    itb(size_t lineNr() const) 
        should return the (1-based) number of the tt(istream) object passed to
the tt(Input) object. At construction time the tt(istream) has just been
opened and so at that point tt(lineNr) should return 1.
    itb(size_t nPending() const) 
        should return the number of pending characters (i.e., the number of
characters which were passed back to the tt(Input) object using its tt(reRead)
members which were not yet retrieved again by its tt(get) member).
    itb(void setPending(size_t nPending))
        should remove tt(nPending) characters from the head of the tt(Input)
object's pending input queue. The lexical scanner always passes the value
received from tt(nPending) to tt(setPending), without calling tt(get) in
between.
     itb(void reRead(size_t ch))
       if provided with a value smaller than 0x100 tt(ch) should be pushed
back onto the tt(istream), where it becomes the character next to be
returned. Physically the character doesn't have to be pushed back. The default
implementation uses a tt(deque) onto which the character is pushed-front. Only
when this tt(deque) is exhausted characters are retrieved from the tt(Input)
object's tt(istream).
    itb(void reRead(std::string const &str, size_t fmIdx))
        the characters in tt(str) from tt(fmIdx) until the string's final
character are pushed back onto the tt(istream) object so that the string's
first character is retrieved first and the string's last character is
retrieved last. 
    itb(void close()) 
        the tt(istream) object initially passed to the tt(Input) object is
deleted by tt(close), thereby not only freeing the stream's memory, but also
closing the stream if the stream in fact was an tt(ifstream). Note that the
tt(Input)'s destructor should em(not) destroy the tt(Input)'s tt(istream)
object.
    )
    
