Skip to content

Commit

Permalink
Tokenizer: treat Ctrl+Z as EOF if ms extensions are enabled
Browse files Browse the repository at this point in the history
  • Loading branch information
Vexu committed Oct 1, 2023
1 parent 26e0f26 commit bfa419c
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 4 deletions.
8 changes: 7 additions & 1 deletion src/Diagnostics.zig
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ pub const Options = packed struct {
@"language-extension-token": Kind = .default,
@"complex-component-init": Kind = .default,
@"microsoft-include": Kind = .default,
@"microsoft-end-of-file": Kind = .default,
};

const messages = struct {
Expand Down Expand Up @@ -2410,7 +2411,6 @@ const messages = struct {
const opt = "pedantic";
const extra = .str;
const kind = .off;
const pedantic = true;
};
pub const not_floating_type = struct {
const msg = "argument type '{s}' is not a real floating point type";
Expand All @@ -2428,6 +2428,12 @@ const messages = struct {
const opt = "microsoft-include";
const kind = .warning;
};
pub const ctrl_z_eof = struct {
const msg = "treating Ctrl-Z as end-of-file is a Microsoft extension";
const opt = "microsoft-end-of-file";
const kind = .off;
const pedantic = true;
};
};

list: std.ArrayListUnmanaged(Message) = .{},
Expand Down
9 changes: 6 additions & 3 deletions src/Preprocessor.zig
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,13 @@ pub fn deinit(pp: *Preprocessor) void {

/// Preprocess a source file, returns eof token.
pub fn preprocess(pp: *Preprocessor, source: Source) Error!Token {
return pp.preprocessExtra(source) catch |er| switch (er) {
const eof = pp.preprocessExtra(source) catch |er| switch (er) {
// This cannot occur in the main file and is handled in `include`.
error.StopPreprocessing => unreachable,
else => |e| return e,
};
try eof.checkMsEof(source, pp.comp);
return eof;
}

/// Return the name of the #ifndef guard macro that starts a source, if any.
Expand Down Expand Up @@ -2338,10 +2340,11 @@ fn include(pp: *Preprocessor, tokenizer: *Tokenizer, which: Compilation.WhichInc
pp.verboseLog(first, "include file {s}", .{new_source.path});
}

_ = pp.preprocessExtra(new_source) catch |er| switch (er) {
error.StopPreprocessing => {},
const eof = pp.preprocessExtra(new_source) catch |er| switch (er) {
error.StopPreprocessing => return,
else => |e| return e,
};
try eof.checkMsEof(new_source, pp.comp);
}

/// tokens that are part of a pragma directive can happen in 3 ways:
Expand Down
8 changes: 8 additions & 0 deletions src/Tokenizer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1120,6 +1120,14 @@ pub fn next(self: *Tokenizer) Token {
self.index += 1;
break;
},
0x1A => if (self.comp.langopts.ms_extensions) {
id = .eof;
break;
} else {
id = .invalid;
self.index += 1;
break;
},
0x80...0xFF => state = .extended_identifier,
else => {
id = .invalid;
Expand Down
14 changes: 14 additions & 0 deletions src/Tree.zig
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,20 @@ pub const Token = struct {
return copy;
}

pub fn checkMsEof(tok: Token, source: Source, comp: *Compilation) !void {
std.debug.assert(tok.id == .eof);
if (source.buf.len > tok.loc.byte_offset and source.buf[tok.loc.byte_offset] == 0x1A) {
try comp.diag.add(.{
.tag = .ctrl_z_eof,
.loc = .{
.id = source.id,
.byte_offset = tok.loc.byte_offset,
.line = tok.loc.line,
},
}, &.{});
}
}

pub const List = std.MultiArrayList(Token);
pub const Id = Tokenizer.Token.Id;
};
Expand Down
2 changes: 2 additions & 0 deletions test/cases/ms-extensions.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@
#ifndef OTHER_INCLUDED
#error Microsoft search rule should work
#endif

don't mind me ;)

0 comments on commit bfa419c

Please sign in to comment.