mirror of
https://gitlab.gnome.org/GNOME/nautilus
synced 2024-10-02 14:03:39 +00:00
7b469dfa87
The lineup-parameters.c is hard to use with meson. Let's use the python rewrite from https://gitlab.gnome.org/GNOME/epiphany/-/blob/master/data/lineup-parameters instead.
211 lines
6.7 KiB
Python
Executable file
211 lines
6.7 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
#
|
|
# Copyright © 2019 Michael Catanzaro <mcatanzaro@gnome.org>
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
# Based on original C lineup-parameters by Sébastien Wilmet <swilmet@gnome.org>
|
|
# Rewritten in Python to allow simple execution from source directory.
|
|
#
|
|
# Usage: lineup-parameters [file]
|
|
# If the file is not given, stdin is read.
|
|
# The result is printed to stdout.
|
|
#
|
|
# The restrictions:
|
|
# - The function name must be at column 0, followed by a space and an opening
|
|
# parenthesis;
|
|
# - One parameter per line;
|
|
# - A parameter must follow certain rules (see the regex in the code), but it
|
|
# doesn't accept all possibilities of the C language.
|
|
# - The opening curly brace ("{") of the function must also be at column 0.
|
|
#
|
|
# If one restriction is missing, the function declaration is not modified.
|
|
#
|
|
# Example:
|
|
#
|
|
# gboolean
|
|
# frobnitz (Frobnitz *frobnitz,
|
|
# gint magic_number,
|
|
# GError **error)
|
|
# {
|
|
# ...
|
|
# }
|
|
#
|
|
# Becomes:
|
|
#
|
|
# gboolean
|
|
# frobnitz (Frobnitz *frobnitz,
|
|
# gint magic_number,
|
|
# GError **error)
|
|
# {
|
|
# ...
|
|
# }
|
|
#
|
|
# TODO: support "..." vararg parameter
|
|
|
|
import argparse
|
|
import re
|
|
import sys
|
|
|
|
from typing import NamedTuple
|
|
|
|
# https://regexr.com/ is your friend.
|
|
functionNameRegex = re.compile(r'^(\w+) ?\(')
|
|
parameterRegex = re.compile(
|
|
r'^\s*(?P<type>(const\s+)?\w+)'
|
|
r'\s+(?P<stars>\**)'
|
|
r'\s*(?P<name>\w+)'
|
|
r'\s*(?P<end>,|\))'
|
|
r'\s*$')
|
|
openingCurlyBraceRegex = re.compile(r'^{\s*$')
|
|
|
|
|
|
def matchFunctionName(line):
|
|
match = functionNameRegex.match(line)
|
|
if match:
|
|
functionName = match.group(1)
|
|
firstParamPosition = match.end(0)
|
|
return (functionName, firstParamPosition)
|
|
return (None, 0)
|
|
|
|
|
|
class ParameterInfo(NamedTuple):
|
|
paramType: str
|
|
name: str
|
|
numStars: int
|
|
isLastParameter: bool
|
|
|
|
|
|
def matchParameter(line):
|
|
_, firstParamPosition = matchFunctionName(line)
|
|
match = parameterRegex.match(line[firstParamPosition:])
|
|
if match is None:
|
|
return None
|
|
paramType = match.group('type')
|
|
assert(paramType is not None)
|
|
name = match.group('name')
|
|
assert(name is not None)
|
|
stars = match.group('stars')
|
|
numStars = len(stars) if stars is not None else 0
|
|
end = match.group('end')
|
|
isLastParameter = True if end is not None and end == ')' else False
|
|
return ParameterInfo(paramType, name, numStars, isLastParameter)
|
|
|
|
|
|
def matchOpeningCurlyBrace(line):
|
|
return True if openingCurlyBraceRegex.match(line) is not None else False
|
|
|
|
|
|
# Length returned is number of lines the declaration takes up
|
|
def getFunctionDeclarationLength(remainingLines):
|
|
for i in range(len(remainingLines)):
|
|
currentLine = remainingLines[i]
|
|
parameterInfo = matchParameter(currentLine)
|
|
if parameterInfo is None:
|
|
return 0
|
|
if parameterInfo.isLastParameter:
|
|
if i + 1 == len(remainingLines):
|
|
return 0
|
|
nextLine = remainingLines[i + 1]
|
|
if not matchOpeningCurlyBrace(nextLine):
|
|
return 0
|
|
return i + 1
|
|
return 0
|
|
|
|
|
|
def getParameterInfos(remainingLines, length):
|
|
parameterInfos = []
|
|
for i in range(length):
|
|
parameterInfos.append(matchParameter(remainingLines[i]))
|
|
return parameterInfos
|
|
|
|
|
|
def computeSpacing(parameterInfos):
|
|
maxTypeLength = 0
|
|
maxStarsLength = 0
|
|
for parameterInfo in parameterInfos:
|
|
maxTypeLength = max(maxTypeLength, len(parameterInfo.paramType))
|
|
maxStarsLength = max(maxStarsLength, parameterInfo.numStars)
|
|
return (maxTypeLength, maxStarsLength)
|
|
|
|
|
|
def printParameter(parameterInfo, maxTypeLength, maxStarsLength, outfile):
|
|
outfile.write(f'{parameterInfo.paramType:<{maxTypeLength + 1}}')
|
|
paramNamePaddedWithStars = f'{parameterInfo.name:*>{parameterInfo.numStars + len(parameterInfo.name)}}'
|
|
outfile.write(f'{paramNamePaddedWithStars:>{maxStarsLength + len(parameterInfo.name)}}')
|
|
|
|
|
|
def printFunctionDeclaration(remainingLines, length, useTabs, outfile):
|
|
functionName, _ = matchFunctionName(remainingLines[0])
|
|
assert(functionName is not None)
|
|
outfile.write(f'{functionName} (')
|
|
numSpacesToParenthesis = len(functionName) + 2
|
|
whitespace = ''
|
|
if useTabs:
|
|
tabs = ''.ljust(numSpacesToParenthesis // 8, '\t')
|
|
spaces = ''.ljust(numSpacesToParenthesis % 8)
|
|
whitespace = tabs + spaces
|
|
else:
|
|
whitespace = ''.ljust(numSpacesToParenthesis)
|
|
parameterInfos = getParameterInfos(remainingLines, length)
|
|
maxTypeLength, maxStarsLength = computeSpacing(parameterInfos)
|
|
numParameters = len(parameterInfos)
|
|
for i in range(numParameters):
|
|
parameterInfo = parameterInfos[i]
|
|
if i != 0:
|
|
outfile.write(whitespace)
|
|
printParameter(parameterInfo, maxTypeLength, maxStarsLength, outfile)
|
|
if i + 1 != numParameters:
|
|
outfile.write(',\n')
|
|
outfile.write(')\n')
|
|
|
|
|
|
def parseContents(infile, useTabs, outfile):
|
|
lines = infile.readlines()
|
|
i = 0
|
|
while i < len(lines):
|
|
line = lines[i]
|
|
functionName, _ = matchFunctionName(line)
|
|
if functionName is None:
|
|
outfile.write(line)
|
|
i += 1
|
|
continue
|
|
remainingLines = lines[i:]
|
|
length = getFunctionDeclarationLength(remainingLines)
|
|
if length == 0:
|
|
outfile.write(line)
|
|
i += 1
|
|
continue
|
|
printFunctionDeclaration(remainingLines, length, useTabs, outfile)
|
|
i += length
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser(
|
|
description='Line up parameters of C functions')
|
|
parser.add_argument('infile', nargs='?',
|
|
type=argparse.FileType('r'),
|
|
default=sys.stdin,
|
|
help='input C source file')
|
|
parser.add_argument('-o', metavar='outfile', nargs='?',
|
|
type=argparse.FileType('w'),
|
|
default=sys.stdout,
|
|
help='where to output modified file')
|
|
parser.add_argument('--tabs', action='store_true',
|
|
help='whether use tab characters in the output')
|
|
args = parser.parse_args()
|
|
parseContents(args.infile, args.tabs, args.o)
|
|
args.infile.close()
|
|
args.o.close()
|