]> git.donarmstrong.com Git - lilypond.git/blob - lily/includable-lexer.cc
release: 1.0.1
[lilypond.git] / lily / includable-lexer.cc
1 /*
2   includable-lexer.cc -- implement Includable_lexer
3
4   source file of the LilyPond music typesetter
5
6   (c)  1997--1998 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include <strstream.h>
10
11 #include "includable-lexer.hh"
12 #include "source-file.hh"
13 #include "source.hh"
14 #include "debug.hh"
15
16 #ifndef YY_BUF_SIZE
17 #define YY_BUF_SIZE 16384
18 #endif
19
20 #ifndef YY_START
21 #define YY_START ((yy_start - 1) / 2)
22 #define YYSTATE YY_START
23 #endif
24
25 Includable_lexer::Includable_lexer ()
26 {
27   yy_current_buffer = 0;
28 }
29
30 /** set the  new input to s, remember old file.
31 */
32 void
33 Includable_lexer::new_input (String s, Sources  * global_sources)
34 {
35   Source_file * sl = global_sources->get_file_l (s);
36   if (!sl)
37     {
38       String msg = _f ("can't find file: `%s\'", s);
39       LexerError (msg.ch_C ());
40       return;
41     }
42   filename_str_arr_.push (sl->name_str ());
43
44   char_count_stack_.push (0);
45   if (yy_current_buffer)
46     state_stack_.push (yy_current_buffer);
47   *mlog << "[" << s<<flush;
48   include_stack_.push (sl);
49
50   /*
51     ugh. We'd want to create a buffer from the bytes directly.
52
53     Whoops. The size argument to yy_create_buffer is not the
54     filelength but a BUFFERSIZE. Maybe this is why reading stdin fucks up.
55
56     */
57   yy_switch_to_buffer (yy_create_buffer (sl->istream_l (), YY_BUF_SIZE));
58
59 }
60 void
61 Includable_lexer::new_input (String name, String data, Sources* sources)
62 {
63   Source_file* file = new Source_file (name, data);
64   sources->add (file);
65   filename_str_arr_.push (name);
66
67   char_count_stack_.push (0);
68   if (yy_current_buffer)
69     state_stack_.push (yy_current_buffer);
70   *mlog << "[" << name << flush;
71   include_stack_.push (file);
72
73   yy_switch_to_buffer (yy_create_buffer (file->istream_l (), YY_BUF_SIZE));
74 }
75
76 /** pop the inputstack.  conceptually this is a destructor, but it
77   does not destruct the Source_file that Includable_lexer::new_input creates.  */
78 bool
79 Includable_lexer::close_input ()
80 {
81   include_stack_.pop ();
82   char_count_stack_.pop ();
83   *mlog << "]"<<flush;
84   yy_delete_buffer (yy_current_buffer);
85   yy_current_buffer = 0;
86   if (state_stack_.empty ())
87     {
88       yy_current_buffer = 0;
89       return false;
90     }
91   else
92       {
93         yy_switch_to_buffer (state_stack_.pop ());
94         return true;
95       }
96 }
97
98 char const*
99 Includable_lexer::here_ch_C ()
100 {
101   if (include_stack_.empty ())
102     return 0;
103   return include_stack_.top ()->ch_C () + char_count_stack_.top ();
104 }
105
106 Includable_lexer::~Includable_lexer ()
107 {
108   while (!include_stack_.empty ())
109     {
110       close_input ();
111     }
112 }
113 /**
114   Since we don't create the buffer state from the bytes directly, we
115   don't know about the location of the lexer. Add this as a
116   YY_USER_ACTION */
117 void
118 Includable_lexer::add_lexed_char (int count)
119 {
120   char_count_stack_.top () += count;
121 }
122
123 Source_file*
124 Includable_lexer::source_file_l () const
125 {
126   if (include_stack_.empty ())
127     return 0;
128   else
129     return include_stack_.top ();
130 }