Help needed to count lines between preprocessor directives

Discussion in 'C Programming' started by Nalla, Sep 8, 2003.

  1. Nalla

    Nalla Guest

    Hi,
    I want a program. It should be a command line one. you can input the
    path of a folder(preferably) or a file...it should count the no. of
    lines between the compiler directives,
    ifdef win32 and # endif.can u pls help me out...
     
    Nalla, Sep 8, 2003
    #1
    1. Advertising

  2. Nalla

    rzed Guest

    Nalla wrote:
    > Hi,
    > I want a program. It should be a command line one. you can input
    > the path of a folder(preferably) or a file...it should count the
    > no. of lines between the compiler directives,
    > ifdef win32 and # endif.can u pls help me out...


    Glad to.

    Write a program that accepts arguments from the command line. Decide
    what to do with input that doesn't make sense in terms of your
    assignment, and write the code to do that.

    For valid input, which will, I assume, be the name of a file that
    contains at least one compiler directive, open the file. If it opens
    correctly, read it one line at a time and determine whether the line
    contains a compiler directive. If it does, begin counting with the
    next line. When you reach the next compiler directive, emit a message
    that tells you how many lines you have counted, and prepare to start
    counting again. Continue until you run out of lines. Decide how you
    will handle reporting on the last set of lines (if there are any after
    the last compiler directive). Close the file. Emit any concluding
    messages you think appropriate.

    I can attest that I am writing this on a machine running Windows 2000.

    Hope that helps.

    Here's some code (untested):


    #include <stdlib.h>

    int main( int argc, char * argv[] )
    {

    /* do the stuff I talked about */

    return EXIT_SUCCESS;
    }

    --
    rzed
     
    rzed, Sep 8, 2003
    #2
    1. Advertising

  3. Nalla

    -berlin.de Guest

    Nalla <> wrote:
    > I want a program. It should be a command line one. you can input the
    > path of a folder(preferably) or a file...it should count the no. of
    > lines between the compiler directives,
    > ifdef win32 and # endif.can u pls help me out...


    Sorry, but clc is neither alt.source.wanted nor has your question
    anything to do with C.

    <OT>
    Since I feel like being nice today here's an (completely untested!)
    Perl script (I don't know what you mean by "path of folder" because
    a folder rarely has lines in it. and even less compiler directives.
    I also would usually try to avoid doing something like this in C
    because I am too lazy or got better things to do):

    #!/usr/bin/perl -w

    use strict;

    my $f;
    my ( $level, $lc, $found, $in_sec ) = ( 0, 0, 0, 0 );

    open( $f, "<$ARGV[ 0 ]" ) or die "Can't open file $ARGV[ 0 ]: $!\n";

    while ( <$f> ) {
    if ( /\s*#endif\s*/ ) {
    $level-- ;
    die "More \"#endif\" than \"#ifxxx\" found in file $ARGV[ 0 ]\n"
    if $level < 0;
    $in_sec = 0;
    }
    $lc++ if $in_sec;
    if ( /\s*#if\s+win32\s*/ ) {
    $found++;
    $in_sec = 1;
    }
    $level++ if /\s*#if/;
    }

    die "Missing #endif in file $ARGV[ 0 ]\n" unless ! $level;
    if ( $lc ) {
    print "Found $lc lines between \"#if win32\" and the corresponding " .
    "\"#endif\" directives (in $found sections)\n";
    } else {
    print "No \"#if win32\" directive found in file $ARGV[ 0 ]\n";
    }

    Not counting continuation lines is left as an exercise for the reader ;-)
    </OT>
    Regards, Jens
    --
    _ _____ _____
    | ||_ _||_ _| -berlin.de
    _ | | | | | |
    | |_| | | | | | http://www.physik.fu-berlin.de/~toerring
    \___/ens|_|homs|_|oerring
     
    -berlin.de, Sep 8, 2003
    #3
  4. Nalla

    Malcolm Guest

    "Nalla" <> wrote in message
    >
    > I want a program. It should be a command line one. you can input the
    > path of a folder(preferably) or a file...it should count the no. of
    > lines between the compiler directives,
    > ifdef win32 and # endif.can u pls help me out...
    >

    Unfortunately none of the regs are likely to have time to offer a free
    programming service.
    However your problem shouldn't be too difficult, particularly if you are not
    too fussy about being robust for degenerate cases such as preprocessor
    directives being themselves redefined or placed in comments.

    C offers no directory services so to do a whole folder at once you need a
    platform-specific extension.

    Simply open the file, read in the lines one at a time, and search for #ifdef
    win32.
    Then search though counting #if... s and #endifs, until you come to the
    matching #endif.
     
    Malcolm, Sep 8, 2003
    #4
  5. Nalla

    Mike Wahler Guest

    Nalla <> wrote in message
    news:...
    > Hi,
    > I want a program. It should be a command line one. you can input the
    > path of a folder(preferably) or a file...it should count the no. of
    > lines between the compiler directives,
    > ifdef win32 and # endif.can u pls help me out...


    Since we don't do people's work for them here, I'll offer
    a more general solution that you should be able to adapt
    to your specific needs. This shows the line number where
    each directive appears (and the line itself), and how many
    lines appear between successive directives. A directive is
    considered to exist on any line whose first non-whitespace
    character is a '#' character.



    #define COMPILE_THIS


    #ifdef COMPILE_THIS

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    #define LINE_SIZE 128
    #define DIRECTIVE_CHAR '#'

    int is_directive(const char *line, size_t len)
    {
    static char tok[LINE_SIZE];
    return sscanf(line, "%s", tok) != EOF &&
    *tok == DIRECTIVE_CHAR;
    }

    int main(int argc, char **argv)
    {
    char line[512] = {0};
    size_t line_no = 0;
    size_t between = 0;
    FILE *input = NULL;

    if(argc < 2)
    {
    puts("Requires file name argument");
    return EXIT_FAILURE;
    }

    if(!(input = fopen(argv[1], "r")))
    {
    puts("Cannot open input\n");
    return EXIT_FAILURE;
    }

    while(fgets(line, sizeof line, input))
    {
    ++line_no;

    if(is_directive(line, sizeof line))
    {
    if(between)
    printf("[%lu line%c]\n",
    (unsigned long)between, " s"[between > 1]);

    printf("[Line %lu] %s", (unsigned long)line_no, line);
    between = 0;
    }
    else
    ++between;
    }

    fclose(input);
    return 0;
    }

    #endif



    Output when given its own source:

    [Line 1] #define COMPILE_THIS
    [2 lines]
    [Line 4] #ifdef COMPILE_THIS
    [1 line ]
    [Line 6] #include <stdio.h>
    [Line 7] #include <stdlib.h>
    [Line 8] #include <string.h>
    [1 line ]
    [Line 10] #define LINE_SIZE 128
    [Line 11] #define DIRECTIVE_CHAR '#'
    [48 lines]
    [Line 60] #endif


    I did not test this thoroughly; I'll let you discover
    and fix any bugs that might exist. :)

    HTH,
    -Mike
     
    Mike Wahler, Sep 8, 2003
    #5
  6. Nalla

    Mike Wahler Guest

    Re: [corr] Help needed to count lines between preprocessor directives

    Mike Wahler <> wrote in message
    news:VO37b.3619$...

    [snip]

    > int main(int argc, char **argv)
    > {
    > char line[512] = {0};


    Oops, forgot to change all my 'hardcodes' to #defined values.
    Make that:

    char line[LINE_SIZE] = {0};

    [snip]

    Sorry about that.

    -Mike
     
    Mike Wahler, Sep 8, 2003
    #6
  7. Nalla

    richard Guest

    On Mon, 8 Sep 2003 08:48:13 -0400, "rzed" <> wrote:

    >Nalla wrote:
    >> Hi,
    >> I want a program. It should be a command line one. you can input
    >> the path of a folder(preferably) or a file...it should count the
    >> no. of lines between the compiler directives,
    >> ifdef win32 and # endif.can u pls help me out...

    >
    >Glad to.
    >
    >Write a program that accepts arguments from the command line. Decide
    >what to do with input that doesn't make sense in terms of your
    >assignment, and write the code to do that.


    LOL!

    >Hope that helps.


    It does. I feel much better after reading your post.

    >Here's some code (untested):
    >
    >
    >#include <stdlib.h>
    >
    >int main( int argc, char * argv[] )
    >{
    >
    > /* do the stuff I talked about */
    >
    > return EXIT_SUCCESS;
    >}


    I got warning message about unused parameters argc and argv, but otherwise
    worked perfectly in my tests.
     
    richard, Sep 8, 2003
    #7
  8. Nalla

    MikeyD Guest

    "Nalla" <> wrote in message
    news:...
    > Hi,
    > I want a program. It should be a command line one. you can input the
    > path of a folder(preferably) or a file...it should count the no. of
    > lines between the compiler directives,
    > ifdef win32 and # endif.can u pls help me out...


    Not robust or anything, but should work...
    #include <stdio.h>
    char filepath[100];
    char tstr[10];
    int lines;
    FILE* cfile
    int main(void){
    lines=0
    printf("OK, so what's the file then?\n");
    gets(filepath);
    cfile=fopen(filepath, "r");
    fseek(cfile,SEEK_SET);//not sure if this is correctly formulated
    for(;strcmp(tstr,"#ifdef win32")!=0;fgets(cfile,tstr));//value for strcmp
    may be wrong, fgets args may also be wrong
    for(;strcmp(tstr,"#endif")!=0;fgets(cfile,tstr)) lines++;
    printf("There were %d lines between the pre-processor commands\n",lines);
    //is this how you want it returned?
    return lines; //or return 0;
    }
     
    MikeyD, Sep 8, 2003
    #8
  9. MikeyD wrote:

    > Not robust or anything, but should work...


    And is grossly antisocial. The lack of indentation and the gratuitous use
    of filescope variables, and '//' comments on very long lines suggests that
    yours is a joke post (but not a very good one). Be that as it may,
    > gets(filepath);

    is a terrible thing to suggest. Not even the most clueless poster deserves
    to be treated that way.



    --
    Martin Ambuhl
     
    Martin Ambuhl, Sep 8, 2003
    #9
  10. Nalla

    LibraryUser Guest

    Mike Wahler wrote:
    >

    .... snip ...
    >
    > lines appear between successive directives. A directive is
    > considered to exist on any line whose first non-whitespace
    > character is a '#' character.


    #define whatsit "I am a \
    # marker containing string "

    --
    Replies should be to the newsgroup
    Chuck Falconer, on vacation.
     
    LibraryUser, Sep 9, 2003
    #10
  11. Nalla

    Mike Wahler Guest

    LibraryUser <> wrote in message
    news:...
    > Mike Wahler wrote:
    > >

    > ... snip ...
    > >
    > > lines appear between successive directives. A directive is
    > > considered to exist on any line whose first non-whitespace
    > > character is a '#' character.

    >
    > #define whatsit "I am a \
    > # marker containing string "


    OK, you broke my toy program. When someone pays me,
    I'll make it better. :)

    -Mike
     
    Mike Wahler, Sep 9, 2003
    #11
  12. Nalla

    MikeyD Guest

    > > Not robust or anything, but should work...
    >
    > And is grossly antisocial. The lack of indentation and the gratuitous use
    > of filescope variables, and '//' comments on very long lines suggests that
    > yours is a joke post (but not a very good one). Be that as it may,
    > > gets(filepath);

    > is a terrible thing to suggest. Not even the most clueless poster

    deserves
    > to be treated that way.
    >

    What? He asked for a program and I gave him one. Not a very good one, but it
    would work. No-one else even bothered to write one.
     
    MikeyD, Sep 9, 2003
    #12
  13. Nalla

    Mike Wahler Guest

    MikeyD <> wrote in message
    news:...
    > > > Not robust or anything, but should work...

    > >
    > > And is grossly antisocial. The lack of indentation and the gratuitous

    use
    > > of filescope variables, and '//' comments on very long lines suggests

    that
    > > yours is a joke post (but not a very good one). Be that as it may,
    > > > gets(filepath);

    > > is a terrible thing to suggest. Not even the most clueless poster

    > deserves
    > > to be treated that way.
    > >

    > What? He asked for a program and I gave him one. Not a very good one, but

    it
    > would work. No-one else even bothered to write one.


    Really? My example can beat up your example. :)

    -Mike
     
    Mike Wahler, Sep 10, 2003
    #13
  14. Nalla

    MikeyD Guest

    > > What? He asked for a program and I gave him one. Not a very good one,
    but
    > it
    > > would work. No-one else even bothered to write one.

    >
    > Really? My example can beat up your example. :)
    >
    > -Mike
    >

    Sorry, yes, you're right as a general program. But if he just wants to count
    between those two particular directives then mine'll be easier for him to
    use. I'll just fix it for commandline input, but that was chapter...actually
    it wasn't in C for dummies at all.
    Maybe this should be used as an example of how not to code whilst still
    getting a working program.
    #include <stdio.h>
    char filepath[100];
    char tstr[10];
    int lines;
    FILE* cfile
    int main(int whatever, char**notaclue){
    lines=0
    if(whatever==1)goto meaninglesslabel;
    printf("I didn't understand the arguments you gave me, so what's the file
    then?\n");
    gets(filepath);
    goto evenworse;
    meaninglesslabel: filepath=notaclue[1];//or should this be 0? I never really
    //worked out how the ags are arranged
    evenworse:
    cfile=fopen(filepath, "r");
    fseek(cfile,SEEK_SET);//not sure if this is correctly formulated
    for(;strcmp(tstr,"#ifdef win32")!=0;fgets(cfile,tstr));//value for strcmp
    //may be wrong, fgets args may also be wrong
    for(;strcmp(tstr,"#endif")!=0;fgets(cfile,tstr)) lines++;
    printf("There were %d lines between the pre-processor commands\n",lines);
    //is this how you want it returned?
    return lines; //or return 0;
    }
     
    MikeyD, Sep 10, 2003
    #14
  15. MikeyD wrote:

    > gets(filepath);


    Please stop this. No one deserves to be treated to this antisocial "advise."

    --
    Martin Ambuhl
     
    Martin Ambuhl, Sep 11, 2003
    #15
  16. Nalla

    pete Guest

    pete, Sep 11, 2003
    #16
  17. Nalla

    MikeyD Guest

    "Martin Ambuhl" <> wrote in message
    news:ZbO7b.1515$...
    > MikeyD wrote:
    >
    > > gets(filepath);

    >
    > Please stop this. No one deserves to be treated to this antisocial

    "advise."
    >

    It's just there as a backup now that I've fixed the commandline bit. There
    are flaws with fgets() as well (the site mentions its failure to delete \n
    at the end, I'm sure I've read of others) Obviously it's best to use your
    own getstring() function but I can't rely on him having my personal function
    library. For a utility program like this, gets() is perfectly suitable.
    And on what grounds do you claim it's antisocial??
     
    MikeyD, Sep 11, 2003
    #17
  18. "MikeyD" <> wrote:

    >"Martin Ambuhl" <> wrote in message
    >news:ZbO7b.1515$...
    >> MikeyD wrote:
    >>
    >> > gets(filepath);

    >>
    >> Please stop this. No one deserves to be treated to this antisocial

    >"advise."
    >>

    >It's just there as a backup now that I've fixed the commandline bit. There
    >are flaws with fgets() as well (the site mentions its failure to delete \n
    >at the end, I'm sure I've read of others) Obviously it's best to use your
    >own getstring() function but I can't rely on him having my personal function
    >library. For a utility program like this, gets() is perfectly suitable.
    >And on what grounds do you claim it's antisocial??
    >

    gets() is suitable for absolutely nothing, except breaking your code.
    And AFICS that's why Martin claimed it antisocial to suggest to use it.

    Irrwahn
    --
    Close your eyes and press escape three times.
     
    Irrwahn Grausewitz, Sep 11, 2003
    #18
  19. MikeyD wrote:

    > "Martin Ambuhl" <> wrote in message
    > news:ZbO7b.1515$...
    >
    >>MikeyD wrote:
    >>
    >>
    >>>gets(filepath);

    >>
    >>Please stop this. No one deserves to be treated to this antisocial

    >
    > "advise."
    >
    > It's just there as a backup now that I've fixed the commandline bit. There
    > are flaws with fgets() as well (the site mentions its failure to delete \n
    > at the end, I'm sure I've read of others)


    There may be flaws in fgets(), but not deleting '\n' is not one of them.
    Dan Pop will probably provide a list of what's *really* wrong (on his vies)
    with fgets(). If you think not deleting '\n' is a flaw, then you haven't
    been programming long enough.

    There is no such thing as using gets "as a backup." Using an inherently
    dangerous function that ought never be used is not "a backup."

    > Obviously it's best to use your
    > own getstring() function


    That's not obvious. There are situation in which having your own
    getstring() function has attractions, though.

    > but I can't rely on him having my personal function
    > library.


    What crap. If you want your own getstring() function just write the damn
    thing and stick it in and you will be 100% sure of having it.

    > For a utility program like this, gets() is perfectly suitable.


    Bullshit.

    > And on what grounds do you claim it's antisocial??


    You are suggesting the use of inherently unsafe functions for which use
    there is no excuse. Why not just hand out guns to children?




    --
    Martin Ambuhl
     
    Martin Ambuhl, Sep 11, 2003
    #19
  20. Nalla

    MikeyD Guest

    Fine then.
    #include <stdio.h>
    #include <stdlib.h>
    char filepath[100];
    char tstr[10];
    int lines;
    FILE* cfile
    int main(int whatever, char**notaclue){
    lines=0
    if(whatever==1)goto meaninglesslabel;
    printf("I didn't understand the arguments you gave me, so what's the file
    then?\n");
    for(int i=0;i<100;i++){filepath=getchar();
    if(filepath=='\n'){
    filepath='\0';
    break;}
    if(i==99){
    printf("You entered too long a filename");
    exit(1);
    }}
    goto evenworse;
    meaninglesslabel: strcpy(filepath,notaclue[1]);//or should this be 0? I
    never really
    //worked out how the ags are arranged
    evenworse:
    cfile=fopen(filepath, "r");
    fseek(cfile,SEEK_SET);//not sure if this is correctly formulated
    for(;strcmp(tstr,"#ifdef win32")!=0;fgets(cfile,tstr));//value for strcmp
    //may be wrong, fgets args may also be wrong
    for(;strcmp(tstr,"#endif")!=0;fgets(cfile,tstr)) lines++;
    printf("There were %d lines between the pre-processor commands\n",lines);
    //is this how you want it returned?
    return lines; //or return 0;
    }
    Happy now?
     
    MikeyD, Sep 12, 2003
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    0
    Views:
    2,727
  2. seemanta dutta

    how to make elegant use of preprocessor directives

    seemanta dutta, Nov 27, 2003, in forum: C Programming
    Replies:
    13
    Views:
    657
    Randy Howard
    Dec 1, 2003
  3. IndyChris
    Replies:
    1
    Views:
    9,014
    bruce barker \(sqlwork.com\)
    Aug 9, 2006
  4. Theon Greyjoy

    Preprocessor directives in codebehind file

    Theon Greyjoy, Oct 6, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    1,612
    bruce barker \(sqlwork.com\)
    Oct 6, 2006
  5. Water Cooler v2

    Preprocessor Directives

    Water Cooler v2, Jul 4, 2005, in forum: C Programming
    Replies:
    5
    Views:
    584
    Lawrence Kirby
    Jul 5, 2005
Loading...

Share This Page