85 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
		
		
			
		
	
	
			85 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
| 
								 | 
							
								#!/bin/bash
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# clang-format-all: a tool to run clang-format on an entire project
							 | 
						||
| 
								 | 
							
								# Copyright (C) 2016 Evan Klitzke <evan@eklitzke.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/>.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function usage {
							 | 
						||
| 
								 | 
							
								    echo "Usage: $0 DIR..."
							 | 
						||
| 
								 | 
							
								    exit 1
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if [ $# -eq 0 ]; then
							 | 
						||
| 
								 | 
							
								    usage
							 | 
						||
| 
								 | 
							
								fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Variable that will hold the name of the clang-format command
							 | 
						||
| 
								 | 
							
								FMT=""
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Some distros just call it clang-format. Others (e.g. Ubuntu) are insistent
							 | 
						||
| 
								 | 
							
								# that the version number be part of the command. We prefer clang-format if
							 | 
						||
| 
								 | 
							
								# that's present, otherwise we work backwards from highest version to lowest
							 | 
						||
| 
								 | 
							
								# version.
							 | 
						||
| 
								 | 
							
								for clangfmt in clang-format{,-{4,3}.{9,8,7,6,5,4,3,2,1,0}}; do
							 | 
						||
| 
								 | 
							
								    if which "$clangfmt" &>/dev/null; then
							 | 
						||
| 
								 | 
							
								        FMT="$clangfmt"
							 | 
						||
| 
								 | 
							
								        break
							 | 
						||
| 
								 | 
							
								    fi
							 | 
						||
| 
								 | 
							
								done
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Check if we found a working clang-format
							 | 
						||
| 
								 | 
							
								if [ -z "$FMT" ]; then
							 | 
						||
| 
								 | 
							
								    echo "failed to find clang-format"
							 | 
						||
| 
								 | 
							
								    exit 1
							 | 
						||
| 
								 | 
							
								fi
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Check all of the arguments first to make sure they're all directories
							 | 
						||
| 
								 | 
							
								for dir in "$@"; do
							 | 
						||
| 
								 | 
							
								    if [ ! -d "${dir}" ]; then
							 | 
						||
| 
								 | 
							
								        echo "${dir} is not a directory"
							 | 
						||
| 
								 | 
							
								        usage
							 | 
						||
| 
								 | 
							
								    fi
							 | 
						||
| 
								 | 
							
								done
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Find a dominating file, starting from a given directory and going up.
							 | 
						||
| 
								 | 
							
								find-dominating-file() {
							 | 
						||
| 
								 | 
							
								    if [ -r "$1"/"$2" ]; then
							 | 
						||
| 
								 | 
							
								        return 0
							 | 
						||
| 
								 | 
							
								    fi
							 | 
						||
| 
								 | 
							
								    if [ "$1" = "/" ]; then
							 | 
						||
| 
								 | 
							
								        return 1
							 | 
						||
| 
								 | 
							
								    fi
							 | 
						||
| 
								 | 
							
								    find-dominating-file "$(realpath "$1"/..)" "$2"
							 | 
						||
| 
								 | 
							
								    return $?
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Run clang-format -i on all of the things
							 | 
						||
| 
								 | 
							
								for dir in "$@"; do
							 | 
						||
| 
								 | 
							
								    pushd "${dir}" &>/dev/null
							 | 
						||
| 
								 | 
							
								    if ! find-dominating-file . .clang-format; then
							 | 
						||
| 
								 | 
							
								        echo "Failed to find dominating .clang-format starting at $PWD"
							 | 
						||
| 
								 | 
							
								        continue
							 | 
						||
| 
								 | 
							
								    fi
							 | 
						||
| 
								 | 
							
								    find . \
							 | 
						||
| 
								 | 
							
								         \( -name '*.c' \
							 | 
						||
| 
								 | 
							
								         -o -name '*.cc' \
							 | 
						||
| 
								 | 
							
								         -o -name '*.cpp' \
							 | 
						||
| 
								 | 
							
								         -o -name '*.h' \
							 | 
						||
| 
								 | 
							
								         -o -name '*.hh' \
							 | 
						||
| 
								 | 
							
								         -o -name '*.hpp' \) \
							 | 
						||
| 
								 | 
							
								         -exec "${FMT}" -i '{}' \;
							 | 
						||
| 
								 | 
							
								    popd &>/dev/null
							 | 
						||
| 
								 | 
							
								done
							 |