BOOST_WORKAROUND and g++ -Wundef

Compiling the attached code with g++ 3.4.4 as g++ -Wundef -Iboost/cvs -o trial trial.cpp produces a heap of warnings warning: "__BORLANDC__" is not defined warning: "_MSC_FULL_VER" is not defined warning: "__MWERKS__" is not defined The warnings are produced by code like: #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) and are, of course, silenced by: #if defined(__MWERKS__) && \ BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) Grepping around the boost sources, I see that my 'fix' has been applied about 70 times already in the 1260 uses of BOOST_WORKAROUND. Assuming that the lack of consistency reflects only the size of the task, I've made a patch applying the fix to Boost.Random. Chipping away at the block... Hoping that this is useful, Angus

Angus Leeming ha escrito:
Compiling the attached code with g++ 3.4.4 as g++ -Wundef -Iboost/cvs -o trial trial.cpp produces a heap of warnings warning: "__BORLANDC__" is not defined warning: "_MSC_FULL_VER" is not defined warning: "__MWERKS__" is not defined
The warnings are produced by code like: #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
and are, of course, silenced by: #if defined(__MWERKS__) && \ BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
Grepping around the boost sources, I see that my 'fix' has been applied about 70 times already in the 1260 uses of BOOST_WORKAROUND. Assuming that the lack of consistency reflects only the size of the task, I've made a patch applying the fix to Boost.Random. Chipping away at the block...
But I think it makes much more sense if BOOST_WORKAROUND itself includes the patch, so that instead of its current definition # define BOOST_WORKAROUND(symbol, test) \ ((symbol != 0) && (1 % (( (symbol test) ) + 1))) it looks like # define BOOST_WORKAROUND(symbol, test) \ (defined(symbol) && (symbol != 0) && (1 % (( (symbol test) ) + 1))) Anyone sees some problem with this? Best, Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
Hoping that this is useful, Angus
------------------------------------------------------------------------ Name: random.diff random.diff Type: text/x-diff Encoding: 8Bit
Name: trial.cpp trial.cpp Type: Archivo de código fuente de C++ (application/x-unknown-content-type-cppfile) Encoding: 8Bit
------------------------------------------------------------------------ _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Joaquín Mª López Muñoz wrote:
But I think it makes much more sense if BOOST_WORKAROUND itself includes the patch, so that instead of its current definition
# define BOOST_WORKAROUND(symbol, test) \ ((symbol != 0) && (1 % (( (symbol test) ) + 1)))
it looks like
# define BOOST_WORKAROUND(symbol, test) \ (defined(symbol) && (symbol != 0) && (1 % (( (symbol test) ) + 1)))
Anyone sees some problem with this?
That would be much nicer. However, reverting my patch and applying yours (below, to confirm I got it right :)), I get this when compiling my test case: $ g++ -Wundef -Iboost/cvs -o trial trial.cpp In file included from boost/cvs/boost/random.hpp:36, from trial.cpp:1: boost/cvs/boost/random/linear_congruential.hpp:139:64: operator "defined" requires an identifier boost/cvs/boost/random/linear_congruential.hpp:139:64: missing '(' in expression Index: boost/detail/workaround.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/detail/workaround.hpp,v retrieving revision 1.11 diff -u -p -r1.11 workaround.hpp --- boost/detail/workaround.hpp 25 Aug 2005 16:27:20 -0000 1.11 +++ boost/detail/workaround.hpp 14 Oct 2005 09:07:35 -0000 @@ -39,7 +39,7 @@ # ifndef BOOST_STRICT_CONFIG # define BOOST_WORKAROUND(symbol, test) \ - ((symbol != 0) && (1 % (( (symbol test) ) + 1))) + (defined(symbol) && (symbol != 0) && (1 % (( (symbol test) ) + 1))) // ^ ^ ^ ^ // The extra level of parenthesis nesting above, along with the // BOOST_OPEN_PAREN indirection below, is required to satisfy the [angus@boris cvs]$

Angus Leeming ha escrito:
Joaquín Mª López Muñoz wrote:
But I think it makes much more sense if BOOST_WORKAROUND itself includes the patch, so that instead of its current definition
# define BOOST_WORKAROUND(symbol, test) \ ((symbol != 0) && (1 % (( (symbol test) ) + 1)))
it looks like
# define BOOST_WORKAROUND(symbol, test) \ (defined(symbol) && (symbol != 0) && (1 % (( (symbol test) ) + 1)))
Anyone sees some problem with this?
That would be much nicer. However, reverting my patch and applying yours (below, to confirm I got it right :)), I get this when compiling my test case:
$ g++ -Wundef -Iboost/cvs -o trial trial.cpp In file included from boost/cvs/boost/random.hpp:36, from trial.cpp:1: boost/cvs/boost/random/linear_congruential.hpp:139:64: operator "defined" requires an identifier boost/cvs/boost/random/linear_congruential.hpp:139:64: missing '(' in expression
Oh, my bad. Seems like a problem with the replacement semantics of the preprocessor, turns out defined() can only be used inside an #if or #elif directive, and not inside a #define as I tried, hence the problem --and I guess that's the reason why my proposed patch wasn't there in the first place when BOOST_WORKAROUND was written. Probably Mr. Mensonides can clarify this issue further. Sorry for the noise, Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

Angus Leeming <angus.leeming@btopenworld.com> writes:
Compiling the attached code with g++ 3.4.4 as g++ -Wundef -Iboost/cvs -o trial trial.cpp produces a heap of warnings warning: "__BORLANDC__" is not defined warning: "_MSC_FULL_VER" is not defined warning: "__MWERKS__" is not defined
The warnings are produced by code like: #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
and are, of course, silenced by: #if defined(__MWERKS__) && \ BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
Grepping around the boost sources, I see that my 'fix' has been applied about 70 times already in the 1260 uses of BOOST_WORKAROUND. Assuming that the lack of consistency reflects only the size of the task, I've made a patch applying the fix to Boost.Random. Chipping away at the block...
I object to adding all these specific silencing tests. IIRC we were going to handle this by creating boost macros for each compiler, similar to BOOST_MSVC, that were always #defined (possibly to 0), and using those in the BOOST_WORKAROUND tests. Otherwise, we will end up uglifying a lot of code, where BOOST_WORKAROUND is supposed to make the code much simpler and more readable. -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Angus Leeming <angus.leeming@btopenworld.com> writes:
Compiling the attached code with g++ 3.4.4 as g++ -Wundef -Iboost/cvs -o trial trial.cpp produces a heap of warnings warning: "__BORLANDC__" is not defined warning: "_MSC_FULL_VER" is not defined warning: "__MWERKS__" is not defined
The warnings are produced by code like: #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
and are, of course, silenced by: #if defined(__MWERKS__) && \ BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
Grepping around the boost sources, I see that my 'fix' has been applied about 70 times already in the 1260 uses of BOOST_WORKAROUND. Assuming that the lack of consistency reflects only the size of the task, I've made a patch applying the fix to Boost.Random. Chipping away at the block...
I object to adding all these specific silencing tests. IIRC we were going to handle this by creating boost macros for each compiler, similar to BOOST_MSVC, that were always #defined (possibly to 0), and using those in the BOOST_WORKAROUND tests. Otherwise, we will end up uglifying a lot of code, where BOOST_WORKAROUND is supposed to make the code much simpler and more readable.
Right. Agree 100%. The problem is that, at the moment, no such macro is always defined. How about macros like this in workaround.hpp: ====================================================== #if defined(__BORLANDC__) # define BOOST_WORKAROUND_BORLANDC(X) BOOST_WORKAROUND(__BORLANDC__, X) #else # define BOOST_WORKAROUND_BORLANDC(X) 0 #endif #if defined(__GNUC__) # define BOOST_WORKAROUND_GNUC(X) BOOST_WORKAROUND(__GNUC__, X) #else # define BOOST_WORKAROUND_GNUC(X) 0 #endif ====================================================== to be used so: ====================================================== #include <boost/detail/workaround.hpp> #if BOOST_WORKAROUND_BORLANDC(BOOST_TESTED_AT(0x3003)) # error __BORLANDC__ < 0x3003 #elif BOOST_WORKAROUND_GNUC(BOOST_TESTED_AT(4)) # error __GNUC__ < 4 #elif BOOST_WORKAROUND_GNUC(BOOST_TESTED_AT(3)) # error __GNUC__ < 3 #endif ====================================================== That would be simple and readable, no? Sorting through the sources, it appears that there are BOOST_WORKAROUNDS used for the following macros (extraction script also below). Would you like me to proceed on a bitwise basis, defining macros as above and then applying it to the code base, or can you describe a better way (for me) to proceed? Regards, Angus BOOST_DINKUMWARE_STDLIB BOOST_DYNAMIC_BITSET_GNUC_VERSION BOOST_INTEL BOOST_INTEL_CXX_VERSION BOOST_INTEL_WIN BOOST_IOSTREAMS_GCC BOOST_MPL_CFG_GCC BOOST_MSVC BOOST_RWSTD_VER __BORLANDC__ __COMO__ __COMO_VERSION__ _COMPILER_VERSION _CRAYC __DECCXX_VER __DMC__ __EDG__ __EDG_VERSION__ __GLIBCPP__ __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__ __HP_aCC __IBMCPP__ __ICL __INTEL_COMPILER _MSC_FULL_VER _MSC_VER MSVC __MWERKS__ _RWSTD_VER __SGI_STL_PORT _STLPORT_VERSION __SUNPRO_CC symbol $ grep -r BOOST_WORKAROUND boost | \ sed ' # Strip filename s/[^:]*:// # Ignore comments s/\/\/.*// # Strip lines that no longer contain BOOST_WORKAROUND /BOOST_WORKAROUND/!d # Extract the compiler macro s/.*BOOST_WORKAROUND *( *\([^ ,]\{1,\}\).*/\1/ ' workaround.txt | sort -u

Angus Leeming <angus.leeming@btopenworld.com> writes:
David Abrahams wrote:
I object to adding all these specific silencing tests. IIRC we were going to handle this by creating boost macros for each compiler, similar to BOOST_MSVC, that were always #defined (possibly to 0), and using those in the BOOST_WORKAROUND tests. Otherwise, we will end up uglifying a lot of code, where BOOST_WORKAROUND is supposed to make the code much simpler and more readable.
Right. Agree 100%.
The problem is that, at the moment, no such macro is always defined.
That should be done in boost/config/suffix.hpp
How about macros like this in workaround.hpp:
====================================================== #if defined(__BORLANDC__) # define BOOST_WORKAROUND_BORLANDC(X) BOOST_WORKAROUND(__BORLANDC__, X) #else # define BOOST_WORKAROUND_BORLANDC(X) 0 #endif
No thanks. We need BOOST_BORLANDC, etc. There are times when those values will be useful without the BOOST_WORKAROUND macro.
Sorting through the sources, it appears that there are BOOST_WORKAROUNDS used for the following macros (extraction script also below). Would you like me to proceed on a bitwise basis, defining macros as above and then applying it to the code base, or can you describe a better way (for me) to proceed?
It isn't just the uses of BOOST_WORKAROUND that will benefit. I'm sure there are plenty of legacy tests that should be converted. -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Angus Leeming <angus.leeming@btopenworld.com> writes:
David Abrahams wrote:
I object to adding all these specific silencing tests. IIRC we were going to handle this by creating boost macros for each compiler, similar to BOOST_MSVC, that were always #defined (possibly to 0), and using those in the BOOST_WORKAROUND tests. Otherwise, we will end up uglifying a lot of code, where BOOST_WORKAROUND is supposed to make the code much simpler and more readable.
Right. Agree 100%.
The problem is that, at the moment, no such macro is always defined.
That should be done in boost/config/suffix.hpp
Ie, you'd like to see this in boost/config/suffix.hpp: #if !defined(BOOST_MSVC) # define BOOST_MSVC 0 #endif ?
It isn't just the uses of BOOST_WORKAROUND that will benefit. I'm sure there are plenty of legacy tests that should be converted.
Certainly it means lots of change $ find boost -name '*' | \ while read file do grep BOOST_MSVC "$file" >> boost_msvc.txt done $ wc -l boost_msvc.txt 810 boost_msvc.txt I don't think that such a mammoth change could be done by hand without significant risk of regressions. That suggests, therefore, that it should be automated. In itself, that isn't too difficult to contemplate, but some questions need answering: I guess that '#if !defined(BOOST_MSVC)' becomes '#if (BOOST_MSVC > 0)'. Or would you prefer '#if BOOST_MSVC' ? Is there any need for 'BOOST_WORKAROUND(BOOST_MSVC, < foo)' anymore. Why not just 'BOOST_MSVC < foo' Of course, '#ifdef BOOST_MSVC && BOOST_WORKAROUND(BOOST_MSVC, < 1300)' is simplified, but to automate the simplification is bloody hard because preprocessor directives can span multiple lines... Hmmm. I guess that sed is powerful enough to do the job though. (There are no TABS in boost's sources, right?) So, Dave. If you can answer my questions above, I'll give this a shot if you think that the approach merits further work. Regards, Angus $ find boost -name '*' | \ while read file do test -d $file && continue echo "$file" | grep CVS >/dev/null && continue sed -n ' # Ignore #includes /^ *# *include/b # If the pattern space contains a preprocessor instruction /^ *#/{ # If the line ends with \ then the instruction continues # on the next line. Pull that in too. # Take account of C++-style comments :loop /\\ *\(\/\/[^\n]*\)\{0,1\}$/{ $!{ N bloop } } # The pattern space now contains a complete # preprocessor instruction. # For now, just print it out if it contains BOOST_MSVC /BOOST_MSVC/p }' $file >> boost_msvc2.txt done

Angus Leeming <angus.leeming@btopenworld.com> writes:
Is there any need for 'BOOST_WORKAROUND(BOOST_MSVC, < foo)' anymore. Why not just 'BOOST_MSVC < foo'
Yes. Read the documentation in boost/detail/workaround.hpp. It does a whole lot more than that. -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Angus Leeming <angus.leeming@btopenworld.com> writes:
Is there any need for 'BOOST_WORKAROUND(BOOST_MSVC, < foo)' anymore. Why not just 'BOOST_MSVC < foo'
Yes. Read the documentation in boost/detail/workaround.hpp. It does a whole lot more than that.
Dave, Rene, all interested in cleaning up these macros, I've written a little script to convert the current preprocessor commands to the ones that I think you'd like to see. It's a shell script but would be trivial to convert to python if you want the script itself and want it to run from a Windows box. For now, I've concentrated solely on BOOST_MSVC. Moreover, the script checks only the files in the boost subdirectory. It doesn't go into libs or test. I anticipate that it'll be straightforward to extend to cover other macros and subdirectories. The script, attached as boost_msvc.sh, produces boost_msvc.txt, also attached, when run from the top-level directory of the boost tree. At the moment, the script simply prints out the 'before' and 'after' of any preprocessor commands it's changed, separating each one with a blank line to improve legibility. -#if !defined(BOOST_MSVC) +#if (BOOST_MSVC == 0) -#ifdef BOOST_MSVC +#if (BOOST_MSVC > 0) -#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) +#if (BOOST_MSVC < 1300) I believe that the script performs the conversion that you'd like to see. Please confirm that I'm on the right track. Reading through the output, however, it appears to me that the script could go further. For example, to test for BOOST_MSVC and to then use _MSC_VER seems slightly ridiculous: -defined(BOOST_MSVC) && (_MSC_VER <= 1300) +(BOOST_MSVC > 0) && (_MSC_VER <= 1300) Wouldn't you rather see: +BOOST_WORKAROUND(BOOST_MSVC, <= 1300) ? Similarly, there are a lot of naked (BOOST_MSVC <= 1300). Would you prefer to see these replaced by the equivalent BOOST_WORKAROUND(BOOST_MSVC, <= 1300) ? One final question: it appears that many (most?) tests ignore the existence of BOOST_TESTED_AT(X). Is there a real reason for doing so, or is it simply that '<= 1300' is less typing than BOOST_TESTED_AT(1300)? Would you like me to extend the script to use BOOST_TESTED_AT(X) consistently? Regards, Angus

One final question: it appears that many (most?) tests ignore the existence of BOOST_TESTED_AT(X). Is there a real reason for doing so, or is it simply that '<= 1300' is less typing than BOOST_TESTED_AT(1300)? Would you like me to extend the script to use BOOST_TESTED_AT(X) consistently?
BOOST_TESTED_AT(1300) and <= 1300 aren't the same thing: the first says: "We know this bug was present in version 1300, and probably *in newer versions as well* until we know otherwise", the second says "only in versions prior to 1300". John.

John Maddock wrote:
One final question: it appears that many (most?) tests ignore the existence of BOOST_TESTED_AT(X). Is there a real reason for doing so, or is it simply that '<= 1300' is less typing than BOOST_TESTED_AT(1300)? Would you like me to extend the script to use BOOST_TESTED_AT(X) consistently?
BOOST_TESTED_AT(1300) and <= 1300 aren't the same thing: the first says: "We know this bug was present in version 1300, and probably *in newer versions as well* until we know otherwise", the second says "only in versions prior to 1300".
Thanks, John. Angus

Angus Leeming <angus.leeming@btopenworld.com> writes:
-#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) +#if (BOOST_MSVC < 1300)
I believe that the script performs the conversion that you'd like to see. Please confirm that I'm on the right track.
This transformation won't work. Consider what happens on GCC. False in the first case and true in the second. -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
-#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) +#if (BOOST_MSVC < 1300) I believe that the script performs the conversion that you'd like to see. Please confirm that I'm on the right track.
This transformation won't work. Consider what happens on GCC. False in the first case and true in the second.
Bleedin' obvious, now that you point it out :( I'm going to take this as answering one of my questions: should I transform the original expression above into one using BOOST_WORKAROUND? YES! Running the attached script on the boost/detail directory produces the changes below (repeated many times). The script is meant to be very conservative. The only "optimization" that it makes is removing "(BOOST_MSVC > 0) &&" from #if (BOOST_MSVC > 0) && BOOST_WORKAROUND(BOOST_MSVC, <= 1300) and then only if the command following "(BOOST_MSVC > 0) &&" contains BOOST_MSVC. I wrote a second little script to post-process the results for the entire boost subdirectory and throw away repeated changes so we can see just what the thing is doing. It transpires the script changes 887 preprocessor commands, but only 187 of those are unique. See boost_msvc_unique.txt. The one thing that I have seen so far that hasn't been changed to use BOOST_WORKAROUND but that perhaps should be is: -#if _MSC_VER+0 >= 1000 +#if BOOST_MSVC+0 >= 1000 I don't think any script could cope with such esoterica :) Finally, it is interesting to see which commands are processed by the script but are unchanged. See boost_msvc_unchanged.txt. It seems to me that the script has done its job. If you're happy with what it produces then I'll prepare a patch and move onto the next macro. Regards, Angus -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1020) -#elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN ) +#elif (BOOST_MSVC > 0) || defined( BOOST_INTEL_WIN ) -#if defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) || defined(BOOST_MSVC) && BOOST_MSVC <= 1300 +#if defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) || BOOST_WORKAROUND(BOOST_MSVC, <= 1300) -#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) -# if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround +# if (BOOST_MSVC > 0) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround

Angus Leeming wrote:
It seems to me that the script has done its job. If you're happy with what it produces then I'll prepare a patch and move onto the next macro.
Looking through the output really carefully led me to squash a couple of bugs and make one test more explicit. Revised script attached. A. $ diff -u boost_msvc_orig.sh boost_msvc.sh --- boost_msvc_orig.sh 2005-10-18 16:04:24.000000000 +0100 +++ boost_msvc.sh 2005-10-18 15:55:22.000000000 +0100 @@ -34,6 +34,10 @@ # of BOOST_MSVC itself! /^ *# *define \{1,\}BOOST_MSVC \{1,\}/b +# Nor are we interested in changing the definition of _MSC_VER +/^ *# *define \{1,\}_MSC_VER \{1,\}/b +/^ *# *undef \{1,\}_MSC_VER *$/b + # Save the preprocessor command in the hold space. # We will use it to pretty-print the output in "diff -u" style. s/$/ANGUS_SEPARATOR/ @@ -45,6 +49,11 @@ s/_MSC_VER\([^_]\)/BOOST_MSVC\1/g s/_MSC_VER$/BOOST_MSVC/ +# Be explicit! +# "#if BOOST_MSVC" -> "#if (BOOST_MSVC > 0)" +s/\(if \{1,\}\)BOOST_MSVC *$/\1(BOOST_MSVC > 0)/ +s/\(if \{1,\}! *\)BOOST_MSVC *$/\1(BOOST_MSVC == 0)/ + # We are interested in the BOOST_MSVC macro; # no false positives please. s/BOOST_MSVC_/ANGUS_MSVC_/g @@ -137,7 +146,7 @@ # Do not transform "BOOST_MSVC == 0" or "BOOST_MSVC > 0" /BOOST_MSVC \{1,\}\(==\|>\) \{1,\}0[ )]/ !{ - s/\(BOOST_MSVC\) *\(<=\|<\|==\|!=\|>=\|>\) * \([0-9]\{1 \}\)/BOOST_WORKAROUND(\1, \2 \3)/g + s/\(BOOST_MSVC\) *\(<=\|<\|==\|!=\|>=\|>\) *\([0-9]\{1 \}\)/BOOST_WORKAROUND(\1, \2 \3)/g } #================================================================

Angus Leeming <angus.leeming@btopenworld.com> writes:
It seems to me that the script has done its job. If you're happy with what it produces then I'll prepare a patch and move onto the next macro.
Hi Angus, I appreciate your efforts in this direction, but maybe we should wait until http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?BoostConfig is resolved? -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Angus Leeming <angus.leeming@btopenworld.com> writes:
It seems to me that the script has done its job. If you're happy with what it produces then I'll prepare a patch and move onto the next macro.
Hi Angus, I appreciate your efforts in this direction, but maybe we should wait until http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?BoostConfig is resolved?
Sure. As I read it, the suggestion is that BOOST_MSVC and MSC_VER would be replaced in the Boost code base with BOOST_CXX_MSVC. Using the script it would be trivial to both use the changed semantics (already done) and change the macro name (1 extra line). I don't read the Boost list too closely anymore (too much traffic, too little time) so it's possible that I'd miss any "wake up, Angus" call. Feel free to ping direct. Meantime, I'll move onto Borland. Regards, Angus ps, I tried to redo the script in Python, but since it's just a bunch of regex's, sed and the 'find -name boost '*' | while read file' loop is the optimal solution here; the Python version is twice as long. Admittedly, my Python skills aren't what they might be :)
participants (4)
-
Angus Leeming
-
David Abrahams
-
Joaquín Mª López Muñoz
-
John Maddock