+static void skip_line_comment(void)
+{
+ if(do_print_spaces)
+ counted_spaces++;
+
+ while(1) {
+ switch(CC) {
+ case EOF:
+ return;
+
+ case '\n':
+ case '\r':
+ return;
+
+ default:
+ next_char();
+ break;
+ }
+ }
+}
+
+static void skip_multiline_comment(void)
+{
+ if(do_print_spaces)
+ counted_spaces++;
+
+ unsigned start_linenr = input.position.linenr;
+ while(1) {
+ switch(CC) {
+ case '/':
+ next_char();
+ if (CC == '*') {
+ /* TODO: nested comment, warn here */
+ }
+ break;
+ case '*':
+ next_char();
+ if(CC == '/') {
+ next_char();
+ return;
+ }
+ break;
+
+ MATCH_NEWLINE(
+ if(do_print_spaces) {
+ counted_newlines++;
+ counted_spaces = 0;
+ }
+ break;
+ )
+
+ case EOF: {
+ source_position_t source_position;
+ source_position.input_name = pp_token.source_position.input_name;
+ source_position.linenr = start_linenr;
+ errorf(&source_position, "at end of file while looking for comment end");
+ return;
+ }
+
+ default:
+ next_char();
+ break;
+ }
+ }
+}
+
+/* skip spaces advancing at the start of the next preprocessing token */
+static void skip_spaces(bool skip_newline)
+{
+ while (true) {
+ switch (CC) {
+ case ' ':
+ case '\t':
+ if(do_print_spaces)
+ counted_spaces++;
+ next_char();
+ continue;
+ case '/':
+ next_char();
+ if (CC == '/') {
+ next_char();
+ skip_line_comment();
+ continue;
+ } else if (CC == '*') {
+ next_char();
+ skip_multiline_comment();
+ continue;
+ } else {
+ put_back(CC);
+ CC = '/';
+ }
+ return;
+
+ case '\r':
+ if (!skip_newline)
+ return;
+
+ next_char();
+ if(CC == '\n') {
+ next_char();
+ }
+ ++input.position.linenr;
+ if (do_print_spaces)
+ ++counted_newlines;
+ continue;
+
+ case '\n':
+ if (!skip_newline)
+ return;
+
+ next_char();
+ ++input.position.linenr;
+ if (do_print_spaces)
+ ++counted_newlines;
+ continue;
+
+ default:
+ return;
+ }
+ }
+}
+
+static void eat_pp(int type)
+{
+ (void) type;
+ assert(pp_token.type == type);
+ next_preprocessing_token();
+}
+