Giter VIP home page Giter VIP logo

py-c-preprocessor's Introduction

py-c-preprocessor

A preprocessor for C files written in python

What?

This is a preprocessor for C files written in python. It consumes C source and headers and generates outputs that are useful for code analysis and generation, such as:

  • Preprocessed C source
  • List of defined macros
  • Helpers for expanding and evaluating expresions

File can be passed in by paths, and headers included by #include directives, or passed in directly.

Why?

I wanted to be able to parse C headers programmatically in python, and use found definitions for code generation. This originally started as just a way to gather all defined macros, but it turns out you need to do most other tasks to do that correctly in a realistic code base. All other features are an eventual result of this requirement.

I could have solved this by just using gcc -E, but I had some reasons not to:

  • Didnt want to write to the file system
  • Didnt want to introduce a compiler as a dependancy
  • Having all expressions in python makes code generation/examination very tidy

How?

Mostly regex. Github Copilot was actually much more useful that expected.

Usage

from preprocessor import Preprocessor
p = Preprocessor()

# Include paths for headers can be specified
p.add_include_path('/path/to/headers')

# You can ignore missing includes to skip system included headers, such as stdio.h
p.ignore_missing_includes = True

# Macros can be defined before parsing
p.define('MACRO_A', '1')
p.define('MACRO_B', '(x + y / z)', ['x', 'y', 'z'])

# Source or headers can be included
p.include('/path/to/file.c')

# Multiple files can be included
# Source can also be supplied in place
p.include('/dummy/path.c', """
#ifdef MACRO_A
#define MACRO_C(x,y,z)  MACRO_B(x,y,z)
#else
#define MACRO_C(x,y,z)  (1)
#endif 

int main()
{
    return MACRO_C(1,2,3);
}
"""
)

# once the required source is parsed, expressions can be expanded
print(p.expand('MACRO_A + MACRO_C(1,2,3)')) # returns "1 + (1 + 2 / 3)"

# expressions can also be evaluated if they resolve to to primitive expressions
print(p.evaluate('MACRO_A + MACRO_C(1,2,3)')) # returns 2

# The preprocessed source can then be expanded
print(p.source())
# prints:
# int main()
# {
#     return 1 + 2 / 3;
# }

py-c-preprocessor's People

Contributors

lambosaurus avatar mati-ir avatar

Stargazers

__七把刀__ avatar ZhangMingzhe avatar  avatar  avatar Jonathon Reinhart avatar Munawwar Hussain Shelia avatar  avatar  avatar Ren Yanjie avatar Stanislav Zhelnio avatar

Watchers

Jonathon Reinhart avatar  avatar

Forkers

amoiz3567 mati-ir

py-c-preprocessor's Issues

Nested brackets are not handled correctly when parsing macro arguments

The following lines all show macros that are incorrectly split by the argument parser

test_assert(p.evaluate("MACRO_A(1,MACRO_B(2))"), 4)
# check alternate spacing
test_assert(p.evaluate("MACRO_A ( 1, MACRO_B( 2 ) )"), 4)
# try other orientation
test_assert(p.evaluate("MACRO_A(MACRO_B( 2 ), 1)"), 4)
# check for macro expansion in strings
test_assert(p.evaluate("\"MACRO_A(1,MACRO_B(2))\""), "MACRO_A(1,MACRO_B(2))")

Please specify a license

Hi, cool project! I'm impressed with how easy it was to get started with your library.

There's currently no license specified in this codebase. Would you mind adding one? I recommend Apache 2.0 or MIT.

definitions to structures not properly handled.

here is what I get when I try to parse

`#define AFLASH_0 (*(volatile struct AFLASH_tag *) 0xC3F33000UL)

from preprocessor import Preprocessor
p = Preprocessor()
p.include('/home/ubuntu/works/perf_definitions/MRC7765.h')
print(p.evaluate('AFLASH')) 
  result = eval(expr)
  File "<string>", line 1
    (*(AFLASH_tag *)      0xC3F44000UL)
                   ^
SyntaxError: invalid syntax

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.