Pregunta

Below is a typo for a C++ include guard. Both should read _MYFILE_H_.

#ifndef _MYFILE_H_
#define _MYFLIE_H_

How would you suggest searching a bunch of header files for a typo like this using GNU coreutils (e.g. grep, awk)?

¿Fue útil?

Solución

You could use awk:

{
  if ($1 == "#ifndef") { was_ifdef = 1; def = $2 }
  else if ($1 == "#define" && was_ifdef) 
    { 
      if ($2 != def)   printf("Mismatch in %s: expected %s found %s\n", FILENAME, def, $2);
    }
  else was_ifdef = 0;
}

There may be more clever ways to do this, but this is (to me) quite clear and easy.

Note: This will show "false positives" if the file contains something like

#ifndef FOO_DEFINED
typedef int foo;
#define FOO_DEFINED 
#endif

Otros consejos

grep by itself will not work here because regular expressions are not powerful enough to match the set of strings you're describing.

Specifically, the language of all strings of the form

#ifndef X
#define Y

Where XY is not a regular language. You can prove this by using the Myhill-Nerode theorem (since any two strings of the form #ifndef X for different choices of X fall into different equivalence classes of the distinguishability relation). As a result, there is no way to write a regular expression that can match strings of this form, and since grep uses pure mathematical regular expressions, there is no way to use grep to solve this problem.

Sorry for the negative result, but I hope this helps!

Multiple sed commands could do the trick.

for FILENAME in ./*.h; do
     [[ $(sed -n '1p' "$FILENAME" | sed -e 's/#ifndef //') != $(sed -n '2p' "$FILENAME" | sed -e 's/#define //') ]] && echo "$FILENAME"
end

Problem with that implementation is, that there may be no copyright header above the guard.

And I'm quite sure that this could be written more concise.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top