LEFT | RIGHT |
1 /* | 1 /* |
2 This file is part of LilyPond, the GNU music typesetter. | 2 This file is part of LilyPond, the GNU music typesetter. |
3 | 3 |
4 Copyright (C) 1997--2020 Jan Nieuwenhuizen <janneke@gnu.org> | 4 Copyright (C) 1997--2020 Jan Nieuwenhuizen <janneke@gnu.org> |
5 Han-Wen Nienhuys <hanwen@xs4all.nl> | 5 Han-Wen Nienhuys <hanwen@xs4all.nl> |
6 | 6 |
7 LilyPond is free software: you can redistribute it and/or modify | 7 LilyPond is free software: you can redistribute it and/or modify |
8 it under the terms of the GNU General Public License as published by | 8 it under the terms of the GNU General Public License as published by |
9 the Free Software Foundation, either version 3 of the License, or | 9 the Free Software Foundation, either version 3 of the License, or |
10 (at your option) any later version. | 10 (at your option) any later version. |
(...skipping 27 matching lines...) Expand all Loading... |
38 #include "lily-imports.hh" | 38 #include "lily-imports.hh" |
39 | 39 |
40 using std::istream; | 40 using std::istream; |
41 using std::istringstream; | 41 using std::istringstream; |
42 using std::string; | 42 using std::string; |
43 using std::vector; | 43 using std::vector; |
44 | 44 |
45 void | 45 void |
46 Source_file::load_stdin () | 46 Source_file::load_stdin () |
47 { | 47 { |
48 characters_.clear (); | 48 data_.clear (); |
49 int c; | 49 int c; |
50 while ((c = fgetc (stdin)) != EOF) | 50 while ((c = fgetc (stdin)) != EOF) |
51 characters_.push_back ((char)c); | 51 data_.push_back ((char)c); |
52 } | 52 } |
53 | 53 |
54 /* | 54 /* |
55 return contents of FILENAME. *Not 0-terminated!* | 55 return contents of FILENAME. |
56 */ | 56 */ |
57 vector<char> | 57 string |
58 gulp_file (const string &filename, size_t desired_size) | 58 gulp_file (const string &filename, size_t desired_size) |
59 { | 59 { |
60 /* "b" must ensure to open literally, avoiding text (CR/LF) | 60 /* "b" must ensure to open literally, avoiding text (CR/LF) |
61 conversions. */ | 61 conversions. */ |
62 FILE *f = fopen (filename.c_str (), "rb"); // TODO: RAII | 62 FILE *f = fopen (filename.c_str (), "rb"); // TODO: RAII |
63 if (!f) | 63 if (!f) |
64 { | 64 { |
65 warning (_f ("cannot open file: `%s'", filename.c_str ())); | 65 warning (_f ("cannot open file: `%s'", filename.c_str ())); |
66 return {}; | 66 return {}; |
67 } | 67 } |
68 | 68 |
69 fseek (f, 0, SEEK_END); | 69 fseek (f, 0, SEEK_END); |
70 const auto real_size = ftell (f); | 70 const auto real_size = ftell (f); |
71 if (real_size < 0) | 71 if (real_size < 0) |
72 { | 72 { |
73 warning (_f ("failed to get file size: `%s'", filename.c_str ())); | 73 warning (_f ("failed to get file size: `%s'", filename.c_str ())); |
74 fclose (f); | 74 fclose (f); |
75 return {}; | 75 return {}; |
76 } | 76 } |
77 size_t read_count = real_size; | 77 size_t read_count = real_size; |
78 | 78 |
79 if (desired_size > 0) | 79 if (desired_size > 0) |
80 read_count = std::min (read_count, desired_size); | 80 read_count = std::min (read_count, desired_size); |
81 | 81 |
82 rewind (f); | 82 rewind (f); |
83 | 83 |
84 vector<char> cxx_arr (read_count); | 84 string dest (read_count, 0); |
85 size_t bytes_read = fread (cxx_arr.data (), sizeof (char), read_count, f); | 85 size_t bytes_read = fread (&dest[0], sizeof (char), read_count, f); |
86 if (bytes_read < read_count) | 86 if (bytes_read < read_count) |
87 { | 87 { |
88 warning (_f ("expected to read %zu characters, got %zu", read_count, | 88 warning (_f ("expected to read %zu characters, got %zu", read_count, |
89 bytes_read)); | 89 bytes_read)); |
90 cxx_arr.resize (bytes_read); | 90 dest.resize (bytes_read); |
91 } | 91 } |
92 fclose (f); | 92 fclose (f); |
93 return cxx_arr; | 93 return dest; |
94 } | 94 } |
95 | 95 |
96 void | 96 void |
97 Source_file::init () | 97 Source_file::init () |
98 { | 98 { |
99 istream_ = 0; | 99 istream_ = 0; |
100 line_offset_ = 0; | 100 line_offset_ = 0; |
101 smobify_self (); | 101 smobify_self (); |
102 } | 102 } |
103 | 103 |
104 Source_file::Source_file (const string &filename, const string &data) | 104 Source_file::Source_file (const string &filename, const string &data) |
105 { | 105 { |
106 init (); | 106 init (); |
107 | 107 |
108 name_ = filename; | 108 name_ = filename; |
109 | 109 |
110 characters_.resize (data.length ()); | 110 data_ = data; |
111 copy (data.begin (), data.end (), characters_.begin ()); | 111 |
112 | 112 init_newlines (); |
113 characters_.push_back (0); | 113 } |
114 | 114 |
115 for (vsize i = 0; i < characters_.size (); i++) | 115 void |
116 if (characters_[i] == '\n') | 116 Source_file::init_newlines () |
117 newline_locations_.push_back (&characters_[0] + i); | 117 { |
| 118 for (vsize i = 0; i < data_.size (); i++) |
| 119 if (data_[i] == '\n') |
| 120 newline_locations_.push_back (&data_[0] + i); |
118 } | 121 } |
119 | 122 |
120 Source_file::Source_file (const string &filename_string) | 123 Source_file::Source_file (const string &filename_string) |
121 { | 124 { |
122 init (); | 125 init (); |
123 | 126 |
124 name_ = filename_string; | 127 name_ = filename_string; |
125 | 128 |
126 if (filename_string == "-") | 129 if (filename_string == "-") |
127 load_stdin (); | 130 load_stdin (); |
128 else | 131 else |
129 { | 132 data_ = gulp_file (filename_string, -1); |
130 characters_ = gulp_file (filename_string, -1); | 133 |
131 } | 134 init_newlines (); |
132 | |
133 characters_.push_back (0); | |
134 | |
135 for (vsize i = 0; i < characters_.size (); i++) | |
136 if (characters_[i] == '\n') | |
137 newline_locations_.push_back (&characters_[0] + i); | |
138 } | 135 } |
139 | 136 |
140 istream * | 137 istream * |
141 Source_file::get_istream () | 138 Source_file::get_istream () |
142 { | 139 { |
143 if (!istream_) | 140 if (!istream_) |
144 { | 141 { |
145 if (length ()) // can-t this be done without such a hack? | 142 if (length ()) // can-t this be done without such a hack? |
146 istream_ = new istringstream (c_str ()); | 143 istream_ = new istringstream (c_str ()); |
147 else | 144 else |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 | 315 |
319 assert (line == get_line (pos_str0)); | 316 assert (line == get_line (pos_str0)); |
320 } | 317 } |
321 else | 318 else |
322 line_offset_ = line; | 319 line_offset_ = line; |
323 } | 320 } |
324 | 321 |
325 size_t | 322 size_t |
326 Source_file::length () const | 323 Source_file::length () const |
327 { | 324 { |
328 return characters_.size (); | 325 return data_.size (); |
329 } | 326 } |
330 | 327 |
331 char const * | 328 char const * |
332 Source_file::c_str () const | 329 Source_file::c_str () const |
333 { | 330 { |
334 return &characters_[0]; | 331 return data_.c_str (); |
335 } | 332 } |
336 | 333 |
337 /****************************************************************/ | 334 /****************************************************************/ |
338 | 335 |
339 | 336 |
340 const char * const Source_file::type_p_name_ = "ly:source-file?"; | 337 const char * const Source_file::type_p_name_ = "ly:source-file?"; |
341 | 338 |
342 int | 339 int |
343 Source_file::print_smob (SCM port, scm_print_state *) const | 340 Source_file::print_smob (SCM port, scm_print_state *) const |
344 { | 341 { |
345 scm_puts ("#<Source_file ", port); | 342 scm_puts ("#<Source_file ", port); |
346 scm_puts (name_.c_str (), port); | 343 scm_puts (name_.c_str (), port); |
347 | 344 |
348 /* Do not print properties, that is too much hassle. */ | 345 /* Do not print properties, that is too much hassle. */ |
349 scm_puts (" >", port); | 346 scm_puts (" >", port); |
350 return 1; | 347 return 1; |
351 } | 348 } |
LEFT | RIGHT |