From nobody Tue Nov 26 13:32:04 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 207.211.31.120 as permitted sender) client-ip=207.211.31.120; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-1.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of redhat.com designates 207.211.31.120 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1573483513; cv=none; d=zoho.com; s=zohoarc; b=cDikeZ+6YRSI+jXSvseg+2vc8D/xfLAWlaRjJ+3QyQ0qGD/93aCT2Yh6To2WKdWRw9fHHugtfX4tTLIdbUFJLgU7ip8b3pxy0uqNSjE4bjCOu5dxCiNE0LburjREiaJPDPRM7oAD1waCclW2jN3gjfO5UhzPvR4uLd038aI+D6k= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573483513; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=k/Zar0IWWwmQ6IBQt+aLK1DL4zzwdLCNe8gp/Py1IYE=; b=jA/ulGIWrKKpqOV/sty0oniTfuw2LtsZZqeVapbJ5lHkGnLZ9mqy2qGsRHjR4oPV4GphStpGw5CpfUZpF18pZbn6ocgo2wuD9xyGQ7G2dgCtpOUiYWMOn7vyBWqdqMavBZ/IUwxU90JQ2P+Q+p5X5/1qMVOvBSTh8kQh6G2xdl4= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of redhat.com designates 207.211.31.120 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.120]) by mx.zohomail.com with SMTPS id 1573483513819691.5192981219024; Mon, 11 Nov 2019 06:45:13 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-119-0lJVFTYhNHOaEONxbBVOKA-1; Mon, 11 Nov 2019 09:45:10 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 8493C890F0A; Mon, 11 Nov 2019 14:45:01 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 607BD1001B03; Mon, 11 Nov 2019 14:45:01 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 197D54E56D; Mon, 11 Nov 2019 14:45:01 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id xABEirVc020358 for ; Mon, 11 Nov 2019 09:44:53 -0500 Received: by smtp.corp.redhat.com (Postfix) id 3B44F17AD4; Mon, 11 Nov 2019 14:44:53 +0000 (UTC) Received: from catbus.gsslab.fab.redhat.com (dhcp-32.gsslab.fab.redhat.com [10.33.9.32]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7EA7B5D9C9; Mon, 11 Nov 2019 14:44:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573483512; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=k/Zar0IWWwmQ6IBQt+aLK1DL4zzwdLCNe8gp/Py1IYE=; b=hARpBOwCuQulObJ4y5i7MaRY9Ew/lOE2zuTMn3GjG7fKgUDwcA6yRVcjRTf9BVZ8rVOStM lP4hY/to0Ei5O/C1rBFK6zAu7eolZCofWrjOsdiRsNItfUHtJRbXPCcEA+3RCJViQ7ipyx uT/AWn5T4UHtAQrw1JYSkETY9XqbTUA= From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Date: Mon, 11 Nov 2019 14:38:07 +0000 Message-Id: <20191111143826.16050-5-berrange@redhat.com> In-Reply-To: <20191111143826.16050-1-berrange@redhat.com> References: <20191111143826.16050-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v5 04/23] build-aux: rewrite header ifdef checker in Python X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-MC-Unique: 0lJVFTYhNHOaEONxbBVOKA-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" As part of an goal to eliminate Perl from libvirt build tools, rewrite the header-ifdef.pl tool in Python. This was a straight conversion, manually going line-by-line to change the syntax from Perl to Python. Thus the overall structure of the file and approach is the same. Signed-off-by: Daniel P. Berrang=C3=A9 Reviewed-by: J=C3=A1n Tomko Tested-by: Cole Robinson --- Makefile.am | 2 +- build-aux/header-ifdef.pl | 182 ------------------------------ build-aux/syntax-check.mk | 4 +- scripts/header-ifdef.py | 231 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 234 insertions(+), 185 deletions(-) delete mode 100644 build-aux/header-ifdef.pl create mode 100644 scripts/header-ifdef.py diff --git a/Makefile.am b/Makefile.am index d9369c9197..6cccbf38da 100644 --- a/Makefile.am +++ b/Makefile.am @@ -47,7 +47,7 @@ EXTRA_DIST =3D \ AUTHORS.in \ scripts/augeas-gentest.py \ scripts/check-spacing.py \ - build-aux/header-ifdef.pl \ + scripts/header-ifdef.py \ scripts/minimize-po.py \ scripts/mock-noinline.py \ scripts/prohibit-duplicate-header.py \ diff --git a/build-aux/header-ifdef.pl b/build-aux/header-ifdef.pl deleted file mode 100644 index dba3dbcbdc..0000000000 --- a/build-aux/header-ifdef.pl +++ /dev/null @@ -1,182 +0,0 @@ -#!/usr/bin/perl -# -# Validate that header files follow a standard layout: -# -# /* -# ...copyright header... -# */ -# -# #pragma once -# ....content.... -# -#--- -# -# For any file ending priv.h, before the #pragma once -# We will have a further section -# -# #ifndef SYMBOL_ALLOW -# # error .... -# #endif /* SYMBOL_ALLOW */ -# -# -#--- -# -# For public headers (files in include/), use the standard header guard in= stead of #pragma once: -# #ifndef SYMBOL -# # define SYMBOL -# ....content.... -# #endif /* SYMBOL */ - -use strict; -use warnings; - -my $STATE_COPYRIGHT_COMMENT =3D 0; -my $STATE_COPYRIGHT_BLANK =3D 1; -my $STATE_PRIV_START =3D 2; -my $STATE_PRIV_ERROR =3D 3; -my $STATE_PRIV_END =3D 4; -my $STATE_PRIV_BLANK =3D 5; -my $STATE_GUARD_START =3D 6; -my $STATE_GUARD_DEFINE =3D 7; -my $STATE_GUARD_END =3D 8; -my $STATE_EOF =3D 9; -my $STATE_PRAGMA =3D 10; - -my $file =3D " "; -my $ret =3D 0; -my $ifdef =3D ""; -my $ifdefpriv =3D ""; -my $publicheader =3D 0; - -my $state =3D $STATE_EOF; -my $mistake =3D 0; - -sub mistake { - my $msg =3D shift; - warn $msg; - $mistake =3D 1; - $ret =3D 1; -} - -while (<>) { - if (not $file eq $ARGV) { - if ($state =3D=3D $STATE_COPYRIGHT_COMMENT) { - &mistake("$file: missing copyright comment"); - } elsif ($state =3D=3D $STATE_COPYRIGHT_BLANK) { - &mistake("$file: missing blank line after copyright header"); - } elsif ($state =3D=3D $STATE_PRIV_START) { - &mistake("$file: missing '#ifndef $ifdefpriv'"); - } elsif ($state =3D=3D $STATE_PRIV_ERROR) { - &mistake("$file: missing '# error ...priv allow...'"); - } elsif ($state =3D=3D $STATE_PRIV_END) { - &mistake("$file: missing '#endif /* $ifdefpriv */'"); - } elsif ($state =3D=3D $STATE_PRIV_BLANK) { - &mistake("$file: missing blank line after priv header check"); - } elsif ($state =3D=3D $STATE_GUARD_START) { - if ($publicheader) { - &mistake("$file: missing '#ifndef $ifdef'"); - } else { - &mistake("$file: missing '#pragma once' header guard"); - } - } elsif ($state =3D=3D $STATE_GUARD_DEFINE) { - &mistake("$file: missing '# define $ifdef'"); - } elsif ($state =3D=3D $STATE_GUARD_END) { - &mistake("$file: missing '#endif /* $ifdef */'"); - } - - $ifdef =3D uc $ARGV; - $ifdef =3D~ s,.*/,,; - $ifdef =3D~ s,[^A-Z0-9],_,g; - $ifdef =3D~ s,__+,_,g; - unless ($ifdef =3D~ /^LIBVIRT_/ && $ARGV !~ /libvirt_internal.h/) { - $ifdef =3D "LIBVIRT_" . $ifdef; - } - $ifdefpriv =3D $ifdef . "_ALLOW"; - - $file =3D $ARGV; - $state =3D $STATE_COPYRIGHT_COMMENT; - $mistake =3D 0; - $publicheader =3D ($ARGV =3D~ /include\//); - } - - if ($mistake || - $ARGV =3D~ /config-post\.h$/ || - $ARGV =3D~ /vbox_(CAPI|XPCOM)/) { - $state =3D $STATE_EOF; - next; - } - - if ($state =3D=3D $STATE_COPYRIGHT_COMMENT) { - if (m,\*/,) { - $state =3D $STATE_COPYRIGHT_BLANK; - } - } elsif ($state =3D=3D $STATE_COPYRIGHT_BLANK) { - if (! /^$/) { - &mistake("$file: missing blank line after copyright header"); - } - if ($ARGV =3D~ /priv\.h$/) { - $state =3D $STATE_PRIV_START; - } else { - $state =3D $STATE_GUARD_START; - } - } elsif ($state =3D=3D $STATE_PRIV_START) { - if (/^$/) { - &mistake("$file: too many blank lines after copyright header"); - } elsif (/#ifndef $ifdefpriv$/) { - $state =3D $STATE_PRIV_ERROR; - } else { - &mistake("$file: missing '#ifndef $ifdefpriv'"); - } - } elsif ($state =3D=3D $STATE_PRIV_ERROR) { - if (/# error ".*"$/) { - $state =3D $STATE_PRIV_END; - } else { - &mistake("$file: missing '# error ...priv allow...'"); - } - } elsif ($state =3D=3D $STATE_PRIV_END) { - if (m,#endif /\* $ifdefpriv \*/,) { - $state =3D $STATE_PRIV_BLANK; - } else { - &mistake("$file: missing '#endif /* $ifdefpriv */'"); - } - } elsif ($state =3D=3D $STATE_PRIV_BLANK) { - if (! /^$/) { - &mistake("$file: missing blank line after priv guard"); - } - $state =3D $STATE_GUARD_START; - } elsif ($state =3D=3D $STATE_GUARD_START) { - if (/^$/) { - &mistake("$file: too many blank lines after copyright header"); - } - if ($publicheader) { - if (/#ifndef $ifdef$/) { - $state =3D $STATE_GUARD_DEFINE; - } else { - &mistake("$file: missing '#ifndef $ifdef'"); - } - } else { - if (/#pragma once/) { - $state =3D $STATE_PRAGMA; - } else { - &mistake("$file: missing '#pragma once' header guard"); - } - } - } elsif ($state =3D=3D $STATE_GUARD_DEFINE) { - if (/# define $ifdef$/) { - $state =3D $STATE_GUARD_END; - } else { - &mistake("$file: missing '# define $ifdef'"); - } - } elsif ($state =3D=3D $STATE_GUARD_END) { - if (m,#endif /\* $ifdef \*/$,) { - $state =3D $STATE_EOF; - } - } elsif ($state =3D=3D $STATE_PRAGMA) { - next; - } elsif ($state =3D=3D $STATE_EOF) { - die "$file: unexpected content after '#endif /* $ifdef */'"; - } else { - die "$file: unexpected state $state"; - } -} -exit $ret; diff --git a/build-aux/syntax-check.mk b/build-aux/syntax-check.mk index 0cfd181224..016e05e7a2 100644 --- a/build-aux/syntax-check.mk +++ b/build-aux/syntax-check.mk @@ -2166,8 +2166,8 @@ mock-noinline: $(PYTHON) $(top_srcdir)/scripts/mock-noinline.py =20 header-ifdef: - $(AM_V_GEN)$(VC_LIST) | $(GREP) '\.[h]$$' | xargs \ - $(PERL) $(top_srcdir)/build-aux/header-ifdef.pl + $(AM_V_GEN)$(VC_LIST) | $(GREP) '\.[h]$$' | $(RUNUTF8) xargs \ + $(PYTHON) $(top_srcdir)/scripts/header-ifdef.py =20 test-wrap-argv: $(AM_V_GEN)$(VC_LIST) | $(GREP) -E '\.(ldargs|args)' | xargs \ diff --git a/scripts/header-ifdef.py b/scripts/header-ifdef.py new file mode 100644 index 0000000000..94c2882225 --- /dev/null +++ b/scripts/header-ifdef.py @@ -0,0 +1,231 @@ +#!/usr/bin/env python +# +# Copyright (C) 2018-2019 Red Hat, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library. If not, see +# . +# +# Validate that header files follow a standard layout: +# +# /* +# ...copyright header... +# */ +# +# #pragma once +# ....content.... +# +# --- +# +# For any file ending priv.h, before the #pragma once +# We will have a further section +# +# #ifndef SYMBOL_ALLOW +# # error .... +# #endif /* SYMBOL_ALLOW */ +# +# +# --- +# +# For public headers (files in include/), use the standard +# header guard instead of #pragma once: +# #ifndef SYMBOL +# # define SYMBOL +# ....content.... +# #endif /* SYMBOL */ + +from __future__ import print_function + +import os.path +import re +import sys + +STATE_COPYRIGHT_COMMENT =3D 0 +STATE_COPYRIGHT_BLANK =3D 1 +STATE_PRIV_START =3D 2 +STATE_PRIV_ERROR =3D 3 +STATE_PRIV_END =3D 4 +STATE_PRIV_BLANK =3D 5 +STATE_GUARD_START =3D 6 +STATE_GUARD_DEFINE =3D 7 +STATE_GUARD_END =3D 8 +STATE_EOF =3D 9 +STATE_PRAGMA =3D 10 + + +def check_header(filename): + ifdef =3D "" + ifdefpriv =3D "" + + state =3D STATE_EOF + + ifdef =3D os.path.basename(filename).upper() + ifdef =3D re.sub(r"""[^A-Z0-9]""", "_", ifdef) + ifdef =3D re.sub(r"""__+""", "_", ifdef) + + if (not ifdef.startswith("LIBVIRT_") or + filename.find("libvirt_internal.h") !=3D -1): + ifdef =3D "LIBVIRT_" + ifdef + + ifdefpriv =3D ifdef + "_ALLOW" + + state =3D STATE_COPYRIGHT_COMMENT + publicheader =3D False + if filename.find("include/") !=3D -1: + publicheader =3D True + + with open(filename, "r") as fh: + for line in fh: + line =3D line.rstrip("\n") + if state =3D=3D STATE_COPYRIGHT_COMMENT: + if line.find("*/") !=3D -1: + state =3D STATE_COPYRIGHT_BLANK + elif state =3D=3D STATE_COPYRIGHT_BLANK: + if line !=3D "": + print("%s: missing blank line after copyright header" % + filename, file=3Dsys.stderr) + return True + + if filename.endswith("priv.h"): + state =3D STATE_PRIV_START + else: + state =3D STATE_GUARD_START + elif state =3D=3D STATE_PRIV_START: + if line =3D=3D "": + print("%s: too many blank lines after copyright header= " % + filename, file=3Dsys.stderr) + return True + elif re.search(r"""#ifndef %s$""" % ifdefpriv, line): + state =3D STATE_PRIV_ERROR + else: + print("%s: missing '#ifndef %s'" % (filename, ifdefpri= v), + file=3Dsys.stderr) + return True + elif state =3D=3D STATE_PRIV_ERROR: + if re.search(r"""# error ".*"$""", line): + state =3D STATE_PRIV_END + else: + print("%s: missing '# error ...priv allow...'" % + filename, file=3Dsys.stderr) + return True + elif state =3D=3D STATE_PRIV_END: + if re.search(r"""#endif /\* %s \*/""" % ifdefpriv, line): + state =3D STATE_PRIV_BLANK + else: + print("%s: missing '#endif /* %s */'" % + (filename, ifdefpriv), file=3Dsys.stderr) + return True + elif state =3D=3D STATE_PRIV_BLANK: + if line !=3D "": + print("%s: missing blank line after priv guard" % + filename, file=3Dsys.stderr) + return True + state =3D STATE_GUARD_START + elif state =3D=3D STATE_GUARD_START: + if line =3D=3D "": + print("%s: too many blank lines after copyright header= " % + filename, file=3Dsys.stderr) + return True + if publicheader: + if re.search(r"""#ifndef %s$""" % ifdef, line): + state =3D STATE_GUARD_DEFINE + else: + print("%s: missing '#ifndef %s'" % + (filename, ifdef), file=3Dsys.stderr) + return True + else: + if re.search(r"""#pragma once""", line): + state =3D STATE_PRAGMA + else: + print("%s: missing '#pragma once' header guard" % + filename, file=3Dsys.stderr) + return True + elif state =3D=3D STATE_GUARD_DEFINE: + if re.search(r"""# define %s$""" % ifdef, line): + state =3D STATE_GUARD_END + else: + print("%s: missing '# define %s'" % + (filename, ifdef), file=3Dsys.stderr) + return True + elif state =3D=3D STATE_GUARD_END: + if re.search(r"""#endif /\* %s \*/$""" % ifdef, line): + state =3D STATE_EOF + elif state =3D=3D STATE_PRAGMA: + next + elif state =3D=3D STATE_EOF: + print("%s: unexpected content after '#endif /* %s */'" % + (filename, ifdef), file=3Dsys.stderr) + return True + else: + print("%s: unexpected state $state" % + filename, file=3Dsys.stderr) + return True + + if state =3D=3D STATE_COPYRIGHT_COMMENT: + print("%s: missing copyright comment" % + filename, file=3Dsys.stderr) + return True + elif state =3D=3D STATE_COPYRIGHT_BLANK: + print("%s: missing blank line after copyright header" % + filename, file=3Dsys.stderr) + return True + elif state =3D=3D STATE_PRIV_START: + print("%s: missing '#ifndef %s'" % + (filename, ifdefpriv), file=3Dsys.stderr) + return True + elif state =3D=3D STATE_PRIV_ERROR: + print("%s: missing '# error ...priv allow...'" % + filename, file=3Dsys.stderr) + return True + elif state =3D=3D STATE_PRIV_END: + print("%s: missing '#endif /* %s */'" % + (filename, ifdefpriv), file=3Dsys.stderr) + return True + elif state =3D=3D STATE_PRIV_BLANK: + print("%s: missing blank line after priv header check" % + filename, file=3Dsys.stderr) + return True + elif state =3D=3D STATE_GUARD_START: + if publicheader: + print("%s: missing '#ifndef %s'" % + (filename, ifdef), file=3Dsys.stderr) + return True + else: + print("%s: missing '#pragma once' header guard" % + filename, file=3Dsys.stderr) + return True + elif state =3D=3D STATE_GUARD_DEFINE: + print("%s: missing '# define %s'" % + (filename, ifdef), file=3Dsys.stderr) + return True + elif state =3D=3D STATE_GUARD_END: + print("%s: missing '#endif /* %s */'" % + (filename, ifdef), file=3Dsys.stderr) + return True + + return False + + +ret =3D 0 + +for filename in sys.argv[1:]: + if filename.find("config-post.h") !=3D -1: + continue + if filename.find("vbox_CAPI") !=3D -1: + continue + if filename.find("vbox_XPCOM") !=3D -1: + continue + if check_header(filename): + ret =3D 1 + +sys.exit(ret) --=20 2.21.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list