Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Using S_ISREG() (and other macros) as parameter to function

I am trying to create a function that will be generally used to determine if a file/directory exists, if it is within a certain path, and if it is of the specified type (S_ISREG, S_ISDIR, …

Here are the parts of the source pertaining to this question:

int checkExists(const char *name, void *func(int))) {
   struct stat st ;
   int returnValue = DOES_NOT_EXIST ;
   BOOL isInSourceHierarchy, isInTargetHierarchy ;

   if (stat(name, &st) != -1) {
      returnValue = EXISTS ;
      if (memcmp(name, top_dir, strlen(top_dir)))
         returnValue |= IN_SOURCE_STRUCTURE ;
      if (memcmp(name, tgt_dir, strlen(tgt_dir)))
         returnValue |= IN_TARGET_STRUCTURE ;
      if (func != NULL) {
         if (objType == func(st.st_mode))
            returnValue |= RIGHT_TYPE ;
      }
      return returnValue ;
   }
}

. . . 

if (S_ISREG(0)) {} // Yes, I know, I know.  This is for demonstration only.
if (checkExists(old, S_ISREG)) {
   // Do something
 } else { // Old file doesn't exist
   // Do something else
 }

When trying to compile this, I get:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

linkStructure.c:642:31: error: ‘S_ISREG’ undeclared (first use in this function)
  642 |          if (checkExists(old, S_ISREG)) {
      |                               ^~~~~~~

As can be seen, there is no complaint about the macro used as designed, of course. So my question is: Is there a way for me to reference the macro in my source like this? Or will I be left to basically emulate the macro in my function? (I suppose I could pass the expected type rather than the function, but for the sake of clarity, I would like to understand this limitation.)

>Solution :

It says S_ISREG is undefined because the preprocessor doesn’t ignore the parenthesis. #define FOO() defines FOO(), not FOO.

Also, your function expects a function pointer as parameter, but macros are compile-time only symbols, you can’t take its address.

But you can just wrap it in a function instead:

int isReg(int mode)
{
    return S_ISREG(mode);
}

Now you can use it as you wanted:

checkExists(old, isReg);

And you keep the flexibility of your original code.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading