]> git.donarmstrong.com Git - lilypond.git/blob - lily/paper-stream.cc
patch::: 1.3.130.jcn2
[lilypond.git] / lily / paper-stream.cc
1 /*
2   paper-stream.cc -- implement Paper_stream
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  1997--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include <errno.h>
10 #include <sys/stat.h>
11 #include <sys/types.h>
12 #include <fstream.h>
13
14 #include "main.hh"
15 #include "paper-stream.hh"
16 #include "file-path.hh"
17 #include "debug.hh"
18
19 const int MAXLINELEN = 200;
20
21 ostream *
22 open_file_stream (String filename)
23 {
24   ostream *os;
25   if (!filename.empty_b () && (filename != "-"))
26     {
27       Path p = split_path (filename);
28       if (!p.dir.empty_b ())
29         if (mkdir (p.dir.ch_C (), 0777) == -1 && errno != EEXIST)
30           error (_f ("can't create directory: `%s'", p.dir));
31       os = new ofstream (filename.ch_C ());
32     }
33   else
34     os = new ostream (cout._strbuf);
35   if (!*os)
36     error (_f ("can't open file: `%s'", filename));
37   return os;
38 }
39
40 void
41 close_file_stream (ostream *os)
42 {
43   *os << flush;
44   if (!*os)
45     {
46       warning (_ ("Error syncing file (disk full?)"));
47       exit_status_i_ = 1;
48     }
49   delete os;
50 }  
51
52 Paper_stream::Paper_stream (String filename)
53 {
54   os_ = open_file_stream (filename);
55   nest_level = 0;
56   line_len_i_ = 0;
57   outputting_comment_b_=false;
58 }
59
60 Paper_stream::~Paper_stream ()
61 {
62   close_file_stream (os_);
63   assert (nest_level == 0);
64 }
65
66 // print string. don't forget indent.
67 Paper_stream&
68 Paper_stream::operator << (String s)
69 {
70   for (char const *cp = s.ch_C (); *cp; cp++)
71     {
72       if (outputting_comment_b_)
73         {
74           *os_ << *cp;
75           if (*cp == '\n')
76             {
77               outputting_comment_b_=false;
78               line_len_i_ =0;
79             }
80           continue;
81         }
82       line_len_i_ ++;
83       switch (*cp)
84         {
85         case '%':
86           outputting_comment_b_ = true;
87           *os_ << *cp;
88           break;
89         case '{':
90           nest_level++;
91           *os_ << *cp;
92           break;
93         case '}':
94           nest_level--;
95           *os_ << *cp;
96
97           if (nest_level < 0)
98             {
99               delete os_;       // we want to see the remains.
100               assert (nest_level>=0);
101             }
102
103           /* don't break line if not nested; very ugly for ps */
104           if (nest_level == 0)
105             break;
106
107           *os_ << '%';
108           break_line ();
109           break;
110         case '\n':
111           break_line ();
112           break;
113         case ' ':
114           *os_ <<  ' ';
115           if (line_len_i_ > MAXLINELEN)
116             break_line ();
117
118           break;
119         default:
120           *os_ << *cp;
121           break;
122         }
123     }
124   //urg, for debugging only!!
125   *os_ << flush;
126   return *this;
127 }
128
129 void
130 Paper_stream::break_line ()
131 {
132   *os_ << '\n';
133   *os_ << to_str (' ', nest_level);
134   outputting_comment_b_ = false;
135   line_len_i_ = 0;
136 }
137