]> git.donarmstrong.com Git - lilypond.git/blob - lily/includable-lexer.cc
release: 1.1.13
[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   allow_includes_b_ = true;
29 }
30
31 /** set the  new input to s, remember old file.
32 */
33 void
34 Includable_lexer::new_input (String s, Sources  * global_sources)
35 {
36   if (!allow_includes_b_)
37     {
38       LexerError ("include files are disallowed.");
39       return;
40     }
41   
42   Source_file * sl = global_sources->get_file_l (s);
43   if (!sl)
44     {
45       String msg = _f ("can't find file: `%s\'", s);
46       LexerError (msg.ch_C ());
47       return;
48     }
49   filename_str_arr_.push (sl->name_str ());
50
51   char_count_stack_.push (0);
52   if (yy_current_buffer)
53     state_stack_.push (yy_current_buffer);
54   *mlog << "[" << s<< flush;
55   include_stack_.push (sl);
56
57   /*
58     ugh. We'd want to create a buffer from the bytes directly.
59
60     Whoops. The size argument to yy_create_buffer is not the
61     filelength but a BUFFERSIZE. Maybe this is why reading stdin fucks up.
62
63     */
64   yy_switch_to_buffer (yy_create_buffer (sl->istream_l (), YY_BUF_SIZE));
65
66 }
67 void
68 Includable_lexer::new_input (String name, String data, Sources* sources)
69 {
70   Source_file* file = new Source_file (name, data);
71   sources->add (file);
72   filename_str_arr_.push (name);
73
74   char_count_stack_.push (0);
75   if (yy_current_buffer)
76     state_stack_.push (yy_current_buffer);
77   *mlog << "[" << name << flush;
78   include_stack_.push (file);
79
80   yy_switch_to_buffer (yy_create_buffer (file->istream_l (), YY_BUF_SIZE));
81 }
82
83 /** pop the inputstack.  conceptually this is a destructor, but it
84   does not destruct the Source_file that Includable_lexer::new_input creates.  */
85 bool
86 Includable_lexer::close_input ()
87 {
88   include_stack_.pop ();
89   char_count_stack_.pop ();
90   *mlog << "]"<<flush;
91   yy_delete_buffer (yy_current_buffer);
92   yy_current_buffer = 0;
93   if (state_stack_.empty ())
94     {
95       yy_current_buffer = 0;
96       return false;
97     }
98   else
99       {
100         yy_switch_to_buffer (state_stack_.pop ());
101         return true;
102       }
103 }
104
105 char const*
106 Includable_lexer::here_ch_C ()
107 {
108   if (include_stack_.empty ())
109     return 0;
110   return include_stack_.top ()->ch_C () + char_count_stack_.top ();
111 }
112
113 Includable_lexer::~Includable_lexer ()
114 {
115   while (!include_stack_.empty ())
116     {
117       close_input ();
118     }
119 }
120 /**
121   Since we don't create the buffer state from the bytes directly, we
122   don't know about the location of the lexer. Add this as a
123   YY_USER_ACTION */
124 void
125 Includable_lexer::add_lexed_char (int count)
126 {
127   char_count_stack_.top () += count;
128 }
129
130 Source_file*
131 Includable_lexer::source_file_l () const
132 {
133   if (include_stack_.empty ())
134     return 0;
135   else
136     return include_stack_.top ();
137 }