Thread: Help understanding C syntax

  1. #1
    Living to Learn
    Join Date
    Feb 2006
    Location
    Aberdeen, UK
    Posts
    33

    Help understanding C syntax

    Hello,

    I have been given this program to modify. The original program totals up files and directories in a file tree and has functions to detect the difference between them (whether they use / or .). I would like to modify it to use a linked list structure to create a copy of a file tree in memory.

    The problem I'm having is that I'm having trouble understanding the original program. I thought it might be beneficial to comment the program first to break it up into smaller chunks.

    Code:
    /* du for file count
     *
     * show where the numerous files are
     */
    
    #include <dirent.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
    #include <sys/stat.h>
    
    // Function to generate the full name of a file or directory
    // Declare pointers to root and name
    char * fullname(const char *root, const char * name)
    {
    // A constant to hold the seperation character     
        const char * sep = "/";
    // A pointer to res holding the result of the name, allocating memory based on length of component constants    
        char * res = (char *) malloc(strlen(root)+strlen(sep)+strlen(name)+1);
    // Copy res into root    
        strcpy(res,root);
    // Join parts of the name together    
        strcat(res,sep);
        strcat(res,name);
    // Return the result    
        return res;
    }
    
    // Function to detect full stops
    int notdot (const char * s)
    {
    // Compare two strings for full stops    
        return  strcmp(s,".") != 0  && strcmp(s,"..")!= 0 ;
    }
    
    // I don't understand this function, and the UNIX statements are foreign to me!
    int issymlink(const char * name)
    {
        struct stat buf;
        lstat(name, &buf);
        return (buf.st_mode & S_IFMT) == S_IFLNK;
    }
    
    // Function to detect directories - again I don't understand, UNIX statements are foreign
    int isdir(const char * name)
    {
        struct stat buf;
        lstat(name, &buf);
        return (buf.st_mode & S_IFMT) == S_IFDIR;
    }
    
    // Somehow count up number of names
    int filecount( const char * dirname)
    {
        DIR *dd;
        struct dirent *dp;
        int res = 0;
        dd = opendir( dirname );
        assert(dd);
        while ( (dp = readdir( dd )) )
            if ( notdot(dp->d_name)){
                char * name2 = fullname( dirname, dp->d_name);
                if (issymlink(name2))  fprintf(stderr, "sym link %s\n", name2);
                else if (isdir(name2)) res += filecount(name2);
                else                   res ++;
            }
        printf("%10d %s\n",res, dirname);
        closedir(dd);
        return res;
    }
    
    // Wrap everything up and output number of files and directories
    int main(int argc, char * argv[]) {
        char * dirname = strdup(( argc >1) ? argv[1] : getenv("HOME"));
        printf("%10d %s\n",filecount(dirname), dirname);
        return (0);
    }
    Now, apart from those functions which I just don't understand (I use Windows and always have, but this program uses UNIX commands from what I can see):

    1. char * fullname(const char *root, const char * name)
    What is the difference between an asterisk directly before a name (*root) (which I know is a pointer) and one with a space between the asterisk and the name (char * fullname)?

    2. I don't understand the issymlink function and the one that follows it. A structure seems to be defined, but what's its purpose?

    3. The filecount function, there are a lot of functions, readdir, etc and pointers, *dd and *dp I've never seen before. I assume these are derived from the included dirent.h and assert.h files, so I'd need to look at those to work out what's going on?

    I've worked out that basically I need to replace the constants and variables that are being used at the moment (and the pointers and other stuff (see Q1), define a new structure for the file tree (which I've been provided with, see below) and then change the references to the original pointers and stuff to those in the new structure. I'm pretty sure I could probably do that using net references and examples of linked lists, but not understand the program in its original form means I'm struggling to work out what I can remove and what are actual vital functions.

    The structure I'll be replacing and modifying references to point to it is:

    Code:
    enum Tnodetype {n_file, n_directory, n_symlink};
       typedef enum Tnodetype Nodetype;
       
       struct Tcell{
           struct Tcell *next;
           char * localname;
           char * fullname;
           struct Tcell * content;  // list of files in directory
           Nodetype nodetype;
           };
       typedef struct Tcell Cell, *List;
    localname is the name within this directory, e.g. ddd.c
    fullname is the full pathname for this file e.g. /home/staff/jrl/source/c/ddd.c
    nodetype is the type of this entry
    for a directory,content is a list of files in the directory

    BTW, likewise here:
    4. Are n_file, n_directory and n_symlink variables of the enum type Tnodetype?

    5. I understand the structure Tcell as the actual node for the linked list, but what is Nodetype nodetype? What is Nodetype that has nodetype as an instance of itself? Is Nodetype an offset of TNodetype?

    6. And why, after the struct Tcell has been declared does it re-declare a typedef struct Tcell?

    I'm sorry if this is a bit much or if it's overly simple. I thought trying to break it down would help, but it seems to have left me even more confused.

    Thanks for any insight you can give me. I'm happy to read any pages/texts that you would recommend if you feel that would be useful.

    Thanks.

    Hussein.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by hpteenagewizkid
    1. char * fullname(const char *root, const char * name)
    What is the difference between an asterisk directly before a name (*root) (which I know is a pointer) and one with a space between the asterisk and the name (char * fullname)?
    A space. Seriously, that's all.

    Quote Originally Posted by hpteenagewizkid
    2. I don't understand the issymlink function and the one that follows it. A structure seems to be defined, but what's its purpose?
    Windows doesn't have simlinks. Think of it as checking to see if it is a shortcut to some place else, or if it's a real file or directory.
    Quote Originally Posted by hpteenagewizkid
    3. The filecount function, there are a lot of functions, readdir, etc and pointers, *dd and *dp I've never seen before. I assume these are derived from the included dirent.h and assert.h files, so I'd need to look at those to work out what's going on?
    Yep. Also consider using a search engine with the keywords "man functionname", such as "man fopen".

    Quote Originally Posted by hpteenagewizkid
    4. Are n_file, n_directory and n_symlink variables of the enum type Tnodetype?
    Yes. Look at the line which declares them.
    Quote Originally Posted by hpteenagewizkid
    5. I understand the structure Tcell as the actual node for the linked list, but what is Nodetype nodetype? What is Nodetype that has nodetype as an instance of itself? Is Nodetype an offset of TNodetype?
    "Nodetype" is just a way to make enum type variables with a name like int or char.
    Quote Originally Posted by hpteenagewizkid
    6. And why, after the struct Tcell has been declared does it re-declare a typedef struct Tcell?
    Same reason. Too lazy to actually type struct before the name of their structure, so they typedef it to a new name.


    Quzah.
    Last edited by quzah; 12-04-2006 at 08:29 AM.
    Hope is the first step on the road to disappointment.

  3. #3
    Living to Learn
    Join Date
    Feb 2006
    Location
    Aberdeen, UK
    Posts
    33
    Hi. thanks very much for that - it seems so simple when you put it like that, and I can't believe that it was simply white space for Q1!

    OK, I'll go ahead and try to strip out the original bits and put in the linked list, and take it from there. I want to try to do as must of it as I can myself but maybe I could call back if I get in a rut?

    Also, I assume the UNIX bits will cause a problem as I'm not running UNIX. I use Bloodshed Dev C++ as my compiler which doesn't recognise them. Can anyone offer a solution to this? Cygwin seems to have the same problem when last I checked.

    Hussein.

  4. #4
    Living to Learn
    Join Date
    Feb 2006
    Location
    Aberdeen, UK
    Posts
    33
    EDIT: cygwin seems to work fine.

    Hussein.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. more then 100errors in header
    By hallo007 in forum Windows Programming
    Replies: 20
    Last Post: 05-13-2007, 08:26 AM
  2. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  3. Using VC Toolkit 2003
    By Noobwaker in forum Windows Programming
    Replies: 8
    Last Post: 03-13-2006, 07:33 AM
  4. Connecting to a mysql server and querying problem
    By Diod in forum C++ Programming
    Replies: 8
    Last Post: 02-13-2006, 10:33 AM
  5. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM