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