]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
ci: add an Emacs script to format C files
authorVincent Bernat <vincent@bernat.ch>
Sat, 5 Nov 2022 23:40:51 +0000 (00:40 +0100)
committerVincent Bernat <vincent@bernat.ch>
Sat, 5 Nov 2022 23:40:51 +0000 (00:40 +0100)
    git ls-files '*.c' '*.h' \
        | grep -v '^include/' \
        | xargs emacs -Q --batch -l tests/ci/openbsd-knf-style.el

tests/ci/openbsd-knf-style.el [new file with mode: 0644]

diff --git a/tests/ci/openbsd-knf-style.el b/tests/ci/openbsd-knf-style.el
new file mode 100644 (file)
index 0000000..fa6a4d6
--- /dev/null
@@ -0,0 +1,203 @@
+;;
+;; OpenBSD KNF style - batch style converter
+;;
+;; Copyright (c) 2014,2015 Doug Hogan <doug@openbsd.org>
+;; Copyright (c) 2005 Nicholas Marriott <nicm@openbsd.org>
+;; Copyright (c) 2022 Vincent Bernat
+;;
+;; Permission to use, copy, modify, and distribute this software for any
+;; purpose with or without fee is hereby granted, provided that the above
+;; copyright notice and this permission notice appear in all copies.
+;;
+;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+;; The OpenBSD KNF style is from https://github.com/hogand/openbsd-knf-emacs
+
+;; This function is from nicm@
+(defun openbsd-knf-space-indent (langelem)
+  "Indents either 4 spaces or none.
+
+This function is from nicm@ and also in gsoares@'s config.
+Most useful with c-offset-alist entries that are lists such as
+arglist-cont-nonempty"
+  (save-excursion
+    (goto-char (cdr langelem))
+    (setq syntax (car (car (c-guess-basic-syntax))))
+    (while (or (eq syntax 'arglist-intro)
+              (or (eq syntax 'arglist-cont)
+                  (eq syntax 'arglist-cont-nonempty)))
+      (forward-line -1)
+      (setq syntax (car (car (c-guess-basic-syntax)))))
+    (beginning-of-line)
+    (re-search-forward "[^ \t]" (c-point 'eol))
+    (goto-char (+ (match-beginning 0) 4))
+    (vector (current-column))))
+
+;; OpenBSD KNF that doug@ uses.
+(defconst openbsd-knf-style
+  '(
+    ;; Debugging
+    ;; (c-echo-syntactic-information-p . t) ;; display C-c C-s when hit 'tab'
+    ;;
+    ;; General settings that should be enabled in c-mode
+    (indent-tabs-mode . t)      ;; use tabs whenever feasible
+    (fill-column . 80)          ;; Assume KNF tries to maintain 80 char lines
+    (show-trailing-whitespace . t)  ;; KNF says to not have trailing WS
+    (tab-width . 8)             ;; When displaying literal tab, show 8 spaces
+    ;; c-mode
+    (c-progress-interval . 1)   ;; display progress meter during long indents
+    (c-basic-offset . 8)        ;; KNF uses 8 space tabs
+    (c-comment-only-line-offset . 0)  ;; don't indent comments extra
+    (c-backspace-function . delete-backward-char)
+    (c-delete-function . delete-char)
+    (c-syntactic-indentation-in-macros . t) ;; indent inside macro defs
+    (c-tab-always-indent . t)  ;; indent line: Use C-q 'tab' to insert literal
+    (c-continued-statement-offset 0)
+    ;; (c-electric-flag . nil)   ;; if you don't like auto-indent
+    (c-electric-continued-statement . t)
+    ;;
+    (c-indent-comments-syntactically-p . nil)
+    ;;
+    ;; Offsets for the various c-mode symbols.  Offsets are sometimes based
+    ;; upon other offsets.  For instance, arglist-intro is the 1st argument
+    ;; line.  If you define arglist-cont, it uses arglist-intro plus that.
+    ;; c-echo-syntactic-information-p is your friend when debugging indents.
+    ;;
+    ;; [N] means absolute column.  All the others are relative.
+    ;;  0 = no extra indentation.  For literal column 0, use [0]
+    ;;  N = extra N spaces.  For literal column N, use [N]
+    ;; ++ = c-basic-offset * 2
+    ;; -- = c-basic-offset * -2
+    ;;  + = c-basic-offset * 1
+    ;;  - = c-basic-offset * -1
+    ;;  * = c-basic-offset * 0.5
+    ;;  / = c-basic-offset * -0.5
+    (c-offsets-alist . (
+                       ;; Literal symbols
+                       (func-decl-cont . 0)        ; C++ style func mod
+                       (block-open . 0)            ; '{' for block
+                       (label . [1])               ; goto label in column 1
+                       (comment-intro . 0)         ; C comment
+                       (cpp-macro . [0])           ; #define in column 0
+                       ;; Multiline macro symbols
+                       (cpp-define-intro . [0])    ; first list = column 0
+                       (cpp-macro-cont . +)        ; add'l lines in macro
+                       ;; Function symbols
+                       (defun-open . 0)            ; '{' alone for func
+                       (defun-close . 0)           ; '}' alone for func
+                       (defun-block-intro . +)     ; first line of func
+                       (topmost-intro . 0)         ; outermost part
+                       (topmost-intro-cont . 0)    ; outermost part cont
+                       (statement . 0)             ; func stmt (already off)
+                       ;; XXX statement-cont should be 4 unless
+                       ;; it is part of a macro, then 8.
+                       (statement-cont . *)        ; continue stmt
+                       ;; Class symbols.  XXX Should add support since there
+                       ;; is a little C++ in the tree (GNU)
+                       ;; Java
+                       ;; K&R
+                       (knr-argdecl-intro . +)     ; rare K&R (from KNF)
+                       (knr-argdecl . 0)           ; add'l indent for rest
+                       ;; Conditional construct symbols
+                       (block-close . 0)           ; '}' for block
+                       (statement-block-intro . +) ; stmt in loop/cond
+                       (substatement . +)          ; non-braced stmt if()
+                       (substatement-open . 0)     ; '{' in loop/cond
+                       (substatement-label . [1])  ; goto label in loop/cond
+                       (do-while-closure . 0)      ; 'while' alone in 'do'
+                       (else-clause . 0)           ; 'else' when not nested
+                       ;; Brace list symbols
+                       (brace-list-close . 0)      ; enum/agg list close
+                       (brace-list-intro . +)      ; 1st line of enum/agg
+                       (brace-list-entry . 0)      ; add'l indent for entries
+                       (brace-list-open . 0)       ; enum/agg init open
+                       ;; Switch statement symbols
+                       (statement-case-open . +)   ; '{' in case
+                       (statement-case-intro . +)  ; 1st line in case stmt
+                       (case-label . 0)            ; case label in switch
+                       ;; Paren list symbols
+                       ;; XXX This is typically a list so need to handle it
+                       ;; differently from the rest.  Emacs adds the indents.
+                       (arglist-intro . openbsd-knf-space-indent) ; 1st line
+                       (arglist-cont . openbsd-knf-space-indent)
+                       (arglist-cont-nonempty . openbsd-knf-space-indent)
+                       (arglist-close . 0)         ; ')' alone
+                       ;; External scope symbols
+                       (extern-lang-open . [0])    ; '{' alone in 'extern C'
+                       (extern-lang-close . [0])   ; '}' alone in 'extern C'
+                       (inextern-lang . +)         ; lines inside 'extern C'
+                       ;; Statement block
+                       (inexpr-statement . +)))    ; gcc extension stmt expr
+    ;; If not specified, the default is "before after".  All variables are
+    ;; defined here.
+    (c-hanging-braces-alist . (
+                              ;; All variables
+                              (defun-open before after)  ; function, enum
+                              (defun-close before after) ; function
+                              (class-open after) ; struct too
+                              (class-close before after)
+                              (inline-open after)
+                              (inline-close before after)
+                              (block-open after)
+                               (block-close . c-snug-do-while)
+                              (statement-cont after)
+                              (substatement-open after)
+                              (statement-case-open before after)
+                              (brace-list-open after)
+                              (brace-list-close before close)
+                              (brace-list-intro after)
+                              (brace-entry-open after)
+                              (extern-lang-open after)
+                              (extern-lang-close before after)
+                              (namespace-open after)           ;; C++
+                              (namespace-close before afetr)   ;; C++
+                              (module-open after)              ;; CORBA
+                              (module-close before after)      ;; CORBA
+                              (composition-open after)         ;; CORBA
+                              (composition-close before after) ;; CORBA
+                              (inexpr-class-open after)
+                              (inexpr-class-close before after)
+                              (arglist-cont-nonempty before after)))
+    ;; Whether to auto-insert newline before/after colon
+    (c-hanging-colons-alist . ((case-label after)
+                               (label after)
+                               (access-label after)  ;; C++
+                               (member-init-intro before)
+                               (inher-intro)))
+    ;; Whether to insert newlines after ';' or ','
+    (c-hanging-semi&comma-criteria . (
+                                     ;; supress newline when next line non-blank
+                                     c-semi&comma-no-newlines-before-nonblanks
+                                     ;; suppress newline in paren (for loop etc)
+                                     c-semi&comma-inside-parenlist
+                                     ;; supress newline for one liner
+                                     c-semi&comma-no-newlines-for-oneline-inliners))
+    ;; When autonewline mode is enabled, clean up some extra newlines
+    (c-cleanup-list . (brace-else-brace    ; } else {
+                       brace-elseif-brace  ; } else if {
+                       brace-catch-brace   ; } catch (...) {
+                       ;; empty-defun-braces ; {} instead of multiple lines
+                       defun-close-semi    ; struct: no \n between '}' and ';'
+                       list-close-comma    ; remove final comma
+                       scope-operator
+                      ;; space-before-funcall ; GNU standard
+                      ;; compact-empty-funcall ; another GNU standard
+                      ;; comment-close-slash ; term comment with slash
+                      ))
+    ))
+
+(c-add-style "openbsd" openbsd-knf-style)
+(dolist (file command-line-args-left)
+  (when (not (eq file "--"))
+    (save-excursion
+      (find-file file)
+      (c-mode)
+      (c-set-style "openbsd")
+      (indent-region (point-min) (point-max) nil)
+      (save-buffer))))