cgmb / guardonce

Utilities for converting from C/C++ include guards to #pragma once and back again.
MIT License
142 stars 3 forks source link

Support other include guard conventions #3

Closed cgmb closed 7 years ago

cgmb commented 11 years ago

The function to transform the file name into the include guard needs to be more flexible. It's particularly important in guard2once.py since we're trying to match any existing convention a user might have for their files.

Workaround: Edit guardSymbol(fileName) in crules.py to transform the file name and return the include guard symbol for the file.

cgmb commented 8 years ago

I want to package guardonce up for PyPI, but clearly it's not reasonable to ask people to open up and change scripts that are under package management. So, my thought is to have a mini-language that allows you to specify the transformation from the file information to include guard.

Part of this should be a survey of projects to check what sorts of transformations are actually used in practice. I've written a few for my own projects that look like this:

def fileNameGuardSymbol(ctx):
    return ctx.fileName.upper().replace('.', '_')

def filePathGuardSymbol(ctx):
    return ctx.filePath.upper().replace('.', '_').replace('/','_')

This sort of pipeline seems to work well. However, if we're designing a language specifically for describing these sorts of transformations, we can (and should) optimize for terseness. The transformation rule is probably going to be a quoted string, written by hand on the command line.

My thought is that you'd ultimately be able to specify the first pattern with a pipeline like so: checkguard -p 'name | upper'. Here's how that language would work.

Pattern Language

A pattern description is made up of a series of pipeline stages. It starts with a source to provide the initial string, which then goes through a bunch of filters that modify it. After the last filter, all characters that cannot exist in include guards are replaced with _.

Filters are separated by |. Filters can take arguments, which are separated by spaces. Strings generally do not need to be quoted, unless they contain |, whitespace or start with @ (which is reserved).

Sources

name

returns the file's basename

path

if recursive, returns the file's path relative to the root directory given to the program. if not recursive, returns the path to the file given when invoking the program.

Filters

upper

returns the input, converted to uppercase

e.g. Match.h -> MATCH.H

lower

returns the input, converted to uppercase

e.g. Match.h -> match.h

pascal

converts snake_case to PascalCase

e.g. sprite_animator.h -> SpriteAnimator.h

snake

converts PascalCase to snake_case

e.g. SpriteAnimator.h -> sprite_animator.h

replace

substitutes one character for another

e.g. replace . _ does Match.h -> Match_h

append

appends the given string to the end of the input

e.g. append __ does Match.h -> Match.h__

prepend

prepends the given string to the beginning of the input

e.g. prepend __ does Match.h -> __Match.h

surround

surround the input with the given string

e.g. surround __ does Match.h -> __Match.h__

Sink

raw

if the pipeline ends in a raw sink, then the normal substitution of illegal characters by _ is suppressed

cgmb commented 7 years ago

The pattern language specification has been moved into the repository.

This was fixed with the release of v2.0.0