Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ gen:

install:
install -d $(PREFIX)/bin $(PREFIX)/share/qrintf
install -m 755 bin/qrintf-gcc bin/qrintf-gcc-wrapper bin/qrintf-pp $(PREFIX)/bin
install -m 755 bin/qrintf bin/qrintf-pp $(PREFIX)/bin
install -m 644 share/qrintf/qrintf.h $(PREFIX)/share/qrintf

test:
bin/qrintf-gcc -D_QRINTF_COUNT_CALL=1 -Wall -g -Werror t/test.c -o ./test && ./test
bin/qrintf $(CC) -D_QRINTF_COUNT_CALL=1 -Wall -g -Werror t/test.c -o ./test && ./test

.PHONY: gen install test
13 changes: 5 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,11 @@ make install PREFIX=/usr/local
COMMANDS
---

### qrintf-gcc
### qrintf

`qrintf-gcc` is the wrapper command for GCC.
`qrintf` is the command that wraps the C compiler (GCC or clang).

It preprocesses the source files using GCC, applies `qrintf-pp`, and compiles the output using GCC.

The command accepts all options that are known by GCC (with the exception of `-no-intgrated-cpp` and `-wrapper`, which are used internally by the command).
It preprocesses the source files using the preprocessor (by calling the compiler with `-E` option), applies `qrintf-pp`, and then once again invokes the compiler to compile the processed file.

### qrintf-pp

Expand Down Expand Up @@ -82,11 +80,10 @@ note: Invocations of sprintf using other conversion specifiers are left as is.
__Q. How do I run the tests?__

```
make test
make test CC=gcc
make test CC=clang
```

note: The test invokes `qrintf-gcc` which in turn invokes `gcc`. So GCC should exist within the PATH. `Clang-gcc` is not supported.

__Q. Shouldn't such feature be implemented in the compiler?__

Agreed.
Expand Down
77 changes: 77 additions & 0 deletions bin/qrintf
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#! /usr/bin/perl

use strict;
use warnings;
use File::Basename qw(basename dirname);
use File::Temp qw(tempdir);
use POSIX qw(WIFEXITED WEXITSTATUS WTERMSIG);

if (@ARGV < 2 || grep { $_ =~ /^(-h|--help)$/s } @ARGV) {
print "Usage: $0 compiler [compiler-options...] filename\n";
exit 0;
}

my @cflags = @ARGV;
my $cc = shift @cflags;
my $output_fn;
for (my $i = 0; $i < @cflags;) {
if ($i + 1 < @cflags && $cflags[$i] eq '-o') {
$output_fn = $cflags[$i + 1];
splice @cflags, $i, 2;
} else {
++$i;
}
}
my $fn = pop @cflags;

my $pwd = dirname($0);

my $tempdir = tempdir(CLEANUP => 1);
my $tempfn = basename($fn);
$tempfn =~ s{\.c(.*)$}{.i@{[$1 ? 'i' : '']}}s
or $tempfn = "$tempfn.i";
$tempfn = "$tempdir/$tempfn";

# invoke cpp
open(my $fh, "-|", $cc, '-E', (grep { $_ ne '-c' } @cflags), '-DQRINTF=1', '-include', "$pwd/../share/qrintf/qrintf.h", $fn)
or die "failed to invoke $cc -E:$!";
my $src = do { local $/; <$fh> };
close $fh
or delegate_exit_status("$cc -E", $?);

# apply qrintf-pp
open $fh, "|-", "$pwd/qrintf-pp > $tempfn"
or die "failed to invoke $pwd/qrintf-pp:$!";
print $fh $src;
close $fh
or delegate_exit_status("$pwd/qrintf-pp", $?);

# restore -o fn
push @cflags, '-o', $output_fn
if defined $output_fn;

# special case for -E
if (grep { $_ eq '-E' } @cflags) {
open $fh, '<', $tempfn
or die "failed to open file:$tempfn:$!";
while (<$fh>) {
print $_;
}
close $fh;
exit 0;
}

# invoke cc
system($cc, @cflags, $tempfn)
or delegate_exit_status("$cc", $?);

exit 0;

sub delegate_exit_status {
my ($prog, $status) = @_;
if (WIFEXITED($status)) {
exit WEXITSTATUS($status);
} else {
die "$prog exitted due to signal @{[WTERMSIG($status)]}\n";
}
}
3 changes: 0 additions & 3 deletions bin/qrintf-gcc

This file was deleted.

33 changes: 0 additions & 33 deletions bin/qrintf-gcc-wrapper

This file was deleted.