From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124])
	by inbox.dpdk.org (Postfix) with ESMTP id A618BA09E4;
	Thu, 22 Apr 2021 11:02:19 +0200 (CEST)
Received: from [217.70.189.124] (localhost [127.0.0.1])
	by mails.dpdk.org (Postfix) with ESMTP id 2953D413E6;
	Thu, 22 Apr 2021 11:02:19 +0200 (CEST)
Received: from mga05.intel.com (mga05.intel.com [192.55.52.43])
 by mails.dpdk.org (Postfix) with ESMTP id 28F224069D
 for <dev@dpdk.org>; Thu, 22 Apr 2021 11:02:17 +0200 (CEST)
IronPort-SDR: D/nANlxxjNPPtH44MenV1teVuQmB3vpWC4BeaOqdStejxaq2HFq0lw7XJRK2b5JTVAuP6bZTHC
 EToh7bM9+K+w==
X-IronPort-AV: E=McAfee;i="6200,9189,9961"; a="281182397"
X-IronPort-AV: E=Sophos;i="5.82,242,1613462400"; d="scan'208";a="281182397"
Received: from orsmga007.jf.intel.com ([10.7.209.58])
 by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;
 22 Apr 2021 02:02:17 -0700
IronPort-SDR: jQVHMzbKlnxsMjhlHQUXM47/hYjpT1NZg1iVyU7ZoehBIADOUupcb6XzB16Ou4oZYU23l6H8yw
 NoshdCtmIckw==
X-ExtLoop1: 1
X-IronPort-AV: E=Sophos;i="5.82,242,1613462400"; d="scan'208";a="423830347"
Received: from silpixa00399126.ir.intel.com ([10.237.223.116])
 by orsmga007.jf.intel.com with ESMTP; 22 Apr 2021 02:02:15 -0700
From: Bruce Richardson <bruce.richardson@intel.com>
To: dev@dpdk.org
Cc: thomas@monjalon.net,
	Bruce Richardson <bruce.richardson@intel.com>
Date: Thu, 22 Apr 2021 10:02:11 +0100
Message-Id: <20210422090211.320855-1-bruce.richardson@intel.com>
X-Mailer: git-send-email 2.27.0
In-Reply-To: <20210421220358.2597249-1-thomas@monjalon.net>
References: <20210421220358.2597249-1-thomas@monjalon.net>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Subject: [dpdk-dev] [RFC PATCH] devtools: script to check meson indentation
 of lists
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org
Sender: "dev" <dev-bounces@dpdk.org>

This is a draft script developed when I was working on the whitespace rework
changes, since extended a little to attempt to fix some trailing comma issues.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
 devtools/dpdk_meson_check.py | 106 +++++++++++++++++++++++++++++++++++
 1 file changed, 106 insertions(+)
 create mode 100755 devtools/dpdk_meson_check.py

diff --git a/devtools/dpdk_meson_check.py b/devtools/dpdk_meson_check.py
new file mode 100755
index 000000000..dc4c714ad
--- /dev/null
+++ b/devtools/dpdk_meson_check.py
@@ -0,0 +1,106 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2021 Intel Corporation
+
+'''
+A Python script to run some checks on meson.build files in DPDK
+'''
+
+import sys
+import os
+from os.path import relpath, join
+from argparse import ArgumentParser
+
+VERBOSE = False
+FIX = False
+
+def scan_dir(path):
+    '''return meson.build files found in path'''
+    for root, dirs, files in os.walk(path):
+        if 'meson.build' in files:
+            yield(relpath(join(root, 'meson.build')))
+
+
+def check_indentation(filename, contents):
+    '''check that a list or files() is correctly indented'''
+    infiles = False
+    inlist = False
+    edit_count = 0
+    for lineno in range(len(contents)):
+        line = contents[lineno].rstrip()
+        if not line:
+            continue
+        if line.endswith('files('):
+            if infiles:
+                raise(f'Error parsing {filename}:{lineno}, got "files(" when already parsing files list')
+            if inlist:
+                print(f'Error parsing {filename}:{lineno}, got "files(" when already parsing array list')
+            infiles = True
+            indent = 0
+            while line[indent] == ' ':
+                indent += 1
+            indent += 8  # double indent required
+        elif line.endswith('= ['):
+            if infiles:
+                raise(f'Error parsing {filename}:{lineno}, got start of array when already parsing files list')
+            if inlist:
+                print(f'Error parsing {filename}:{lineno}, got start of array when already parsing array list')
+            inlist = True
+            indent = 0
+            while line[indent] == ' ':
+                indent += 1
+            indent += 8  # double indent required
+        elif infiles and (line.endswith(')') or line.strip().startswith(')')):
+            infiles = False
+            continue
+        elif inlist and line.endswith(']') or line.strip().startswith(']'):
+            inlist = False
+            continue
+        elif inlist or infiles:
+            # skip further subarrays or lists
+            if '[' in line  or ']' in line:
+                continue
+            if not line.startswith(' ' * indent) or line[indent] == ' ':
+                print(f'Error: Incorrect indent at {filename}:{lineno + 1}')
+                contents[lineno] = (' ' * indent) + line.strip() + '\n'
+                line = contents[lineno].rstrip()
+                edit_count += 1
+            if not line.endswith(',') and '#' not in line:
+                # TODO: support stripping comment and adding ','
+                print(f'Error: Missing trailing "," in list at {filename}:{lineno + 1}')
+                contents[lineno] = line + ',\n'
+                line = contents[lineno].rstrip()
+                edit_count += 1
+    return edit_count
+
+
+def process_file(filename):
+    '''run checks on file "filename"'''
+    if VERBOSE:
+        print(f'Processing {filename}')
+    with open(filename) as f:
+        contents = f.readlines()
+
+    if check_indentation(filename, contents) > 0 and FIX:
+        print(f"Fixing {filename}")
+        with open(filename, 'w') as f:
+            f.writelines(contents)
+
+
+def main():
+    '''parse arguments and then call other functions to do work'''
+    global VERBOSE
+    global FIX
+    parser = ArgumentParser(description='Run syntax checks on DPDK meson.build files')
+    parser.add_argument('-d', metavar='directory', default='.', help='Directory to process')
+    parser.add_argument('--fix', action='store_true', help='Attempt to fix errors')
+    parser.add_argument('-v', action='store_true', help='Verbose output')
+    args = parser.parse_args()
+
+    VERBOSE = args.v
+    FIX = args.fix
+    for f in scan_dir(args.d):
+        process_file(f)
+
+if __name__ == "__main__":
+    main()
--
2.27.0