J
jacob navia
Recently we had poor Mr "teapot" that was horrified at the heresy
of lcc-win of accepting // comments.
C is a nice language, and you can do anything with it, inclusive a
program that transforms // comments into well behaved /* ... */
ones...
------------------------------------------------cut here
/*
This program reads a C source file and writes it modified to stdout
All // comments will be replaced by / * ... * / comments, to easy the
porting to old environments or to post it in usenet, where
// comments can be broken in several lines, and messed up.
*/
#include <stdio.h>
#include <stdlib.h>
/* This function reads a character and writes it to stdout */
static int Fgetc(FILE *f)
{
int c = fgetc(f);
if (c != EOF)
putchar(c);
return c;
}
/* This function skips strings */
static int ParseString(FILE *f)
{
int c = Fgetc(f);
while (c != EOF && c != '"') {
if (c == '\\')
c = Fgetc(f);
if (c != EOF)
c = Fgetc(f);
}
if (c == '"')
c = Fgetc(f);
return c;
}
/* Skips multi-line comments */
static int ParseComment(FILE *f)
{
int c = Fgetc(f);
while (1) {
while (c != '*') {
c = Fgetc(f);
if (c == EOF)
return EOF;
}
c = Fgetc(f);
if (c == '/')
break;
}
return Fgetc(f);
}
/* Skips // comments. Note that we use fgetc here and NOT Fgetc */
/* since we want to modify the output before gets echoed */
static int ParseCppComment(FILE *f)
{
int c = fgetc(f);
while (c != EOF && c != '\n') {
putchar(c);
c = fgetc(f);
if (c == '*') {
c = fgetc(f);
if (c == '/') {
c = fgetc(f);
putchar(' ');
}
else {
putchar('*');
}
}
}
if (c == '\n') {
puts(" */");
c = Fgetc(f);
}
return c;
}
/* Checks if a comment is followed after a '/' char */
static int CheckComment(int c,FILE *f)
{
if (c == '/') {
c = fgetc(f);
if (c == '*') {
putchar('*');
c = ParseComment(f);
}
else if (c == '/') {
putchar('*');
c = ParseCppComment(f);
}
else {
putchar(c);
c = Fgetc(f);
}
}
return c;
}
/* Skips chars between simple quotes */
static int ParseQuotedChar(FILE *f)
{
int c = Fgetc(f);
while (c != EOF && c != '\'') {
if (c == '\\')
c = Fgetc(f);
if (c != EOF)
c = Fgetc(f);
}
if (c == '\'')
c = Fgetc(f);
return c;
}
int main(int argc,char *argv[])
{
FILE *f;
int c;
if (argc == 1) {
puts("Usage: give an input file name. Writes to stdout");
return EXIT_FAILURE;
}
f = fopen(argv[1],"r");
if (f == NULL) {
puts("Can't find the input file");
return EXIT_FAILURE;
}
c = Fgetc(f);
while (c != EOF) {
/* Note that each of the switches must advance the character */
/* read so that we avoid an infinite loop. */
switch (c) {
case '"':
c = ParseString(f);
break;
case '/':
c = CheckComment(c,f);
break;
case '\'':
c = ParseQuotedChar(f);
break;
default:
c = Fgetc(f);
}
}
fclose(f);
return 0;
}
----------------------------------------------------------cut here
Note that trigraphs are not supported. Homework: Add that feature
Compiled with lcc-win, this program makes only 3 616 bytes. C is
an efficient language.
P.S. Note that I have avoided printf... If you add printf the size
will be a HUGE 37K.
of lcc-win of accepting // comments.
C is a nice language, and you can do anything with it, inclusive a
program that transforms // comments into well behaved /* ... */
ones...
------------------------------------------------cut here
/*
This program reads a C source file and writes it modified to stdout
All // comments will be replaced by / * ... * / comments, to easy the
porting to old environments or to post it in usenet, where
// comments can be broken in several lines, and messed up.
*/
#include <stdio.h>
#include <stdlib.h>
/* This function reads a character and writes it to stdout */
static int Fgetc(FILE *f)
{
int c = fgetc(f);
if (c != EOF)
putchar(c);
return c;
}
/* This function skips strings */
static int ParseString(FILE *f)
{
int c = Fgetc(f);
while (c != EOF && c != '"') {
if (c == '\\')
c = Fgetc(f);
if (c != EOF)
c = Fgetc(f);
}
if (c == '"')
c = Fgetc(f);
return c;
}
/* Skips multi-line comments */
static int ParseComment(FILE *f)
{
int c = Fgetc(f);
while (1) {
while (c != '*') {
c = Fgetc(f);
if (c == EOF)
return EOF;
}
c = Fgetc(f);
if (c == '/')
break;
}
return Fgetc(f);
}
/* Skips // comments. Note that we use fgetc here and NOT Fgetc */
/* since we want to modify the output before gets echoed */
static int ParseCppComment(FILE *f)
{
int c = fgetc(f);
while (c != EOF && c != '\n') {
putchar(c);
c = fgetc(f);
if (c == '*') {
c = fgetc(f);
if (c == '/') {
c = fgetc(f);
putchar(' ');
}
else {
putchar('*');
}
}
}
if (c == '\n') {
puts(" */");
c = Fgetc(f);
}
return c;
}
/* Checks if a comment is followed after a '/' char */
static int CheckComment(int c,FILE *f)
{
if (c == '/') {
c = fgetc(f);
if (c == '*') {
putchar('*');
c = ParseComment(f);
}
else if (c == '/') {
putchar('*');
c = ParseCppComment(f);
}
else {
putchar(c);
c = Fgetc(f);
}
}
return c;
}
/* Skips chars between simple quotes */
static int ParseQuotedChar(FILE *f)
{
int c = Fgetc(f);
while (c != EOF && c != '\'') {
if (c == '\\')
c = Fgetc(f);
if (c != EOF)
c = Fgetc(f);
}
if (c == '\'')
c = Fgetc(f);
return c;
}
int main(int argc,char *argv[])
{
FILE *f;
int c;
if (argc == 1) {
puts("Usage: give an input file name. Writes to stdout");
return EXIT_FAILURE;
}
f = fopen(argv[1],"r");
if (f == NULL) {
puts("Can't find the input file");
return EXIT_FAILURE;
}
c = Fgetc(f);
while (c != EOF) {
/* Note that each of the switches must advance the character */
/* read so that we avoid an infinite loop. */
switch (c) {
case '"':
c = ParseString(f);
break;
case '/':
c = CheckComment(c,f);
break;
case '\'':
c = ParseQuotedChar(f);
break;
default:
c = Fgetc(f);
}
}
fclose(f);
return 0;
}
----------------------------------------------------------cut here
Note that trigraphs are not supported. Homework: Add that feature
Compiled with lcc-win, this program makes only 3 616 bytes. C is
an efficient language.
P.S. Note that I have avoided printf... If you add printf the size
will be a HUGE 37K.