python regex to match multi-line preprocessor macro

What follows is a regular expression I have written to match multi-line pre-processor macros in C / C++ code. I'm by no means a regular expressions guru, so I'd welcome any advice on how I can make this better.

Here's the regex:

\s*#define(.*\\\n)+[\S]+(?!\\)

It should match all of this:

#define foo(x) if(x) \
doSomething(x)

But only some of this (shouldn't match the next line of code:

#define foo(x) if(x) \
doSomething(x)
normalCode();

And also shouldn't match single-line preprocessor macros.

I'm pretty sure that the regex above works - but as I said, there probably a better way of doing it, and I imagine that there are ways of breaking it. Can anyone suggest any?


Asked by: Melanie475 | Posted: 24-09-2021






Answer 1

This is a simple test program I knocked up:

#!/usr/bin/env python

TEST1="""
#include "Foo.h"
#define bar foo\\
    x
#include "Bar.h"
"""

TEST2="""
#define bar foo
#define x 1 \\
    12 \\
    2 \\\\ 3
Foobar
"""

TEST3="""
#define foo(x) if(x) \\
doSomething(x)
"""

TEST4="""
#define foo(x) if(x) \\
doSomething(x)
normalCode();
"""

import re
matcher = re.compile(r"^[ \t]*#define(.*\\\n)+.*$",re.MULTILINE)

def extractDefines(s):
    mo = matcher.search(s)
    if not mo:
        print mo
        return
    print mo.group(0)

extractDefines(TEST1)
extractDefines(TEST2)
extractDefines(TEST3)
extractDefines(TEST4)

The re I used:

r"^[ \t]*#define(.*\\\n)+.*$"

Is very similar to the one use used, the changes:

  1. [ \t] To avoid newlines at the start of the define.
  2. I rely on + being greedy, so I can use a simple .*$ at the end to get the first line of the define that doesn't end with \

Answered by: Fenton129 | Posted: 25-10-2021



Answer 2

start        = r"^\s*#define\s+"
continuation = r"(?:.*\\\n)+"
lastline     = r".*$"

re_multiline_macros = re.compile(start + continuation + lastline, 
                                 re.MULTILINE)

Answered by: Anna599 | Posted: 25-10-2021



Similar questions

How would you do the equivalent of preprocessor directives in Python?

Is there a way to do the following preprocessor directives in Python? #if DEBUG < do some code > #else < do some other code > #endif


preprocessor - python equivalent of '#define func() ' or how to comment out a function call in python

my python code is interlaced with lots of function calls used for (debugging|profiling|tracing etc.) for example: import logging logging.root.setLevel(logging.DEBUG) logging.debug('hello') j = 0 for i in range(10): j += i logging.debug('i %d j %d' % (i,j)) print(j) logging.debug('bye') i want to #define these resource consuming functions out of the code. something like the c equiv...


Mimic C preprocessor with Python/Ruby?

I need to mimic the preprocessor feature of C with Python. If I want to run the debug release, I use as follows with C #ifdef DEBUG printf(...) #endif I just use -DDEBUG or similar to trigger it on or off. What method can I use for Python/Ruby? I mean, what should I do to control the behavior of python/ruby scripts in such a way that I can change a variable that affects al...


python - Choose Mako preprocessor based on file extension?

I would like to somehow instrument a mako.lookup.TemplateLookup such that it applies certain preprocessors only for certain file extensions. Specifically, I have a haml.preprocessor that I would like to apply to all templates whose file name ends with .haml. Thanks!


Lout preprocessor writtten in python used during the production of the book entitled <C++ GUI Programming with Qt>

The authors (Jasmin Blanchette &amp; Mark Summerfield) of C++ GUI Programming with Qt has disclosed production details at the end of the book. Quote: The authors wrote the text using NEdit and Vim. They typeset and indexed the text themselves, marking it up with a modified Lout syntax that they converted to pure Lout using a custom preprocess...


preprocessor - How do you implement "#ifdef" in python?

Programming in C I used to have code sections only used for debugging purposes (logging commands and the like). Those statements could be completely disabled for production by using #ifdef pre-processor directives, like this: #ifdef MACRO controlled text #endif /* MACRO */ What is the best way to do something similar in python?


c - Making a preprocessor with Python

I basically need to write a C preprocessor with Python, I've search around and since i need to fully custom my code and have a perfect understanding of what's going on, I better writting on my own. Here's where I am : I first parse some header files (.h) to find #define keyword and build up a dictionnary with all the founded directives (with their values they have one). Then I need to parse source files (.c) depend...


python - SWIG with preprocessor macro from boost preprocessor

I'm utilizing the enum with ToString implementation that was suggested here: How to convert an enum type variable to a string? It utilizes and works fine as far as I can tell. My issues arise when I try to wrap and export the macro to a Python library wrapped with SWIG. Similar question:


python - How to run the Sage preprocessor from command line

I'm running my Sage program with sage -python file.py, How do I get sage to run the same preprocessor on 'file.py' as it does on code in the Sage notebook? (Also, why would Sage not do this by default?)


python - gdb API preprocessor macro

I would like to access preprocessor macro definitions using GDB's embedded Python interpreter. Is there a Python macro API for GDB? in GDB you can do: gdb> info macro MACRO But there is no mention of a Python API for macro's in the documentation. https://sourceware.org/gdb/onlinedocs/gdb/Python-API....






Still can't find your answer? Check out these communities...



PySlackers | Full Stack Python | NHS Python | Pythonist Cafe | Hacker Earth | Discord Python



top