Preprocessor C program to replace include headers - c

I have homework assignment where I need to write a program to replace include commands (assuming there are no standard library includes) of C file with the actual .h' file (performing the preprocessor's job).
I thought using regex matching, but since we are only allowed to use ansi-C's standard libraries regex is not allowed.
I am not sure what is the efficient way to do so?
edit: there is no need to check for #defines or #ifdefs.

I suggest you follow this guide to create your program:
Open the target c file read only.
Open the destination file write only.
Create a function that you pass the input file and the output file, i will call this function "expand_function".
In the expand_function read each byte of the input, and while reading each character check if it is a #, then test if it is a include keyword, and finally if all conditions matches open the filename that will be in front the include, then call again the expand_function with the new input file and the same output file (don't forget closing all open files), and finally continue the loop. If any conditions not match write all read bytes in the output file.
Extra: Check if you are not in a dead loop of includes in the beginning of expand_function.

Related

how to get the file name in C program, that i had given in input redirection?

steps:
Let's say I have a C program inputFileName.c
I run inputFileName with input redirection such as ./inputFileName < file
How can I print the name of the file in my C program that I have typed in the terminal as an input redirection file?
The input redirection is a function of the shell. Your inputFileName executable see this as standard input. Depending on the exact operating system, you may be able to use system-specific functions to get the information you want, but there is not a standard means of doing so.
Input redirection can be achieved not only with the '<' symbol, but also with '|'.
program < filename
is equivalent to
cat filename | program
From there, one could go to
cat file1 file2 file3 | program
You begin to see why the initial 'stdin' for an executable cannot and does not have a "filename" associated with it.
If input comes from a pipe, there can't be an associated filename. Also if the file has been deleted or moved before closing the file descriptor, there is no associated filename. A file can have multiple names. In that case there are multiple filenames.
Given that, the "associated filename" of a file descriptor doesn't really make much sense. And even if you could get that info, using the filename in any way might make race conditions an issue.
The linux kernel does try to track an associated filename if a file descriptor was created by opening a file. But the keyword here is "tries".
If you are running Linux, you can find the filenname for standard input as a symlink under "/proc/self/fd/0". Just remember that you should not rely on that name for anything more than debug or display purposes.

replace a substring in a string in C, windows

I want to do the following:
open and read and ASCII file
locate a substring (geographical coordinates)
create its replacement (apply corrections to the original coordinates)
overwrite the original substring (write in the original file the corrected coordinates).
The format of the ASCII file is:
$GPGGA,091306.00,4548.17420,N,00905.47990,E,1,09,0.87,233.5,M,47.2,M,,*53
I will paste here only the part of the code that is responsible for this operation:
opnmea = fopen (argv[1], "r+");
if (fgets(row_nmea, ROW, opnmea)==NULL){
if (strstr(row_nmea,"$GPGGA")!=NULL) {
sscanf(row_nmea+17, "%10c", old_phi);
sscanf(row_nmea+30, "%11c", old_lam);
sscanf(row_nmea+54, "%5c", old_h);
fputs();
}
}
What I do till now is to extract in a variable the old coordinates and I was thinking to use fputs() for overwriting the old with new values. But I could not do it. The other part of the code that is not here is computing the correct coordinates. My idea is to correct the rows one by one, as the fgets() function reads each line.
I would appreciate very much any suggestion that can show me how to use fputs() or another function to complete my work. I am looking for something simple as I am beginner with C.
Thank you in advance.
Patching a text file in place is not a good solution for this problem, for multiple reasons:
the modified version might have a different length, hence patching cannot be done in place.
the read-write operation of standard streams is not so easy to handle correctly and defeats the buffering mechanism.
if you encounter an error during the patching phase, a partially modified file can be considered corrupted as one cannot tell which coordinates have been modified and which have not.
other programs might be reading from the same file as you are writing it. They will read invalid or inconsistent data.
I strongly recommend to write a program that reads the original file and writes a modified version to a different output file.
For this you need to:
open the original file for reading opnmea = fopen(argv[1], "r");
open the output file for writing: outfile = fopen(temporary_file_name, "w");
copy the lines that do not require modification: just call fputs(row_nmea, outfile).
parse relevant data in lines that require modification with whatever method you are comfortable with: sscanf, strtok, ...
compute the modified fields and write the modified line to outfile with fprintf.
Once the file has been completely and correctly handled, you can replace the original file with rename. The rename operation is usually atomic at the file-system level, so other programs will either finish reading from the previous version or open the new version.
Of course, if the file has only one line, you could simply rewind the stream and write back the line with fprintf, but this is a special case and it will fail if the new version is shorter than the original. Truncating the extra data is not easy. An alternative is to reopen the file in write mode ("w") before writing the modified line.
I would recommend strtok(), followed by your revision, followed by strcat().
strtok() will let you separate the line using the comma as a delimiter, so you will get the field you want reliably. You can break up the line into separate strings, revise the coordinates you wish, and reassemble the line, including the commas, with strcat().
These pages include nice usage examples, too:
http://www.cplusplus.com/reference/cstring/strtok/
http://www.cplusplus.com/reference/cstring/strcat/?kw=strcat

Program to compile files in a directory in openedge

Could someone help me in writing a program that has to compile all the files in the directory and report error, if any. For which my program has to get the list of all files under the folder with its full path and store it in a temp-table and then it has to loop through the temp table and compile the files.
Below is a very rough start.
Look for more info around the COMPILE statement and the COMPILER system handle in the online help (F1).
Be aware that compiling requires you to have a developer license installed. Without it the COMPILE statement will fail.
DEFINE VARIABLE cDir AS CHARACTER NO-UNDO.
DEFINE VARIABLE cFile AS CHARACTER NO-UNDO FORMAT "x(30)".
ASSIGN
cDir = "c:\temp\".
INPUT FROM OS-DIR(cDir).
REPEAT:
IMPORT cFile.
IF cFile MATCHES "*..p" THEN DO:
COMPILE VALUE(cDir + cFile) SAVE NO-ERROR.
IF COMPILER:ERROR THEN DO:
DISPLAY
cFile
COMPILER:GET-MESSAGE(1) FORMAT "x(60)"
WITH FRAME frame1 WIDTH 300 20 DOWN.
END.
END.
END.
INPUT CLOSE.
Since the comment wouldn't let me paste this much into it... using INPUT FROM OS-DIR returns all of the files and directories under a directory. You can use this information to keep going down the directory tree to find all sub directories
OS-DIR documentation:
Sometimes, rather than reading the contents of a file, you want to read a list of the files in a directory. You can use the OS–DIR option of the INPUT FROM statement for this purpose.
Each line read from OS–DIR contains three values:
*The simple (base) name of the file.
*The full pathname of the file.
*A string value containing one or more attribute characters. These characters indicate the type of the file and its status.
Every file has one of the following attribute characters:
*F — Regular file or FIFO pipe
*D — Directory
*S — Special device
*X — Unknown file type
In addition, the attribute string for each file might contain one or more of the following attribute characters:
*H — Hidden file
*L — Symbolic link
*P — Pipe file
The tokens are returned in the standard ABL format that can be read by the IMPORT or SET statements.

how make include import in flex/bison

I'm making a programming language converter and, and it has import and include.
For example:
import com.nanana.MyClassFile
include "myfile.any"
I'm newbie which means I'm lost in how can I make it.
I wondering if is possible parse another file while one is been parsing.
And how can I do it?
EDIT:
The code I'm using to parse files in main function is:
yyin = fopen( argv[1], "r" );
return yyparse();
Can I use this same code, or there is another?
The lexer uses the YY_INPUT macro to obtain its data. Within the parser, once the include "myfile.any" command has been parsed, the parser will need to open up the new file and arrange that its data will be returned from YY_INPUT, instead of the original file. Once EOF has been reached, then YY_INPUT will need to continue reading from the original file. You'll probably want to store those open files on a stack so that included files can in turn include other files, but watch out for an infinite include loop.

How to read output and give input to a program from c program?

This is with reference to the below question:
Execute program from within a C program
How do I do the same on Windows with Tiny C Compiler?
I need to execute a .exe fro c program and give input to it from within the same C program by using a file or string as source and read the output from it into a string or file.I have been using system() frunction. Any suggesstions or examples are welcome..Thanks in advance
The simplest way if you don't have popen() etc, or you want to avoid the complexity, is to simplly write a data file eg. infile with fwrite() execute the external program with system() and then read outfile.
system("prog.exe <infile >outfile")
Your prog.exe only has to read stdin and write stdout.
This way you can easily test it with the contents of in/out file.
You would normally do this in your tmp directory and then delete them when you are finished.
The only thing to be careful of is the path to the .exe
Google for "windows popen" and you find this link:
lists.trolltech.com/qt-interest/1999-09/thread00282-0.html
The C runtime library also has _popen(), but I would recommend against it.

Resources