]> git.donarmstrong.com Git - lilypond.git/blob - lily/paper-stream.cc
release: 1.3.148
[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 ostream *
26 open_file_stream (String filename, int mode)
27 {
28   ostream *os;
29   if ((filename == "-"))
30     os = new ostream (cout._strbuf);
31   else
32     {
33       Path p = split_path (filename);
34       if (!p.dir.empty_b ())
35         if (mkdir (p.dir.ch_C (), 0777) == -1 && errno != EEXIST)
36           error (_f ("can't create directory: `%s'", p.dir));
37       os = new ofstream (filename.ch_C (), mode);
38     }
39   if (!*os)
40     error (_f ("can't open file: `%s'", filename));
41   return os;
42 }
43
44 void
45 close_file_stream (ostream *os)
46 {
47   *os << flush;
48   if (!*os)
49     {
50       warning (_ ("Error syncing file (disk full?)"));
51       exit_status_global = 1;
52     }
53   delete os;
54   os = 0;
55 }  
56
57 Paper_stream::Paper_stream (String filename)
58 {
59   os_ = open_file_stream (filename);
60   nest_level = 0;
61   line_len_i_ = 0;
62   outputting_comment_b_=false;
63 }
64
65 Paper_stream::~Paper_stream ()
66 {
67   close_file_stream (os_);
68   assert (nest_level == 0);
69 }
70
71 // print string. don't forget indent.
72 Paper_stream&
73 Paper_stream::operator << (String s)
74 {
75   for (char const *cp = s.ch_C (); *cp; cp++)
76     {
77       if (outputting_comment_b_)
78         {
79           *os_ << *cp;
80           if (*cp == '\n')
81             {
82               outputting_comment_b_=false;
83               line_len_i_ =0;
84             }
85           continue;
86         }
87       line_len_i_ ++;
88       switch (*cp)
89         {
90         case '%':
91           outputting_comment_b_ = true;
92           *os_ << *cp;
93           break;
94         case '{':
95           nest_level++;
96           *os_ << *cp;
97           break;
98         case '}':
99           nest_level--;
100           *os_ << *cp;
101
102           if (nest_level < 0)
103             {
104               delete os_;       // we want to see the remains.
105               assert (nest_level>=0);
106             }
107
108           /* don't break line if not nested; very ugly for ps */
109           if (nest_level == 0)
110             break;
111
112           *os_ << '%';
113           break_line ();
114           break;
115         case '\n':
116           break_line ();
117           break;
118         case ' ':
119           *os_ <<  ' ';
120           if (line_len_i_ > MAXLINELEN)
121             break_line ();
122
123           break;
124         default:
125           *os_ << *cp;
126           break;
127         }
128     }
129   //urg, for debugging only!!
130   *os_ << flush;
131   return *this;
132 }
133
134 void
135 Paper_stream::break_line ()
136 {
137   *os_ << '\n';
138   *os_ << to_str (' ', nest_level);
139   outputting_comment_b_ = false;
140   line_len_i_ = 0;
141 }
142