C script to ident another c file

Hi

I need to build a C script that add indents (1 tab) or remove (indents) to another C script file, without using beautifier or any software.

For example

I want it to run from the console like this : myidentificator.c <fileToIdent.c >formatedFile.c

I want the script to avoid any comments and find { and }. When it finds a { it adds one indent to the next lines until he finds a }. Then he remove indents until it finds { and etc etc. The { and } are always alone in their lines.

I have checked on the internet, but I dont even know where to start. I heard C have problems with big buffers and I want my program to not be limited by line size or line numbers.

What sould I do ? Put all the lines into strings ? then arrays ?

Ex

Source

void hello1
{
ads;
}

   void hello 2
{
adssads;
}

Open in new window


Modified will look like
void hello1
{
      ads;
}

void hello 2
{
     adssads;
}

Open in new window

metraonAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
phoffricConnect With a Mentor Commented:
If you want, you can deal with one char at a time using fgetc instead of fgets.
    http://www.cplusplus.com/reference/cstdio/fgetc/

If using fgetc, you will need another state variable. (Give it a try and you will see what I mean.) I think you should write out pseudo-code since this has become a design question. Then later if you have problems with C programming, you can address them one question at a time.
0
 
jkrCommented:
Instead of reinventing the wheel, you might be interested in http://uncrustify.sourceforge.net/ ("Uncrustify - Source Code Beautifier for C, C++, C#, ObjectiveC, D, Java, Pawn and VALA") or http://www.faqs.org/docs/Linux-HOWTO/C-C++Beautifier-HOWTO.html#installing_bcpp
0
 
metraonAuthor Commented:
I need to do it myself, in C language

What I think I am gonna do is convert each line into a array series characters example

[h][e][l][l][o][/n]

Analyse the array and append it into the file.

Then Go to line 2 etc etc
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
phoffricCommented:
fgets will read a line putting each char in the line in a char:
    http://www.cplusplus.com/reference/cstdio/fgets/
/* fgets example */
#include <stdio.h>

int main()
{
   FILE * pFile;
   char mystring [100];

   pFile = fopen ("myfile.txt" , "r");
   if (pFile == NULL) perror ("Error opening file");
   else {
     if ( fgets (mystring , 100 , pFile) != NULL )
       puts (mystring);
     fclose (pFile);
   }
   return 0;
}

Open in new window

mystring  is an array of char.
You also have to handle {{.
0
 
HooKooDooKuCommented:
Just how much are you wanting to modify the text vs. leave as much of it alone as possible?

If you want to somewhat standardize the look of the code, I would try a program that does something like the following pseudo-code

Set IndentLevel = 0;
LOOP1:
Read a Line of Text into MyString
LOOP2:
Search for the 1st '{' or '}' character in MyString
Extract a sub-string from MyString of all characters before the 1st '{' or '}'
Perform a Left & Right Trim on the subs-string
Write 4*IndentLevel number of spaces to the file
Write the sub-string and a newline character
If 1st found character was '{' then...
    Write 4*IndentLevel number of spaces to the file
    Write '{' and a newline  character
    Increment IndentLevel
Else if 1st found charater was '}' then...
    Decrement IndentLevel
    Write 4*IndentLevel number of spaces to the file
    Write '}' and a newline  character
Replace MyString with all the text that followed the 1st '{' or '}'
If MyString is not empty
    Return to 'Loop2'
If NOT at End of File
    Return to 'Loop1'
0
 
TommySzalapskiCommented:
You don't have to worry about buffer space. Just read in one line at a time, process it, and read the next line. You'll only need to store one line at a time in any buffer.

The things you'll need to keep track of are the current indent size and whether or not your are inside a comment when you see the { or } characters.

without using beautifier or any software
Can we then assume this is a homework assignment?
0
 
metraonAuthor Commented:
So far, I got this. Is there a reason it print  Detected on every line ? I wanted to be clever and add \0 so it would only print the message on { at the end of a line.

Yes its an assignment !


#include <stdio.h>

void main()
{
    char str[200];
    FILE *fp;

    fp = fopen("test.c", "r");
    if(!fp) return 1; // bail out if file not found
    while(fgets(str,sizeof(str),fp) != NULL)
    {
        int len = strlen(str)-1;
        if(str[len] == '\n')
        {
            str[len] = 0;
        }
        char *ptr=strchr(str,'{\0');
        if(ptr)
        {
            sprintf(str,"%s { Detected",str);

        }
        else
        {
            ptr=strchr(str,'}\n');
            if(ptr)
            {
                sprintf(str,"%s } Detected ",str);
            }
        }
        printf("\n%s", str);

    }

    fclose(fp);
}

Open in new window

0
 
phoffricCommented:
>> Is there a reason it print  Detected on every line ?

The code you posted should not compile without problems. If you are getting warnings, fix them first before posting.

But the gist of the problem is that you are searching for '\0' which you always find. Since your ptr is pointing to the '\0', then ptr is not NULL, and you get Detected.

By the way, the EE policy is one question per thread.
0
 
TommySzalapskiConnect With a Mentor Commented:
'{\0' doesn't make sense (and should generate the warning phoffric is talking about). When you pass characters, you don't need to null-terminate them. Only strings get the null terminators.  '{' and '}' will do what you want.
0
 
metraonAuthor Commented:
In the orginal post, I mentioned that I want the script to avoid any comments, I think its still related to the same question.

I putted the {\0, because I thought It will only finds the lone { and ignore the ones commented. If i put only char *ptr=strchr(str,'{'); The { in comments will not be ignored, and will output a non desired behavior.

I added this : sprintf(str,"%s } Detected ",str); just to get more visibility and for debugging purposes.
0
 
phoffricCommented:
Since you want to ignore {} in comments, then you can define a flag, in_a_comment, to let you know when you must ignore curlys.
0
 
phoffricCommented:
strchr 2nd arg takes an int.
    http://www.cplusplus.com/reference/cstring/strchr/

'{\0' is not a legitimate way to form an int, as Tommy already explained.
0
 
phoffricCommented:
I take back what I said earlier that you are searching for null. Maybe you are searching for '{'. I do not always know what compilers will generate when the code has warnings like yours.

If you are in_a_comment, then just indent according to your indent_level state variable, and in that line, continue your search for end of comment. From that point in the line, you still must search for new comments as well as curlys.

After reading in a line, just examine one char at a time keeping track of the states, in_a_comment, as well as your indent_level state.
0
 
TommySzalapskiCommented:
You are going to have to parse the line looking for the characters that mean comment. I don't think strchr is what you need since you need to look for // and /*
Just make the boolean phoffric suggests and set and unset it when you see // and \n or /* and */
0
 
phoffricCommented:
That's right, strchr has its place. But here you should look at one char at a time to keep track of your states. For advanced credit, you will need to keep track of ignoring comment tokens like // when you are already within a comment. You should also compile the program first with no warnings to get rid of what may appear as nested comments. Also, you need a state variable to indicate when you are in a string or a char literal, so that you can ignore curlys within those entities.
0
 
metraonAuthor Commented:
Thanks. I am going to work on this by myself for the rest. There is no better way to learn with experiments.
0
All Courses

From novice to tech pro — start learning today.