summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.checkpatch.conf23
-rw-r--r--Android.mk7
-rw-r--r--COPYING674
-rw-r--r--MAINTAINERS8
-rw-r--r--android_versions.mk39
-rw-r--r--call.c167
-rw-r--r--client.c51
-rw-r--r--data.c337
-rw-r--r--ipc.c94
-rw-r--r--misc.c12
-rw-r--r--network.c88
-rw-r--r--power.c2
-rw-r--r--ril-versions-compat.h49
-rw-r--r--samsung-ril.c253
-rw-r--r--samsung-ril.h40
-rwxr-xr-xscripts/checkpatch.pl6799
-rw-r--r--scripts/const_structs.checkpatch64
-rw-r--r--scripts/guix.scm322
-rw-r--r--scripts/spelling.txt1489
-rw-r--r--sim.c224
-rw-r--r--sms.c6
-rw-r--r--srs-client/srs-client.c4
-rw-r--r--srs.c19
-rw-r--r--ss.c12
-rw-r--r--tools/srs-test.c5
-rw-r--r--utils.c13
26 files changed, 10253 insertions, 548 deletions
diff --git a/.checkpatch.conf b/.checkpatch.conf
new file mode 100644
index 0000000..ed8f1c6
--- /dev/null
+++ b/.checkpatch.conf
@@ -0,0 +1,23 @@
+# libsamsung-ril is not Linux. Make checkpatch.pl to not expect a Linux tree.
+--no-tree
+
+# libsamsung-ril doesn't have SPDX tags, and we would need to do some research
+# to find out if using SPDX in libsamsung-ril is a good thing or not.
+--ignore SPDX_LICENSE_TAG
+
+# Linux introduced shortcuts for compiler attributes in the following commit:
+# 82ddcb040570 [PATCH] extend the set of "__attribute__" shortcut macros
+# We might want to do the same later on, but for now we'll just ignore the
+# warnings until we implement that.
+--ignore PREFER_ALIGNED
+--ignore PREFER_PACKED
+--ignore PREFER_PRINTF
+--ignore PREFER_SCANF
+--ignore PREFER_SECTION
+
+# We currently have only one maintainer. It would be great to have more
+# co-maintainers, however until then we don't need to check for file patch
+# changes. Feel free to step in if you want to maintain the devices you added,
+# especially if it's a device that is not supported by Replicant or that
+# Replicant doesn't want to support for some reason.
+--ignore FILE_PATH_CHANGES
diff --git a/Android.mk b/Android.mk
index 6585a31..2b92a56 100644
--- a/Android.mk
+++ b/Android.mk
@@ -19,6 +19,7 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
+include $(LOCAL_PATH)/android_versions.mk
LOCAL_SRC_FILES := \
samsung-ril.c \
@@ -42,8 +43,8 @@ LOCAL_SRC_FILES := \
LOCAL_C_INCLUDES := \
$(LOCAL_PATH) \
$(LOCAL_PATH)/include \
- external/libsamsung-ipc/include \
hardware/libhardware_legacy/include \
+ hardware/ril/include/ \
system/core/include
LOCAL_CFLAGS := -DRIL_SHLIB
@@ -57,12 +58,14 @@ LOCAL_MODULE := libsamsung-ril
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
+include $(LOCAL_PATH)/android_versions.mk
LOCAL_SRC_FILES := srs-client/srs-client.c
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/include \
$(LOCAL_PATH)/srs-client/include \
+ hardware/ril/include/ \
LOCAL_SHARED_LIBRARIES := liblog libcutils
@@ -73,12 +76,14 @@ LOCAL_MODULE := libsrs-client
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
+include $(LOCAL_PATH)/android_versions.mk
LOCAL_SRC_FILES := tools/srs-test.c
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/include \
$(LOCAL_PATH)/srs-client/include \
+ hardware/ril/include/ \
LOCAL_SHARED_LIBRARIES := liblog libcutils libsrs-client
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..f288702
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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 <https://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<https://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<https://www.gnu.org/licenses/why-not-lgpl.html>.
diff --git a/MAINTAINERS b/MAINTAINERS
new file mode 100644
index 0000000..f7eb070
--- /dev/null
+++ b/MAINTAINERS
@@ -0,0 +1,8 @@
+Maintainers List
+----------------
+M: Replicant contributors <replicant@osuosl.org>
+L: replicant@osuosl.org
+T: git git://git.replicant.us/replicant/hardware_replicant_libsamsung-ril.git
+S: Maintained
+F: *
+F: */
diff --git a/android_versions.mk b/android_versions.mk
new file mode 100644
index 0000000..f34ce57
--- /dev/null
+++ b/android_versions.mk
@@ -0,0 +1,39 @@
+# This file is part of libsamsung-ipc.
+#
+# Copyright (C) 2021 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
+#
+# libsamsung-ipc 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.
+#
+# libsamsung-ipc 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 libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>.
+
+# We need to keep the compatibility with older Replicant versions, at least for
+# testing purposes: some of the devices we support in libsamsung-ipc are not
+# supported (yet) in newer Android versions or recent GNU/Linux distributions,
+# and doing tests on older devices might enable us to also understand better
+# the modem protocol and/or the EFS.
+
+# To limit the amount of work, we need to avoid modifying older Android versions
+# to be able to use recent libsamsung-ril and libsamsung-ipc.
+
+# Here's how different Android distributions behave with
+# LOCAL_PROPRIETARY_MODULE := true in libsamsung-ipc's Android.mk:
+# Replicant 4.2: It probably breaks the modem support
+# Replicant 6.0: It break the modem support
+# Replicant 9.0: The modem integration doesn't work because it was not finished
+# Replicant 10.0: The modem integration doesn't work because it was not finished
+# Replicant 11.0: It is required for the modem to work
+
+# Set a default value for build systems like Guix
+PLATFORM_VERSION ?= 7
+ifneq (1,$(filter 1,$(shell echo "$$(( $$(echo $(PLATFORM_VERSION) | sed 's/\..*//g') < 7 ))" )))
+ LOCAL_PROPRIETARY_MODULE := true
+endif
diff --git a/call.c b/call.c
index bd36335..007d65a 100644
--- a/call.c
+++ b/call.c
@@ -82,7 +82,7 @@ int ril_request_dial(void *data, size_t size, RIL_Token token)
if (data == NULL || size < sizeof(RIL_Dial))
goto error;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -92,20 +92,25 @@ int ril_request_dial(void *data, size_t size, RIL_Token token)
goto error;
identity = ril2ipc_call_identity(dial->clir);
- prefix = dial->address[0] == '+' ? IPC_CALL_PREFIX_INTL : IPC_CALL_PREFIX_NONE;
+ prefix = dial->address[0] ==
+ '+' ? IPC_CALL_PREFIX_INTL : IPC_CALL_PREFIX_NONE;
- rc = ipc_call_outgoing_setup(&request_data, IPC_CALL_TYPE_VOICE, identity, prefix, dial->address);
+ rc = ipc_call_outgoing_setup(&request_data, IPC_CALL_TYPE_VOICE,
+ identity, prefix, dial->address);
if (rc < 0)
goto error;
free(dial->address);
dial = NULL;
- rc = ipc_gen_phone_res_expect_complete(ipc_fmt_request_seq(token), IPC_CALL_OUTGOING);
+ rc = ipc_gen_phone_res_expect_complete(ipc_fmt_request_seq(token),
+ IPC_CALL_OUTGOING);
if (rc < 0)
goto error;
- rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_CALL_OUTGOING, IPC_TYPE_EXEC, (void *) &request_data, sizeof(request_data));
+ rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_CALL_OUTGOING,
+ IPC_TYPE_EXEC, (void *) &request_data,
+ sizeof(request_data));
if (rc < 0)
goto error;
@@ -139,18 +144,20 @@ int ril_request_hangup(__attribute__((unused)) void *data,
int hangup;
int rc;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
hangup = 1;
ril_request_data_set_uniq(RIL_REQUEST_HANGUP, &hangup, sizeof(hangup));
- rc = ipc_gen_phone_res_expect_complete(ipc_fmt_request_seq(token), IPC_CALL_RELEASE);
+ rc = ipc_gen_phone_res_expect_complete(ipc_fmt_request_seq(token),
+ IPC_CALL_RELEASE);
if (rc < 0)
goto error;
- rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_CALL_RELEASE, IPC_TYPE_EXEC, NULL, 0);
+ rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_CALL_RELEASE,
+ IPC_TYPE_EXEC, NULL, 0);
if (rc < 0)
goto error;
@@ -176,15 +183,17 @@ int ril_request_answer(__attribute__((unused)) void *data,
{
int rc;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
- rc = ipc_gen_phone_res_expect_complete(ipc_fmt_request_seq(token), IPC_CALL_ANSWER);
+ rc = ipc_gen_phone_res_expect_complete(ipc_fmt_request_seq(token),
+ IPC_CALL_ANSWER);
if (rc < 0)
goto error;
- rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_CALL_ANSWER, IPC_TYPE_EXEC, NULL, 0);
+ rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_CALL_ANSWER,
+ IPC_TYPE_EXEC, NULL, 0);
if (rc < 0)
goto error;
@@ -209,19 +218,22 @@ int ipc_call_status(struct ipc_message *message)
void *hangup_data;
size_t hangup_size;
- if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_call_status_data))
+ if (message == NULL || message->data == NULL ||
+ message->size < sizeof(struct ipc_call_status_data))
return -1;
data = (struct ipc_call_status_data *) message->data;
- // Nobody will ask for a call fail cause when we hangup ourselves
+ /* Nobody will ask for a call fail cause when we hangup ourselves */
hangup_size = ril_request_data_size_get(RIL_REQUEST_HANGUP);
hangup_data = ril_request_data_get(RIL_REQUEST_HANGUP);
- if (data->status == IPC_CALL_STATUS_RELEASED && (hangup_data == NULL || hangup_size == 0)) {
+ if (data->status == IPC_CALL_STATUS_RELEASED && (hangup_data == NULL ||
+ hangup_size == 0)) {
fail_cause = ipc2ril_call_fail_cause(data->end_cause);
- ril_request_data_set_uniq(RIL_REQUEST_LAST_CALL_FAIL_CAUSE, &fail_cause, sizeof(fail_cause));
+ ril_request_data_set_uniq(RIL_REQUEST_LAST_CALL_FAIL_CAUSE,
+ &fail_cause, sizeof(fail_cause));
} else if (hangup_data != NULL && hangup_size > 0) {
free(hangup_data);
}
@@ -240,12 +252,14 @@ int ril_request_last_call_fail_cause(__attribute__((unused)) void *data,
int fail_cause;
int rc;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
- fail_cause_size = ril_request_data_size_get(RIL_REQUEST_LAST_CALL_FAIL_CAUSE);
- fail_cause_data = ril_request_data_get(RIL_REQUEST_LAST_CALL_FAIL_CAUSE);
+ fail_cause_size = ril_request_data_size_get(
+ RIL_REQUEST_LAST_CALL_FAIL_CAUSE);
+ fail_cause_data = ril_request_data_get(
+ RIL_REQUEST_LAST_CALL_FAIL_CAUSE);
if (fail_cause_data == NULL || fail_cause_size < sizeof(fail_cause)) {
ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0);
@@ -254,7 +268,8 @@ int ril_request_last_call_fail_cause(__attribute__((unused)) void *data,
fail_cause = *((int *) fail_cause_data);
- ril_request_complete(token, RIL_E_SUCCESS, &fail_cause, sizeof(fail_cause));
+ ril_request_complete(token, RIL_E_SUCCESS, &fail_cause,
+ sizeof(fail_cause));
free(fail_cause_data);
@@ -271,7 +286,8 @@ int ipc_call_list(struct ipc_message *message)
unsigned char index;
char *number;
- if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_call_list_header))
+ if (message == NULL || message->data == NULL ||
+ message->size < sizeof(struct ipc_call_list_header))
return -1;
if (message->type != IPC_TYPE_RESP || !ipc_seq_valid(message->aseq))
@@ -279,7 +295,8 @@ int ipc_call_list(struct ipc_message *message)
count = ipc_call_list_count_extract(message->data, message->size);
if (count == 0) {
- ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_SUCCESS, NULL, 0);
+ ril_request_complete(ipc_fmt_request_token(message->aseq),
+ RIL_E_SUCCESS, NULL, 0);
return 0;
}
@@ -287,7 +304,8 @@ int ipc_call_list(struct ipc_message *message)
calls = (RIL_Call **) calloc(1, calls_size);
for (index = 0; index < count; index++) {
- entry = ipc_call_list_entry_extract(message->data, message->size, index);
+ entry = ipc_call_list_entry_extract(message->data,
+ message->size, index);
if (entry == NULL)
goto error;
@@ -296,7 +314,8 @@ int ipc_call_list(struct ipc_message *message)
goto error;
calls[index] = (RIL_Call *) calloc(1, sizeof(RIL_Call));
- calls[index]->state = ipc2ril_call_list_entry_state(entry->status);
+ calls[index]->state =
+ ipc2ril_call_list_entry_state(entry->status);
calls[index]->index = entry->id;
calls[index]->isMpty = entry->mpty;
calls[index]->isMT = entry->term == IPC_CALL_TERM_MT;
@@ -304,12 +323,14 @@ int ipc_call_list(struct ipc_message *message)
calls[index]->isVoice = entry->type == IPC_CALL_TYPE_VOICE;
calls[index]->isVoicePrivacy = 0;
calls[index]->number = strdup(number);
- calls[index]->numberPresentation = (entry->number_length > 0) ? 0 : 2;
+ calls[index]->numberPresentation =
+ (entry->number_length > 0) ? 0 : 2;
calls[index]->name = NULL;
calls[index]->namePresentation = 2;
calls[index]->uusInfo = NULL;
- if (entry->number_length > 0 && number != NULL && number[0] == '+')
+ if (entry->number_length > 0 &&
+ number != NULL && number[0] == '+')
calls[index]->toa = 145;
else
calls[index]->toa = 129;
@@ -319,12 +340,14 @@ int ipc_call_list(struct ipc_message *message)
calls_size = calls_count * sizeof(RIL_Call *);
- ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_SUCCESS, (void *) calls, calls_size);
+ ril_request_complete(ipc_fmt_request_token(message->aseq),
+ RIL_E_SUCCESS, (void *) calls, calls_size);
goto complete;
error:
- ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
+ ril_request_complete(ipc_fmt_request_token(message->aseq),
+ RIL_E_GENERIC_FAILURE, NULL, 0);
complete:
if (calls != NULL && calls_size > 0) {
@@ -350,13 +373,14 @@ int ril_request_get_current_calls(__attribute__((unused)) void *data,
{
int rc;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0) {
ril_request_complete(token, RIL_E_SUCCESS, NULL, 0);
return RIL_REQUEST_COMPLETED;
}
- rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_CALL_LIST, IPC_TYPE_GET, NULL, 0);
+ rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_CALL_LIST,
+ IPC_TYPE_GET, NULL, 0);
if (rc < 0) {
ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0);
return RIL_REQUEST_COMPLETED;
@@ -373,7 +397,8 @@ int ipc_call_cont_dtmf_callback(struct ipc_message *message)
char tone;
int rc;
- if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_gen_phone_res_data))
+ if (message == NULL || message->data == NULL ||
+ message->size < sizeof(struct ipc_gen_phone_res_data))
return -1;
data = (struct ipc_gen_phone_res_data *) message->data;
@@ -388,8 +413,9 @@ int ipc_call_cont_dtmf_callback(struct ipc_message *message)
if (dtmf_data != NULL && dtmf_size >= sizeof(tone)) {
tone = *((char *) dtmf_data);
- // Register a new DTMF tone
- ril_request_data_set(RIL_REQUEST_DTMF_START, dtmf_data, dtmf_size);
+ /* Register a new DTMF tone */
+ ril_request_data_set(RIL_REQUEST_DTMF_START, dtmf_data,
+ dtmf_size);
free(dtmf_data);
@@ -416,7 +442,8 @@ int ipc_call_cont_dtmf_callback(struct ipc_message *message)
goto complete;
error:
- ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
+ ril_request_complete(ipc_fmt_request_token(message->aseq),
+ RIL_E_GENERIC_FAILURE, NULL, 0);
complete:
return 0;
@@ -424,13 +451,15 @@ complete:
int ipc_call_burst_dtmf(struct ipc_message *message)
{
- if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_call_burst_dtmf_response_data))
+ if (message == NULL || message->data == NULL ||
+ message->size < sizeof(struct ipc_call_burst_dtmf_response_data))
return -1;
if (!ipc_seq_valid(message->aseq))
return 0;
- ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_SUCCESS, NULL, 0);
+ ril_request_complete(ipc_fmt_request_token(message->aseq),
+ RIL_E_SUCCESS, NULL, 0);
return 0;
}
@@ -458,7 +487,8 @@ int ril_request_dtmf_complete(unsigned char aseq, char tone)
if (rc < 0)
goto error;
- rc = ipc_fmt_send(aseq, IPC_CALL_BURST_DTMF, IPC_TYPE_EXEC, request_data, request_size);
+ rc = ipc_fmt_send(aseq, IPC_CALL_BURST_DTMF, IPC_TYPE_EXEC,
+ request_data, request_size);
if (rc < 0)
goto error;
@@ -486,35 +516,41 @@ int ril_request_dtmf(void *data, size_t size, RIL_Token token)
if (data == NULL || size < sizeof(char))
goto error;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
- request = ril_request_find_request_status(RIL_REQUEST_DTMF, RIL_REQUEST_HANDLED);
+ request = ril_request_find_request_status(RIL_REQUEST_DTMF,
+ RIL_REQUEST_HANDLED);
if (request != NULL)
return RIL_REQUEST_UNHANDLED;
- request = ril_request_find_request_status(RIL_REQUEST_DTMF_START, RIL_REQUEST_HANDLED);
+ request = ril_request_find_request_status(RIL_REQUEST_DTMF_START,
+ RIL_REQUEST_HANDLED);
if (request != NULL)
return RIL_REQUEST_UNHANDLED;
- request = ril_request_find_request_status(RIL_REQUEST_DTMF_STOP, RIL_REQUEST_HANDLED);
+ request = ril_request_find_request_status(RIL_REQUEST_DTMF_STOP,
+ RIL_REQUEST_HANDLED);
if (request != NULL)
return RIL_REQUEST_UNHANDLED;
tone = *((char *) data);
- // A previous DTMF tone was started
+ /* A previous DTMF tone was started */
dtmf_size = ril_request_data_size_get(RIL_REQUEST_DTMF_START);
dtmf_data = ril_request_data_get(RIL_REQUEST_DTMF_START);
if (dtmf_data != NULL && dtmf_size >= sizeof(tone)) {
free(dtmf_data);
- // Let the callback know what to do after completing the previous DTMF tone
+ /* Let the callback know what to do after completing the
+ * previous DTMF tone
+ */
ril_request_data_set(RIL_REQUEST_DTMF, data, size);
- rc = ril_request_dtmf_stop_complete(ipc_fmt_request_seq(token), 1);
+ rc = ril_request_dtmf_stop_complete(ipc_fmt_request_seq(token),
+ 1);
if (rc < 0) {
ril_request_data_free(RIL_REQUEST_DTMF);
goto error;
@@ -553,7 +589,8 @@ int ril_request_dtmf_start_complete(unsigned char aseq, char tone)
if (rc < 0)
return -1;
- rc = ipc_fmt_send(aseq, IPC_CALL_CONT_DTMF, IPC_TYPE_SET, (void *) &request_data, sizeof(request_data));
+ rc = ipc_fmt_send(aseq, IPC_CALL_CONT_DTMF, IPC_TYPE_SET,
+ (void *) &request_data, sizeof(request_data));
if (rc < 0)
return -1;
@@ -571,35 +608,41 @@ int ril_request_dtmf_start(void *data, size_t size, RIL_Token token)
if (data == NULL || size < sizeof(char))
goto error;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
- request = ril_request_find_request_status(RIL_REQUEST_DTMF, RIL_REQUEST_HANDLED);
+ request = ril_request_find_request_status(RIL_REQUEST_DTMF,
+ RIL_REQUEST_HANDLED);
if (request != NULL)
return RIL_REQUEST_UNHANDLED;
- request = ril_request_find_request_status(RIL_REQUEST_DTMF_START, RIL_REQUEST_HANDLED);
+ request = ril_request_find_request_status(RIL_REQUEST_DTMF_START,
+ RIL_REQUEST_HANDLED);
if (request != NULL)
return RIL_REQUEST_UNHANDLED;
- request = ril_request_find_request_status(RIL_REQUEST_DTMF_STOP, RIL_REQUEST_HANDLED);
+ request = ril_request_find_request_status(RIL_REQUEST_DTMF_STOP,
+ RIL_REQUEST_HANDLED);
if (request != NULL)
return RIL_REQUEST_UNHANDLED;
tone = *((char *) data);
- // A previous DTMF tone was started
+ /* A previous DTMF tone was started */
dtmf_size = ril_request_data_size_get(RIL_REQUEST_DTMF_START);
dtmf_data = ril_request_data_get(RIL_REQUEST_DTMF_START);
if (dtmf_data != NULL && dtmf_size >= sizeof(tone)) {
free(dtmf_data);
- // Let the callback know what to do after completing the previous DTMF tone
+ /* Let the callback know what to do after completing the
+ * previous DTMF tone
+ */
ril_request_data_set(RIL_REQUEST_DTMF_START, data, size);
- rc = ril_request_dtmf_stop_complete(ipc_fmt_request_seq(token), 1);
+ rc = ril_request_dtmf_stop_complete(ipc_fmt_request_seq(token),
+ 1);
if (rc < 0) {
ril_request_data_free(RIL_REQUEST_DTMF_START);
goto error;
@@ -609,7 +652,7 @@ int ril_request_dtmf_start(void *data, size_t size, RIL_Token token)
goto complete;
}
- // Register a new DTMF tone
+ /* Register a new DTMF tone */
ril_request_data_set(RIL_REQUEST_DTMF_START, data, size);
rc = ril_request_dtmf_start_complete(ipc_fmt_request_seq(token), tone);
@@ -640,14 +683,17 @@ int ril_request_dtmf_stop_complete(unsigned char aseq, int callback)
request_data.tone = 0;
if (callback)
- rc = ipc_gen_phone_res_expect_callback(aseq, IPC_CALL_CONT_DTMF, ipc_call_cont_dtmf_callback);
+ rc = ipc_gen_phone_res_expect_callback(
+ aseq, IPC_CALL_CONT_DTMF, ipc_call_cont_dtmf_callback);
else
- rc = ipc_gen_phone_res_expect_complete(aseq, IPC_CALL_CONT_DTMF);
+ rc = ipc_gen_phone_res_expect_complete(
+ aseq, IPC_CALL_CONT_DTMF);
if (rc < 0)
return -1;
- rc = ipc_fmt_send(aseq, IPC_CALL_CONT_DTMF, IPC_TYPE_SET, (void *) &request_data, sizeof(request_data));
+ rc = ipc_fmt_send(aseq, IPC_CALL_CONT_DTMF, IPC_TYPE_SET,
+ (void *) &request_data, sizeof(request_data));
if (rc < 0)
return -1;
@@ -663,19 +709,22 @@ int ril_request_dtmf_stop(__attribute__((unused)) void *data,
size_t dtmf_size;
int rc;
- request = ril_request_find_request_status(RIL_REQUEST_DTMF, RIL_REQUEST_HANDLED);
+ request = ril_request_find_request_status(RIL_REQUEST_DTMF,
+ RIL_REQUEST_HANDLED);
if (request != NULL)
return RIL_REQUEST_UNHANDLED;
- request = ril_request_find_request_status(RIL_REQUEST_DTMF_START, RIL_REQUEST_HANDLED);
+ request = ril_request_find_request_status(RIL_REQUEST_DTMF_START,
+ RIL_REQUEST_HANDLED);
if (request != NULL)
return RIL_REQUEST_UNHANDLED;
- request = ril_request_find_request_status(RIL_REQUEST_DTMF_STOP, RIL_REQUEST_HANDLED);
+ request = ril_request_find_request_status(RIL_REQUEST_DTMF_STOP,
+ RIL_REQUEST_HANDLED);
if (request != NULL)
return RIL_REQUEST_UNHANDLED;
- // Clear the DTMF tone
+ /* Clear the DTMF tone */
dtmf_size = ril_request_data_size_get(RIL_REQUEST_DTMF_START);
dtmf_data = ril_request_data_get(RIL_REQUEST_DTMF_START);
diff --git a/client.c b/client.c
index 8958fd4..2fc5944 100644
--- a/client.c
+++ b/client.c
@@ -92,11 +92,26 @@ int ril_client_open(struct ril_client *client)
{
int rc = 0;
- if (client == NULL)
+ if (client == NULL) {
+ RIL_LOGD("%s: Skipping open due to Invalid client "
+ "(client is NULL)",
+ __func__);
+ return -1;
+ }
+
+ if (client->handlers == NULL) {
+ RIL_LOGD("%s: Skipping open due to Invalid client "
+ "(client->handlers is NULL)",
+ __func__);
return -1;
+ }
- if (client->handlers == NULL || client->handlers->open == NULL)
+ if (client->handlers->open == NULL) {
+ RIL_LOGD("%s: Skipping open due to Invalid client "
+ "(client->handlers->open is NULL)",
+ __func__);
return -1;
+ }
rc = client->handlers->open(client);
if (rc < 0) {
@@ -165,7 +180,8 @@ void *ril_client_thread(void *data)
rc = client->handlers->loop(client);
if (rc < 0) {
- RIL_LOGE("%s client loop failed", client->name);
+ RIL_LOGE("%s client loop failed with error %d",
+ client->name, rc);
goto failure;
} else {
RIL_LOGE("%s client loop terminated", client->name);
@@ -193,16 +209,30 @@ int ril_client_loop(struct ril_client *client)
pthread_attr_t attr;
int rc;
- if (client == NULL)
+ if (client == NULL) {
+ RIL_LOGD("%s: Skipping loop due to Invalid client "
+ "(client is NULL)", __func__);
+ return -1;
+ }
+
+ if (client->handlers == NULL) {
+ RIL_LOGD("%s: Skipping loop due to Invalid client "
+ "(client->handlers is NULL)", __func__);
return -1;
+ }
- if (client->handlers == NULL || client->handlers->loop == NULL)
+ if (client->handlers->loop == NULL) {
+ RIL_LOGD("%s: Skipping loop due to Invalid client "
+ "(client->handlers->loop is NULL)",
+ __func__);
return -1;
+ }
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- rc = pthread_create(&client->thread, &attr, ril_client_thread, (void *) client);
+ rc = pthread_create(&client->thread, &attr, ril_client_thread,
+ (void *) client);
if (rc != 0) {
RIL_LOGE("Starting %s client loop failed", client->name);
return -1;
@@ -218,7 +248,8 @@ int ril_client_request_register(struct ril_client *client, int request,
{
int rc = 0;
- if (client == NULL || client->callbacks == NULL || client->callbacks->request_register == NULL)
+ if (client == NULL || client->callbacks == NULL ||
+ client->callbacks->request_register == NULL)
return -1;
rc = client->callbacks->request_register(client, request, token);
@@ -233,7 +264,8 @@ int ril_client_request_unregister(struct ril_client *client, int request,
{
int rc = 0;
- if (client == NULL || client->callbacks == NULL || client->callbacks->request_unregister == NULL)
+ if (client == NULL || client->callbacks == NULL ||
+ client->callbacks->request_unregister == NULL)
return -1;
rc = client->callbacks->request_unregister(client, request, token);
@@ -247,7 +279,8 @@ int ril_client_flush(struct ril_client *client)
{
int rc = 0;
- if (client == NULL || client->callbacks == NULL || client->callbacks->flush == NULL)
+ if (client == NULL || client->callbacks == NULL ||
+ client->callbacks->flush == NULL)
return -1;
rc = client->callbacks->flush(client);
diff --git a/data.c b/data.c
index 5fedf92..e41a205 100644
--- a/data.c
+++ b/data.c
@@ -18,6 +18,8 @@
* along with Samsung-RIL. If not, see <http://www.gnu.org/licenses/>.
*/
+#define _GNU_SOURCE
+#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
@@ -25,6 +27,7 @@
#include <utils/Log.h>
#include <netutils/ifc.h>
+#include <ril-versions-compat.h>
#include <samsung-ril.h>
#include <utils.h>
@@ -59,7 +62,7 @@ int ipc2ril_gprs_fail_cause(unsigned char fail_cause)
return PDP_FAIL_NSAPI_IN_USE;
case IPC_GPRS_FAIL_CAUSE_NETWORK_FAILURE:
return PDP_FAIL_DATA_REGISTRATION_FAIL;
- case IPC_GPRS_FAIL_CAUSE_UNKOWN_PDP_CONTEXT:
+ case IPC_GPRS_FAIL_CAUSE_UNKNOWN_PDP_CONTEXT:
case IPC_GPRS_FAIL_CAUSE_INVALID_MSG:
case IPC_GPRS_FAIL_CAUSE_PROTOCOL_ERROR:
return PDP_FAIL_PROTOCOL_ERRORS;
@@ -81,7 +84,8 @@ int ril_data_connection_register(unsigned int cid, char *apn, char *username,
if (apn == NULL || ril_data == NULL)
return -1;
- data_connection = (struct ril_data_connection *) calloc(1, sizeof(struct ril_data_connection));
+ data_connection = (struct ril_data_connection *) calloc(
+ 1, sizeof(struct ril_data_connection));
data_connection->cid = cid;
data_connection->enabled = 0;
data_connection->apn = apn;
@@ -111,7 +115,8 @@ int ril_data_connection_unregister(struct ril_data_connection *data_connection)
list = ril_data->data_connections;
while (list != NULL) {
if (list->data == (void *) data_connection) {
- memset(data_connection, 0, sizeof(struct ril_data_connection));
+ memset(data_connection, 0,
+ sizeof(struct ril_data_connection));
free(data_connection);
if (list == ril_data->data_connections)
@@ -140,11 +145,13 @@ int ril_data_connection_flush(void)
list = ril_data->data_connections;
while (list != NULL) {
if (list->data != NULL) {
- data_connection = (struct ril_data_connection *) list->data;
+ data_connection =
+ (struct ril_data_connection *) list->data;
ril_data_connection_stop(data_connection);
- memset(data_connection, 0, sizeof(struct ril_data_connection));
+ memset(data_connection, 0,
+ sizeof(struct ril_data_connection));
free(data_connection);
}
@@ -234,7 +241,8 @@ struct ril_data_connection *ril_data_connection_start(char *apn, char *username,
if (ipc_fmt_data->ipc_client == NULL)
goto error;
- rc = ipc_client_gprs_get_capabilities(ipc_fmt_data->ipc_client, &gprs_capabilities);
+ rc = ipc_client_gprs_get_capabilities(ipc_fmt_data->ipc_client,
+ &gprs_capabilities);
if (rc < 0)
goto error;
@@ -247,7 +255,8 @@ struct ril_data_connection *ril_data_connection_start(char *apn, char *username,
cid = i + 1;
if (cid > gprs_capabilities.cid_count) {
- RIL_LOGE("%s: No place left for a new data connection", __func__);
+ RIL_LOGE("%s: No place left for a new data connection",
+ __func__);
goto error;
}
@@ -263,7 +272,8 @@ struct ril_data_connection *ril_data_connection_start(char *apn, char *username,
if (data_connection == NULL)
goto error;
- RIL_LOGD("Starting new data connection with cid: %d and iface: %s", cid, iface);
+ RIL_LOGD("Starting new data connection with cid: %d and iface: %s", cid,
+ iface);
goto complete;
@@ -329,7 +339,11 @@ int ril_data_connection_enable(struct ril_data_connection *data_connection)
in_addr_t dns2_addr;
int rc;
- if (data_connection == NULL || data_connection->iface == NULL || data_connection->ip == NULL || data_connection->gateway == NULL || data_connection->subnet_mask == NULL)
+ if (data_connection == NULL ||
+ data_connection->iface == NULL ||
+ data_connection->ip == NULL ||
+ data_connection->gateway == NULL ||
+ data_connection->subnet_mask == NULL)
return -1;
client = ril_client_find_id(RIL_CLIENT_IPC_FMT);
@@ -340,7 +354,8 @@ int ril_data_connection_enable(struct ril_data_connection *data_connection)
if (ipc_fmt_data->ipc_client == NULL)
return -1;
- rc = ipc_client_gprs_activate(ipc_fmt_data->ipc_client, data_connection->cid);
+ rc = ipc_client_gprs_activate(ipc_fmt_data->ipc_client,
+ data_connection->cid);
if (rc < 0)
return -1;
@@ -358,13 +373,16 @@ int ril_data_connection_enable(struct ril_data_connection *data_connection)
else
dns2_addr = 0;
- rc = ifc_configure(data_connection->iface, ip_addr, ipv4NetmaskToPrefixLength(subnet_mask_addr), gateway_addr, dns1_addr, dns2_addr);
+ rc = ifc_configure(data_connection->iface, ip_addr,
+ ipv4NetmaskToPrefixLength(subnet_mask_addr),
+ gateway_addr, dns1_addr, dns2_addr);
if (rc < 0)
return -1;
data_connection->enabled = 1;
- RIL_LOGD("%s: Enabled data connection with cid %d", __func__, data_connection->cid);
+ RIL_LOGD("%s: Enabled data connection with cid %d",
+ __func__, data_connection->cid);
return 0;
}
@@ -386,7 +404,8 @@ int ril_data_connection_disable(struct ril_data_connection *data_connection)
if (ipc_fmt_data->ipc_client == NULL)
return -1;
- rc = ifc_reset_connections(data_connection->iface, RESET_IPV4_ADDRESSES);
+ rc = ifc_reset_connections(data_connection->iface,
+ RESET_IPV4_ADDRESSES);
if (rc < 0)
return -1;
@@ -394,13 +413,15 @@ int ril_data_connection_disable(struct ril_data_connection *data_connection)
if (rc < 0)
return -1;
- rc = ipc_client_gprs_deactivate(ipc_fmt_data->ipc_client, data_connection->cid);
+ rc = ipc_client_gprs_deactivate(ipc_fmt_data->ipc_client,
+ data_connection->cid);
if (rc < 0)
return -1;
data_connection->enabled = 0;
- RIL_LOGD("%s: Disabled data connection with cid %d", __func__, data_connection->cid);
+ RIL_LOGD("%s: Disabled data connection with cid %d",
+ __func__, data_connection->cid);
return 0;;
}
@@ -412,14 +433,17 @@ int ipc_gprs_define_pdp_context_callback(struct ipc_message *message)
struct ipc_gen_phone_res_data *data;
int rc;
- if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_gen_phone_res_data))
+ if (message == NULL || message->data == NULL ||
+ message->size < sizeof(struct ipc_gen_phone_res_data))
return -1;
data = (struct ipc_gen_phone_res_data *) message->data;
- data_connection = ril_data_connection_find_token(ipc_fmt_request_token(message->aseq));
+ data_connection = ril_data_connection_find_token(
+ ipc_fmt_request_token(message->aseq));
if (data_connection == NULL) {
- ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
+ ril_request_complete(ipc_fmt_request_token(message->aseq),
+ RIL_E_GENERIC_FAILURE, NULL, 0);
return 0;
}
@@ -427,15 +451,25 @@ int ipc_gprs_define_pdp_context_callback(struct ipc_message *message)
if (rc < 0)
goto error;
- rc = ipc_gprs_pdp_context_request_set_setup(&request_data, 1, data_connection->cid, data_connection->username, data_connection->password);
+ rc = ipc_gprs_pdp_context_request_set_setup(&request_data,
+ 1,
+ data_connection->cid,
+ data_connection->username,
+ data_connection->password);
if (rc < 0)
goto error;
- rc = ipc_gen_phone_res_expect_callback(message->aseq, IPC_GPRS_PDP_CONTEXT, ipc_gprs_pdp_context_callback);
+ rc = ipc_gen_phone_res_expect_callback(message->aseq,
+ IPC_GPRS_PDP_CONTEXT,
+ ipc_gprs_pdp_context_callback);
if (rc < 0)
goto error;
- rc = ipc_fmt_send(message->aseq, IPC_GPRS_PDP_CONTEXT, IPC_TYPE_SET, (void *) &request_data, sizeof(request_data));
+ rc = ipc_fmt_send(message->aseq,
+ IPC_GPRS_PDP_CONTEXT,
+ IPC_TYPE_SET,
+ (void *) &request_data,
+ sizeof(request_data));
if (rc < 0)
goto error;
@@ -444,7 +478,10 @@ int ipc_gprs_define_pdp_context_callback(struct ipc_message *message)
error:
ril_data_connection_stop(data_connection);
- ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
+ ril_request_complete(ipc_fmt_request_token(message->aseq),
+ RIL_E_GENERIC_FAILURE,
+ NULL,
+ 0);
complete:
return 0;
@@ -464,13 +501,17 @@ int ril_request_setup_data_call(void *data, size_t size, RIL_Token token)
if (data == NULL || size < 6 * sizeof(char *))
goto error;
- rc = ril_radio_state_check(RADIO_STATE_SIM_READY);
+ rc = ril_sim_has_reached_state(SIM_STATE_READY);
if (rc < 0) {
- ril_request_complete(token, RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW, NULL, 0);
+ ril_request_complete(token,
+ RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW,
+ NULL,
+ 0);
return RIL_REQUEST_COMPLETED;
}
- request = ril_request_find_request_status(RIL_REQUEST_SETUP_DATA_CALL, RIL_REQUEST_HANDLED);
+ request = ril_request_find_request_status(RIL_REQUEST_SETUP_DATA_CALL,
+ RIL_REQUEST_HANDLED);
if (request != NULL)
return RIL_REQUEST_UNHANDLED;
@@ -492,7 +533,9 @@ int ril_request_setup_data_call(void *data, size_t size, RIL_Token token)
strings_array_free(values, size);
values = NULL;
- RIL_LOGD("Setting up data connection to APN: %s with username/password: %s/%s", apn, username, password);
+ RIL_LOGD("Setting up data connection to APN:"
+ " %s with username/password: %s/%s",
+ apn, username, password);
data_connection = ril_data_connection_start(apn, username, password);
if (data_connection == NULL)
@@ -500,15 +543,23 @@ int ril_request_setup_data_call(void *data, size_t size, RIL_Token token)
data_connection->token = token;
- rc = ipc_gprs_define_pdp_context_setup(&request_data, 1, data_connection->cid, data_connection->apn);
+ rc = ipc_gprs_define_pdp_context_setup(&request_data, 1,
+ data_connection->cid,
+ data_connection->apn);
if (rc < 0)
goto error;
- rc = ipc_gen_phone_res_expect_callback(ipc_fmt_request_seq(token), IPC_GPRS_DEFINE_PDP_CONTEXT, ipc_gprs_define_pdp_context_callback);
+ rc = ipc_gen_phone_res_expect_callback(
+ ipc_fmt_request_seq(token),
+ IPC_GPRS_DEFINE_PDP_CONTEXT,
+ ipc_gprs_define_pdp_context_callback);
if (rc < 0)
goto error;
- rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_GPRS_DEFINE_PDP_CONTEXT, IPC_TYPE_SET, (void *) &request_data, sizeof(request_data));
+ rc = ipc_fmt_send(ipc_fmt_request_seq(token),
+ IPC_GPRS_DEFINE_PDP_CONTEXT,
+ IPC_TYPE_SET, (void *) &request_data,
+ sizeof(request_data));
if (rc < 0)
goto error;
@@ -545,7 +596,8 @@ int ipc_gprs_ps(struct ipc_message *message)
struct ipc_gprs_ps_data *data;
struct ril_data_connection *data_connection;
- if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_gprs_ps_data))
+ if (message == NULL || message->data == NULL ||
+ message->size < sizeof(struct ipc_gprs_ps_data))
return -1;
data = (struct ipc_gprs_ps_data *) message->data;
@@ -563,22 +615,22 @@ int ipc_gprs_pdp_context(struct ipc_message *message)
{
struct ipc_gprs_pdp_context_request_get_data *data;
struct ril_data_connection *data_connection;
-#if RIL_VERSION >= 6
- RIL_Data_Call_Response_v6 response[3];
-#else
- RIL_Data_Call_Response response[3];
-#endif
+ RIL_Data_Call_Response_compat response[3];
unsigned int entries_count;
unsigned int index = 0;
size_t size;
unsigned int i;
- if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_gprs_pdp_context_request_get_data))
+ if (message == NULL || message->data == NULL ||
+ message->size < sizeof(
+ struct ipc_gprs_pdp_context_request_get_data))
return -1;
data = (struct ipc_gprs_pdp_context_request_get_data *) message->data;
- entries_count = sizeof(data->entries) / sizeof(struct ipc_gprs_pdp_context_request_get_entry);
+ entries_count =
+ sizeof(data->entries) /
+ sizeof(struct ipc_gprs_pdp_context_request_get_entry);
memset(&response, 0, sizeof(response));
@@ -586,7 +638,8 @@ int ipc_gprs_pdp_context(struct ipc_message *message)
if (!data->entries[i].active)
continue;
- data_connection = ril_data_connection_find_cid(data->entries[i].cid);
+ data_connection =
+ ril_data_connection_find_cid(data->entries[i].cid);
if (data_connection == NULL)
continue;
@@ -608,10 +661,12 @@ int ipc_gprs_pdp_context(struct ipc_message *message)
if (data_connection->ip != NULL)
response[index].addresses = strdup(data_connection->ip);
- asprintf(&response[index].dnses, "%s %s", data_connection->dns1, data_connection->dns2);
+ asprintf(&response[index].dnses, "%s %s", data_connection->dns1,
+ data_connection->dns2);
if (data_connection->gateway != NULL)
- response[index].gateways = strdup(data_connection->gateway);
+ response[index].gateways = strdup(
+ data_connection->gateway);
#else
if (data_connection->apn != NULL)
response[index].apn = strdup(data_connection->apn);
@@ -623,16 +678,14 @@ int ipc_gprs_pdp_context(struct ipc_message *message)
index++;
}
-#if RIL_VERSION >= 6
- size = index * sizeof(RIL_Data_Call_Response_v6);
-#else
- size = index * sizeof(RIL_Data_Call_Response);
-#endif
+ size = index * sizeof(RIL_Data_Call_Response_compat);
if (!ipc_seq_valid(message->aseq))
- ril_request_unsolicited(RIL_UNSOL_DATA_CALL_LIST_CHANGED, &response, size);
+ ril_request_unsolicited(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
+ &response, size);
else
- ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_SUCCESS, &response, size);
+ ril_request_complete(ipc_fmt_request_token(message->aseq),
+ RIL_E_SUCCESS, &response, size);
for (i = 0; i < index; i++) {
if (response[i].type != NULL)
@@ -668,13 +721,14 @@ int ril_request_data_call_list(__attribute__((unused)) void *data,
{
int rc;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0) {
ril_request_complete(token, RIL_E_SUCCESS, NULL, 0);
return RIL_REQUEST_COMPLETED;
}
- rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_GPRS_PDP_CONTEXT, IPC_TYPE_GET, NULL, 0);
+ rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_GPRS_PDP_CONTEXT,
+ IPC_TYPE_GET, NULL, 0);
if (rc < 0)
goto error;
@@ -696,14 +750,17 @@ int ipc_gprs_pdp_context_callback(struct ipc_message *message)
struct ipc_gen_phone_res_data *data;
int rc;
- if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_gen_phone_res_data))
+ if (message == NULL || message->data == NULL ||
+ message->size < sizeof(struct ipc_gen_phone_res_data))
return -1;
data = (struct ipc_gen_phone_res_data *) message->data;
- data_connection = ril_data_connection_find_token(ipc_fmt_request_token(message->aseq));
+ data_connection = ril_data_connection_find_token(
+ ipc_fmt_request_token(message->aseq));
if (data_connection == NULL) {
- ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
+ ril_request_complete(ipc_fmt_request_token(message->aseq),
+ RIL_E_GENERIC_FAILURE, NULL, 0);
return 0;
}
@@ -716,7 +773,8 @@ int ipc_gprs_pdp_context_callback(struct ipc_message *message)
error:
ril_data_connection_stop(data_connection);
- ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
+ ril_request_complete(ipc_fmt_request_token(message->aseq),
+ RIL_E_GENERIC_FAILURE, NULL, 0);
complete:
return 0;
@@ -734,11 +792,12 @@ int ril_request_deactivate_data_call(void *data, size_t size, RIL_Token token)
if (data == NULL || size < 2 * sizeof(char *))
goto error;
- rc = ril_radio_state_check(RADIO_STATE_SIM_READY);
+ rc = ril_sim_has_reached_state(SIM_STATE_READY);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
- request = ril_request_find_request_status(RIL_REQUEST_DEACTIVATE_DATA_CALL, RIL_REQUEST_HANDLED);
+ request = ril_request_find_request_status(
+ RIL_REQUEST_DEACTIVATE_DATA_CALL, RIL_REQUEST_HANDLED);
if (request != NULL)
return RIL_REQUEST_UNHANDLED;
@@ -760,15 +819,22 @@ int ril_request_deactivate_data_call(void *data, size_t size, RIL_Token token)
data_connection->token = token;
- rc = ipc_gprs_pdp_context_request_set_setup(&request_data, 0, data_connection->cid, NULL, NULL);
+ rc = ipc_gprs_pdp_context_request_set_setup(&request_data,
+ 0, data_connection->cid,
+ NULL, NULL);
if (rc < 0)
goto error;
- rc = ipc_gen_phone_res_expect_callback(ipc_fmt_request_seq(token), IPC_GPRS_PDP_CONTEXT, ipc_gprs_pdp_context_callback);
+ rc = ipc_gen_phone_res_expect_callback(ipc_fmt_request_seq(token),
+ IPC_GPRS_PDP_CONTEXT,
+ ipc_gprs_pdp_context_callback);
if (rc < 0)
goto error;
- rc = ipc_fmt_send(ipc_fmt_request_seq(token), IPC_GPRS_PDP_CONTEXT, IPC_TYPE_SET, (void *) &request_data, sizeof(request_data));
+ rc = ipc_fmt_send(ipc_fmt_request_seq(token),
+ IPC_GPRS_PDP_CONTEXT, IPC_TYPE_SET,
+ (void *) &request_data,
+ sizeof(request_data));
if (rc < 0)
goto error;
@@ -795,7 +861,8 @@ int ipc_gprs_ip_configuration(struct ipc_message *message)
struct ipc_gprs_ip_configuration_data *data;
struct ril_data_connection *data_connection;
- if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_gprs_ip_configuration_data))
+ if (message == NULL || message->data == NULL ||
+ message->size < sizeof(struct ipc_gprs_ip_configuration_data))
return -1;
data = (struct ipc_gprs_ip_configuration_data *) message->data;
@@ -803,7 +870,10 @@ int ipc_gprs_ip_configuration(struct ipc_message *message)
data_connection = ril_data_connection_find_cid(data->cid);
if (data_connection == NULL) {
if (ipc_seq_valid(message->aseq))
- ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
+ ril_request_complete(
+ ipc_fmt_request_token(message->aseq),
+ RIL_E_GENERIC_FAILURE,
+ NULL, 0);
return 0;
}
@@ -811,12 +881,14 @@ int ipc_gprs_ip_configuration(struct ipc_message *message)
if (data_connection->ip != NULL)
free(data_connection->ip);
- asprintf(&data_connection->ip, "%i.%i.%i.%i", data->ip[0], data->ip[1], data->ip[2], data->ip[3]);
+ asprintf(&data_connection->ip, "%i.%i.%i.%i",
+ data->ip[0], data->ip[1], data->ip[2], data->ip[3]);
if (data_connection->gateway != NULL)
free(data_connection->gateway);
- asprintf(&data_connection->gateway, "%i.%i.%i.%i", data->ip[0], data->ip[1], data->ip[2], data->ip[3]);
+ asprintf(&data_connection->gateway, "%i.%i.%i.%i",
+ data->ip[0], data->ip[1], data->ip[2], data->ip[3]);
if (data_connection->subnet_mask != NULL)
free(data_connection->subnet_mask);
@@ -826,12 +898,14 @@ int ipc_gprs_ip_configuration(struct ipc_message *message)
if (data_connection->dns1 != NULL)
free(data_connection->dns1);
- asprintf(&data_connection->dns1, "%i.%i.%i.%i", data->dns1[0], data->dns1[1], data->dns1[2], data->dns1[3]);
+ asprintf(&data_connection->dns1, "%i.%i.%i.%i",
+ data->dns1[0], data->dns1[1], data->dns1[2], data->dns1[3]);
if (data_connection->dns2 != NULL)
free(data_connection->dns2);
- asprintf(&data_connection->dns2, "%i.%i.%i.%i", data->dns2[0], data->dns2[1], data->dns2[2], data->dns2[3]);
+ asprintf(&data_connection->dns2, "%i.%i.%i.%i",
+ data->dns2[0], data->dns2[1], data->dns2[2], data->dns2[3]);
return 0;
}
@@ -842,7 +916,8 @@ int ipc_gprs_hsdpa_status(struct ipc_message *message)
struct ril_client *client;
struct ipc_fmt_data *ipc_fmt_data;
- if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_gprs_hsdpa_status_data))
+ if (message == NULL || message->data == NULL ||
+ message->size < sizeof(struct ipc_gprs_hsdpa_status_data))
return -1;
client = ril_client_find_id(RIL_CLIENT_IPC_FMT);
@@ -857,9 +932,12 @@ int ipc_gprs_hsdpa_status(struct ipc_message *message)
ipc_fmt_data->hsdpa_status_data.status = data->status;
#if RIL_VERSION >= 6
- ril_request_unsolicited(RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, NULL, 0);
+ ril_request_unsolicited(
+ RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED,
+ NULL, 0);
#else
- ril_request_unsolicited(RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED, NULL, 0);
+ ril_request_unsolicited(
+ RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED, NULL, 0);
#endif
}
@@ -868,22 +946,21 @@ int ipc_gprs_hsdpa_status(struct ipc_message *message)
int ipc_gprs_call_status(struct ipc_message *message)
{
-#if RIL_VERSION >= 6
- RIL_Data_Call_Response_v6 response;
-#else
- char *setup_data_call_response[3];
- int fail_cause;
- unsigned int i;
-#endif
+ RIL_Data_Call_Response_compat response;
struct ipc_gprs_call_status_data *data;
struct ril_data_connection *data_connection;
struct ril_request *request;
int rc;
+#if RIL_VERSION < 6
+ int fail_cause;
+ unsigned int i;
+#endif
- if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_gprs_call_status_data))
+ if (message == NULL || message->data == NULL ||
+ message->size < sizeof(struct ipc_gprs_call_status_data))
return -1;
- rc = ril_radio_state_check(RADIO_STATE_SIM_READY);
+ rc = ril_sim_has_reached_state(SIM_STATE_READY);
if (rc < 0)
return 0;
@@ -891,10 +968,14 @@ int ipc_gprs_call_status(struct ipc_message *message)
data_connection = ril_data_connection_find_cid(data->cid);
if (data_connection == NULL) {
- RIL_LOGE("%s: Finding data connection with cid: %d failed", __func__, data->cid);
+ RIL_LOGE("%s: Finding data connection with cid: %d failed",
+ __func__, data->cid);
if (ipc_seq_valid(message->aseq))
- ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
+ ril_request_complete(
+ ipc_fmt_request_token(message->aseq),
+ RIL_E_GENERIC_FAILURE,
+ NULL, 0);
return 0;
}
@@ -903,44 +984,61 @@ int ipc_gprs_call_status(struct ipc_message *message)
if (data->status == IPC_GPRS_STATUS_ENABLED) {
if (data_connection->enabled) {
- if (request != NULL && request->request == RIL_REQUEST_DEACTIVATE_DATA_CALL)
+ if (request != NULL &&
+ request->request ==
+ RIL_REQUEST_DEACTIVATE_DATA_CALL)
goto error;
else
- RIL_LOGD("%s: Data connection with cid %d is already enabled", __func__, data_connection->cid);
+ RIL_LOGD("%s: Data connection with cid %d"
+ " is already enabled",
+ __func__, data_connection->cid);
} else {
rc = ril_data_connection_enable(data_connection);
if (rc < 0)
goto error;
- if (request != NULL && request->request == RIL_REQUEST_SETUP_DATA_CALL) {
+ if (request != NULL &&
+ request->request == RIL_REQUEST_SETUP_DATA_CALL) {
memset(&response, 0, sizeof(response));
#if RIL_VERSION >= 6
- response.status = ipc2ril_gprs_fail_cause(data->fail_cause);
+ response.status =
+ ipc2ril_gprs_fail_cause(
+ data->fail_cause);
response.cid = data_connection->cid;
response.active = 2;
response.type = strdup("IP");
if (data_connection->iface != NULL)
- response.ifname = strdup(data_connection->iface);
+ response.ifname =
+ strdup(data_connection->iface);
if (data_connection->ip != NULL)
- response.addresses = strdup(data_connection->ip);
+ response.addresses =
+ strdup(data_connection->ip);
- asprintf(&response.dnses, "%s %s", data_connection->dns1, data_connection->dns2);
+ asprintf(&response.dnses, "%s %s",
+ data_connection->dns1,
+ data_connection->dns2);
if (data_connection->gateway != NULL)
- response.gateways = strdup(data_connection->gateway);
+ response.gateways = strdup(
+ data_connection->gateway);
#else
- asprintf(&response[0], "%d", gprs_connection->cid);
+ asprintf(&response[0], "%d",
+ gprs_connection->cid);
if (data_connection->iface != NULL)
- response[1] = strdup(data_connection->iface);
+ response[1] =
+ strdup(data_connection->iface);
if (data_connection->ip != NULL)
- response[2] = strdup(data_connection->ip);
+ response[2] =
+ strdup(data_connection->ip);
#endif
- ril_request_complete(data_connection->token, RIL_E_SUCCESS, &response, sizeof(response));
+ ril_request_complete(data_connection->token,
+ RIL_E_SUCCESS, &response,
+ sizeof(response));
data_connection->token = NULL;
#if RIL_VERSION >= 6
@@ -965,10 +1063,13 @@ int ipc_gprs_call_status(struct ipc_message *message)
}
#endif
} else {
- RIL_LOGD("%s: Data connection with cid: %d got unexpectedly enabled", __func__, data_connection->cid);
+ RIL_LOGD("%s: Data connection with cid:"
+ " %d got unexpectedly enabled",
+ __func__, data_connection->cid);
}
}
- } else if (data->status == IPC_GPRS_STATUS_DISABLED || data->status == IPC_GPRS_STATUS_NOT_ENABLED) {
+ } else if (data->status == IPC_GPRS_STATUS_DISABLED ||
+ data->status == IPC_GPRS_STATUS_NOT_ENABLED) {
if (data_connection->enabled) {
rc = ril_data_connection_disable(data_connection);
if (rc < 0)
@@ -976,33 +1077,51 @@ int ipc_gprs_call_status(struct ipc_message *message)
ril_data_connection_stop(data_connection);
- if (request != NULL && request->request == RIL_REQUEST_DEACTIVATE_DATA_CALL)
- ril_request_complete(request->token, RIL_E_SUCCESS, NULL, 0);
+ if (request != NULL &&
+ request->request ==
+ RIL_REQUEST_DEACTIVATE_DATA_CALL)
+ ril_request_complete(request->token,
+ RIL_E_SUCCESS,
+ NULL, 0);
else
- RIL_LOGD("%s: Data connection with cid: %d got unexpectedly disabled", __func__, data->cid);
+ RIL_LOGD("%s: Data connection with cid:"
+ " %d got unexpectedly disabled",
+ __func__, data->cid);
} else {
- if (request != NULL && request->request == RIL_REQUEST_SETUP_DATA_CALL) {
+ if (request != NULL &&
+ request->request == RIL_REQUEST_SETUP_DATA_CALL) {
#if RIL_VERSION >= 6
memset(&response, 0, sizeof(response));
- response.status = ipc2ril_gprs_fail_cause(data->fail_cause);
+ response.status = ipc2ril_gprs_fail_cause(
+ data->fail_cause);
- ril_request_complete(request->token, RIL_E_SUCCESS, (void *) &response, sizeof(response));
+ ril_request_complete(request->token,
+ RIL_E_SUCCESS,
+ (void *) &response,
+ sizeof(response));
// Avoid completing the request twice
request = NULL;
#else
- fail_cause = ipc2ril_gprs_fail_cause(data->fail_cause);
+ fail_cause = ipc2ril_gprs_fail_cause(
+ data->fail_cause);
- ril_request_data_set_uniq(RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE, (void *) &fail_cause, sizeof(fail_cause));
+ ril_request_data_set_uniq(
+ RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE,
+ (void *) &fail_cause,
+ sizeof(fail_cause));
#endif
goto error;
} else {
- RIL_LOGD("%s: Data connection with cid: %d is already disabled", __func__, data_connection->cid);
+ RIL_LOGD("%s: Data connection with cid: "
+ "%d is already disabled",
+ __func__, data_connection->cid);
}
}
}
if (request == NULL) {
- rc = ipc_fmt_send(0, IPC_GPRS_PDP_CONTEXT, IPC_TYPE_GET, NULL, 0);
+ rc = ipc_fmt_send(0, IPC_GPRS_PDP_CONTEXT, IPC_TYPE_GET,
+ NULL, 0);
if (rc < 0)
goto error;
}
@@ -1013,7 +1132,8 @@ error:
ril_data_connection_stop(data_connection);
if (request != NULL)
- ril_request_complete(request->token, RIL_E_GENERIC_FAILURE, NULL, 0);
+ ril_request_complete(request->token, RIL_E_GENERIC_FAILURE,
+ NULL, 0);
complete:
return 0;
@@ -1028,12 +1148,14 @@ int ril_request_last_data_call_fail_cause(__attribute__((unused)) void *data,
int fail_cause;
int rc;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
- fail_cause_size = ril_request_data_size_get(RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE);
- fail_cause_data = ril_request_data_get(RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE);
+ fail_cause_size = ril_request_data_size_get(
+ RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE);
+ fail_cause_data = ril_request_data_get(
+ RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE);
if (fail_cause_data != NULL && fail_cause_size >= sizeof(int)) {
fail_cause = *((int *) fail_cause_data);
@@ -1042,7 +1164,8 @@ int ril_request_last_data_call_fail_cause(__attribute__((unused)) void *data,
fail_cause = PDP_FAIL_ERROR_UNSPECIFIED;
}
- ril_request_complete(token, RIL_E_SUCCESS, (void *) &fail_cause, sizeof(fail_cause));
+ ril_request_complete(token, RIL_E_SUCCESS, (void *) &fail_cause,
+ sizeof(fail_cause));
return RIL_REQUEST_COMPLETED;
}
diff --git a/ipc.c b/ipc.c
index 3286370..812926a 100644
--- a/ipc.c
+++ b/ipc.c
@@ -18,12 +18,14 @@
* along with Samsung-RIL. If not, see <http://www.gnu.org/licenses/>.
*/
+#define LOG_TAG "RIL-IPC"
+
#include <stdlib.h>
+
#include <sys/eventfd.h>
-#define LOG_TAG "RIL-IPC"
-#include <utils/Log.h>
#include <hardware_legacy/power.h>
+#include <utils/Log.h>
#include <samsung-ril.h>
#include <utils.h>
@@ -65,7 +67,8 @@ int ipc_fmt_send(unsigned char mseq, unsigned short command, unsigned char type,
RIL_CLIENT_LOCK(client);
acquire_wake_lock(PARTIAL_WAKE_LOCK, RIL_VERSION_STRING);
- rc = ipc_client_send(ipc_fmt_data->ipc_client, mseq, command, type, data, size);
+ rc = ipc_client_send(ipc_fmt_data->ipc_client, mseq, command, type,
+ data, size);
if (rc < 0) {
RIL_LOGE("Sending to %s client failed", client->name);
goto error;
@@ -180,7 +183,8 @@ int ipc_fmt_create(struct ril_client *client)
goto error;
}
- rc = ipc_client_log_callback_register(ipc_client, ipc_log_handler, NULL);
+ rc = ipc_client_log_callback_register(ipc_client, ipc_log_handler,
+ NULL);
if (rc < 0) {
RIL_LOGE("Setting %s client log handler failed", client->name);
goto error;
@@ -377,7 +381,8 @@ int ipc_fmt_dispatch(struct ril_client *client, struct ipc_message *message)
}
}
- RIL_LOGD("Unhandled %s message: %s", client->name, ipc_command_string(message->command));
+ RIL_LOGD("Unhandled %s message: %s", client->name,
+ ipc_command_string(message->command));
rc = 0;
goto complete;
@@ -401,12 +406,22 @@ int ipc_fmt_loop(struct ril_client *client)
eventfd_t event;
int rc;
- if (client == NULL || client->data == NULL)
+ if (client == NULL) {
+ RIL_LOGE("%s client is NULL", client->name);
+ return -1;
+ } else if (client->data == NULL) {
+ RIL_LOGE("%s client data is NULL", client->name);
return -1;
+ }
data = (struct ipc_fmt_data *) client->data;
- if (data->ipc_client == NULL || data->event_fd < 0)
+ if (data->ipc_client == NULL) {
+ RIL_LOGE("%s data ipc_client is NULL", client->name);
+ return -1;
+ } else if (data->event_fd < 0) {
+ RIL_LOGE("%s data event_fd < 0", client->name);
return -1;
+ }
memset(&fds, 0, sizeof(fds));
fds.fds = (int *) &fds_array;
@@ -430,14 +445,24 @@ int ipc_fmt_loop(struct ril_client *client)
if (fds.fds[0] == data->event_fd && fds.count > 0) {
rc = eventfd_recv(data->event_fd, &event);
- if (rc < 0)
+ if (rc < 0) {
+ RIL_LOGE("Receiving %s data with eventfd_recv "
+ "failed with error %d",
+ client->name, rc);
goto error;
+ }
switch (event) {
case IPC_CLIENT_CLOSE:
+ RIL_LOGE("Closing %s due to "
+ "IPC_CLIENT_CLOSE",
+ client->name);
rc = 0;
goto complete;
case IPC_CLIENT_IO_ERROR:
+ RIL_LOGE("Exiting %s due to "
+ "IPC_CLIENT_IO_ERROR",
+ client->name);
goto error;
}
}
@@ -453,7 +478,8 @@ int ipc_fmt_loop(struct ril_client *client)
rc = ipc_client_recv(data->ipc_client, &message);
if (rc < 0) {
- RIL_LOGE("Receiving from %s client failed", client->name);
+ RIL_LOGE("Receiving from %s client failed",
+ client->name);
release_wake_lock(RIL_VERSION_STRING);
RIL_CLIENT_UNLOCK(client);
@@ -512,7 +538,8 @@ int ipc_fmt_request_register(struct ril_client *client, int request,
RIL_CLIENT_LOCK(client);
- ipc_fmt_request = (struct ipc_fmt_request *) calloc(1, sizeof(struct ipc_fmt_request));
+ ipc_fmt_request = (struct ipc_fmt_request *) calloc(
+ 1, sizeof(struct ipc_fmt_request));
ipc_fmt_request->request = request;
ipc_fmt_request->token = token;
ipc_fmt_request->seq = 0xff;
@@ -552,8 +579,10 @@ int ipc_fmt_request_unregister(struct ril_client *client, int request,
ipc_fmt_request = (struct ipc_fmt_request *) list->data;
- if (ipc_fmt_request->request == request && ipc_fmt_request->token == token) {
- memset(ipc_fmt_request, 0, sizeof(struct ipc_fmt_request));
+ if (ipc_fmt_request->request == request &&
+ ipc_fmt_request->token == token) {
+ memset(ipc_fmt_request, 0,
+ sizeof(struct ipc_fmt_request));
free(ipc_fmt_request);
if (list == data->requests)
@@ -592,7 +621,8 @@ int ipc_fmt_request_flush(struct ril_client *client)
if (list->data != NULL) {
ipc_fmt_request = (struct ipc_fmt_request *) list->data;
- memset(ipc_fmt_request, 0, sizeof(struct ipc_fmt_request));
+ memset(ipc_fmt_request, 0,
+ sizeof(struct ipc_fmt_request));
free(ipc_fmt_request);
}
@@ -733,7 +763,8 @@ int ipc_rfs_send(unsigned char mseq, unsigned short command, const void *data,
RIL_CLIENT_LOCK(client);
acquire_wake_lock(PARTIAL_WAKE_LOCK, RIL_VERSION_STRING);
- rc = ipc_client_send(ipc_rfs_data->ipc_client, mseq, command, 0x00, data, size);
+ rc = ipc_client_send(ipc_rfs_data->ipc_client, mseq, command,
+ 0x00, data, size);
if (rc < 0) {
RIL_LOGE("Sending to %s client failed", client->name);
goto error;
@@ -794,7 +825,8 @@ int ipc_rfs_create(struct ril_client *client)
goto error;
}
- rc = ipc_client_log_callback_register(ipc_client, ipc_log_handler, NULL);
+ rc = ipc_client_log_callback_register(ipc_client, ipc_log_handler,
+ NULL);
if (rc < 0) {
RIL_LOGE("Setting %s client log handler failed", client->name);
goto error;
@@ -966,7 +998,8 @@ int ipc_rfs_dispatch(struct ril_client *client, struct ipc_message *message)
}
}
- RIL_LOGD("Unhandled %s message: %s", client->name, ipc_command_string(message->command));
+ RIL_LOGD("Unhandled %s message: %s", client->name,
+ ipc_command_string(message->command));
rc = 0;
goto complete;
@@ -990,12 +1023,22 @@ int ipc_rfs_loop(struct ril_client *client)
eventfd_t event;
int rc;
- if (client == NULL || client->data == NULL)
+ if (client == NULL) {
+ RIL_LOGE("%s client is NULL", client->name);
+ return -1;
+ } else if (client->data == NULL) {
+ RIL_LOGE("%s client data is NULL", client->name);
return -1;
+ }
data = (struct ipc_rfs_data *) client->data;
- if (data->ipc_client == NULL || data->event_fd < 0)
+ if (data->ipc_client == NULL) {
+ RIL_LOGE("%s data ipc_client is NULL", client->name);
+ return -1;
+ } else if (data->event_fd < 0) {
+ RIL_LOGE("%s data event_fd < 0", client->name);
return -1;
+ }
memset(&fds, 0, sizeof(fds));
fds.fds = (int *) &fds_array;
@@ -1019,13 +1062,23 @@ int ipc_rfs_loop(struct ril_client *client)
if (fds.fds[0] == data->event_fd && fds.count > 0) {
rc = eventfd_recv(data->event_fd, &event);
- if (rc < 0)
+ if (rc < 0) {
+ RIL_LOGE("Receiving %s data with eventfd_recv "
+ "failed with error %d",
+ client->name, rc);
return -1;
+ }
switch (event) {
case IPC_CLIENT_CLOSE:
+ RIL_LOGE("Closing %s due to "
+ "IPC_CLIENT_CLOSE",
+ client->name);
return 0;
case IPC_CLIENT_IO_ERROR:
+ RIL_LOGE("Exiting %s due to "
+ "IPC_CLIENT_IO_ERROR",
+ client->name);
return -1;
}
}
@@ -1041,7 +1094,8 @@ int ipc_rfs_loop(struct ril_client *client)
rc = ipc_client_recv(data->ipc_client, &message);
if (rc < 0) {
- RIL_LOGE("Receiving from %s client failed", client->name);
+ RIL_LOGE("Receiving from %s client failed",
+ client->name);
release_wake_lock(RIL_VERSION_STRING);
RIL_CLIENT_UNLOCK(client);
diff --git a/misc.c b/misc.c
index d69f5bd..08eab50 100644
--- a/misc.c
+++ b/misc.c
@@ -18,6 +18,8 @@
* along with Samsung-RIL. If not, see <http://www.gnu.org/licenses/>.
*/
+#define _GNU_SOURCE
+#include <stdio.h>
#include <stdlib.h>
#define LOG_TAG "RIL"
@@ -55,7 +57,7 @@ int ril_request_baseband_version(__attribute__((unused)) void *data,
struct ril_request *request;
int rc;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -113,7 +115,7 @@ int ril_request_get_imsi(__attribute__((unused)) void *data,
struct ril_request *request;
int rc;
- rc = ril_radio_state_check(RADIO_STATE_SIM_READY);
+ rc = ril_sim_has_reached_state(SIM_STATE_READY);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -189,7 +191,7 @@ int ril_request_get_imei(__attribute__((unused)) void *data,
struct ril_request *request;
int rc;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -221,7 +223,7 @@ int ril_request_get_imeisv(__attribute__((unused)) void *data,
struct ril_request *request;
int rc;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -275,7 +277,7 @@ int ril_request_screen_state(void *data, size_t size, RIL_Token token)
return RIL_REQUEST_COMPLETED;
}
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
diff --git a/network.c b/network.c
index dff666b..6f2e168 100644
--- a/network.c
+++ b/network.c
@@ -21,32 +21,27 @@
* along with Samsung-RIL. If not, see <http://www.gnu.org/licenses/>.
*/
+#define _GNU_SOURCE
+#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define LOG_TAG "RIL"
#include <utils/Log.h>
+#include <ril-versions-compat.h>
#include <samsung-ril.h>
#include <utils.h>
#include <plmn_list.h>
-#if RIL_VERSION >= 6
-int ipc2ril_disp_rssi(unsigned char rssi, RIL_SignalStrength_v6 *strength)
-#else
-int ipc2ril_disp_rssi(unsigned char rssi, RIL_SignalStrength *strength)
-#endif
+int ipc2ril_disp_rssi(unsigned char rssi, RIL_SignalStrength_compat *strength)
{
int asu;
if (strength == NULL)
return -1;
-#if RIL_VERSION >= 6
- memset(strength, -1, sizeof(RIL_SignalStrength_v6));
-#else
- memset(strength, -1, sizeof(RIL_SignalStrength));
-#endif
+ memset(strength, -1, sizeof(RIL_SignalStrength_compat));
asu = (int) rssi / -2 + 56;
@@ -63,13 +58,8 @@ int ipc2ril_disp_rssi(unsigned char rssi, RIL_SignalStrength *strength)
return 0;
}
-#if RIL_VERSION >= 6
-int ipc2ril_disp_icon_info(struct ipc_disp_icon_info_response_data *data,
- RIL_SignalStrength_v6 *strength)
-#else
int ipc2ril_disp_icon_info(struct ipc_disp_icon_info_response_data *data,
- RIL_SignalStrength *strength)
-#endif
+ RIL_SignalStrength_compat *strength)
{
int asu_bars[] = { 1, 3, 5, 8, 12, 15 };
unsigned int asu_bars_count = sizeof(asu_bars) / sizeof(int);
@@ -81,11 +71,7 @@ int ipc2ril_disp_icon_info(struct ipc_disp_icon_info_response_data *data,
if (!(data->flags & IPC_DISP_ICON_INFO_FLAG_RSSI))
return -1;
-#if RIL_VERSION >= 6
- memset(strength, -1, sizeof(RIL_SignalStrength_v6));
-#else
- memset(strength, -1, sizeof(RIL_SignalStrength));
-#endif
+ memset(strength, -1, sizeof(RIL_SignalStrength_compat));
asu_bars_index = data->rssi;
if (asu_bars_index >= asu_bars_count)
@@ -100,13 +86,8 @@ int ipc2ril_disp_icon_info(struct ipc_disp_icon_info_response_data *data,
return 0;
}
-#if RIL_VERSION >= 6
-int ipc2ril_disp_rssi_info(struct ipc_disp_rssi_info_data *data,
- RIL_SignalStrength_v6 *strength)
-#else
int ipc2ril_disp_rssi_info(struct ipc_disp_rssi_info_data *data,
- RIL_SignalStrength *strength)
-#endif
+ RIL_SignalStrength_compat *strength)
{
int rc;
@@ -379,11 +360,7 @@ int ipc2ril_net_mode_sel(struct ipc_net_mode_sel_data *data)
#if RIL_VERSION >= 6
unsigned char ril2ipc_net_mode_sel(RIL_PreferredNetworkType type)
-#else
-unsigned char ril2ipc_net_mode_sel(int type)
-#endif
{
-#if RIL_VERSION >= 6
switch (type) {
case PREF_NET_TYPE_GSM_WCDMA:
case PREF_NET_TYPE_GSM_WCDMA_AUTO:
@@ -395,7 +372,10 @@ unsigned char ril2ipc_net_mode_sel(int type)
default:
return IPC_NET_MODE_SEL_GSM_UMTS;
}
+}
#else
+unsigned char ril2ipc_net_mode_sel(int type)
+{
switch (type) {
case 0:
case 3:
@@ -407,23 +387,19 @@ unsigned char ril2ipc_net_mode_sel(int type)
default:
return IPC_NET_MODE_SEL_GSM_UMTS;
}
-#endif
}
+#endif
int ipc_disp_icon_info(struct ipc_message *message)
{
struct ipc_disp_icon_info_response_data *data;
-#if RIL_VERSION >= 6
- RIL_SignalStrength_v6 strength;
-#else
- RIL_SignalStrength strength;
-#endif
+ RIL_SignalStrength_compat strength;
int rc;
if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_disp_icon_info_response_data))
return -1;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return 0;
@@ -452,7 +428,7 @@ int ril_request_signal_strength(__attribute__((unused)) void *data,
struct ipc_disp_icon_info_request_data request_data;
int rc;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -471,17 +447,13 @@ int ril_request_signal_strength(__attribute__((unused)) void *data,
int ipc_disp_rssi_info(struct ipc_message *message)
{
struct ipc_disp_rssi_info_data *data;
-#if RIL_VERSION >= 6
- RIL_SignalStrength_v6 strength;
-#else
- RIL_SignalStrength strength;
-#endif
+ RIL_SignalStrength_compat strength;
int rc;
if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_disp_rssi_info_data))
return -1;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return 0;
@@ -505,7 +477,7 @@ int ipc_net_plmn_sel(struct ipc_message *message)
if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_net_plmn_sel_response_data))
return -1;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return 0;
@@ -527,7 +499,7 @@ int ril_request_query_network_selection_mode(__attribute__((unused)) void *data,
{
int rc;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -573,7 +545,7 @@ int ril_request_set_network_selection_automatic(__attribute__((unused)) void *da
struct ipc_net_plmn_sel_request_data request_data;
int rc;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -612,7 +584,7 @@ int ril_request_set_network_selection_manual(void *data, size_t size,
return RIL_REQUEST_COMPLETED;
}
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -651,7 +623,7 @@ int ipc_net_serving_network(struct ipc_message *message)
if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_net_regist_response_data))
return -1;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return 0;
@@ -698,7 +670,7 @@ int ril_request_operator(__attribute__((unused)) void *data,
unsigned int i;
int rc;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -748,7 +720,7 @@ int ipc_net_plmn_list(struct ipc_message *message)
if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_net_plmn_list_header))
return -1;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return 0;
@@ -824,7 +796,7 @@ int ril_request_query_available_networks(__attribute__((unused)) void *data,
struct ril_request *request;
int rc;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -863,7 +835,7 @@ int ipc_net_regist(struct ipc_message *message)
if (client == NULL || client->data == NULL)
return 0;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return 0;
@@ -964,7 +936,7 @@ int ril_request_registration_state(__attribute__((unused)) void *data,
unsigned int i;
int rc;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -1039,7 +1011,7 @@ int ril_request_gprs_registration_state(__attribute__((unused)) void *data,
unsigned int i;
int rc;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -1104,7 +1076,7 @@ int ipc_net_mode_sel(struct ipc_message *message)
if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_net_mode_sel_data))
return -1;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return 0;
@@ -1126,7 +1098,7 @@ int ril_request_get_preferred_network_type(__attribute__((unused)) void *data,
{
int rc;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
diff --git a/power.c b/power.c
index 011570f..9b68c4d 100644
--- a/power.c
+++ b/power.c
@@ -63,7 +63,7 @@ int ipc_pwr_phone_state(struct ipc_message *message)
RIL_LOGD("Power state is normal");
ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_SUCCESS, NULL, 0);
- ril_radio_state_update(RADIO_STATE_SIM_NOT_READY);
+ ril_radio_state_update(RADIO_STATE_ON);
break;
}
diff --git a/ril-versions-compat.h b/ril-versions-compat.h
new file mode 100644
index 0000000..7c791ae
--- /dev/null
+++ b/ril-versions-compat.h
@@ -0,0 +1,49 @@
+/*
+ * This file is part of Samsung-RIL.
+ *
+ * Copyright (C) 2019 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
+ *
+ * Samsung-RIL 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.
+ *
+ * Samsung-RIL 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 Samsung-RIL. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _RIL_VERSIONS_H_
+#define _RIL_VERSIONS_H_
+
+#include <telephony/ril.h>
+
+#if RIL_VERSION >= 6
+#define RIL_Data_Call_Response_compat RIL_Data_Call_Response_v6
+#else
+#define RIL_Data_Call_Response_compat RIL_Data_Call_Response
+#endif
+
+#if RIL_VERSION >= 6
+#define RIL_CardStatus_compat RIL_CardStatus_v6
+#else
+#define RIL_CardStatus_compat RIL_CardStatus_v6
+#endif
+
+#if RIL_VERSION >= 6
+#define RIL_SignalStrength_compat RIL_SignalStrength_v6
+#else
+#define RIL_SignalStrength_compat RIL_SignalStrength
+#endif
+
+#if RIL_VERSION >= 6
+#define RIL_SIM_IO_compat RIL_SIM_IO_v6
+#else
+#define RIL_SIM_IO_compat RIL_SIM_IO
+#endif
+
+#endif /* _RIL_VERSIONS_H_ */
diff --git a/samsung-ril.c b/samsung-ril.c
index 84e3074..aaeedeb 100644
--- a/samsung-ril.c
+++ b/samsung-ril.c
@@ -23,8 +23,8 @@
#define LOG_TAG "RIL"
#include <utils/Log.h>
-#include <telephony/ril.h>
+#include <ril-versions-compat.h>
#include <samsung-ril.h>
#include <utils.h>
@@ -121,7 +121,7 @@ struct ipc_dispatch_handler ipc_fmt_dispatch_handlers[] = {
.handler = ipc_sec_sim_icc_type,
},
{
- .command = IPC_SEC_LOCK_INFOMATION,
+ .command = IPC_SEC_LOCK_INFORMATION,
.handler = ipc_sec_lock_infomation,
},
/* Network */
@@ -208,8 +208,8 @@ struct ipc_dispatch_handler ipc_fmt_dispatch_handlers[] = {
},
};
-unsigned int ipc_fmt_dispatch_handlers_count = sizeof(ipc_fmt_dispatch_handlers) /
- sizeof(struct ipc_dispatch_handler);
+unsigned int ipc_fmt_dispatch_handlers_count =
+ sizeof(ipc_fmt_dispatch_handlers) / sizeof(struct ipc_dispatch_handler);
struct ipc_dispatch_handler ipc_rfs_dispatch_handlers[] = {
{
@@ -222,8 +222,8 @@ struct ipc_dispatch_handler ipc_rfs_dispatch_handlers[] = {
},
};
-unsigned int ipc_rfs_dispatch_handlers_count = sizeof(ipc_rfs_dispatch_handlers) /
- sizeof(struct ipc_dispatch_handler);
+unsigned int ipc_rfs_dispatch_handlers_count =
+ sizeof(ipc_rfs_dispatch_handlers) / sizeof(struct ipc_dispatch_handler);
struct srs_dispatch_handler srs_dispatch_handlers[] = {
{
@@ -520,7 +520,9 @@ list_continue:
list = list->next;
}
- RIL_LOGD("%d RIL request%s in the queue (%d pending, %d handled, %d unhandled)", count, count > 1 ? "s" : "", pending, handled, unhandled);
+ RIL_LOGD("%d RIL request%s in the queue"
+ " (%d pending, %d handled, %d unhandled)",
+ count, count > 1 ? "s" : "", pending, handled, unhandled);
count = 0;
@@ -532,7 +534,8 @@ list_continue:
}
if (count > 0)
- RIL_LOGD("%d RIL request%s data in the queue", count, count > 1 ? "s" : "");
+ RIL_LOGD("%d RIL request%s data in the queue", count,
+ count > 1 ? "s" : "");
RIL_REQUEST_UNLOCK();
@@ -551,7 +554,8 @@ int ril_request_register(int request, void *data, size_t size, RIL_Token token)
RIL_REQUEST_LOCK();
- ril_request = (struct ril_request *) calloc(1, sizeof(struct ril_request));
+ ril_request = (struct ril_request *) calloc(1,
+ sizeof(struct ril_request));
ril_request->request = request;
ril_request->data = NULL;
ril_request->size = size;
@@ -598,7 +602,8 @@ int ril_request_unregister(struct ril_request *request)
if (ril_clients[i] == NULL)
continue;
- ril_client_request_unregister(ril_clients[i], request->request, request->token);
+ ril_client_request_unregister(ril_clients[i], request->request,
+ request->token);
}
list = ril_data->requests;
@@ -710,7 +715,8 @@ struct ril_request *ril_request_find_request_status(int request, int status)
ril_request = (struct ril_request *) list->data;
- if (ril_request->request == request && ril_request->status == status) {
+ if (ril_request->request == request &&
+ ril_request->status == status) {
RIL_REQUEST_UNLOCK();
return ril_request;
}
@@ -822,7 +828,8 @@ int ril_request_complete(RIL_Token token, RIL_Errno error, void *data,
{
struct ril_request *request;
- if (ril_data == NULL || ril_data->env == NULL || ril_data->env->OnRequestComplete == NULL)
+ if (ril_data == NULL || ril_data->env == NULL ||
+ ril_data->env->OnRequestComplete == NULL)
return -1;
if (token == NULL)
@@ -846,7 +853,8 @@ complete:
int ril_request_unsolicited(int request, void *data, size_t size)
{
- if (ril_data == NULL || ril_data->env == NULL || ril_data->env->OnUnsolicitedResponse == NULL)
+ if (ril_data == NULL || ril_data->env == NULL ||
+ ril_data->env->OnUnsolicitedResponse == NULL)
return -1;
ril_data->env->OnUnsolicitedResponse(request, data, size);
@@ -857,7 +865,8 @@ int ril_request_unsolicited(int request, void *data, size_t size)
int ril_request_timed_callback(RIL_TimedCallback callback, void *data,
const struct timeval *time)
{
- if (ril_data == NULL || ril_data->env == NULL || ril_data->env->RequestTimedCallback == NULL)
+ if (ril_data == NULL || ril_data->env == NULL ||
+ ril_data->env->RequestTimedCallback == NULL)
return -1;
ril_data->env->RequestTimedCallback(callback, data, time);
@@ -878,7 +887,8 @@ int ril_request_dispatch(struct ril_request *request)
continue;
if (ril_request_handlers[i].request == request->request) {
- status = ril_request_handlers[i].handler(request->data, request->size, request->token);
+ status = ril_request_handlers[i].handler(
+ request->data, request->size, request->token);
switch (status) {
case RIL_REQUEST_PENDING:
case RIL_REQUEST_HANDLED:
@@ -888,7 +898,10 @@ int ril_request_dispatch(struct ril_request *request)
case RIL_REQUEST_COMPLETED:
break;
default:
- RIL_LOGE("Handling RIL request %d failed", request->request);
+ RIL_LOGE(
+ "Handling RIL request %d"
+ " failed",
+ request->request);
return -1;
}
@@ -897,7 +910,8 @@ int ril_request_dispatch(struct ril_request *request)
}
RIL_LOGD("Unhandled RIL request: %d", request->request);
- ril_request_complete(request->token, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
+ ril_request_complete(request->token, RIL_E_REQUEST_NOT_SUPPORTED, NULL,
+ 0);
return 0;
}
@@ -915,14 +929,15 @@ void *ril_request_loop(__attribute__((unused)) void *data)
RIL_LOCK();
- rc = ril_radio_state_check(RADIO_STATE_OFF);
+ rc = ril_radio_has_reached_state(RADIO_STATE_OFF);
if (rc < 0) {
RIL_UNLOCK();
continue;
}
do {
- request = ril_request_find_status(RIL_REQUEST_UNHANDLED);
+ request = ril_request_find_status(
+ RIL_REQUEST_UNHANDLED);
if (request == NULL)
break;
@@ -958,7 +973,8 @@ int ril_request_data_register(int request, void *data, size_t size)
if (data == NULL || ril_data == NULL)
return -1;
- request_data = (struct ril_request_data *) calloc(1, sizeof(struct ril_request_data));
+ request_data = (struct ril_request_data *) calloc(
+ 1, sizeof(struct ril_request_data));
request_data->request = request;
request_data->data = data;
request_data->size = size;
@@ -985,7 +1001,8 @@ int ril_request_data_unregister(struct ril_request_data *request_data)
list = ril_data->requests_data;
while (list != NULL) {
if (list->data == (void *) request_data) {
- memset(request_data, 0, sizeof(struct ril_request_data));
+ memset(request_data, 0,
+ sizeof(struct ril_request_data));
free(request_data);
if (list == ril_data->requests_data)
@@ -1016,10 +1033,12 @@ int ril_request_data_flush(void)
if (list->data != NULL) {
request_data = (struct ril_request_data *) list->data;
- if (request_data->data != NULL && request_data->size > 0)
+ if (request_data->data != NULL &&
+ request_data->size > 0)
free(request_data->data);
- memset(request_data, 0, sizeof(struct ril_request_data));
+ memset(request_data, 0,
+ sizeof(struct ril_request_data));
free(request_data);
}
@@ -1155,7 +1174,8 @@ int ril_radio_state_update(RIL_RadioState radio_state)
RIL_LOGD("Updating RIL radio state to %d", radio_state);
ril_data->radio_state = radio_state;
- ril_request_unsolicited(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL, 0);
+ ril_request_unsolicited(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL,
+ 0);
switch (ril_data->radio_state) {
case RADIO_STATE_UNAVAILABLE:
@@ -1164,7 +1184,10 @@ int ril_radio_state_update(RIL_RadioState radio_state)
if (request == NULL)
break;
- ril_request_complete(request->token, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
+ ril_request_complete(request->token,
+ RIL_E_RADIO_NOT_AVAILABLE,
+ NULL,
+ 0);
ril_request_unregister(request);
} while (request != NULL);
@@ -1183,10 +1206,15 @@ int ril_radio_state_update(RIL_RadioState radio_state)
case RADIO_STATE_OFF:
ril_data_connection_flush();
- ril_request_unsolicited(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0);
- ril_request_unsolicited(RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, NULL, 0);
- ril_request_unsolicited(RIL_UNSOL_DATA_CALL_LIST_CHANGED, NULL, 0);
- ril_request_unsolicited(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0);
+ ril_request_unsolicited(
+ RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0);
+ ril_request_unsolicited(
+ RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED,
+ NULL, 0);
+ ril_request_unsolicited(
+ RIL_UNSOL_DATA_CALL_LIST_CHANGED, NULL, 0);
+ ril_request_unsolicited(
+ RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0);
break;
default:
RIL_REQUEST_LOOP_UNLOCK();
@@ -1196,38 +1224,82 @@ int ril_radio_state_update(RIL_RadioState radio_state)
return 0;
}
-int ril_radio_state_check(RIL_RadioState radio_state)
+/*
+ * RIL SIM state
+ */
+
+int ril_sim_state_update(enum sim_state sim_state)
+{
+ if (ril_data == NULL)
+ return -1;
+
+ if (ril_data->sim_state == sim_state)
+ return 0;
+
+ RIL_LOGD("Updating RIL SIM state to %d", sim_state);
+
+ ril_data->sim_state = sim_state;
+
+ ril_request_unsolicited(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0);
+
+ return 0;
+}
+
+/*
+ * Returns 0 if the RIL has reached the given radio_state
+ * Returns -1 otherwise
+ */
+int ril_radio_has_reached_state(RIL_RadioState given_state)
{
RIL_RadioState radio_states[] = {
- RADIO_STATE_UNAVAILABLE,
RADIO_STATE_OFF,
+ RADIO_STATE_UNAVAILABLE,
RADIO_STATE_ON,
- RADIO_STATE_NV_NOT_READY,
- RADIO_STATE_NV_READY,
- RADIO_STATE_SIM_NOT_READY,
- RADIO_STATE_SIM_LOCKED_OR_ABSENT,
- RADIO_STATE_SIM_READY,
};
- unsigned int index;
- unsigned int count;
+
+ RIL_RadioState curr_state;
+
+ unsigned int curr_state_index;
+ unsigned int given_state_index;
+ unsigned int radio_states_count;
unsigned int i;
if (ril_data == NULL)
return -1;
- count = sizeof(radio_states) / sizeof(RIL_RadioState);
+ curr_state = ril_data->radio_state;
+ radio_states_count = sizeof(radio_states) / sizeof(RIL_RadioState);
- for (i = 0; i < count; i++)
- if (radio_states[i] == radio_state)
+ for (i = 0; i < radio_states_count; i++)
+ if (radio_states[i] == given_state)
break;
+ given_state_index = i;
- index = i;
-
- for (i = 0; i < count; i++)
- if (radio_states[i] == ril_data->radio_state)
+ for (i = 0; i < radio_states_count; i++)
+ if (radio_states[i] == curr_state)
break;
+ curr_state_index = i;
- if (i < index)
+ if (curr_state_index < given_state_index)
+ return -1;
+
+ return 0;
+}
+
+/*
+ * Returns 0 if the RIL has reached the given sim_state
+ * Returns -1 otherwise
+ */
+int ril_sim_has_reached_state(enum sim_state given_state)
+{
+ enum sim_state curr_state;
+
+ if (ril_data == NULL)
+ return -1;
+
+ curr_state = ril_data->sim_state;
+
+ if (curr_state < given_state)
return -1;
return 0;
@@ -1295,7 +1367,8 @@ void ril_on_request(int request, void *data, size_t size, RIL_Token token)
memcpy(buffer, data, size);
if (((RIL_Dial *) data)->address != NULL)
- ((RIL_Dial *) buffer)->address = strdup(((RIL_Dial *) data)->address);
+ ((RIL_Dial *) buffer)->address = strdup(
+ ((RIL_Dial *) data)->address);
data = buffer;
break;
@@ -1309,10 +1382,12 @@ void ril_on_request(int request, void *data, size_t size, RIL_Token token)
memcpy(buffer, data, size);
if (((RIL_SMS_WriteArgs *) data)->pdu != NULL)
- ((RIL_SMS_WriteArgs *) buffer)->pdu = strdup(((RIL_SMS_WriteArgs *) data)->pdu);
+ ((RIL_SMS_WriteArgs *) buffer)->pdu = strdup(
+ ((RIL_SMS_WriteArgs *) data)->pdu);
if (((RIL_SMS_WriteArgs *) data)->smsc != NULL)
- ((RIL_SMS_WriteArgs *) buffer)->smsc = strdup(((RIL_SMS_WriteArgs *) data)->smsc);
+ ((RIL_SMS_WriteArgs *) buffer)->smsc = strdup(
+ ((RIL_SMS_WriteArgs *) data)->smsc);
data = buffer;
break;
@@ -1329,38 +1404,28 @@ void ril_on_request(int request, void *data, size_t size, RIL_Token token)
strings_count = size / sizeof(char *);
break;
case RIL_REQUEST_SIM_IO:
-#if RIL_VERSION >= 6
- if (data == NULL || size < sizeof(RIL_SIM_IO_v6))
-#else
- if (data == NULL || size < sizeof(RIL_SIM_IO))
-#endif
+ if (data == NULL || size < sizeof(RIL_SIM_IO_compat))
break;
buffer = calloc(1, size);
memcpy(buffer, data, size);
-#if RIL_VERSION >= 6
- if (((RIL_SIM_IO_v6 *) data)->path != NULL)
- ((RIL_SIM_IO_v6 *) buffer)->path = strdup(((RIL_SIM_IO_v6 *) data)->path);
-
- if (((RIL_SIM_IO_v6 *) data)->data != NULL)
- ((RIL_SIM_IO_v6 *) buffer)->data = strdup(((RIL_SIM_IO_v6 *) data)->data);
+ if (((RIL_SIM_IO_compat *) data)->path != NULL)
+ ((RIL_SIM_IO_compat *) buffer)->path = strdup(
+ ((RIL_SIM_IO_compat *) data)->path);
- if (((RIL_SIM_IO_v6 *) data)->pin2 != NULL)
- ((RIL_SIM_IO_v6 *) buffer)->pin2 = strdup(((RIL_SIM_IO_v6 *) data)->pin2);
+ if (((RIL_SIM_IO_compat *) data)->data != NULL)
+ ((RIL_SIM_IO_compat *) buffer)->data = strdup(
+ ((RIL_SIM_IO_compat *) data)->data);
- if (((RIL_SIM_IO_v6 *) data)->aidPtr != NULL)
- ((RIL_SIM_IO_v6 *) buffer)->aidPtr = strdup(((RIL_SIM_IO_v6 *) data)->aidPtr);
-#else
- if (((RIL_SIM_IO *) data)->path != NULL)
- ((RIL_SIM_IO *) buffer)->path = strdup(((RIL_SIM_IO *) data)->path);
-
- if (((RIL_SIM_IO *) data)->data != NULL)
- ((RIL_SIM_IO *) buffer)->data = strdup(((RIL_SIM_IO *) data)->data);
-
- if (((RIL_SIM_IO *) data)->pin2 != NULL)
- ((RIL_SIM_IO *) buffer)->pin2 = strdup(((RIL_SIM_IO *) data)->pin2);
+ if (((RIL_SIM_IO_compat *) data)->pin2 != NULL)
+ ((RIL_SIM_IO_compat *) buffer)->pin2 = strdup(
+ ((RIL_SIM_IO_compat *) data)->pin2);
+#if RIL_VERSION >= 6
+ if (((RIL_SIM_IO_compat *) data)->aidPtr != NULL)
+ ((RIL_SIM_IO_compat *) buffer)->aidPtr = strdup
+ (((RIL_SIM_IO_compat *) data)->aidPtr);
#endif
data = buffer;
@@ -1379,13 +1444,16 @@ void ril_on_request(int request, void *data, size_t size, RIL_Token token)
if (i > 0 && c[i] == '\0') {
size = i + 1;
- RIL_LOGD("Detected string with a size of %d byte%s", size, size > 0 ? "s" : "");
+ RIL_LOGD("Detected string with a size of %d "
+ "byte%s",
+ size, size > 0 ? "s" : "");
}
break;
}
- if (strings_count > 0 && data != NULL && size >= strings_count * sizeof(char *)) {
+ if (strings_count > 0 && data != NULL &&
+ size >= strings_count * sizeof(char *)) {
buffer = calloc(1, size);
for (i = 0; i < strings_count; i++) {
@@ -1477,12 +1545,17 @@ const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env,
unsigned int i;
int rc;
- if (env == NULL)
+ RIL_LOGD("libsamsung-ril: Started from %s\n", __func__);
+
+ if (env == NULL) {
+ RIL_LOGE("%s: Aborting: Invalid RIL_Env (RIL_Env is NULL)",
+ __func__);
return NULL;
+ }
rc = ril_data_create();
if (rc < 0) {
- RIL_LOGE("Creating RIL data failed");
+ RIL_LOGE("%s: Creating RIL data failed", __func__);
return NULL;
}
@@ -1491,17 +1564,26 @@ const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env,
ril_data->env = env;
for (i = 0; i < ril_clients_count; i++) {
- if (ril_clients[i] == NULL)
+ if (ril_clients[i] == NULL) {
+ RIL_LOGD("%s: Skipping ril_client_create "
+ "due to Invalid client (client is NULL)",
+ __func__);
continue;
+ }
rc = ril_client_create(ril_clients[i]);
if (rc < 0)
+ /* ril_client_create already prints an error if it fails */
goto error;
}
for (i = 0; i < ril_clients_count; i++) {
- if (ril_clients[i] == NULL)
+ if (ril_clients[i] == NULL) {
+ RIL_LOGD("%s: Skipping ril_client_open "
+ "due to Invalid client (client is NULL)",
+ __func__);
continue;
+ }
failures = 0;
@@ -1513,18 +1595,27 @@ const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env,
}
} while (rc < 0 && failures < RIL_CLIENT_RETRY_COUNT);
- if (rc < 0)
+ if (rc < 0) {
+ RIL_LOGD("%s: "
+ "gave up trying to open the %s client "
+ "after %d retries",
+ __func__,
+ (ril_clients[i])->name,
+ RIL_CLIENT_RETRY_COUNT);
goto error;
+ }
rc = ril_client_loop(ril_clients[i]);
if (rc < 0)
+ /* ril_client_loop already prints an error if it fails */
goto error;
}
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- rc = pthread_create(&ril_data->request_thread, &attr, ril_request_loop, NULL);
+ rc = pthread_create(&ril_data->request_thread, &attr, ril_request_loop,
+ NULL);
if (rc != 0) {
RIL_LOGE("Starting request loop failed");
goto error;
diff --git a/samsung-ril.h b/samsung-ril.h
index cf6dc15..8cc012d 100644
--- a/samsung-ril.h
+++ b/samsung-ril.h
@@ -47,22 +47,34 @@
* Macros
*/
-#ifdef ALOGI
+#if defined(RLOGI)
+#define RIL_LOGI RLOGI
+#elif defined(ALOGI)
#define RIL_LOGI ALOGI
-#else
+#elif defined(LOGI)
#define RIL_LOGI LOGI
+#else
+#error "Cannot define RIL_LOGI"
#endif
-#ifdef ALOGD
+#if defined(RLOGD)
+#define RIL_LOGD RLOGD
+#elif defined(ALOGD)
#define RIL_LOGD ALOGD
-#else
+#elif defined(LOGD)
#define RIL_LOGD LOGD
+#else
+#error "Cannot define RIL_LOGD"
#endif
-#ifdef ALOGE
+#if defined(RLOGE)
+#define RIL_LOGE RLOGE
+#elif defined(ALOGE)
#define RIL_LOGE ALOGE
-#else
+#elif defined(LOGE)
#define RIL_LOGE LOGE
+#else
+#error "Cannot define RIL_LOGE"
#endif
#define RIL_LOCK() pthread_mutex_lock(&ril_data->mutex)
@@ -199,11 +211,22 @@ size_t ril_request_data_size_get(int request);
void *ril_request_data_get(int request);
/*
- * RIL radio state
+ * RIL state
*/
+enum sim_state {
+ SIM_STATE_ERROR,
+ SIM_STATE_NOT_READY,
+ SIM_STATE_LOCKED_OR_ABSENT,
+ SIM_STATE_READY,
+ SIM_STATE_MAX,
+};
+
int ril_radio_state_update(RIL_RadioState radio_state);
-int ril_radio_state_check(RIL_RadioState radio_state);
+int ril_radio_has_reached_state(RIL_RadioState radio_state);
+
+int ril_sim_state_update(enum sim_state sim_state);
+int ril_sim_has_reached_state(enum sim_state sim_state);
/*
* RIL data
@@ -213,6 +236,7 @@ struct ril_data {
const struct RIL_Env *env;
RIL_RadioState radio_state;
+ enum sim_state sim_state;
char *sim_pin;
struct list_head *requests;
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
new file mode 100755
index 0000000..a63380c
--- /dev/null
+++ b/scripts/checkpatch.pl
@@ -0,0 +1,6799 @@
+#!/usr/bin/env perl
+# SPDX-License-Identifier: GPL-2.0
+#
+# (c) 2001, Dave Jones. (the file handling bit)
+# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
+# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)
+# (c) 2008-2010 Andy Whitcroft <apw@canonical.com>
+# (c) 2010-2018 Joe Perches <joe@perches.com>
+
+use strict;
+use warnings;
+use POSIX;
+use File::Basename;
+use Cwd 'abs_path';
+use Term::ANSIColor qw(:constants);
+use Encode qw(decode encode);
+
+my $P = $0;
+my $D = dirname(abs_path($P));
+
+my $V = '0.32';
+
+use Getopt::Long qw(:config no_auto_abbrev);
+
+my $quiet = 0;
+my $tree = 1;
+my $chk_signoff = 1;
+my $chk_patch = 1;
+my $tst_only;
+my $emacs = 0;
+my $terse = 0;
+my $showfile = 0;
+my $file = 0;
+my $git = 0;
+my %git_commits = ();
+my $check = 0;
+my $check_orig = 0;
+my $summary = 1;
+my $mailback = 0;
+my $summary_file = 0;
+my $show_types = 0;
+my $list_types = 0;
+my $fix = 0;
+my $fix_inplace = 0;
+my $root;
+my %debug;
+my %camelcase = ();
+my %use_type = ();
+my @use = ();
+my %ignore_type = ();
+my @ignore = ();
+my $help = 0;
+my $configuration_file = ".checkpatch.conf";
+my $max_line_length = 80;
+my $ignore_perl_version = 0;
+my $minimum_perl_version = 5.10.0;
+my $min_conf_desc_length = 4;
+my $spelling_file = "$D/spelling.txt";
+my $codespell = 0;
+my $codespellfile = "/usr/share/codespell/dictionary.txt";
+my $conststructsfile = "$D/const_structs.checkpatch";
+my $typedefsfile = "";
+my $color = "auto";
+my $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE
+# git output parsing needs US English output, so first set backtick child process LANGUAGE
+my $git_command ='export LANGUAGE=en_US.UTF-8; git';
+
+sub help {
+ my ($exitcode) = @_;
+
+ print << "EOM";
+Usage: $P [OPTION]... [FILE]...
+Version: $V
+
+Options:
+ -q, --quiet quiet
+ --no-tree run without a kernel tree
+ --no-signoff do not check for 'Signed-off-by' line
+ --patch treat FILE as patchfile (default)
+ --emacs emacs compile window format
+ --terse one line per report
+ --showfile emit diffed file position, not input file position
+ -g, --git treat FILE as a single commit or git revision range
+ single git commit with:
+ <rev>
+ <rev>^
+ <rev>~n
+ multiple git commits with:
+ <rev1>..<rev2>
+ <rev1>...<rev2>
+ <rev>-<count>
+ git merges are ignored
+ -f, --file treat FILE as regular source file
+ --subjective, --strict enable more subjective tests
+ --list-types list the possible message types
+ --types TYPE(,TYPE2...) show only these comma separated message types
+ --ignore TYPE(,TYPE2...) ignore various comma separated message types
+ --show-types show the specific message type in the output
+ --max-line-length=n set the maximum line length, if exceeded, warn
+ --min-conf-desc-length=n set the min description length, if shorter, warn
+ --root=PATH PATH to the kernel tree root
+ --no-summary suppress the per-file summary
+ --mailback only produce a report in case of warnings/errors
+ --summary-file include the filename in summary
+ --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of
+ 'values', 'possible', 'type', and 'attr' (default
+ is all off)
+ --test-only=WORD report only warnings/errors containing WORD
+ literally
+ --fix EXPERIMENTAL - may create horrible results
+ If correctable single-line errors exist, create
+ "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
+ with potential errors corrected to the preferred
+ checkpatch style
+ --fix-inplace EXPERIMENTAL - may create horrible results
+ Is the same as --fix, but overwrites the input
+ file. It's your fault if there's no backup or git
+ --ignore-perl-version override checking of perl version. expect
+ runtime errors.
+ --codespell Use the codespell dictionary for spelling/typos
+ (default:/usr/share/codespell/dictionary.txt)
+ --codespellfile Use this codespell dictionary
+ --typedefsfile Read additional types from this file
+ --color[=WHEN] Use colors 'always', 'never', or only when output
+ is a terminal ('auto'). Default is 'auto'.
+ -h, --help, --version display this help and exit
+
+When FILE is - read standard input.
+EOM
+
+ exit($exitcode);
+}
+
+sub uniq {
+ my %seen;
+ return grep { !$seen{$_}++ } @_;
+}
+
+sub list_types {
+ my ($exitcode) = @_;
+
+ my $count = 0;
+
+ local $/ = undef;
+
+ open(my $script, '<', abs_path($P)) or
+ die "$P: Can't read '$P' $!\n";
+
+ my $text = <$script>;
+ close($script);
+
+ my @types = ();
+ # Also catch when type or level is passed through a variable
+ for ($text =~ /(?:(?:\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) {
+ push (@types, $_);
+ }
+ @types = sort(uniq(@types));
+ print("#\tMessage type\n\n");
+ foreach my $type (@types) {
+ print(++$count . "\t" . $type . "\n");
+ }
+
+ exit($exitcode);
+}
+
+my $conf = which_conf($configuration_file);
+if (-f $conf) {
+ my @conf_args;
+ open(my $conffile, '<', "$conf")
+ or warn "$P: Can't find a readable $configuration_file file $!\n";
+
+ while (<$conffile>) {
+ my $line = $_;
+
+ $line =~ s/\s*\n?$//g;
+ $line =~ s/^\s*//g;
+ $line =~ s/\s+/ /g;
+
+ next if ($line =~ m/^\s*#/);
+ next if ($line =~ m/^\s*$/);
+
+ my @words = split(" ", $line);
+ foreach my $word (@words) {
+ last if ($word =~ m/^#/);
+ push (@conf_args, $word);
+ }
+ }
+ close($conffile);
+ unshift(@ARGV, @conf_args) if @conf_args;
+}
+
+# Perl's Getopt::Long allows options to take optional arguments after a space.
+# Prevent --color by itself from consuming other arguments
+foreach (@ARGV) {
+ if ($_ eq "--color" || $_ eq "-color") {
+ $_ = "--color=$color";
+ }
+}
+
+GetOptions(
+ 'q|quiet+' => \$quiet,
+ 'tree!' => \$tree,
+ 'signoff!' => \$chk_signoff,
+ 'patch!' => \$chk_patch,
+ 'emacs!' => \$emacs,
+ 'terse!' => \$terse,
+ 'showfile!' => \$showfile,
+ 'f|file!' => \$file,
+ 'g|git!' => \$git,
+ 'subjective!' => \$check,
+ 'strict!' => \$check,
+ 'ignore=s' => \@ignore,
+ 'types=s' => \@use,
+ 'show-types!' => \$show_types,
+ 'list-types!' => \$list_types,
+ 'max-line-length=i' => \$max_line_length,
+ 'min-conf-desc-length=i' => \$min_conf_desc_length,
+ 'root=s' => \$root,
+ 'summary!' => \$summary,
+ 'mailback!' => \$mailback,
+ 'summary-file!' => \$summary_file,
+ 'fix!' => \$fix,
+ 'fix-inplace!' => \$fix_inplace,
+ 'ignore-perl-version!' => \$ignore_perl_version,
+ 'debug=s' => \%debug,
+ 'test-only=s' => \$tst_only,
+ 'codespell!' => \$codespell,
+ 'codespellfile=s' => \$codespellfile,
+ 'typedefsfile=s' => \$typedefsfile,
+ 'color=s' => \$color,
+ 'no-color' => \$color, #keep old behaviors of -nocolor
+ 'nocolor' => \$color, #keep old behaviors of -nocolor
+ 'h|help' => \$help,
+ 'version' => \$help
+) or help(1);
+
+help(0) if ($help);
+
+list_types(0) if ($list_types);
+
+$fix = 1 if ($fix_inplace);
+$check_orig = $check;
+
+my $exit = 0;
+
+my $perl_version_ok = 1;
+if ($^V && $^V lt $minimum_perl_version) {
+ $perl_version_ok = 0;
+ printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
+ exit(1) if (!$ignore_perl_version);
+}
+
+#if no filenames are given, push '-' to read patch from stdin
+if ($#ARGV < 0) {
+ push(@ARGV, '-');
+}
+
+if ($color =~ /^[01]$/) {
+ $color = !$color;
+} elsif ($color =~ /^always$/i) {
+ $color = 1;
+} elsif ($color =~ /^never$/i) {
+ $color = 0;
+} elsif ($color =~ /^auto$/i) {
+ $color = (-t STDOUT);
+} else {
+ die "Invalid color mode: $color\n";
+}
+
+sub hash_save_array_words {
+ my ($hashRef, $arrayRef) = @_;
+
+ my @array = split(/,/, join(',', @$arrayRef));
+ foreach my $word (@array) {
+ $word =~ s/\s*\n?$//g;
+ $word =~ s/^\s*//g;
+ $word =~ s/\s+/ /g;
+ $word =~ tr/[a-z]/[A-Z]/;
+
+ next if ($word =~ m/^\s*#/);
+ next if ($word =~ m/^\s*$/);
+
+ $hashRef->{$word}++;
+ }
+}
+
+sub hash_show_words {
+ my ($hashRef, $prefix) = @_;
+
+ if (keys %$hashRef) {
+ print "\nNOTE: $prefix message types:";
+ foreach my $word (sort keys %$hashRef) {
+ print " $word";
+ }
+ print "\n";
+ }
+}
+
+hash_save_array_words(\%ignore_type, \@ignore);
+hash_save_array_words(\%use_type, \@use);
+
+my $dbg_values = 0;
+my $dbg_possible = 0;
+my $dbg_type = 0;
+my $dbg_attr = 0;
+for my $key (keys %debug) {
+ ## no critic
+ eval "\${dbg_$key} = '$debug{$key}';";
+ die "$@" if ($@);
+}
+
+my $rpt_cleaners = 0;
+
+if ($terse) {
+ $emacs = 1;
+ $quiet++;
+}
+
+if ($tree) {
+ if (defined $root) {
+ if (!top_of_kernel_tree($root)) {
+ die "$P: $root: --root does not point at a valid tree\n";
+ }
+ } else {
+ if (top_of_kernel_tree('.')) {
+ $root = '.';
+ } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
+ top_of_kernel_tree($1)) {
+ $root = $1;
+ }
+ }
+
+ if (!defined $root) {
+ print "Must be run from the top-level dir. of a kernel tree\n";
+ exit(2);
+ }
+}
+
+my $emitted_corrupt = 0;
+
+our $Ident = qr{
+ [A-Za-z_][A-Za-z\d_]*
+ (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
+ }x;
+our $Storage = qr{extern|static|asmlinkage};
+our $Sparse = qr{
+ __user|
+ __kernel|
+ __force|
+ __iomem|
+ __must_check|
+ __kprobes|
+ __ref|
+ __refconst|
+ __refdata|
+ __rcu|
+ __private
+ }x;
+our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
+our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
+our $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
+our $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
+our $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
+
+# Notes to $Attribute:
+# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
+our $Attribute = qr{
+ const|
+ __percpu|
+ __nocast|
+ __safe|
+ __bitwise|
+ __packed__|
+ __packed2__|
+ __naked|
+ __maybe_unused|
+ __always_unused|
+ __noreturn|
+ __used|
+ __cold|
+ __pure|
+ __noclone|
+ __deprecated|
+ __read_mostly|
+ __ro_after_init|
+ __kprobes|
+ $InitAttribute|
+ ____cacheline_aligned|
+ ____cacheline_aligned_in_smp|
+ ____cacheline_internodealigned_in_smp|
+ __weak
+ }x;
+our $Modifier;
+our $Inline = qr{inline|__always_inline|noinline|__inline|__inline__};
+our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]};
+our $Lval = qr{$Ident(?:$Member)*};
+
+our $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u};
+our $Binary = qr{(?i)0b[01]+$Int_type?};
+our $Hex = qr{(?i)0x[0-9a-f]+$Int_type?};
+our $Int = qr{[0-9]+$Int_type?};
+our $Octal = qr{0[0-7]+$Int_type?};
+our $String = qr{"[X\t]*"};
+our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
+our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
+our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?};
+our $Float = qr{$Float_hex|$Float_dec|$Float_int};
+our $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int};
+our $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
+our $Compare = qr{<=|>=|==|!=|<|(?<!-)>};
+our $Arithmetic = qr{\+|-|\*|\/|%};
+our $Operators = qr{
+ <=|>=|==|!=|
+ =>|->|<<|>>|<|>|!|~|
+ &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
+ }x;
+
+our $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
+
+our $BasicType;
+our $NonptrType;
+our $NonptrTypeMisordered;
+our $NonptrTypeWithAttr;
+our $Type;
+our $TypeMisordered;
+our $Declare;
+our $DeclareMisordered;
+
+our $NON_ASCII_UTF8 = qr{
+ [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
+ | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
+ | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
+ | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
+ | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
+ | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
+ | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
+}x;
+
+our $UTF8 = qr{
+ [\x09\x0A\x0D\x20-\x7E] # ASCII
+ | $NON_ASCII_UTF8
+}x;
+
+our $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
+our $typeOtherOSTypedefs = qr{(?x:
+ u_(?:char|short|int|long) | # bsd
+ u(?:nchar|short|int|long) # sysv
+)};
+our $typeKernelTypedefs = qr{(?x:
+ (?:__)?(?:u|s|be|le)(?:8|16|32|64)|
+ atomic_t
+)};
+our $typeTypedefs = qr{(?x:
+ $typeC99Typedefs\b|
+ $typeOtherOSTypedefs\b|
+ $typeKernelTypedefs\b
+)};
+
+our $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b};
+
+our $logFunctions = qr{(?x:
+ printk(?:_ratelimited|_once|_deferred_once|_deferred|)|
+ (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
+ TP_printk|
+ WARN(?:_RATELIMIT|_ONCE|)|
+ panic|
+ MODULE_[A-Z_]+|
+ seq_vprintf|seq_printf|seq_puts
+)};
+
+our $allocFunctions = qr{(?x:
+ (?:(?:devm_)?
+ (?:kv|k|v)[czm]alloc(?:_node|_array)? |
+ kstrdup(?:_const)? |
+ kmemdup(?:_nul)?) |
+ (?:\w+)?alloc_skb(?:ip_align)? |
+ # dev_alloc_skb/netdev_alloc_skb, et al
+ dma_alloc_coherent
+)};
+
+our $signature_tags = qr{(?xi:
+ Signed-off-by:|
+ Co-developed-by:|
+ Acked-by:|
+ Tested-by:|
+ Reviewed-by:|
+ Reported-by:|
+ Suggested-by:|
+ To:|
+ Cc:
+)};
+
+our @typeListMisordered = (
+ qr{char\s+(?:un)?signed},
+ qr{int\s+(?:(?:un)?signed\s+)?short\s},
+ qr{int\s+short(?:\s+(?:un)?signed)},
+ qr{short\s+int(?:\s+(?:un)?signed)},
+ qr{(?:un)?signed\s+int\s+short},
+ qr{short\s+(?:un)?signed},
+ qr{long\s+int\s+(?:un)?signed},
+ qr{int\s+long\s+(?:un)?signed},
+ qr{long\s+(?:un)?signed\s+int},
+ qr{int\s+(?:un)?signed\s+long},
+ qr{int\s+(?:un)?signed},
+ qr{int\s+long\s+long\s+(?:un)?signed},
+ qr{long\s+long\s+int\s+(?:un)?signed},
+ qr{long\s+long\s+(?:un)?signed\s+int},
+ qr{long\s+long\s+(?:un)?signed},
+ qr{long\s+(?:un)?signed},
+);
+
+our @typeList = (
+ qr{void},
+ qr{(?:(?:un)?signed\s+)?char},
+ qr{(?:(?:un)?signed\s+)?short\s+int},
+ qr{(?:(?:un)?signed\s+)?short},
+ qr{(?:(?:un)?signed\s+)?int},
+ qr{(?:(?:un)?signed\s+)?long\s+int},
+ qr{(?:(?:un)?signed\s+)?long\s+long\s+int},
+ qr{(?:(?:un)?signed\s+)?long\s+long},
+ qr{(?:(?:un)?signed\s+)?long},
+ qr{(?:un)?signed},
+ qr{float},
+ qr{double},
+ qr{bool},
+ qr{struct\s+$Ident},
+ qr{union\s+$Ident},
+ qr{enum\s+$Ident},
+ qr{${Ident}_t},
+ qr{${Ident}_handler},
+ qr{${Ident}_handler_fn},
+ @typeListMisordered,
+);
+
+our $C90_int_types = qr{(?x:
+ long\s+long\s+int\s+(?:un)?signed|
+ long\s+long\s+(?:un)?signed\s+int|
+ long\s+long\s+(?:un)?signed|
+ (?:(?:un)?signed\s+)?long\s+long\s+int|
+ (?:(?:un)?signed\s+)?long\s+long|
+ int\s+long\s+long\s+(?:un)?signed|
+ int\s+(?:(?:un)?signed\s+)?long\s+long|
+
+ long\s+int\s+(?:un)?signed|
+ long\s+(?:un)?signed\s+int|
+ long\s+(?:un)?signed|
+ (?:(?:un)?signed\s+)?long\s+int|
+ (?:(?:un)?signed\s+)?long|
+ int\s+long\s+(?:un)?signed|
+ int\s+(?:(?:un)?signed\s+)?long|
+
+ int\s+(?:un)?signed|
+ (?:(?:un)?signed\s+)?int
+)};
+
+our @typeListFile = ();
+our @typeListWithAttr = (
+ @typeList,
+ qr{struct\s+$InitAttribute\s+$Ident},
+ qr{union\s+$InitAttribute\s+$Ident},
+);
+
+our @modifierList = (
+ qr{fastcall},
+);
+our @modifierListFile = ();
+
+our @mode_permission_funcs = (
+ ["module_param", 3],
+ ["module_param_(?:array|named|string)", 4],
+ ["module_param_array_named", 5],
+ ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
+ ["proc_create(?:_data|)", 2],
+ ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2],
+ ["IIO_DEV_ATTR_[A-Z_]+", 1],
+ ["SENSOR_(?:DEVICE_|)ATTR_2", 2],
+ ["SENSOR_TEMPLATE(?:_2|)", 3],
+ ["__ATTR", 2],
+);
+
+#Create a search pattern for all these functions to speed up a loop below
+our $mode_perms_search = "";
+foreach my $entry (@mode_permission_funcs) {
+ $mode_perms_search .= '|' if ($mode_perms_search ne "");
+ $mode_perms_search .= $entry->[0];
+}
+$mode_perms_search = "(?:${mode_perms_search})";
+
+our %deprecated_apis = (
+ "synchronize_rcu_bh" => "synchronize_rcu",
+ "synchronize_rcu_bh_expedited" => "synchronize_rcu_expedited",
+ "call_rcu_bh" => "call_rcu",
+ "rcu_barrier_bh" => "rcu_barrier",
+ "synchronize_sched" => "synchronize_rcu",
+ "synchronize_sched_expedited" => "synchronize_rcu_expedited",
+ "call_rcu_sched" => "call_rcu",
+ "rcu_barrier_sched" => "rcu_barrier",
+ "get_state_synchronize_sched" => "get_state_synchronize_rcu",
+ "cond_synchronize_sched" => "cond_synchronize_rcu",
+);
+
+#Create a search pattern for all these strings to speed up a loop below
+our $deprecated_apis_search = "";
+foreach my $entry (keys %deprecated_apis) {
+ $deprecated_apis_search .= '|' if ($deprecated_apis_search ne "");
+ $deprecated_apis_search .= $entry;
+}
+$deprecated_apis_search = "(?:${deprecated_apis_search})";
+
+our $mode_perms_world_writable = qr{
+ S_IWUGO |
+ S_IWOTH |
+ S_IRWXUGO |
+ S_IALLUGO |
+ 0[0-7][0-7][2367]
+}x;
+
+our %mode_permission_string_types = (
+ "S_IRWXU" => 0700,
+ "S_IRUSR" => 0400,
+ "S_IWUSR" => 0200,
+ "S_IXUSR" => 0100,
+ "S_IRWXG" => 0070,
+ "S_IRGRP" => 0040,
+ "S_IWGRP" => 0020,
+ "S_IXGRP" => 0010,
+ "S_IRWXO" => 0007,
+ "S_IROTH" => 0004,
+ "S_IWOTH" => 0002,
+ "S_IXOTH" => 0001,
+ "S_IRWXUGO" => 0777,
+ "S_IRUGO" => 0444,
+ "S_IWUGO" => 0222,
+ "S_IXUGO" => 0111,
+);
+
+#Create a search pattern for all these strings to speed up a loop below
+our $mode_perms_string_search = "";
+foreach my $entry (keys %mode_permission_string_types) {
+ $mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
+ $mode_perms_string_search .= $entry;
+}
+our $single_mode_perms_string_search = "(?:${mode_perms_string_search})";
+our $multi_mode_perms_string_search = qr{
+ ${single_mode_perms_string_search}
+ (?:\s*\|\s*${single_mode_perms_string_search})*
+}x;
+
+sub perms_to_octal {
+ my ($string) = @_;
+
+ return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/);
+
+ my $val = "";
+ my $oval = "";
+ my $to = 0;
+ my $curpos = 0;
+ my $lastpos = 0;
+ while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
+ $curpos = pos($string);
+ my $match = $2;
+ my $omatch = $1;
+ last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
+ $lastpos = $curpos;
+ $to |= $mode_permission_string_types{$match};
+ $val .= '\s*\|\s*' if ($val ne "");
+ $val .= $match;
+ $oval .= $omatch;
+ }
+ $oval =~ s/^\s*\|\s*//;
+ $oval =~ s/\s*\|\s*$//;
+ return sprintf("%04o", $to);
+}
+
+our $allowed_asm_includes = qr{(?x:
+ irq|
+ memory|
+ time|
+ reboot
+)};
+# memory.h: ARM has a custom one
+
+# Load common spelling mistakes and build regular expression list.
+my $misspellings;
+my %spelling_fix;
+
+if (open(my $spelling, '<', $spelling_file)) {
+ while (<$spelling>) {
+ my $line = $_;
+
+ $line =~ s/\s*\n?$//g;
+ $line =~ s/^\s*//g;
+
+ next if ($line =~ m/^\s*#/);
+ next if ($line =~ m/^\s*$/);
+
+ my ($suspect, $fix) = split(/\|\|/, $line);
+
+ $spelling_fix{$suspect} = $fix;
+ }
+ close($spelling);
+} else {
+ warn "No typos will be found - file '$spelling_file': $!\n";
+}
+
+if ($codespell) {
+ if (open(my $spelling, '<', $codespellfile)) {
+ while (<$spelling>) {
+ my $line = $_;
+
+ $line =~ s/\s*\n?$//g;
+ $line =~ s/^\s*//g;
+
+ next if ($line =~ m/^\s*#/);
+ next if ($line =~ m/^\s*$/);
+ next if ($line =~ m/, disabled/i);
+
+ $line =~ s/,.*$//;
+
+ my ($suspect, $fix) = split(/->/, $line);
+
+ $spelling_fix{$suspect} = $fix;
+ }
+ close($spelling);
+ } else {
+ warn "No codespell typos will be found - file '$codespellfile': $!\n";
+ }
+}
+
+$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
+
+sub read_words {
+ my ($wordsRef, $file) = @_;
+
+ if (open(my $words, '<', $file)) {
+ while (<$words>) {
+ my $line = $_;
+
+ $line =~ s/\s*\n?$//g;
+ $line =~ s/^\s*//g;
+
+ next if ($line =~ m/^\s*#/);
+ next if ($line =~ m/^\s*$/);
+ if ($line =~ /\s/) {
+ print("$file: '$line' invalid - ignored\n");
+ next;
+ }
+
+ $$wordsRef .= '|' if ($$wordsRef ne "");
+ $$wordsRef .= $line;
+ }
+ close($file);
+ return 1;
+ }
+
+ return 0;
+}
+
+my $const_structs = "";
+read_words(\$const_structs, $conststructsfile)
+ or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
+
+my $typeOtherTypedefs = "";
+if (length($typedefsfile)) {
+ read_words(\$typeOtherTypedefs, $typedefsfile)
+ or warn "No additional types will be considered - file '$typedefsfile': $!\n";
+}
+$typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne "");
+
+sub build_types {
+ my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)";
+ my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)";
+ my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)";
+ my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)";
+ $Modifier = qr{(?:$Attribute|$Sparse|$mods)};
+ $BasicType = qr{
+ (?:$typeTypedefs\b)|
+ (?:${all}\b)
+ }x;
+ $NonptrType = qr{
+ (?:$Modifier\s+|const\s+)*
+ (?:
+ (?:typeof|__typeof__)\s*\([^\)]*\)|
+ (?:$typeTypedefs\b)|
+ (?:${all}\b)
+ )
+ (?:\s+$Modifier|\s+const)*
+ }x;
+ $NonptrTypeMisordered = qr{
+ (?:$Modifier\s+|const\s+)*
+ (?:
+ (?:${Misordered}\b)
+ )
+ (?:\s+$Modifier|\s+const)*
+ }x;
+ $NonptrTypeWithAttr = qr{
+ (?:$Modifier\s+|const\s+)*
+ (?:
+ (?:typeof|__typeof__)\s*\([^\)]*\)|
+ (?:$typeTypedefs\b)|
+ (?:${allWithAttr}\b)
+ )
+ (?:\s+$Modifier|\s+const)*
+ }x;
+ $Type = qr{
+ $NonptrType
+ (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
+ (?:\s+$Inline|\s+$Modifier)*
+ }x;
+ $TypeMisordered = qr{
+ $NonptrTypeMisordered
+ (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
+ (?:\s+$Inline|\s+$Modifier)*
+ }x;
+ $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
+ $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
+}
+build_types();
+
+our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
+
+# Using $balanced_parens, $LvalOrFunc, or $FuncArg
+# requires at least perl version v5.10.0
+# Any use must be runtime checked with $^V
+
+our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
+our $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
+our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
+
+our $declaration_macros = qr{(?x:
+ (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
+ (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
+ (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(|
+ (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(
+)};
+
+sub deparenthesize {
+ my ($string) = @_;
+ return "" if (!defined($string));
+
+ while ($string =~ /^\s*\(.*\)\s*$/) {
+ $string =~ s@^\s*\(\s*@@;
+ $string =~ s@\s*\)\s*$@@;
+ }
+
+ $string =~ s@\s+@ @g;
+
+ return $string;
+}
+
+sub seed_camelcase_file {
+ my ($file) = @_;
+
+ return if (!(-f $file));
+
+ local $/;
+
+ open(my $include_file, '<', "$file")
+ or warn "$P: Can't read '$file' $!\n";
+ my $text = <$include_file>;
+ close($include_file);
+
+ my @lines = split('\n', $text);
+
+ foreach my $line (@lines) {
+ next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
+ if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
+ $camelcase{$1} = 1;
+ } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
+ $camelcase{$1} = 1;
+ } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
+ $camelcase{$1} = 1;
+ }
+ }
+}
+
+our %maintained_status = ();
+
+sub is_maintained_obsolete {
+ my ($filename) = @_;
+
+ return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
+
+ if (!exists($maintained_status{$filename})) {
+ $maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
+ }
+
+ return $maintained_status{$filename} =~ /obsolete/i;
+}
+
+sub is_SPDX_License_valid {
+ my ($license) = @_;
+
+ return 1 if (!$tree || which("python") eq "" || !(-e "$root/scripts/spdxcheck.py") || !(-e "$root/.git"));
+
+ my $root_path = abs_path($root);
+ my $status = `cd "$root_path"; echo "$license" | python scripts/spdxcheck.py -`;
+ return 0 if ($status ne "");
+ return 1;
+}
+
+my $camelcase_seeded = 0;
+sub seed_camelcase_includes {
+ return if ($camelcase_seeded);
+
+ my $files;
+ my $camelcase_cache = "";
+ my @include_files = ();
+
+ $camelcase_seeded = 1;
+
+ if (-e ".git") {
+ my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`;
+ chomp $git_last_include_commit;
+ $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
+ } else {
+ my $last_mod_date = 0;
+ $files = `find $root/include -name "*.h"`;
+ @include_files = split('\n', $files);
+ foreach my $file (@include_files) {
+ my $date = POSIX::strftime("%Y%m%d%H%M",
+ localtime((stat $file)[9]));
+ $last_mod_date = $date if ($last_mod_date < $date);
+ }
+ $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
+ }
+
+ if ($camelcase_cache ne "" && -f $camelcase_cache) {
+ open(my $camelcase_file, '<', "$camelcase_cache")
+ or warn "$P: Can't read '$camelcase_cache' $!\n";
+ while (<$camelcase_file>) {
+ chomp;
+ $camelcase{$_} = 1;
+ }
+ close($camelcase_file);
+
+ return;
+ }
+
+ if (-e ".git") {
+ $files = `${git_command} ls-files "include/*.h"`;
+ @include_files = split('\n', $files);
+ }
+
+ foreach my $file (@include_files) {
+ seed_camelcase_file($file);
+ }
+
+ if ($camelcase_cache ne "") {
+ unlink glob ".checkpatch-camelcase.*";
+ open(my $camelcase_file, '>', "$camelcase_cache")
+ or warn "$P: Can't write '$camelcase_cache' $!\n";
+ foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
+ print $camelcase_file ("$_\n");
+ }
+ close($camelcase_file);
+ }
+}
+
+sub git_commit_info {
+ my ($commit, $id, $desc) = @_;
+
+ return ($id, $desc) if ((which("git") eq "") || !(-e ".git"));
+
+ my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`;
+ $output =~ s/^\s*//gm;
+ my @lines = split("\n", $output);
+
+ return ($id, $desc) if ($#lines < 0);
+
+ if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) {
+# Maybe one day convert this block of bash into something that returns
+# all matching commit ids, but it's very slow...
+#
+# echo "checking commits $1..."
+# git rev-list --remotes | grep -i "^$1" |
+# while read line ; do
+# git log --format='%H %s' -1 $line |
+# echo "commit $(cut -c 1-12,41-)"
+# done
+ } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) {
+ $id = undef;
+ } else {
+ $id = substr($lines[0], 0, 12);
+ $desc = substr($lines[0], 41);
+ }
+
+ return ($id, $desc);
+}
+
+$chk_signoff = 0 if ($file);
+
+my @rawlines = ();
+my @lines = ();
+my @fixed = ();
+my @fixed_inserted = ();
+my @fixed_deleted = ();
+my $fixlinenr = -1;
+
+# If input is git commits, extract all commits from the commit expressions.
+# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
+die "$P: No git repository found\n" if ($git && !-e ".git");
+
+if ($git) {
+ my @commits = ();
+ foreach my $commit_expr (@ARGV) {
+ my $git_range;
+ if ($commit_expr =~ m/^(.*)-(\d+)$/) {
+ $git_range = "-$2 $1";
+ } elsif ($commit_expr =~ m/\.\./) {
+ $git_range = "$commit_expr";
+ } else {
+ $git_range = "-1 $commit_expr";
+ }
+ my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
+ foreach my $line (split(/\n/, $lines)) {
+ $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
+ next if (!defined($1) || !defined($2));
+ my $sha1 = $1;
+ my $subject = $2;
+ unshift(@commits, $sha1);
+ $git_commits{$sha1} = $subject;
+ }
+ }
+ die "$P: no git commits after extraction!\n" if (@commits == 0);
+ @ARGV = @commits;
+}
+
+my $vname;
+$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"};
+for my $filename (@ARGV) {
+ my $FILE;
+ if ($git) {
+ open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
+ die "$P: $filename: git format-patch failed - $!\n";
+ } elsif ($file) {
+ open($FILE, '-|', "diff -u /dev/null $filename") ||
+ die "$P: $filename: diff failed - $!\n";
+ } elsif ($filename eq '-') {
+ open($FILE, '<&STDIN');
+ } else {
+ open($FILE, '<', "$filename") ||
+ die "$P: $filename: open failed - $!\n";
+ }
+ if ($filename eq '-') {
+ $vname = 'Your patch';
+ } elsif ($git) {
+ $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
+ } else {
+ $vname = $filename;
+ }
+ while (<$FILE>) {
+ chomp;
+ push(@rawlines, $_);
+ }
+ close($FILE);
+
+ if ($#ARGV > 0 && $quiet == 0) {
+ print '-' x length($vname) . "\n";
+ print "$vname\n";
+ print '-' x length($vname) . "\n";
+ }
+
+ if (!process($filename)) {
+ $exit = 1;
+ }
+ @rawlines = ();
+ @lines = ();
+ @fixed = ();
+ @fixed_inserted = ();
+ @fixed_deleted = ();
+ $fixlinenr = -1;
+ @modifierListFile = ();
+ @typeListFile = ();
+ build_types();
+}
+
+if (!$quiet) {
+ hash_show_words(\%use_type, "Used");
+ hash_show_words(\%ignore_type, "Ignored");
+
+ if (!$perl_version_ok) {
+ print << "EOM"
+
+NOTE: perl $^V is not modern enough to detect all possible issues.
+ An upgrade to at least perl $minimum_perl_version is suggested.
+EOM
+ }
+ if ($exit) {
+ print << "EOM"
+
+NOTE: If any of the errors are false positives, please report
+ them to the maintainer, see CHECKPATCH in MAINTAINERS.
+EOM
+ }
+}
+
+exit($exit);
+
+sub top_of_kernel_tree {
+ my ($root) = @_;
+
+ my @tree_check = (
+ "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
+ "README", "Documentation", "arch", "include", "drivers",
+ "fs", "init", "ipc", "kernel", "lib", "scripts",
+ );
+
+ foreach my $check (@tree_check) {
+ if (! -e $root . '/' . $check) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+sub parse_email {
+ my ($formatted_email) = @_;
+
+ my $name = "";
+ my $address = "";
+ my $comment = "";
+
+ if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
+ $name = $1;
+ $address = $2;
+ $comment = $3 if defined $3;
+ } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
+ $address = $1;
+ $comment = $2 if defined $2;
+ } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
+ $address = $1;
+ $comment = $2 if defined $2;
+ $formatted_email =~ s/\Q$address\E.*$//;
+ $name = $formatted_email;
+ $name = trim($name);
+ $name =~ s/^\"|\"$//g;
+ # If there's a name left after stripping spaces and
+ # leading quotes, and the address doesn't have both
+ # leading and trailing angle brackets, the address
+ # is invalid. ie:
+ # "joe smith joe@smith.com" bad
+ # "joe smith <joe@smith.com" bad
+ if ($name ne "" && $address !~ /^<[^>]+>$/) {
+ $name = "";
+ $address = "";
+ $comment = "";
+ }
+ }
+
+ $name = trim($name);
+ $name =~ s/^\"|\"$//g;
+ $address = trim($address);
+ $address =~ s/^\<|\>$//g;
+
+ if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
+ $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
+ $name = "\"$name\"";
+ }
+
+ return ($name, $address, $comment);
+}
+
+sub format_email {
+ my ($name, $address) = @_;
+
+ my $formatted_email;
+
+ $name = trim($name);
+ $name =~ s/^\"|\"$//g;
+ $address = trim($address);
+
+ if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
+ $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
+ $name = "\"$name\"";
+ }
+
+ if ("$name" eq "") {
+ $formatted_email = "$address";
+ } else {
+ $formatted_email = "$name <$address>";
+ }
+
+ return $formatted_email;
+}
+
+sub which {
+ my ($bin) = @_;
+
+ foreach my $path (split(/:/, $ENV{PATH})) {
+ if (-e "$path/$bin") {
+ return "$path/$bin";
+ }
+ }
+
+ return "";
+}
+
+sub which_conf {
+ my ($conf) = @_;
+
+ foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
+ if (-e "$path/$conf") {
+ return "$path/$conf";
+ }
+ }
+
+ return "";
+}
+
+sub expand_tabs {
+ my ($str) = @_;
+
+ my $res = '';
+ my $n = 0;
+ for my $c (split(//, $str)) {
+ if ($c eq "\t") {
+ $res .= ' ';
+ $n++;
+ for (; ($n % 8) != 0; $n++) {
+ $res .= ' ';
+ }
+ next;
+ }
+ $res .= $c;
+ $n++;
+ }
+
+ return $res;
+}
+sub copy_spacing {
+ (my $res = shift) =~ tr/\t/ /c;
+ return $res;
+}
+
+sub line_stats {
+ my ($line) = @_;
+
+ # Drop the diff line leader and expand tabs
+ $line =~ s/^.//;
+ $line = expand_tabs($line);
+
+ # Pick the indent from the front of the line.
+ my ($white) = ($line =~ /^(\s*)/);
+
+ return (length($line), length($white));
+}
+
+my $sanitise_quote = '';
+
+sub sanitise_line_reset {
+ my ($in_comment) = @_;
+
+ if ($in_comment) {
+ $sanitise_quote = '*/';
+ } else {
+ $sanitise_quote = '';
+ }
+}
+sub sanitise_line {
+ my ($line) = @_;
+
+ my $res = '';
+ my $l = '';
+
+ my $qlen = 0;
+ my $off = 0;
+ my $c;
+
+ # Always copy over the diff marker.
+ $res = substr($line, 0, 1);
+
+ for ($off = 1; $off < length($line); $off++) {
+ $c = substr($line, $off, 1);
+
+ # Comments we are whacking completely including the begin
+ # and end, all to $;.
+ if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
+ $sanitise_quote = '*/';
+
+ substr($res, $off, 2, "$;$;");
+ $off++;
+ next;
+ }
+ if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
+ $sanitise_quote = '';
+ substr($res, $off, 2, "$;$;");
+ $off++;
+ next;
+ }
+ if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
+ $sanitise_quote = '//';
+
+ substr($res, $off, 2, $sanitise_quote);
+ $off++;
+ next;
+ }
+
+ # A \ in a string means ignore the next character.
+ if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
+ $c eq "\\") {
+ substr($res, $off, 2, 'XX');
+ $off++;
+ next;
+ }
+ # Regular quotes.
+ if ($c eq "'" || $c eq '"') {
+ if ($sanitise_quote eq '') {
+ $sanitise_quote = $c;
+
+ substr($res, $off, 1, $c);
+ next;
+ } elsif ($sanitise_quote eq $c) {
+ $sanitise_quote = '';
+ }
+ }
+
+ #print "c<$c> SQ<$sanitise_quote>\n";
+ if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
+ substr($res, $off, 1, $;);
+ } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
+ substr($res, $off, 1, $;);
+ } elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
+ substr($res, $off, 1, 'X');
+ } else {
+ substr($res, $off, 1, $c);
+ }
+ }
+
+ if ($sanitise_quote eq '//') {
+ $sanitise_quote = '';
+ }
+
+ # The pathname on a #include may be surrounded by '<' and '>'.
+ if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
+ my $clean = 'X' x length($1);
+ $res =~ s@\<.*\>@<$clean>@;
+
+ # The whole of a #error is a string.
+ } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
+ my $clean = 'X' x length($1);
+ $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
+ }
+
+ if ($allow_c99_comments && $res =~ m@(//.*$)@) {
+ my $match = $1;
+ $res =~ s/\Q$match\E/"$;" x length($match)/e;
+ }
+
+ return $res;
+}
+
+sub get_quoted_string {
+ my ($line, $rawline) = @_;
+
+ return "" if (!defined($line) || !defined($rawline));
+ return "" if ($line !~ m/($String)/g);
+ return substr($rawline, $-[0], $+[0] - $-[0]);
+}
+
+sub ctx_statement_block {
+ my ($linenr, $remain, $off) = @_;
+ my $line = $linenr - 1;
+ my $blk = '';
+ my $soff = $off;
+ my $coff = $off - 1;
+ my $coff_set = 0;
+
+ my $loff = 0;
+
+ my $type = '';
+ my $level = 0;
+ my @stack = ();
+ my $p;
+ my $c;
+ my $len = 0;
+
+ my $remainder;
+ while (1) {
+ @stack = (['', 0]) if ($#stack == -1);
+
+ #warn "CSB: blk<$blk> remain<$remain>\n";
+ # If we are about to drop off the end, pull in more
+ # context.
+ if ($off >= $len) {
+ for (; $remain > 0; $line++) {
+ last if (!defined $lines[$line]);
+ next if ($lines[$line] =~ /^-/);
+ $remain--;
+ $loff = $len;
+ $blk .= $lines[$line] . "\n";
+ $len = length($blk);
+ $line++;
+ last;
+ }
+ # Bail if there is no further context.
+ #warn "CSB: blk<$blk> off<$off> len<$len>\n";
+ if ($off >= $len) {
+ last;
+ }
+ if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
+ $level++;
+ $type = '#';
+ }
+ }
+ $p = $c;
+ $c = substr($blk, $off, 1);
+ $remainder = substr($blk, $off);
+
+ #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
+
+ # Handle nested #if/#else.
+ if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
+ push(@stack, [ $type, $level ]);
+ } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
+ ($type, $level) = @{$stack[$#stack - 1]};
+ } elsif ($remainder =~ /^#\s*endif\b/) {
+ ($type, $level) = @{pop(@stack)};
+ }
+
+ # Statement ends at the ';' or a close '}' at the
+ # outermost level.
+ if ($level == 0 && $c eq ';') {
+ last;
+ }
+
+ # An else is really a conditional as long as its not else if
+ if ($level == 0 && $coff_set == 0 &&
+ (!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
+ $remainder =~ /^(else)(?:\s|{)/ &&
+ $remainder !~ /^else\s+if\b/) {
+ $coff = $off + length($1) - 1;
+ $coff_set = 1;
+ #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
+ #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
+ }
+
+ if (($type eq '' || $type eq '(') && $c eq '(') {
+ $level++;
+ $type = '(';
+ }
+ if ($type eq '(' && $c eq ')') {
+ $level--;
+ $type = ($level != 0)? '(' : '';
+
+ if ($level == 0 && $coff < $soff) {
+ $coff = $off;
+ $coff_set = 1;
+ #warn "CSB: mark coff<$coff>\n";
+ }
+ }
+ if (($type eq '' || $type eq '{') && $c eq '{') {
+ $level++;
+ $type = '{';
+ }
+ if ($type eq '{' && $c eq '}') {
+ $level--;
+ $type = ($level != 0)? '{' : '';
+
+ if ($level == 0) {
+ if (substr($blk, $off + 1, 1) eq ';') {
+ $off++;
+ }
+ last;
+ }
+ }
+ # Preprocessor commands end at the newline unless escaped.
+ if ($type eq '#' && $c eq "\n" && $p ne "\\") {
+ $level--;
+ $type = '';
+ $off++;
+ last;
+ }
+ $off++;
+ }
+ # We are truly at the end, so shuffle to the next line.
+ if ($off == $len) {
+ $loff = $len + 1;
+ $line++;
+ $remain--;
+ }
+
+ my $statement = substr($blk, $soff, $off - $soff + 1);
+ my $condition = substr($blk, $soff, $coff - $soff + 1);
+
+ #warn "STATEMENT<$statement>\n";
+ #warn "CONDITION<$condition>\n";
+
+ #print "coff<$coff> soff<$off> loff<$loff>\n";
+
+ return ($statement, $condition,
+ $line, $remain + 1, $off - $loff + 1, $level);
+}
+
+sub statement_lines {
+ my ($stmt) = @_;
+
+ # Strip the diff line prefixes and rip blank lines at start and end.
+ $stmt =~ s/(^|\n)./$1/g;
+ $stmt =~ s/^\s*//;
+ $stmt =~ s/\s*$//;
+
+ my @stmt_lines = ($stmt =~ /\n/g);
+
+ return $#stmt_lines + 2;
+}
+
+sub statement_rawlines {
+ my ($stmt) = @_;
+
+ my @stmt_lines = ($stmt =~ /\n/g);
+
+ return $#stmt_lines + 2;
+}
+
+sub statement_block_size {
+ my ($stmt) = @_;
+
+ $stmt =~ s/(^|\n)./$1/g;
+ $stmt =~ s/^\s*{//;
+ $stmt =~ s/}\s*$//;
+ $stmt =~ s/^\s*//;
+ $stmt =~ s/\s*$//;
+
+ my @stmt_lines = ($stmt =~ /\n/g);
+ my @stmt_statements = ($stmt =~ /;/g);
+
+ my $stmt_lines = $#stmt_lines + 2;
+ my $stmt_statements = $#stmt_statements + 1;
+
+ if ($stmt_lines > $stmt_statements) {
+ return $stmt_lines;
+ } else {
+ return $stmt_statements;
+ }
+}
+
+sub ctx_statement_full {
+ my ($linenr, $remain, $off) = @_;
+ my ($statement, $condition, $level);
+
+ my (@chunks);
+
+ # Grab the first conditional/block pair.
+ ($statement, $condition, $linenr, $remain, $off, $level) =
+ ctx_statement_block($linenr, $remain, $off);
+ #print "F: c<$condition> s<$statement> remain<$remain>\n";
+ push(@chunks, [ $condition, $statement ]);
+ if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
+ return ($level, $linenr, @chunks);
+ }
+
+ # Pull in the following conditional/block pairs and see if they
+ # could continue the statement.
+ for (;;) {
+ ($statement, $condition, $linenr, $remain, $off, $level) =
+ ctx_statement_block($linenr, $remain, $off);
+ #print "C: c<$condition> s<$statement> remain<$remain>\n";
+ last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
+ #print "C: push\n";
+ push(@chunks, [ $condition, $statement ]);
+ }
+
+ return ($level, $linenr, @chunks);
+}
+
+sub ctx_block_get {
+ my ($linenr, $remain, $outer, $open, $close, $off) = @_;
+ my $line;
+ my $start = $linenr - 1;
+ my $blk = '';
+ my @o;
+ my @c;
+ my @res = ();
+
+ my $level = 0;
+ my @stack = ($level);
+ for ($line = $start; $remain > 0; $line++) {
+ next if ($rawlines[$line] =~ /^-/);
+ $remain--;
+
+ $blk .= $rawlines[$line];
+
+ # Handle nested #if/#else.
+ if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
+ push(@stack, $level);
+ } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
+ $level = $stack[$#stack - 1];
+ } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
+ $level = pop(@stack);
+ }
+
+ foreach my $c (split(//, $lines[$line])) {
+ ##print "C<$c>L<$level><$open$close>O<$off>\n";
+ if ($off > 0) {
+ $off--;
+ next;
+ }
+
+ if ($c eq $close && $level > 0) {
+ $level--;
+ last if ($level == 0);
+ } elsif ($c eq $open) {
+ $level++;
+ }
+ }
+
+ if (!$outer || $level <= 1) {
+ push(@res, $rawlines[$line]);
+ }
+
+ last if ($level == 0);
+ }
+
+ return ($level, @res);
+}
+sub ctx_block_outer {
+ my ($linenr, $remain) = @_;
+
+ my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
+ return @r;
+}
+sub ctx_block {
+ my ($linenr, $remain) = @_;
+
+ my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
+ return @r;
+}
+sub ctx_statement {
+ my ($linenr, $remain, $off) = @_;
+
+ my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
+ return @r;
+}
+sub ctx_block_level {
+ my ($linenr, $remain) = @_;
+
+ return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
+}
+sub ctx_statement_level {
+ my ($linenr, $remain, $off) = @_;
+
+ return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
+}
+
+sub ctx_locate_comment {
+ my ($first_line, $end_line) = @_;
+
+ # Catch a comment on the end of the line itself.
+ my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
+ return $current_comment if (defined $current_comment);
+
+ # Look through the context and try and figure out if there is a
+ # comment.
+ my $in_comment = 0;
+ $current_comment = '';
+ for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
+ my $line = $rawlines[$linenr - 1];
+ #warn " $line\n";
+ if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
+ $in_comment = 1;
+ }
+ if ($line =~ m@/\*@) {
+ $in_comment = 1;
+ }
+ if (!$in_comment && $current_comment ne '') {
+ $current_comment = '';
+ }
+ $current_comment .= $line . "\n" if ($in_comment);
+ if ($line =~ m@\*/@) {
+ $in_comment = 0;
+ }
+ }
+
+ chomp($current_comment);
+ return($current_comment);
+}
+sub ctx_has_comment {
+ my ($first_line, $end_line) = @_;
+ my $cmt = ctx_locate_comment($first_line, $end_line);
+
+ ##print "LINE: $rawlines[$end_line - 1 ]\n";
+ ##print "CMMT: $cmt\n";
+
+ return ($cmt ne '');
+}
+
+sub raw_line {
+ my ($linenr, $cnt) = @_;
+
+ my $offset = $linenr - 1;
+ $cnt++;
+
+ my $line;
+ while ($cnt) {
+ $line = $rawlines[$offset++];
+ next if (defined($line) && $line =~ /^-/);
+ $cnt--;
+ }
+
+ return $line;
+}
+
+sub get_stat_real {
+ my ($linenr, $lc) = @_;
+
+ my $stat_real = raw_line($linenr, 0);
+ for (my $count = $linenr + 1; $count <= $lc; $count++) {
+ $stat_real = $stat_real . "\n" . raw_line($count, 0);
+ }
+
+ return $stat_real;
+}
+
+sub get_stat_here {
+ my ($linenr, $cnt, $here) = @_;
+
+ my $herectx = $here . "\n";
+ for (my $n = 0; $n < $cnt; $n++) {
+ $herectx .= raw_line($linenr, $n) . "\n";
+ }
+
+ return $herectx;
+}
+
+sub cat_vet {
+ my ($vet) = @_;
+ my ($res, $coded);
+
+ $res = '';
+ while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
+ $res .= $1;
+ if ($2 ne '') {
+ $coded = sprintf("^%c", unpack('C', $2) + 64);
+ $res .= $coded;
+ }
+ }
+ $res =~ s/$/\$/;
+
+ return $res;
+}
+
+my $av_preprocessor = 0;
+my $av_pending;
+my @av_paren_type;
+my $av_pend_colon;
+
+sub annotate_reset {
+ $av_preprocessor = 0;
+ $av_pending = '_';
+ @av_paren_type = ('E');
+ $av_pend_colon = 'O';
+}
+
+sub annotate_values {
+ my ($stream, $type) = @_;
+
+ my $res;
+ my $var = '_' x length($stream);
+ my $cur = $stream;
+
+ print "$stream\n" if ($dbg_values > 1);
+
+ while (length($cur)) {
+ @av_paren_type = ('E') if ($#av_paren_type < 0);
+ print " <" . join('', @av_paren_type) .
+ "> <$type> <$av_pending>" if ($dbg_values > 1);
+ if ($cur =~ /^(\s+)/o) {
+ print "WS($1)\n" if ($dbg_values > 1);
+ if ($1 =~ /\n/ && $av_preprocessor) {
+ $type = pop(@av_paren_type);
+ $av_preprocessor = 0;
+ }
+
+ } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
+ print "CAST($1)\n" if ($dbg_values > 1);
+ push(@av_paren_type, $type);
+ $type = 'c';
+
+ } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
+ print "DECLARE($1)\n" if ($dbg_values > 1);
+ $type = 'T';
+
+ } elsif ($cur =~ /^($Modifier)\s*/) {
+ print "MODIFIER($1)\n" if ($dbg_values > 1);
+ $type = 'T';
+
+ } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
+ print "DEFINE($1,$2)\n" if ($dbg_values > 1);
+ $av_preprocessor = 1;
+ push(@av_paren_type, $type);
+ if ($2 ne '') {
+ $av_pending = 'N';
+ }
+ $type = 'E';
+
+ } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
+ print "UNDEF($1)\n" if ($dbg_values > 1);
+ $av_preprocessor = 1;
+ push(@av_paren_type, $type);
+
+ } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
+ print "PRE_START($1)\n" if ($dbg_values > 1);
+ $av_preprocessor = 1;
+
+ push(@av_paren_type, $type);
+ push(@av_paren_type, $type);
+ $type = 'E';
+
+ } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
+ print "PRE_RESTART($1)\n" if ($dbg_values > 1);
+ $av_preprocessor = 1;
+
+ push(@av_paren_type, $av_paren_type[$#av_paren_type]);
+
+ $type = 'E';
+
+ } elsif ($cur =~ /^(\#\s*(?:endif))/o) {
+ print "PRE_END($1)\n" if ($dbg_values > 1);
+
+ $av_preprocessor = 1;
+
+ # Assume all arms of the conditional end as this
+ # one does, and continue as if the #endif was not here.
+ pop(@av_paren_type);
+ push(@av_paren_type, $type);
+ $type = 'E';
+
+ } elsif ($cur =~ /^(\\\n)/o) {
+ print "PRECONT($1)\n" if ($dbg_values > 1);
+
+ } elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
+ print "ATTR($1)\n" if ($dbg_values > 1);
+ $av_pending = $type;
+ $type = 'N';
+
+ } elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
+ print "SIZEOF($1)\n" if ($dbg_values > 1);
+ if (defined $2) {
+ $av_pending = 'V';
+ }
+ $type = 'N';
+
+ } elsif ($cur =~ /^(if|while|for)\b/o) {
+ print "COND($1)\n" if ($dbg_values > 1);
+ $av_pending = 'E';
+ $type = 'N';
+
+ } elsif ($cur =~/^(case)/o) {
+ print "CASE($1)\n" if ($dbg_values > 1);
+ $av_pend_colon = 'C';
+ $type = 'N';
+
+ } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
+ print "KEYWORD($1)\n" if ($dbg_values > 1);
+ $type = 'N';
+
+ } elsif ($cur =~ /^(\()/o) {
+ print "PAREN('$1')\n" if ($dbg_values > 1);
+ push(@av_paren_type, $av_pending);
+ $av_pending = '_';
+ $type = 'N';
+
+ } elsif ($cur =~ /^(\))/o) {
+ my $new_type = pop(@av_paren_type);
+ if ($new_type ne '_') {
+ $type = $new_type;
+ print "PAREN('$1') -> $type\n"
+ if ($dbg_values > 1);
+ } else {
+ print "PAREN('$1')\n" if ($dbg_values > 1);
+ }
+
+ } elsif ($cur =~ /^($Ident)\s*\(/o) {
+ print "FUNC($1)\n" if ($dbg_values > 1);
+ $type = 'V';
+ $av_pending = 'V';
+
+ } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
+ if (defined $2 && $type eq 'C' || $type eq 'T') {
+ $av_pend_colon = 'B';
+ } elsif ($type eq 'E') {
+ $av_pend_colon = 'L';
+ }
+ print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
+ $type = 'V';
+
+ } elsif ($cur =~ /^($Ident|$Constant)/o) {
+ print "IDENT($1)\n" if ($dbg_values > 1);
+ $type = 'V';
+
+ } elsif ($cur =~ /^($Assignment)/o) {
+ print "ASSIGN($1)\n" if ($dbg_values > 1);
+ $type = 'N';
+
+ } elsif ($cur =~/^(;|{|})/) {
+ print "END($1)\n" if ($dbg_values > 1);
+ $type = 'E';
+ $av_pend_colon = 'O';
+
+ } elsif ($cur =~/^(,)/) {
+ print "COMMA($1)\n" if ($dbg_values > 1);
+ $type = 'C';
+
+ } elsif ($cur =~ /^(\?)/o) {
+ print "QUESTION($1)\n" if ($dbg_values > 1);
+ $type = 'N';
+
+ } elsif ($cur =~ /^(:)/o) {
+ print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
+
+ substr($var, length($res), 1, $av_pend_colon);
+ if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
+ $type = 'E';
+ } else {
+ $type = 'N';
+ }
+ $av_pend_colon = 'O';
+
+ } elsif ($cur =~ /^(\[)/o) {
+ print "CLOSE($1)\n" if ($dbg_values > 1);
+ $type = 'N';
+
+ } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
+ my $variant;
+
+ print "OPV($1)\n" if ($dbg_values > 1);
+ if ($type eq 'V') {
+ $variant = 'B';
+ } else {
+ $variant = 'U';
+ }
+
+ substr($var, length($res), 1, $variant);
+ $type = 'N';
+
+ } elsif ($cur =~ /^($Operators)/o) {
+ print "OP($1)\n" if ($dbg_values > 1);
+ if ($1 ne '++' && $1 ne '--') {
+ $type = 'N';
+ }
+
+ } elsif ($cur =~ /(^.)/o) {
+ print "C($1)\n" if ($dbg_values > 1);
+ }
+ if (defined $1) {
+ $cur = substr($cur, length($1));
+ $res .= $type x length($1);
+ }
+ }
+
+ return ($res, $var);
+}
+
+sub possible {
+ my ($possible, $line) = @_;
+ my $notPermitted = qr{(?:
+ ^(?:
+ $Modifier|
+ $Storage|
+ $Type|
+ DEFINE_\S+
+ )$|
+ ^(?:
+ goto|
+ return|
+ case|
+ else|
+ asm|__asm__|
+ do|
+ \#|
+ \#\#|
+ )(?:\s|$)|
+ ^(?:typedef|struct|enum)\b
+ )}x;
+ warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
+ if ($possible !~ $notPermitted) {
+ # Check for modifiers.
+ $possible =~ s/\s*$Storage\s*//g;
+ $possible =~ s/\s*$Sparse\s*//g;
+ if ($possible =~ /^\s*$/) {
+
+ } elsif ($possible =~ /\s/) {
+ $possible =~ s/\s*$Type\s*//g;
+ for my $modifier (split(' ', $possible)) {
+ if ($modifier !~ $notPermitted) {
+ warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
+ push(@modifierListFile, $modifier);
+ }
+ }
+
+ } else {
+ warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
+ push(@typeListFile, $possible);
+ }
+ build_types();
+ } else {
+ warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
+ }
+}
+
+my $prefix = '';
+
+sub show_type {
+ my ($type) = @_;
+
+ $type =~ tr/[a-z]/[A-Z]/;
+
+ return defined $use_type{$type} if (scalar keys %use_type > 0);
+
+ return !defined $ignore_type{$type};
+}
+
+sub report {
+ my ($level, $type, $msg) = @_;
+
+ if (!show_type($type) ||
+ (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
+ return 0;
+ }
+ my $output = '';
+ if ($color) {
+ if ($level eq 'ERROR') {
+ $output .= RED;
+ } elsif ($level eq 'WARNING') {
+ $output .= YELLOW;
+ } else {
+ $output .= GREEN;
+ }
+ }
+ $output .= $prefix . $level . ':';
+ if ($show_types) {
+ $output .= BLUE if ($color);
+ $output .= "$type:";
+ }
+ $output .= RESET if ($color);
+ $output .= ' ' . $msg . "\n";
+
+ if ($showfile) {
+ my @lines = split("\n", $output, -1);
+ splice(@lines, 1, 1);
+ $output = join("\n", @lines);
+ }
+ $output = (split('\n', $output))[0] . "\n" if ($terse);
+
+ push(our @report, $output);
+
+ return 1;
+}
+
+sub report_dump {
+ our @report;
+}
+
+sub fixup_current_range {
+ my ($lineRef, $offset, $length) = @_;
+
+ if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
+ my $o = $1;
+ my $l = $2;
+ my $no = $o + $offset;
+ my $nl = $l + $length;
+ $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
+ }
+}
+
+sub fix_inserted_deleted_lines {
+ my ($linesRef, $insertedRef, $deletedRef) = @_;
+
+ my $range_last_linenr = 0;
+ my $delta_offset = 0;
+
+ my $old_linenr = 0;
+ my $new_linenr = 0;
+
+ my $next_insert = 0;
+ my $next_delete = 0;
+
+ my @lines = ();
+
+ my $inserted = @{$insertedRef}[$next_insert++];
+ my $deleted = @{$deletedRef}[$next_delete++];
+
+ foreach my $old_line (@{$linesRef}) {
+ my $save_line = 1;
+ my $line = $old_line; #don't modify the array
+ if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename
+ $delta_offset = 0;
+ } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk
+ $range_last_linenr = $new_linenr;
+ fixup_current_range(\$line, $delta_offset, 0);
+ }
+
+ while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
+ $deleted = @{$deletedRef}[$next_delete++];
+ $save_line = 0;
+ fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
+ }
+
+ while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
+ push(@lines, ${$inserted}{'LINE'});
+ $inserted = @{$insertedRef}[$next_insert++];
+ $new_linenr++;
+ fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
+ }
+
+ if ($save_line) {
+ push(@lines, $line);
+ $new_linenr++;
+ }
+
+ $old_linenr++;
+ }
+
+ return @lines;
+}
+
+sub fix_insert_line {
+ my ($linenr, $line) = @_;
+
+ my $inserted = {
+ LINENR => $linenr,
+ LINE => $line,
+ };
+ push(@fixed_inserted, $inserted);
+}
+
+sub fix_delete_line {
+ my ($linenr, $line) = @_;
+
+ my $deleted = {
+ LINENR => $linenr,
+ LINE => $line,
+ };
+
+ push(@fixed_deleted, $deleted);
+}
+
+sub ERROR {
+ my ($type, $msg) = @_;
+
+ if (report("ERROR", $type, $msg)) {
+ our $clean = 0;
+ our $cnt_error++;
+ return 1;
+ }
+ return 0;
+}
+sub WARN {
+ my ($type, $msg) = @_;
+
+ if (report("WARNING", $type, $msg)) {
+ our $clean = 0;
+ our $cnt_warn++;
+ return 1;
+ }
+ return 0;
+}
+sub CHK {
+ my ($type, $msg) = @_;
+
+ if ($check && report("CHECK", $type, $msg)) {
+ our $clean = 0;
+ our $cnt_chk++;
+ return 1;
+ }
+ return 0;
+}
+
+sub check_absolute_file {
+ my ($absolute, $herecurr) = @_;
+ my $file = $absolute;
+
+ ##print "absolute<$absolute>\n";
+
+ # See if any suffix of this path is a path within the tree.
+ while ($file =~ s@^[^/]*/@@) {
+ if (-f "$root/$file") {
+ ##print "file<$file>\n";
+ last;
+ }
+ }
+ if (! -f _) {
+ return 0;
+ }
+
+ # It is, so see if the prefix is acceptable.
+ my $prefix = $absolute;
+ substr($prefix, -length($file)) = '';
+
+ ##print "prefix<$prefix>\n";
+ if ($prefix ne ".../") {
+ WARN("USE_RELATIVE_PATH",
+ "use relative pathname instead of absolute in changelog text\n" . $herecurr);
+ }
+}
+
+sub trim {
+ my ($string) = @_;
+
+ $string =~ s/^\s+|\s+$//g;
+
+ return $string;
+}
+
+sub ltrim {
+ my ($string) = @_;
+
+ $string =~ s/^\s+//;
+
+ return $string;
+}
+
+sub rtrim {
+ my ($string) = @_;
+
+ $string =~ s/\s+$//;
+
+ return $string;
+}
+
+sub string_find_replace {
+ my ($string, $find, $replace) = @_;
+
+ $string =~ s/$find/$replace/g;
+
+ return $string;
+}
+
+sub tabify {
+ my ($leading) = @_;
+
+ my $source_indent = 8;
+ my $max_spaces_before_tab = $source_indent - 1;
+ my $spaces_to_tab = " " x $source_indent;
+
+ #convert leading spaces to tabs
+ 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
+ #Remove spaces before a tab
+ 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
+
+ return "$leading";
+}
+
+sub pos_last_openparen {
+ my ($line) = @_;
+
+ my $pos = 0;
+
+ my $opens = $line =~ tr/\(/\(/;
+ my $closes = $line =~ tr/\)/\)/;
+
+ my $last_openparen = 0;
+
+ if (($opens == 0) || ($closes >= $opens)) {
+ return -1;
+ }
+
+ my $len = length($line);
+
+ for ($pos = 0; $pos < $len; $pos++) {
+ my $string = substr($line, $pos);
+ if ($string =~ /^($FuncArg|$balanced_parens)/) {
+ $pos += length($1) - 1;
+ } elsif (substr($line, $pos, 1) eq '(') {
+ $last_openparen = $pos;
+ } elsif (index($string, '(') == -1) {
+ last;
+ }
+ }
+
+ return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
+}
+
+sub process {
+ my $filename = shift;
+
+ my $linenr=0;
+ my $prevline="";
+ my $prevrawline="";
+ my $stashline="";
+ my $stashrawline="";
+
+ my $length;
+ my $indent;
+ my $previndent=0;
+ my $stashindent=0;
+
+ our $clean = 1;
+ my $signoff = 0;
+ my $author = '';
+ my $authorsignoff = 0;
+ my $is_patch = 0;
+ my $is_binding_patch = -1;
+ my $in_header_lines = $file ? 0 : 1;
+ my $in_commit_log = 0; #Scanning lines before patch
+ my $has_commit_log = 0; #Encountered lines before patch
+ my $commit_log_lines = 0; #Number of commit log lines
+ my $commit_log_possible_stack_dump = 0;
+ my $commit_log_long_line = 0;
+ my $commit_log_has_diff = 0;
+ my $reported_maintainer_file = 0;
+ my $non_utf8_charset = 0;
+
+ my $last_blank_line = 0;
+ my $last_coalesced_string_linenr = -1;
+
+ our @report = ();
+ our $cnt_lines = 0;
+ our $cnt_error = 0;
+ our $cnt_warn = 0;
+ our $cnt_chk = 0;
+
+ # Trace the real file/line as we go.
+ my $realfile = '';
+ my $realline = 0;
+ my $realcnt = 0;
+ my $here = '';
+ my $context_function; #undef'd unless there's a known function
+ my $in_comment = 0;
+ my $comment_edge = 0;
+ my $first_line = 0;
+ my $p1_prefix = '';
+
+ my $prev_values = 'E';
+
+ # suppression flags
+ my %suppress_ifbraces;
+ my %suppress_whiletrailers;
+ my %suppress_export;
+ my $suppress_statement = 0;
+
+ my %signatures = ();
+
+ # Pre-scan the patch sanitizing the lines.
+ # Pre-scan the patch looking for any __setup documentation.
+ #
+ my @setup_docs = ();
+ my $setup_docs = 0;
+
+ my $camelcase_file_seeded = 0;
+
+ my $checklicenseline = 1;
+
+ sanitise_line_reset();
+ my $line;
+ foreach my $rawline (@rawlines) {
+ $linenr++;
+ $line = $rawline;
+
+ push(@fixed, $rawline) if ($fix);
+
+ if ($rawline=~/^\+\+\+\s+(\S+)/) {
+ $setup_docs = 0;
+ if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) {
+ $setup_docs = 1;
+ }
+ #next;
+ }
+ if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
+ $realline=$1-1;
+ if (defined $2) {
+ $realcnt=$3+1;
+ } else {
+ $realcnt=1+1;
+ }
+ $in_comment = 0;
+
+ # Guestimate if this is a continuing comment. Run
+ # the context looking for a comment "edge". If this
+ # edge is a close comment then we must be in a comment
+ # at context start.
+ my $edge;
+ my $cnt = $realcnt;
+ for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
+ next if (defined $rawlines[$ln - 1] &&
+ $rawlines[$ln - 1] =~ /^-/);
+ $cnt--;
+ #print "RAW<$rawlines[$ln - 1]>\n";
+ last if (!defined $rawlines[$ln - 1]);
+ if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
+ $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
+ ($edge) = $1;
+ last;
+ }
+ }
+ if (defined $edge && $edge eq '*/') {
+ $in_comment = 1;
+ }
+
+ # Guestimate if this is a continuing comment. If this
+ # is the start of a diff block and this line starts
+ # ' *' then it is very likely a comment.
+ if (!defined $edge &&
+ $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
+ {
+ $in_comment = 1;
+ }
+
+ ##print "COMMENT:$in_comment edge<$edge> $rawline\n";
+ sanitise_line_reset($in_comment);
+
+ } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
+ # Standardise the strings and chars within the input to
+ # simplify matching -- only bother with positive lines.
+ $line = sanitise_line($rawline);
+ }
+ push(@lines, $line);
+
+ if ($realcnt > 1) {
+ $realcnt-- if ($line =~ /^(?:\+| |$)/);
+ } else {
+ $realcnt = 0;
+ }
+
+ #print "==>$rawline\n";
+ #print "-->$line\n";
+
+ if ($setup_docs && $line =~ /^\+/) {
+ push(@setup_docs, $line);
+ }
+ }
+
+ $prefix = '';
+
+ $realcnt = 0;
+ $linenr = 0;
+ $fixlinenr = -1;
+ foreach my $line (@lines) {
+ $linenr++;
+ $fixlinenr++;
+ my $sline = $line; #copy of $line
+ $sline =~ s/$;/ /g; #with comments as spaces
+
+ my $rawline = $rawlines[$linenr - 1];
+
+# check if it's a mode change, rename or start of a patch
+ if (!$in_commit_log &&
+ ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ ||
+ ($line =~ /^rename (?:from|to) \S+\s*$/ ||
+ $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) {
+ $is_patch = 1;
+ }
+
+#extract the line range in the file after the patch is applied
+ if (!$in_commit_log &&
+ $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
+ my $context = $4;
+ $is_patch = 1;
+ $first_line = $linenr + 1;
+ $realline=$1-1;
+ if (defined $2) {
+ $realcnt=$3+1;
+ } else {
+ $realcnt=1+1;
+ }
+ annotate_reset();
+ $prev_values = 'E';
+
+ %suppress_ifbraces = ();
+ %suppress_whiletrailers = ();
+ %suppress_export = ();
+ $suppress_statement = 0;
+ if ($context =~ /\b(\w+)\s*\(/) {
+ $context_function = $1;
+ } else {
+ undef $context_function;
+ }
+ next;
+
+# track the line number as we move through the hunk, note that
+# new versions of GNU diff omit the leading space on completely
+# blank context lines so we need to count that too.
+ } elsif ($line =~ /^( |\+|$)/) {
+ $realline++;
+ $realcnt-- if ($realcnt != 0);
+
+ # Measure the line length and indent.
+ ($length, $indent) = line_stats($rawline);
+
+ # Track the previous line.
+ ($prevline, $stashline) = ($stashline, $line);
+ ($previndent, $stashindent) = ($stashindent, $indent);
+ ($prevrawline, $stashrawline) = ($stashrawline, $rawline);
+
+ #warn "line<$line>\n";
+
+ } elsif ($realcnt == 1) {
+ $realcnt--;
+ }
+
+ my $hunk_line = ($realcnt != 0);
+
+ $here = "#$linenr: " if (!$file);
+ $here = "#$realline: " if ($file);
+
+ my $found_file = 0;
+ # extract the filename as it passes
+ if ($line =~ /^diff --git.*?(\S+)$/) {
+ $realfile = $1;
+ $realfile =~ s@^([^/]*)/@@ if (!$file);
+ $in_commit_log = 0;
+ $found_file = 1;
+ } elsif ($line =~ /^\+\+\+\s+(\S+)/) {
+ $realfile = $1;
+ $realfile =~ s@^([^/]*)/@@ if (!$file);
+ $in_commit_log = 0;
+
+ $p1_prefix = $1;
+ if (!$file && $tree && $p1_prefix ne '' &&
+ -e "$root/$p1_prefix") {
+ WARN("PATCH_PREFIX",
+ "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
+ }
+
+ if ($realfile =~ m@^include/asm/@) {
+ ERROR("MODIFIED_INCLUDE_ASM",
+ "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
+ }
+ $found_file = 1;
+ }
+
+#make up the handle for any error we report on this line
+ if ($showfile) {
+ $prefix = "$realfile:$realline: "
+ } elsif ($emacs) {
+ if ($file) {
+ $prefix = "$filename:$realline: ";
+ } else {
+ $prefix = "$filename:$linenr: ";
+ }
+ }
+
+ if ($found_file) {
+ if (is_maintained_obsolete($realfile)) {
+ WARN("OBSOLETE",
+ "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n");
+ }
+ if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
+ $check = 1;
+ } else {
+ $check = $check_orig;
+ }
+ $checklicenseline = 1;
+
+ if ($realfile !~ /^MAINTAINERS/) {
+ my $last_binding_patch = $is_binding_patch;
+
+ $is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@;
+
+ if (($last_binding_patch != -1) &&
+ ($last_binding_patch ^ $is_binding_patch)) {
+ WARN("DT_SPLIT_BINDING_PATCH",
+ "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.txt\n");
+ }
+ }
+
+ next;
+ }
+
+ $here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
+
+ my $hereline = "$here\n$rawline\n";
+ my $herecurr = "$here\n$rawline\n";
+ my $hereprev = "$here\n$prevrawline\n$rawline\n";
+
+ $cnt_lines++ if ($realcnt != 0);
+
+# Verify the existence of a commit log if appropriate
+# 2 is used because a $signature is counted in $commit_log_lines
+ if ($in_commit_log) {
+ if ($line !~ /^\s*$/) {
+ $commit_log_lines++; #could be a $signature
+ }
+ } elsif ($has_commit_log && $commit_log_lines < 2) {
+ WARN("COMMIT_MESSAGE",
+ "Missing commit description - Add an appropriate one\n");
+ $commit_log_lines = 2; #warn only once
+ }
+
+# Check if the commit log has what seems like a diff which can confuse patch
+ if ($in_commit_log && !$commit_log_has_diff &&
+ (($line =~ m@^\s+diff\b.*a/[\w/]+@ &&
+ $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) ||
+ $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
+ $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
+ ERROR("DIFF_IN_COMMIT_MSG",
+ "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
+ $commit_log_has_diff = 1;
+ }
+
+# Check for incorrect file permissions
+ if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
+ my $permhere = $here . "FILE: $realfile\n";
+ if ($realfile !~ m@scripts/@ &&
+ $realfile !~ /\.(py|pl|awk|sh)$/) {
+ ERROR("EXECUTE_PERMISSIONS",
+ "do not set execute permissions for source files\n" . $permhere);
+ }
+ }
+
+# Check the patch for a From:
+ if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) {
+ $author = $1;
+ $author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i);
+ $author =~ s/"//g;
+ }
+
+# Check the patch for a signoff:
+ if ($line =~ /^\s*signed-off-by:/i) {
+ $signoff++;
+ $in_commit_log = 0;
+ if ($author ne '') {
+ my $l = $line;
+ $l =~ s/"//g;
+ if ($l =~ /^\s*signed-off-by:\s*\Q$author\E/i) {
+ $authorsignoff = 1;
+ }
+ }
+ }
+
+# Check if MAINTAINERS is being updated. If so, there's probably no need to
+# emit the "does MAINTAINERS need updating?" message on file add/move/delete
+ if ($line =~ /^\s*MAINTAINERS\s*\|/) {
+ $reported_maintainer_file = 1;
+ }
+
+# Check signature styles
+ if (!$in_header_lines &&
+ $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
+ my $space_before = $1;
+ my $sign_off = $2;
+ my $space_after = $3;
+ my $email = $4;
+ my $ucfirst_sign_off = ucfirst(lc($sign_off));
+
+ if ($sign_off !~ /$signature_tags/) {
+ WARN("BAD_SIGN_OFF",
+ "Non-standard signature: $sign_off\n" . $herecurr);
+ }
+ if (defined $space_before && $space_before ne "") {
+ if (WARN("BAD_SIGN_OFF",
+ "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =
+ "$ucfirst_sign_off $email";
+ }
+ }
+ if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
+ if (WARN("BAD_SIGN_OFF",
+ "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =
+ "$ucfirst_sign_off $email";
+ }
+
+ }
+ if (!defined $space_after || $space_after ne " ") {
+ if (WARN("BAD_SIGN_OFF",
+ "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =
+ "$ucfirst_sign_off $email";
+ }
+ }
+
+ my ($email_name, $email_address, $comment) = parse_email($email);
+ my $suggested_email = format_email(($email_name, $email_address));
+ if ($suggested_email eq "") {
+ ERROR("BAD_SIGN_OFF",
+ "Unrecognized email address: '$email'\n" . $herecurr);
+ } else {
+ my $dequoted = $suggested_email;
+ $dequoted =~ s/^"//;
+ $dequoted =~ s/" </ </;
+ # Don't force email to have quotes
+ # Allow just an angle bracketed address
+ if ("$dequoted$comment" ne $email &&
+ "<$email_address>$comment" ne $email &&
+ "$suggested_email$comment" ne $email) {
+ WARN("BAD_SIGN_OFF",
+ "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
+ }
+ }
+
+# Check for duplicate signatures
+ my $sig_nospace = $line;
+ $sig_nospace =~ s/\s//g;
+ $sig_nospace = lc($sig_nospace);
+ if (defined $signatures{$sig_nospace}) {
+ WARN("BAD_SIGN_OFF",
+ "Duplicate signature\n" . $herecurr);
+ } else {
+ $signatures{$sig_nospace} = 1;
+ }
+
+# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email
+ if ($sign_off =~ /^co-developed-by:$/i) {
+ if ($email eq $author) {
+ WARN("BAD_SIGN_OFF",
+ "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline);
+ }
+ if (!defined $lines[$linenr]) {
+ WARN("BAD_SIGN_OFF",
+ "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline);
+ } elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) {
+ WARN("BAD_SIGN_OFF",
+ "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
+ } elsif ($1 ne $email) {
+ WARN("BAD_SIGN_OFF",
+ "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
+ }
+ }
+ }
+
+# Check email subject for common tools that don't need to be mentioned
+ if ($in_header_lines &&
+ $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
+ WARN("EMAIL_SUBJECT",
+ "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
+ }
+
+# Check for unwanted Gerrit info
+ if ($in_commit_log && $line =~ /^\s*change-id:/i) {
+ ERROR("GERRIT_CHANGE_ID",
+ "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr);
+ }
+
+# Check if the commit log is in a possible stack dump
+ if ($in_commit_log && !$commit_log_possible_stack_dump &&
+ ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
+ $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
+ # timestamp
+ $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) ||
+ $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ ||
+ $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) {
+ # stack dump address styles
+ $commit_log_possible_stack_dump = 1;
+ }
+
+# Check for line lengths > 75 in commit log, warn once
+ if ($in_commit_log && !$commit_log_long_line &&
+ length($line) > 75 &&
+ !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
+ # file delta changes
+ $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||
+ # filename then :
+ $line =~ /^\s*(?:Fixes:|Link:)/i ||
+ # A Fixes: or Link: line
+ $commit_log_possible_stack_dump)) {
+ WARN("COMMIT_LOG_LONG_LINE",
+ "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);
+ $commit_log_long_line = 1;
+ }
+
+# Reset possible stack dump if a blank line is found
+ if ($in_commit_log && $commit_log_possible_stack_dump &&
+ $line =~ /^\s*$/) {
+ $commit_log_possible_stack_dump = 0;
+ }
+
+# Check for git id commit length and improperly formed commit descriptions
+ if ($in_commit_log && !$commit_log_possible_stack_dump &&
+ $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i &&
+ $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
+ ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
+ ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
+ $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
+ $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
+ my $init_char = "c";
+ my $orig_commit = "";
+ my $short = 1;
+ my $long = 0;
+ my $case = 1;
+ my $space = 1;
+ my $hasdesc = 0;
+ my $hasparens = 0;
+ my $id = '0123456789ab';
+ my $orig_desc = "commit description";
+ my $description = "";
+
+ if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
+ $init_char = $1;
+ $orig_commit = lc($2);
+ } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {
+ $orig_commit = lc($1);
+ }
+
+ $short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i);
+ $long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i);
+ $space = 0 if ($line =~ /\bcommit [0-9a-f]/i);
+ $case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
+ if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) {
+ $orig_desc = $1;
+ $hasparens = 1;
+ } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i &&
+ defined $rawlines[$linenr] &&
+ $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) {
+ $orig_desc = $1;
+ $hasparens = 1;
+ } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i &&
+ defined $rawlines[$linenr] &&
+ $rawlines[$linenr] =~ /^\s*[^"]+"\)/) {
+ $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i;
+ $orig_desc = $1;
+ $rawlines[$linenr] =~ /^\s*([^"]+)"\)/;
+ $orig_desc .= " " . $1;
+ $hasparens = 1;
+ }
+
+ ($id, $description) = git_commit_info($orig_commit,
+ $id, $orig_desc);
+
+ if (defined($id) &&
+ ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) {
+ ERROR("GIT_COMMIT_ID",
+ "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr);
+ }
+ }
+
+# Check for added, moved or deleted files
+ if (!$reported_maintainer_file && !$in_commit_log &&
+ ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
+ $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
+ ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
+ (defined($1) || defined($2))))) {
+ $is_patch = 1;
+ $reported_maintainer_file = 1;
+ WARN("FILE_PATH_CHANGES",
+ "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
+ }
+
+# Check for adding new DT bindings not in schema format
+ if (!$in_commit_log &&
+ ($line =~ /^new file mode\s*\d+\s*$/) &&
+ ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {
+ WARN("DT_SCHEMA_BINDING_PATCH",
+ "DT bindings should be in DT schema format. See: Documentation/devicetree/writing-schema.rst\n");
+ }
+
+# Check for wrappage within a valid hunk of the file
+ if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
+ ERROR("CORRUPTED_PATCH",
+ "patch seems to be corrupt (line wrapped?)\n" .
+ $herecurr) if (!$emitted_corrupt++);
+ }
+
+# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
+ if (($realfile =~ /^$/ || $line =~ /^\+/) &&
+ $rawline !~ m/^$UTF8*$/) {
+ my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
+
+ my $blank = copy_spacing($rawline);
+ my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
+ my $hereptr = "$hereline$ptr\n";
+
+ CHK("INVALID_UTF8",
+ "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
+ }
+
+# Check if it's the start of a commit log
+# (not a header line and we haven't seen the patch filename)
+ if ($in_header_lines && $realfile =~ /^$/ &&
+ !($rawline =~ /^\s+(?:\S|$)/ ||
+ $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
+ $in_header_lines = 0;
+ $in_commit_log = 1;
+ $has_commit_log = 1;
+ }
+
+# Check if there is UTF-8 in a commit log when a mail header has explicitly
+# declined it, i.e defined some charset where it is missing.
+ if ($in_header_lines &&
+ $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
+ $1 !~ /utf-8/i) {
+ $non_utf8_charset = 1;
+ }
+
+ if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
+ $rawline =~ /$NON_ASCII_UTF8/) {
+ WARN("UTF8_BEFORE_PATCH",
+ "8-bit UTF-8 used in possible commit log\n" . $herecurr);
+ }
+
+# Check for absolute kernel paths in commit message
+ if ($tree && $in_commit_log) {
+ while ($line =~ m{(?:^|\s)(/\S*)}g) {
+ my $file = $1;
+
+ if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
+ check_absolute_file($1, $herecurr)) {
+ #
+ } else {
+ check_absolute_file($file, $herecurr);
+ }
+ }
+ }
+
+# Check for various typo / spelling mistakes
+ if (defined($misspellings) &&
+ ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
+ while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) {
+ my $typo = $1;
+ my $typo_fix = $spelling_fix{lc($typo)};
+ $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
+ $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
+ my $msg_level = \&WARN;
+ $msg_level = \&CHK if ($file);
+ if (&{$msg_level}("TYPO_SPELLING",
+ "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
+ }
+ }
+ }
+
+# check for invalid commit id
+ if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) {
+ my $id;
+ my $description;
+ ($id, $description) = git_commit_info($2, undef, undef);
+ if (!defined($id)) {
+ WARN("UNKNOWN_COMMIT_ID",
+ "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr);
+ }
+ }
+
+# ignore non-hunk lines and lines being removed
+ next if (!$hunk_line || $line =~ /^-/);
+
+#trailing whitespace
+ if ($line =~ /^\+.*\015/) {
+ my $herevet = "$here\n" . cat_vet($rawline) . "\n";
+ if (ERROR("DOS_LINE_ENDINGS",
+ "DOS line endings\n" . $herevet) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/[\s\015]+$//;
+ }
+ } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
+ my $herevet = "$here\n" . cat_vet($rawline) . "\n";
+ if (ERROR("TRAILING_WHITESPACE",
+ "trailing whitespace\n" . $herevet) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\s+$//;
+ }
+
+ $rpt_cleaners = 1;
+ }
+
+# Check for FSF mailing addresses.
+ if ($rawline =~ /\bwrite to the Free/i ||
+ $rawline =~ /\b675\s+Mass\s+Ave/i ||
+ $rawline =~ /\b59\s+Temple\s+Pl/i ||
+ $rawline =~ /\b51\s+Franklin\s+St/i) {
+ my $herevet = "$here\n" . cat_vet($rawline) . "\n";
+ my $msg_level = \&ERROR;
+ $msg_level = \&CHK if ($file);
+ &{$msg_level}("FSF_MAILING_ADDRESS",
+ "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet)
+ }
+
+# check for Kconfig help text having a real description
+# Only applies when adding the entry originally, after that we do not have
+# sufficient context to determine whether it is indeed long enough.
+ if ($realfile =~ /Kconfig/ &&
+ # 'choice' is usually the last thing on the line (though
+ # Kconfig supports named choices), so use a word boundary
+ # (\b) rather than a whitespace character (\s)
+ $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) {
+ my $length = 0;
+ my $cnt = $realcnt;
+ my $ln = $linenr + 1;
+ my $f;
+ my $is_start = 0;
+ my $is_end = 0;
+ for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
+ $f = $lines[$ln - 1];
+ $cnt-- if ($lines[$ln - 1] !~ /^-/);
+ $is_end = $lines[$ln - 1] =~ /^\+/;
+
+ next if ($f =~ /^-/);
+ last if (!$file && $f =~ /^\@\@/);
+
+ if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
+ $is_start = 1;
+ } elsif ($lines[$ln - 1] =~ /^\+\s*(?:help|---help---)\s*$/) {
+ if ($lines[$ln - 1] =~ "---help---") {
+ WARN("CONFIG_DESCRIPTION",
+ "prefer 'help' over '---help---' for new help texts\n" . $herecurr);
+ }
+ $length = -1;
+ }
+
+ $f =~ s/^.//;
+ $f =~ s/#.*//;
+ $f =~ s/^\s+//;
+ next if ($f =~ /^$/);
+
+ # This only checks context lines in the patch
+ # and so hopefully shouldn't trigger false
+ # positives, even though some of these are
+ # common words in help texts
+ if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice|
+ if|endif|menu|endmenu|source)\b/x) {
+ $is_end = 1;
+ last;
+ }
+ $length++;
+ }
+ if ($is_start && $is_end && $length < $min_conf_desc_length) {
+ WARN("CONFIG_DESCRIPTION",
+ "please write a paragraph that describes the config symbol fully\n" . $herecurr);
+ }
+ #print "is_start<$is_start> is_end<$is_end> length<$length>\n";
+ }
+
+# check for MAINTAINERS entries that don't have the right form
+ if ($realfile =~ /^MAINTAINERS$/ &&
+ $rawline =~ /^\+[A-Z]:/ &&
+ $rawline !~ /^\+[A-Z]:\t\S/) {
+ if (WARN("MAINTAINERS_STYLE",
+ "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
+ }
+ }
+
+# discourage the use of boolean for type definition attributes of Kconfig options
+ if ($realfile =~ /Kconfig/ &&
+ $line =~ /^\+\s*\bboolean\b/) {
+ WARN("CONFIG_TYPE_BOOLEAN",
+ "Use of boolean is deprecated, please use bool instead.\n" . $herecurr);
+ }
+
+ if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
+ ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
+ my $flag = $1;
+ my $replacement = {
+ 'EXTRA_AFLAGS' => 'asflags-y',
+ 'EXTRA_CFLAGS' => 'ccflags-y',
+ 'EXTRA_CPPFLAGS' => 'cppflags-y',
+ 'EXTRA_LDFLAGS' => 'ldflags-y',
+ };
+
+ WARN("DEPRECATED_VARIABLE",
+ "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
+ }
+
+# check for DT compatible documentation
+ if (defined $root &&
+ (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
+ ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
+
+ my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
+
+ my $dt_path = $root . "/Documentation/devicetree/bindings/";
+ my $vp_file = $dt_path . "vendor-prefixes.yaml";
+
+ foreach my $compat (@compats) {
+ my $compat2 = $compat;
+ $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
+ my $compat3 = $compat;
+ $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
+ `grep -Erq "$compat|$compat2|$compat3" $dt_path`;
+ if ( $? >> 8 ) {
+ WARN("UNDOCUMENTED_DT_STRING",
+ "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
+ }
+
+ next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
+ my $vendor = $1;
+ `grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`;
+ if ( $? >> 8 ) {
+ WARN("UNDOCUMENTED_DT_STRING",
+ "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
+ }
+ }
+ }
+
+# check for using SPDX license tag at beginning of files
+ if ($realline == $checklicenseline) {
+ if ($rawline =~ /^[ \+]\s*\#\!\s*\//) {
+ $checklicenseline = 2;
+ } elsif ($rawline =~ /^\+/) {
+ my $comment = "";
+ if ($realfile =~ /\.(h|s|S)$/) {
+ $comment = '/*';
+ } elsif ($realfile =~ /\.(c|dts|dtsi)$/) {
+ $comment = '//';
+ } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc)$/) {
+ $comment = '#';
+ } elsif ($realfile =~ /\.rst$/) {
+ $comment = '..';
+ }
+
+# check SPDX comment style for .[chsS] files
+ if ($realfile =~ /\.[chsS]$/ &&
+ $rawline =~ /SPDX-License-Identifier:/ &&
+ $rawline !~ m@^\+\s*\Q$comment\E\s*@) {
+ WARN("SPDX_LICENSE_TAG",
+ "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr);
+ }
+
+ if ($comment !~ /^$/ &&
+ $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) {
+ WARN("SPDX_LICENSE_TAG",
+ "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
+ } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {
+ my $spdx_license = $1;
+ if (!is_SPDX_License_valid($spdx_license)) {
+ WARN("SPDX_LICENSE_TAG",
+ "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
+ }
+ }
+ }
+ }
+
+# check we are in a valid source file if not then ignore this hunk
+ next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
+
+# check for using SPDX-License-Identifier on the wrong line number
+ if ($realline != $checklicenseline &&
+ $rawline =~ /\bSPDX-License-Identifier:/ &&
+ substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) {
+ WARN("SPDX_LICENSE_TAG",
+ "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr);
+ }
+
+# line length limit (with some exclusions)
+#
+# There are a few types of lines that may extend beyond $max_line_length:
+# logging functions like pr_info that end in a string
+# lines with a single string
+# #defines that are a single string
+# lines with an RFC3986 like URL
+#
+# There are 3 different line length message types:
+# LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length
+# LONG_LINE_STRING a string starts before but extends beyond $max_line_length
+# LONG_LINE all other lines longer than $max_line_length
+#
+# if LONG_LINE is ignored, the other 2 types are also ignored
+#
+
+ if ($line =~ /^\+/ && $length > $max_line_length) {
+ my $msg_type = "LONG_LINE";
+
+ # Check the allowed long line types first
+
+ # logging functions that end in a string that starts
+ # before $max_line_length
+ if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
+ length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
+ $msg_type = "";
+
+ # lines with only strings (w/ possible termination)
+ # #defines with only strings
+ } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
+ $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
+ $msg_type = "";
+
+ # More special cases
+ } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ ||
+ $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) {
+ $msg_type = "";
+
+ # URL ($rawline is used in case the URL is in a comment)
+ } elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) {
+ $msg_type = "";
+
+ # Otherwise set the alternate message types
+
+ # a comment starts before $max_line_length
+ } elsif ($line =~ /($;[\s$;]*)$/ &&
+ length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
+ $msg_type = "LONG_LINE_COMMENT"
+
+ # a quoted string starts before $max_line_length
+ } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
+ length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
+ $msg_type = "LONG_LINE_STRING"
+ }
+
+ if ($msg_type ne "" &&
+ (show_type("LONG_LINE") || show_type($msg_type))) {
+ WARN($msg_type,
+ "line over $max_line_length characters\n" . $herecurr);
+ }
+ }
+
+# check for adding lines without a newline.
+ if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
+ WARN("MISSING_EOF_NEWLINE",
+ "adding a line without newline at end of file\n" . $herecurr);
+ }
+
+# check we are in a valid source file C or perl if not then ignore this hunk
+ next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
+
+# at the beginning of a line any tabs must come first and anything
+# more than 8 must use tabs.
+ if ($rawline =~ /^\+\s* \t\s*\S/ ||
+ $rawline =~ /^\+\s* \s*/) {
+ my $herevet = "$here\n" . cat_vet($rawline) . "\n";
+ $rpt_cleaners = 1;
+ if (ERROR("CODE_INDENT",
+ "code indent should use tabs where possible\n" . $herevet) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
+ }
+ }
+
+# check for space before tabs.
+ if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
+ my $herevet = "$here\n" . cat_vet($rawline) . "\n";
+ if (WARN("SPACE_BEFORE_TAB",
+ "please, no space before tabs\n" . $herevet) &&
+ $fix) {
+ while ($fixed[$fixlinenr] =~
+ s/(^\+.*) {8,8}\t/$1\t\t/) {}
+ while ($fixed[$fixlinenr] =~
+ s/(^\+.*) +\t/$1\t/) {}
+ }
+ }
+
+# check for assignments on the start of a line
+ if ($sline =~ /^\+\s+($Assignment)[^=]/) {
+ CHK("ASSIGNMENT_CONTINUATIONS",
+ "Assignment operator '$1' should be on the previous line\n" . $hereprev);
+ }
+
+# check for && or || at the start of a line
+ if ($rawline =~ /^\+\s*(&&|\|\|)/) {
+ CHK("LOGICAL_CONTINUATIONS",
+ "Logical continuations should be on the previous line\n" . $hereprev);
+ }
+
+# check indentation starts on a tab stop
+ if ($perl_version_ok &&
+ $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
+ my $indent = length($1);
+ if ($indent % 8) {
+ if (WARN("TABSTOP",
+ "Statements should start on a tabstop\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e;
+ }
+ }
+ }
+
+# check multi-line statement indentation matches previous line
+ if ($perl_version_ok &&
+ $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
+ $prevline =~ /^\+(\t*)(.*)$/;
+ my $oldindent = $1;
+ my $rest = $2;
+
+ my $pos = pos_last_openparen($rest);
+ if ($pos >= 0) {
+ $line =~ /^(\+| )([ \t]*)/;
+ my $newindent = $2;
+
+ my $goodtabindent = $oldindent .
+ "\t" x ($pos / 8) .
+ " " x ($pos % 8);
+ my $goodspaceindent = $oldindent . " " x $pos;
+
+ if ($newindent ne $goodtabindent &&
+ $newindent ne $goodspaceindent) {
+
+ if (CHK("PARENTHESIS_ALIGNMENT",
+ "Alignment should match open parenthesis\n" . $hereprev) &&
+ $fix && $line =~ /^\+/) {
+ $fixed[$fixlinenr] =~
+ s/^\+[ \t]*/\+$goodtabindent/;
+ }
+ }
+ }
+ }
+
+# check for space after cast like "(int) foo" or "(struct foo) bar"
+# avoid checking a few false positives:
+# "sizeof(<type>)" or "__alignof__(<type>)"
+# function pointer declarations like "(*foo)(int) = bar;"
+# structure definitions like "(struct foo) { 0 };"
+# multiline macros that define functions
+# known attributes or the __attribute__ keyword
+ if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
+ (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
+ if (CHK("SPACING",
+ "No space is necessary after a cast\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~
+ s/(\(\s*$Type\s*\))[ \t]+/$1/;
+ }
+ }
+
+# Block comment styles
+# Networking with an initial /*
+ if ($realfile =~ m@^(drivers/net/|net/)@ &&
+ $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
+ $rawline =~ /^\+[ \t]*\*/ &&
+ $realline > 2) {
+ WARN("NETWORKING_BLOCK_COMMENT_STYLE",
+ "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
+ }
+
+# Block comments use * on subsequent lines
+ if ($prevline =~ /$;[ \t]*$/ && #ends in comment
+ $prevrawline =~ /^\+.*?\/\*/ && #starting /*
+ $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */
+ $rawline =~ /^\+/ && #line is new
+ $rawline !~ /^\+[ \t]*\*/) { #no leading *
+ WARN("BLOCK_COMMENT_STYLE",
+ "Block comments use * on subsequent lines\n" . $hereprev);
+ }
+
+# Block comments use */ on trailing lines
+ if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */
+ $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/
+ $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/
+ $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */
+ WARN("BLOCK_COMMENT_STYLE",
+ "Block comments use a trailing */ on a separate line\n" . $herecurr);
+ }
+
+# Block comment * alignment
+ if ($prevline =~ /$;[ \t]*$/ && #ends in comment
+ $line =~ /^\+[ \t]*$;/ && #leading comment
+ $rawline =~ /^\+[ \t]*\*/ && #leading *
+ (($prevrawline =~ /^\+.*?\/\*/ && #leading /*
+ $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */
+ $prevrawline =~ /^\+[ \t]*\*/)) { #leading *
+ my $oldindent;
+ $prevrawline =~ m@^\+([ \t]*/?)\*@;
+ if (defined($1)) {
+ $oldindent = expand_tabs($1);
+ } else {
+ $prevrawline =~ m@^\+(.*/?)\*@;
+ $oldindent = expand_tabs($1);
+ }
+ $rawline =~ m@^\+([ \t]*)\*@;
+ my $newindent = $1;
+ $newindent = expand_tabs($newindent);
+ if (length($oldindent) ne length($newindent)) {
+ WARN("BLOCK_COMMENT_STYLE",
+ "Block comments should align the * on each line\n" . $hereprev);
+ }
+ }
+
+# check for missing blank lines after struct/union declarations
+# with exceptions for various attributes and macros
+ if ($prevline =~ /^[\+ ]};?\s*$/ &&
+ $line =~ /^\+/ &&
+ !($line =~ /^\+\s*$/ ||
+ $line =~ /^\+\s*EXPORT_SYMBOL/ ||
+ $line =~ /^\+\s*MODULE_/i ||
+ $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
+ $line =~ /^\+[a-z_]*init/ ||
+ $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
+ $line =~ /^\+\s*DECLARE/ ||
+ $line =~ /^\+\s*builtin_[\w_]*driver/ ||
+ $line =~ /^\+\s*__setup/)) {
+ if (CHK("LINE_SPACING",
+ "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
+ $fix) {
+ fix_insert_line($fixlinenr, "\+");
+ }
+ }
+
+# check for multiple consecutive blank lines
+ if ($prevline =~ /^[\+ ]\s*$/ &&
+ $line =~ /^\+\s*$/ &&
+ $last_blank_line != ($linenr - 1)) {
+ if (CHK("LINE_SPACING",
+ "Please don't use multiple blank lines\n" . $hereprev) &&
+ $fix) {
+ fix_delete_line($fixlinenr, $rawline);
+ }
+
+ $last_blank_line = $linenr;
+ }
+
+# check for missing blank lines after declarations
+ if ($sline =~ /^\+\s+\S/ && #Not at char 1
+ # actual declarations
+ ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
+ # function pointer declarations
+ $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
+ # foo bar; where foo is some local typedef or #define
+ $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
+ # known declaration macros
+ $prevline =~ /^\+\s+$declaration_macros/) &&
+ # for "else if" which can look like "$Ident $Ident"
+ !($prevline =~ /^\+\s+$c90_Keywords\b/ ||
+ # other possible extensions of declaration lines
+ $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
+ # not starting a section or a macro "\" extended line
+ $prevline =~ /(?:\{\s*|\\)$/) &&
+ # looks like a declaration
+ !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
+ # function pointer declarations
+ $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
+ # foo bar; where foo is some local typedef or #define
+ $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
+ # known declaration macros
+ $sline =~ /^\+\s+$declaration_macros/ ||
+ # start of struct or union or enum
+ $sline =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ ||
+ # start or end of block or continuation of declaration
+ $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
+ # bitfield continuation
+ $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
+ # other possible extensions of declaration lines
+ $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) &&
+ # indentation of previous and current line are the same
+ (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) {
+ if (WARN("LINE_SPACING",
+ "Missing a blank line after declarations\n" . $hereprev) &&
+ $fix) {
+ fix_insert_line($fixlinenr, "\+");
+ }
+ }
+
+# check for spaces at the beginning of a line.
+# Exceptions:
+# 1) within comments
+# 2) indented preprocessor commands
+# 3) hanging labels
+ if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) {
+ my $herevet = "$here\n" . cat_vet($rawline) . "\n";
+ if (WARN("LEADING_SPACE",
+ "please, no spaces at the start of a line\n" . $herevet) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
+ }
+ }
+
+# check we are in a valid C source file if not then ignore this hunk
+ next if ($realfile !~ /\.(h|c)$/);
+
+# check for unusual line ending [ or (
+ if ($line =~ /^\+.*([\[\(])\s*$/) {
+ CHK("OPEN_ENDED_LINE",
+ "Lines should not end with a '$1'\n" . $herecurr);
+ }
+
+# check if this appears to be the start function declaration, save the name
+ if ($sline =~ /^\+\{\s*$/ &&
+ $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) {
+ $context_function = $1;
+ }
+
+# check if this appears to be the end of function declaration
+ if ($sline =~ /^\+\}\s*$/) {
+ undef $context_function;
+ }
+
+# check indentation of any line with a bare else
+# (but not if it is a multiple line "if (foo) return bar; else return baz;")
+# if the previous line is a break or return and is indented 1 tab more...
+ if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
+ my $tabs = length($1) + 1;
+ if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
+ ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
+ defined $lines[$linenr] &&
+ $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
+ WARN("UNNECESSARY_ELSE",
+ "else is not generally useful after a break or return\n" . $hereprev);
+ }
+ }
+
+# check indentation of a line with a break;
+# if the previous line is a goto or return and is indented the same # of tabs
+ if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
+ my $tabs = $1;
+ if ($prevline =~ /^\+$tabs(?:goto|return)\b/) {
+ WARN("UNNECESSARY_BREAK",
+ "break is not useful after a goto or return\n" . $hereprev);
+ }
+ }
+
+# check for RCS/CVS revision markers
+ if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
+ WARN("CVS_KEYWORD",
+ "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
+ }
+
+# check for old HOTPLUG __dev<foo> section markings
+ if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
+ WARN("HOTPLUG_SECTION",
+ "Using $1 is unnecessary\n" . $herecurr);
+ }
+
+# Check for potential 'bare' types
+ my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
+ $realline_next);
+#print "LINE<$line>\n";
+ if ($linenr > $suppress_statement &&
+ $realcnt && $sline =~ /.\s*\S/) {
+ ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
+ ctx_statement_block($linenr, $realcnt, 0);
+ $stat =~ s/\n./\n /g;
+ $cond =~ s/\n./\n /g;
+
+#print "linenr<$linenr> <$stat>\n";
+ # If this statement has no statement boundaries within
+ # it there is no point in retrying a statement scan
+ # until we hit end of it.
+ my $frag = $stat; $frag =~ s/;+\s*$//;
+ if ($frag !~ /(?:{|;)/) {
+#print "skip<$line_nr_next>\n";
+ $suppress_statement = $line_nr_next;
+ }
+
+ # Find the real next line.
+ $realline_next = $line_nr_next;
+ if (defined $realline_next &&
+ (!defined $lines[$realline_next - 1] ||
+ substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
+ $realline_next++;
+ }
+
+ my $s = $stat;
+ $s =~ s/{.*$//s;
+
+ # Ignore goto labels.
+ if ($s =~ /$Ident:\*$/s) {
+
+ # Ignore functions being called
+ } elsif ($s =~ /^.\s*$Ident\s*\(/s) {
+
+ } elsif ($s =~ /^.\s*else\b/s) {
+
+ # declarations always start with types
+ } elsif ($prev_values eq 'E' && $s =~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?((?:\s*$Ident)+?)\b(?:\s+$Sparse)?\s*\**\s*(?:$Ident|\(\*[^\)]*\))(?:\s*$Modifier)?\s*(?:;|=|,|\()/s) {
+ my $type = $1;
+ $type =~ s/\s+/ /g;
+ possible($type, "A:" . $s);
+
+ # definitions in global scope can only start with types
+ } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
+ possible($1, "B:" . $s);
+ }
+
+ # any (foo ... *) is a pointer cast, and foo is a type
+ while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
+ possible($1, "C:" . $s);
+ }
+
+ # Check for any sort of function declaration.
+ # int foo(something bar, other baz);
+ # void (*store_gdt)(x86_descr_ptr *);
+ if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
+ my ($name_len) = length($1);
+
+ my $ctx = $s;
+ substr($ctx, 0, $name_len + 1, '');
+ $ctx =~ s/\)[^\)]*$//;
+
+ for my $arg (split(/\s*,\s*/, $ctx)) {
+ if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
+
+ possible($1, "D:" . $s);
+ }
+ }
+ }
+
+ }
+
+#
+# Checks which may be anchored in the context.
+#
+
+# Check for switch () and associated case and default
+# statements should be at the same indent.
+ if ($line=~/\bswitch\s*\(.*\)/) {
+ my $err = '';
+ my $sep = '';
+ my @ctx = ctx_block_outer($linenr, $realcnt);
+ shift(@ctx);
+ for my $ctx (@ctx) {
+ my ($clen, $cindent) = line_stats($ctx);
+ if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
+ $indent != $cindent) {
+ $err .= "$sep$ctx\n";
+ $sep = '';
+ } else {
+ $sep = "[...]\n";
+ }
+ }
+ if ($err ne '') {
+ ERROR("SWITCH_CASE_INDENT_LEVEL",
+ "switch and case should be at the same indent\n$hereline$err");
+ }
+ }
+
+# if/while/etc brace do not go on next line, unless defining a do while loop,
+# or if that brace on the next line is for something else
+ if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
+ my $pre_ctx = "$1$2";
+
+ my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
+
+ if ($line =~ /^\+\t{6,}/) {
+ WARN("DEEP_INDENTATION",
+ "Too many leading tabs - consider code refactoring\n" . $herecurr);
+ }
+
+ my $ctx_cnt = $realcnt - $#ctx - 1;
+ my $ctx = join("\n", @ctx);
+
+ my $ctx_ln = $linenr;
+ my $ctx_skip = $realcnt;
+
+ while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
+ defined $lines[$ctx_ln - 1] &&
+ $lines[$ctx_ln - 1] =~ /^-/)) {
+ ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
+ $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
+ $ctx_ln++;
+ }
+
+ #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
+ #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
+
+ if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
+ ERROR("OPEN_BRACE",
+ "that open brace { should be on the previous line\n" .
+ "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
+ }
+ if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
+ $ctx =~ /\)\s*\;\s*$/ &&
+ defined $lines[$ctx_ln - 1])
+ {
+ my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
+ if ($nindent > $indent) {
+ WARN("TRAILING_SEMICOLON",
+ "trailing semicolon indicates no statements, indent implies otherwise\n" .
+ "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
+ }
+ }
+ }
+
+# Check relative indent for conditionals and blocks.
+ if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
+ ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
+ ctx_statement_block($linenr, $realcnt, 0)
+ if (!defined $stat);
+ my ($s, $c) = ($stat, $cond);
+
+ substr($s, 0, length($c), '');
+
+ # remove inline comments
+ $s =~ s/$;/ /g;
+ $c =~ s/$;/ /g;
+
+ # Find out how long the conditional actually is.
+ my @newlines = ($c =~ /\n/gs);
+ my $cond_lines = 1 + $#newlines;
+
+ # Make sure we remove the line prefixes as we have
+ # none on the first line, and are going to readd them
+ # where necessary.
+ $s =~ s/\n./\n/gs;
+ while ($s =~ /\n\s+\\\n/) {
+ $cond_lines += $s =~ s/\n\s+\\\n/\n/g;
+ }
+
+ # We want to check the first line inside the block
+ # starting at the end of the conditional, so remove:
+ # 1) any blank line termination
+ # 2) any opening brace { on end of the line
+ # 3) any do (...) {
+ my $continuation = 0;
+ my $check = 0;
+ $s =~ s/^.*\bdo\b//;
+ $s =~ s/^\s*{//;
+ if ($s =~ s/^\s*\\//) {
+ $continuation = 1;
+ }
+ if ($s =~ s/^\s*?\n//) {
+ $check = 1;
+ $cond_lines++;
+ }
+
+ # Also ignore a loop construct at the end of a
+ # preprocessor statement.
+ if (($prevline =~ /^.\s*#\s*define\s/ ||
+ $prevline =~ /\\\s*$/) && $continuation == 0) {
+ $check = 0;
+ }
+
+ my $cond_ptr = -1;
+ $continuation = 0;
+ while ($cond_ptr != $cond_lines) {
+ $cond_ptr = $cond_lines;
+
+ # If we see an #else/#elif then the code
+ # is not linear.
+ if ($s =~ /^\s*\#\s*(?:else|elif)/) {
+ $check = 0;
+ }
+
+ # Ignore:
+ # 1) blank lines, they should be at 0,
+ # 2) preprocessor lines, and
+ # 3) labels.
+ if ($continuation ||
+ $s =~ /^\s*?\n/ ||
+ $s =~ /^\s*#\s*?/ ||
+ $s =~ /^\s*$Ident\s*:/) {
+ $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
+ if ($s =~ s/^.*?\n//) {
+ $cond_lines++;
+ }
+ }
+ }
+
+ my (undef, $sindent) = line_stats("+" . $s);
+ my $stat_real = raw_line($linenr, $cond_lines);
+
+ # Check if either of these lines are modified, else
+ # this is not this patch's fault.
+ if (!defined($stat_real) ||
+ $stat !~ /^\+/ && $stat_real !~ /^\+/) {
+ $check = 0;
+ }
+ if (defined($stat_real) && $cond_lines > 1) {
+ $stat_real = "[...]\n$stat_real";
+ }
+
+ #print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s> cond_lines<$cond_lines> stat_real<$stat_real> stat<$stat>\n";
+
+ if ($check && $s ne '' &&
+ (($sindent % 8) != 0 ||
+ ($sindent < $indent) ||
+ ($sindent == $indent &&
+ ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
+ ($sindent > $indent + 8))) {
+ WARN("SUSPECT_CODE_INDENT",
+ "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
+ }
+ }
+
+ # Track the 'values' across context and added lines.
+ my $opline = $line; $opline =~ s/^./ /;
+ my ($curr_values, $curr_vars) =
+ annotate_values($opline . "\n", $prev_values);
+ $curr_values = $prev_values . $curr_values;
+ if ($dbg_values) {
+ my $outline = $opline; $outline =~ s/\t/ /g;
+ print "$linenr > .$outline\n";
+ print "$linenr > $curr_values\n";
+ print "$linenr > $curr_vars\n";
+ }
+ $prev_values = substr($curr_values, -1);
+
+#ignore lines not being added
+ next if ($line =~ /^[^\+]/);
+
+# check for dereferences that span multiple lines
+ if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
+ $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
+ $prevline =~ /($Lval\s*(?:\.|->))\s*$/;
+ my $ref = $1;
+ $line =~ /^.\s*($Lval)/;
+ $ref .= $1;
+ $ref =~ s/\s//g;
+ WARN("MULTILINE_DEREFERENCE",
+ "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
+ }
+
+# check for declarations of signed or unsigned without int
+ while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
+ my $type = $1;
+ my $var = $2;
+ $var = "" if (!defined $var);
+ if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
+ my $sign = $1;
+ my $pointer = $2;
+
+ $pointer = "" if (!defined $pointer);
+
+ if (WARN("UNSPECIFIED_INT",
+ "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
+ $fix) {
+ my $decl = trim($sign) . " int ";
+ my $comp_pointer = $pointer;
+ $comp_pointer =~ s/\s//g;
+ $decl .= $comp_pointer;
+ $decl = rtrim($decl) if ($var eq "");
+ $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
+ }
+ }
+ }
+
+# TEST: allow direct testing of the type matcher.
+ if ($dbg_type) {
+ if ($line =~ /^.\s*$Declare\s*$/) {
+ ERROR("TEST_TYPE",
+ "TEST: is type\n" . $herecurr);
+ } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
+ ERROR("TEST_NOT_TYPE",
+ "TEST: is not type ($1 is)\n". $herecurr);
+ }
+ next;
+ }
+# TEST: allow direct testing of the attribute matcher.
+ if ($dbg_attr) {
+ if ($line =~ /^.\s*$Modifier\s*$/) {
+ ERROR("TEST_ATTR",
+ "TEST: is attr\n" . $herecurr);
+ } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
+ ERROR("TEST_NOT_ATTR",
+ "TEST: is not attr ($1 is)\n". $herecurr);
+ }
+ next;
+ }
+
+# check for initialisation to aggregates open brace on the next line
+ if ($line =~ /^.\s*{/ &&
+ $prevline =~ /(?:^|[^=])=\s*$/) {
+ if (ERROR("OPEN_BRACE",
+ "that open brace { should be on the previous line\n" . $hereprev) &&
+ $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
+ fix_delete_line($fixlinenr - 1, $prevrawline);
+ fix_delete_line($fixlinenr, $rawline);
+ my $fixedline = $prevrawline;
+ $fixedline =~ s/\s*=\s*$/ = {/;
+ fix_insert_line($fixlinenr, $fixedline);
+ $fixedline = $line;
+ $fixedline =~ s/^(.\s*)\{\s*/$1/;
+ fix_insert_line($fixlinenr, $fixedline);
+ }
+ }
+
+#
+# Checks which are anchored on the added line.
+#
+
+# check for malformed paths in #include statements (uses RAW line)
+ if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
+ my $path = $1;
+ if ($path =~ m{//}) {
+ ERROR("MALFORMED_INCLUDE",
+ "malformed #include filename\n" . $herecurr);
+ }
+ if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
+ ERROR("UAPI_INCLUDE",
+ "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
+ }
+ }
+
+# no C99 // comments
+ if ($line =~ m{//}) {
+ if (ERROR("C99_COMMENTS",
+ "do not use C99 // comments\n" . $herecurr) &&
+ $fix) {
+ my $line = $fixed[$fixlinenr];
+ if ($line =~ /\/\/(.*)$/) {
+ my $comment = trim($1);
+ $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
+ }
+ }
+ }
+ # Remove C99 comments.
+ $line =~ s@//.*@@;
+ $opline =~ s@//.*@@;
+
+# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
+# the whole statement.
+#print "APW <$lines[$realline_next - 1]>\n";
+ if (defined $realline_next &&
+ exists $lines[$realline_next - 1] &&
+ !defined $suppress_export{$realline_next} &&
+ ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
+ $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
+ # Handle definitions which produce identifiers with
+ # a prefix:
+ # XXX(foo);
+ # EXPORT_SYMBOL(something_foo);
+ my $name = $1;
+ if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
+ $name =~ /^${Ident}_$2/) {
+#print "FOO C name<$name>\n";
+ $suppress_export{$realline_next} = 1;
+
+ } elsif ($stat !~ /(?:
+ \n.}\s*$|
+ ^.DEFINE_$Ident\(\Q$name\E\)|
+ ^.DECLARE_$Ident\(\Q$name\E\)|
+ ^.LIST_HEAD\(\Q$name\E\)|
+ ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
+ \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
+ )/x) {
+#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
+ $suppress_export{$realline_next} = 2;
+ } else {
+ $suppress_export{$realline_next} = 1;
+ }
+ }
+ if (!defined $suppress_export{$linenr} &&
+ $prevline =~ /^.\s*$/ &&
+ ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
+ $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
+#print "FOO B <$lines[$linenr - 1]>\n";
+ $suppress_export{$linenr} = 2;
+ }
+ if (defined $suppress_export{$linenr} &&
+ $suppress_export{$linenr} == 2) {
+ WARN("EXPORT_SYMBOL",
+ "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
+ }
+
+# check for global initialisers.
+ if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) {
+ if (ERROR("GLOBAL_INITIALISERS",
+ "do not initialise globals to $1\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
+ }
+ }
+# check for static initialisers.
+ if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
+ if (ERROR("INITIALISED_STATIC",
+ "do not initialise statics to $1\n" .
+ $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
+ }
+ }
+
+# check for misordered declarations of char/short/int/long with signed/unsigned
+ while ($sline =~ m{(\b$TypeMisordered\b)}g) {
+ my $tmp = trim($1);
+ WARN("MISORDERED_TYPE",
+ "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
+ }
+
+# check for unnecessary <signed> int declarations of short/long/long long
+ while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) {
+ my $type = trim($1);
+ next if ($type !~ /\bint\b/);
+ next if ($type !~ /\b(?:short|long\s+long|long)\b/);
+ my $new_type = $type;
+ $new_type =~ s/\b\s*int\s*\b/ /;
+ $new_type =~ s/\b\s*(?:un)?signed\b\s*/ /;
+ $new_type =~ s/^const\s+//;
+ $new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/);
+ $new_type = "const $new_type" if ($type =~ /^const\b/);
+ $new_type =~ s/\s+/ /g;
+ $new_type = trim($new_type);
+ if (WARN("UNNECESSARY_INT",
+ "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/;
+ }
+ }
+
+# check for static const char * arrays.
+ if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
+ WARN("STATIC_CONST_CHAR_ARRAY",
+ "static const char * array should probably be static const char * const\n" .
+ $herecurr);
+ }
+
+# check for initialized const char arrays that should be static const
+ if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) {
+ if (WARN("STATIC_CONST_CHAR_ARRAY",
+ "const array should probably be static const\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/;
+ }
+ }
+
+# check for static char foo[] = "bar" declarations.
+ if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
+ WARN("STATIC_CONST_CHAR_ARRAY",
+ "static char array declaration should probably be static const char\n" .
+ $herecurr);
+ }
+
+# check for const <foo> const where <foo> is not a pointer or array type
+ if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
+ my $found = $1;
+ if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
+ WARN("CONST_CONST",
+ "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
+ } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
+ WARN("CONST_CONST",
+ "'const $found const' should probably be 'const $found'\n" . $herecurr);
+ }
+ }
+
+# check for non-global char *foo[] = {"bar", ...} declarations.
+ if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
+ WARN("STATIC_CONST_CHAR_ARRAY",
+ "char * array declaration might be better as static const\n" .
+ $herecurr);
+ }
+
+# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
+ if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
+ my $array = $1;
+ if ($line =~ m@\b(sizeof\s*\(\s*\Q$array\E\s*\)\s*/\s*sizeof\s*\(\s*\Q$array\E\s*\[\s*0\s*\]\s*\))@) {
+ my $array_div = $1;
+ if (WARN("ARRAY_SIZE",
+ "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
+ }
+ }
+ }
+
+# check for function declarations without arguments like "int foo()"
+ if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) {
+ if (ERROR("FUNCTION_WITHOUT_ARGS",
+ "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
+ }
+ }
+
+# check for new typedefs, only function parameters and sparse annotations
+# make sense.
+ if ($line =~ /\btypedef\s/ &&
+ $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
+ $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
+ $line !~ /\b$typeTypedefs\b/ &&
+ $line !~ /\b__bitwise\b/) {
+ WARN("NEW_TYPEDEFS",
+ "do not add new typedefs\n" . $herecurr);
+ }
+
+# * goes on variable not on type
+ # (char*[ const])
+ while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
+ #print "AA<$1>\n";
+ my ($ident, $from, $to) = ($1, $2, $2);
+
+ # Should start with a space.
+ $to =~ s/^(\S)/ $1/;
+ # Should not end with a space.
+ $to =~ s/\s+$//;
+ # '*'s should not have spaces between.
+ while ($to =~ s/\*\s+\*/\*\*/) {
+ }
+
+## print "1: from<$from> to<$to> ident<$ident>\n";
+ if ($from ne $to) {
+ if (ERROR("POINTER_LOCATION",
+ "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) &&
+ $fix) {
+ my $sub_from = $ident;
+ my $sub_to = $ident;
+ $sub_to =~ s/\Q$from\E/$to/;
+ $fixed[$fixlinenr] =~
+ s@\Q$sub_from\E@$sub_to@;
+ }
+ }
+ }
+ while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
+ #print "BB<$1>\n";
+ my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
+
+ # Should start with a space.
+ $to =~ s/^(\S)/ $1/;
+ # Should not end with a space.
+ $to =~ s/\s+$//;
+ # '*'s should not have spaces between.
+ while ($to =~ s/\*\s+\*/\*\*/) {
+ }
+ # Modifiers should have spaces.
+ $to =~ s/(\b$Modifier$)/$1 /;
+
+## print "2: from<$from> to<$to> ident<$ident>\n";
+ if ($from ne $to && $ident !~ /^$Modifier$/) {
+ if (ERROR("POINTER_LOCATION",
+ "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) &&
+ $fix) {
+
+ my $sub_from = $match;
+ my $sub_to = $match;
+ $sub_to =~ s/\Q$from\E/$to/;
+ $fixed[$fixlinenr] =~
+ s@\Q$sub_from\E@$sub_to@;
+ }
+ }
+ }
+
+# avoid BUG() or BUG_ON()
+ if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
+ my $msg_level = \&WARN;
+ $msg_level = \&CHK if ($file);
+ &{$msg_level}("AVOID_BUG",
+ "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
+ }
+
+# avoid LINUX_VERSION_CODE
+ if ($line =~ /\bLINUX_VERSION_CODE\b/) {
+ WARN("LINUX_VERSION_CODE",
+ "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
+ }
+
+# check for uses of printk_ratelimit
+ if ($line =~ /\bprintk_ratelimit\s*\(/) {
+ WARN("PRINTK_RATELIMITED",
+ "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
+ }
+
+# printk should use KERN_* levels
+ if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) {
+ WARN("PRINTK_WITHOUT_KERN_LEVEL",
+ "printk() should include KERN_<LEVEL> facility level\n" . $herecurr);
+ }
+
+ if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) {
+ my $orig = $1;
+ my $level = lc($orig);
+ $level = "warn" if ($level eq "warning");
+ my $level2 = $level;
+ $level2 = "dbg" if ($level eq "debug");
+ WARN("PREFER_PR_LEVEL",
+ "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr);
+ }
+
+ if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
+ my $orig = $1;
+ my $level = lc($orig);
+ $level = "warn" if ($level eq "warning");
+ $level = "dbg" if ($level eq "debug");
+ WARN("PREFER_DEV_LEVEL",
+ "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
+ }
+
+# ENOSYS means "bad syscall nr" and nothing else. This will have a small
+# number of false positives, but assembly files are not checked, so at
+# least the arch entry code will not trigger this warning.
+ if ($line =~ /\bENOSYS\b/) {
+ WARN("ENOSYS",
+ "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
+ }
+
+# function brace can't be on same line, except for #defines of do while,
+# or if closed on same line
+ if ($perl_version_ok &&
+ $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
+ $sline !~ /\#\s*define\b.*do\s*\{/ &&
+ $sline !~ /}/) {
+ if (ERROR("OPEN_BRACE",
+ "open brace '{' following function definitions go on the next line\n" . $herecurr) &&
+ $fix) {
+ fix_delete_line($fixlinenr, $rawline);
+ my $fixed_line = $rawline;
+ $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/;
+ my $line1 = $1;
+ my $line2 = $2;
+ fix_insert_line($fixlinenr, ltrim($line1));
+ fix_insert_line($fixlinenr, "\+{");
+ if ($line2 !~ /^\s*$/) {
+ fix_insert_line($fixlinenr, "\+\t" . trim($line2));
+ }
+ }
+ }
+
+# open braces for enum, union and struct go on the same line.
+ if ($line =~ /^.\s*{/ &&
+ $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
+ if (ERROR("OPEN_BRACE",
+ "open brace '{' following $1 go on the same line\n" . $hereprev) &&
+ $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
+ fix_delete_line($fixlinenr - 1, $prevrawline);
+ fix_delete_line($fixlinenr, $rawline);
+ my $fixedline = rtrim($prevrawline) . " {";
+ fix_insert_line($fixlinenr, $fixedline);
+ $fixedline = $rawline;
+ $fixedline =~ s/^(.\s*)\{\s*/$1\t/;
+ if ($fixedline !~ /^\+\s*$/) {
+ fix_insert_line($fixlinenr, $fixedline);
+ }
+ }
+ }
+
+# missing space after union, struct or enum definition
+ if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
+ if (WARN("SPACING",
+ "missing space after $1 definition\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~
+ s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
+ }
+ }
+
+# Function pointer declarations
+# check spacing between type, funcptr, and args
+# canonical declaration is "type (*funcptr)(args...)"
+ if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
+ my $declare = $1;
+ my $pre_pointer_space = $2;
+ my $post_pointer_space = $3;
+ my $funcname = $4;
+ my $post_funcname_space = $5;
+ my $pre_args_space = $6;
+
+# the $Declare variable will capture all spaces after the type
+# so check it for a missing trailing missing space but pointer return types
+# don't need a space so don't warn for those.
+ my $post_declare_space = "";
+ if ($declare =~ /(\s+)$/) {
+ $post_declare_space = $1;
+ $declare = rtrim($declare);
+ }
+ if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
+ WARN("SPACING",
+ "missing space after return type\n" . $herecurr);
+ $post_declare_space = " ";
+ }
+
+# unnecessary space "type (*funcptr)(args...)"
+# This test is not currently implemented because these declarations are
+# equivalent to
+# int foo(int bar, ...)
+# and this is form shouldn't/doesn't generate a checkpatch warning.
+#
+# elsif ($declare =~ /\s{2,}$/) {
+# WARN("SPACING",
+# "Multiple spaces after return type\n" . $herecurr);
+# }
+
+# unnecessary space "type ( *funcptr)(args...)"
+ if (defined $pre_pointer_space &&
+ $pre_pointer_space =~ /^\s/) {
+ WARN("SPACING",
+ "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
+ }
+
+# unnecessary space "type (* funcptr)(args...)"
+ if (defined $post_pointer_space &&
+ $post_pointer_space =~ /^\s/) {
+ WARN("SPACING",
+ "Unnecessary space before function pointer name\n" . $herecurr);
+ }
+
+# unnecessary space "type (*funcptr )(args...)"
+ if (defined $post_funcname_space &&
+ $post_funcname_space =~ /^\s/) {
+ WARN("SPACING",
+ "Unnecessary space after function pointer name\n" . $herecurr);
+ }
+
+# unnecessary space "type (*funcptr) (args...)"
+ if (defined $pre_args_space &&
+ $pre_args_space =~ /^\s/) {
+ WARN("SPACING",
+ "Unnecessary space before function pointer arguments\n" . $herecurr);
+ }
+
+ if (show_type("SPACING") && $fix) {
+ $fixed[$fixlinenr] =~
+ s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
+ }
+ }
+
+# check for spacing round square brackets; allowed:
+# 1. with a type on the left -- int [] a;
+# 2. at the beginning of a line for slice initialisers -- [0...10] = 5,
+# 3. inside a curly brace -- = { [0...10] = 5 }
+ while ($line =~ /(.*?\s)\[/g) {
+ my ($where, $prefix) = ($-[1], $1);
+ if ($prefix !~ /$Type\s+$/ &&
+ ($where != 0 || $prefix !~ /^.\s+$/) &&
+ $prefix !~ /[{,:]\s+$/) {
+ if (ERROR("BRACKET_SPACE",
+ "space prohibited before open square bracket '['\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~
+ s/^(\+.*?)\s+\[/$1\[/;
+ }
+ }
+ }
+
+# check for spaces between functions and their parentheses.
+ while ($line =~ /($Ident)\s+\(/g) {
+ my $name = $1;
+ my $ctx_before = substr($line, 0, $-[1]);
+ my $ctx = "$ctx_before$name";
+
+ # Ignore those directives where spaces _are_ permitted.
+ if ($name =~ /^(?:
+ if|for|while|switch|return|case|
+ volatile|__volatile__|
+ __attribute__|format|__extension__|
+ asm|__asm__)$/x)
+ {
+ # cpp #define statements have non-optional spaces, ie
+ # if there is a space between the name and the open
+ # parenthesis it is simply not a parameter group.
+ } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
+
+ # cpp #elif statement condition may start with a (
+ } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
+
+ # If this whole things ends with a type its most
+ # likely a typedef for a function.
+ } elsif ($ctx =~ /$Type$/) {
+
+ } else {
+ if (WARN("SPACING",
+ "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~
+ s/\b$name\s+\(/$name\(/;
+ }
+ }
+ }
+
+# Check operator spacing.
+ if (!($line=~/\#\s*include/)) {
+ my $fixed_line = "";
+ my $line_fixed = 0;
+
+ my $ops = qr{
+ <<=|>>=|<=|>=|==|!=|
+ \+=|-=|\*=|\/=|%=|\^=|\|=|&=|
+ =>|->|<<|>>|<|>|=|!|~|
+ &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
+ \?:|\?|:
+ }x;
+ my @elements = split(/($ops|;)/, $opline);
+
+## print("element count: <" . $#elements . ">\n");
+## foreach my $el (@elements) {
+## print("el: <$el>\n");
+## }
+
+ my @fix_elements = ();
+ my $off = 0;
+
+ foreach my $el (@elements) {
+ push(@fix_elements, substr($rawline, $off, length($el)));
+ $off += length($el);
+ }
+
+ $off = 0;
+
+ my $blank = copy_spacing($opline);
+ my $last_after = -1;
+
+ for (my $n = 0; $n < $#elements; $n += 2) {
+
+ my $good = $fix_elements[$n] . $fix_elements[$n + 1];
+
+## print("n: <$n> good: <$good>\n");
+
+ $off += length($elements[$n]);
+
+ # Pick up the preceding and succeeding characters.
+ my $ca = substr($opline, 0, $off);
+ my $cc = '';
+ if (length($opline) >= ($off + length($elements[$n + 1]))) {
+ $cc = substr($opline, $off + length($elements[$n + 1]));
+ }
+ my $cb = "$ca$;$cc";
+
+ my $a = '';
+ $a = 'V' if ($elements[$n] ne '');
+ $a = 'W' if ($elements[$n] =~ /\s$/);
+ $a = 'C' if ($elements[$n] =~ /$;$/);
+ $a = 'B' if ($elements[$n] =~ /(\[|\()$/);
+ $a = 'O' if ($elements[$n] eq '');
+ $a = 'E' if ($ca =~ /^\s*$/);
+
+ my $op = $elements[$n + 1];
+
+ my $c = '';
+ if (defined $elements[$n + 2]) {
+ $c = 'V' if ($elements[$n + 2] ne '');
+ $c = 'W' if ($elements[$n + 2] =~ /^\s/);
+ $c = 'C' if ($elements[$n + 2] =~ /^$;/);
+ $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
+ $c = 'O' if ($elements[$n + 2] eq '');
+ $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
+ } else {
+ $c = 'E';
+ }
+
+ my $ctx = "${a}x${c}";
+
+ my $at = "(ctx:$ctx)";
+
+ my $ptr = substr($blank, 0, $off) . "^";
+ my $hereptr = "$hereline$ptr\n";
+
+ # Pull out the value of this operator.
+ my $op_type = substr($curr_values, $off + 1, 1);
+
+ # Get the full operator variant.
+ my $opv = $op . substr($curr_vars, $off, 1);
+
+ # Ignore operators passed as parameters.
+ if ($op_type ne 'V' &&
+ $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
+
+# # Ignore comments
+# } elsif ($op =~ /^$;+$/) {
+
+ # ; should have either the end of line or a space or \ after it
+ } elsif ($op eq ';') {
+ if ($ctx !~ /.x[WEBC]/ &&
+ $cc !~ /^\\/ && $cc !~ /^;/) {
+ if (ERROR("SPACING",
+ "space required after that '$op' $at\n" . $hereptr)) {
+ $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
+ $line_fixed = 1;
+ }
+ }
+
+ # // is a comment
+ } elsif ($op eq '//') {
+
+ # : when part of a bitfield
+ } elsif ($opv eq ':B') {
+ # skip the bitfield test for now
+
+ # No spaces for:
+ # ->
+ } elsif ($op eq '->') {
+ if ($ctx =~ /Wx.|.xW/) {
+ if (ERROR("SPACING",
+ "spaces prohibited around that '$op' $at\n" . $hereptr)) {
+ $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
+ if (defined $fix_elements[$n + 2]) {
+ $fix_elements[$n + 2] =~ s/^\s+//;
+ }
+ $line_fixed = 1;
+ }
+ }
+
+ # , must not have a space before and must have a space on the right.
+ } elsif ($op eq ',') {
+ my $rtrim_before = 0;
+ my $space_after = 0;
+ if ($ctx =~ /Wx./) {
+ if (ERROR("SPACING",
+ "space prohibited before that '$op' $at\n" . $hereptr)) {
+ $line_fixed = 1;
+ $rtrim_before = 1;
+ }
+ }
+ if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
+ if (ERROR("SPACING",
+ "space required after that '$op' $at\n" . $hereptr)) {
+ $line_fixed = 1;
+ $last_after = $n;
+ $space_after = 1;
+ }
+ }
+ if ($rtrim_before || $space_after) {
+ if ($rtrim_before) {
+ $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
+ } else {
+ $good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
+ }
+ if ($space_after) {
+ $good .= " ";
+ }
+ }
+
+ # '*' as part of a type definition -- reported already.
+ } elsif ($opv eq '*_') {
+ #warn "'*' is part of type\n";
+
+ # unary operators should have a space before and
+ # none after. May be left adjacent to another
+ # unary operator, or a cast
+ } elsif ($op eq '!' || $op eq '~' ||
+ $opv eq '*U' || $opv eq '-U' ||
+ $opv eq '&U' || $opv eq '&&U') {
+ if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
+ if (ERROR("SPACING",
+ "space required before that '$op' $at\n" . $hereptr)) {
+ if ($n != $last_after + 2) {
+ $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
+ $line_fixed = 1;
+ }
+ }
+ }
+ if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
+ # A unary '*' may be const
+
+ } elsif ($ctx =~ /.xW/) {
+ if (ERROR("SPACING",
+ "space prohibited after that '$op' $at\n" . $hereptr)) {
+ $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
+ if (defined $fix_elements[$n + 2]) {
+ $fix_elements[$n + 2] =~ s/^\s+//;
+ }
+ $line_fixed = 1;
+ }
+ }
+
+ # unary ++ and unary -- are allowed no space on one side.
+ } elsif ($op eq '++' or $op eq '--') {
+ if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
+ if (ERROR("SPACING",
+ "space required one side of that '$op' $at\n" . $hereptr)) {
+ $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
+ $line_fixed = 1;
+ }
+ }
+ if ($ctx =~ /Wx[BE]/ ||
+ ($ctx =~ /Wx./ && $cc =~ /^;/)) {
+ if (ERROR("SPACING",
+ "space prohibited before that '$op' $at\n" . $hereptr)) {
+ $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
+ $line_fixed = 1;
+ }
+ }
+ if ($ctx =~ /ExW/) {
+ if (ERROR("SPACING",
+ "space prohibited after that '$op' $at\n" . $hereptr)) {
+ $good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
+ if (defined $fix_elements[$n + 2]) {
+ $fix_elements[$n + 2] =~ s/^\s+//;
+ }
+ $line_fixed = 1;
+ }
+ }
+
+ # << and >> may either have or not have spaces both sides
+ } elsif ($op eq '<<' or $op eq '>>' or
+ $op eq '&' or $op eq '^' or $op eq '|' or
+ $op eq '+' or $op eq '-' or
+ $op eq '*' or $op eq '/' or
+ $op eq '%')
+ {
+ if ($check) {
+ if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
+ if (CHK("SPACING",
+ "spaces preferred around that '$op' $at\n" . $hereptr)) {
+ $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
+ $fix_elements[$n + 2] =~ s/^\s+//;
+ $line_fixed = 1;
+ }
+ } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
+ if (CHK("SPACING",
+ "space preferred before that '$op' $at\n" . $hereptr)) {
+ $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
+ $line_fixed = 1;
+ }
+ }
+ } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
+ if (ERROR("SPACING",
+ "need consistent spacing around '$op' $at\n" . $hereptr)) {
+ $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
+ if (defined $fix_elements[$n + 2]) {
+ $fix_elements[$n + 2] =~ s/^\s+//;
+ }
+ $line_fixed = 1;
+ }
+ }
+
+ # A colon needs no spaces before when it is
+ # terminating a case value or a label.
+ } elsif ($opv eq ':C' || $opv eq ':L') {
+ if ($ctx =~ /Wx./) {
+ if (ERROR("SPACING",
+ "space prohibited before that '$op' $at\n" . $hereptr)) {
+ $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
+ $line_fixed = 1;
+ }
+ }
+
+ # All the others need spaces both sides.
+ } elsif ($ctx !~ /[EWC]x[CWE]/) {
+ my $ok = 0;
+
+ # Ignore email addresses <foo@bar>
+ if (($op eq '<' &&
+ $cc =~ /^\S+\@\S+>/) ||
+ ($op eq '>' &&
+ $ca =~ /<\S+\@\S+$/))
+ {
+ $ok = 1;
+ }
+
+ # for asm volatile statements
+ # ignore a colon with another
+ # colon immediately before or after
+ if (($op eq ':') &&
+ ($ca =~ /:$/ || $cc =~ /^:/)) {
+ $ok = 1;
+ }
+
+ # messages are ERROR, but ?: are CHK
+ if ($ok == 0) {
+ my $msg_level = \&ERROR;
+ $msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
+
+ if (&{$msg_level}("SPACING",
+ "spaces required around that '$op' $at\n" . $hereptr)) {
+ $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
+ if (defined $fix_elements[$n + 2]) {
+ $fix_elements[$n + 2] =~ s/^\s+//;
+ }
+ $line_fixed = 1;
+ }
+ }
+ }
+ $off += length($elements[$n + 1]);
+
+## print("n: <$n> GOOD: <$good>\n");
+
+ $fixed_line = $fixed_line . $good;
+ }
+
+ if (($#elements % 2) == 0) {
+ $fixed_line = $fixed_line . $fix_elements[$#elements];
+ }
+
+ if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
+ $fixed[$fixlinenr] = $fixed_line;
+ }
+
+
+ }
+
+# check for whitespace before a non-naked semicolon
+ if ($line =~ /^\+.*\S\s+;\s*$/) {
+ if (WARN("SPACING",
+ "space prohibited before semicolon\n" . $herecurr) &&
+ $fix) {
+ 1 while $fixed[$fixlinenr] =~
+ s/^(\+.*\S)\s+;/$1;/;
+ }
+ }
+
+# check for multiple assignments
+ if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
+ CHK("MULTIPLE_ASSIGNMENTS",
+ "multiple assignments should be avoided\n" . $herecurr);
+ }
+
+## # check for multiple declarations, allowing for a function declaration
+## # continuation.
+## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
+## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
+##
+## # Remove any bracketed sections to ensure we do not
+## # falsly report the parameters of functions.
+## my $ln = $line;
+## while ($ln =~ s/\([^\(\)]*\)//g) {
+## }
+## if ($ln =~ /,/) {
+## WARN("MULTIPLE_DECLARATION",
+## "declaring multiple variables together should be avoided\n" . $herecurr);
+## }
+## }
+
+#need space before brace following if, while, etc
+ if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
+ $line =~ /\b(?:else|do)\{/) {
+ if (ERROR("SPACING",
+ "space required before the open brace '{'\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/;
+ }
+ }
+
+## # check for blank lines before declarations
+## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
+## $prevrawline =~ /^.\s*$/) {
+## WARN("SPACING",
+## "No blank lines before declarations\n" . $hereprev);
+## }
+##
+
+# closing brace should have a space following it when it has anything
+# on the line
+ if ($line =~ /}(?!(?:,|;|\)|\}))\S/) {
+ if (ERROR("SPACING",
+ "space required after that close brace '}'\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~
+ s/}((?!(?:,|;|\)))\S)/} $1/;
+ }
+ }
+
+# check spacing on square brackets
+ if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
+ if (ERROR("SPACING",
+ "space prohibited after that open square bracket '['\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~
+ s/\[\s+/\[/;
+ }
+ }
+ if ($line =~ /\s\]/) {
+ if (ERROR("SPACING",
+ "space prohibited before that close square bracket ']'\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~
+ s/\s+\]/\]/;
+ }
+ }
+
+# check spacing on parentheses
+ if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
+ $line !~ /for\s*\(\s+;/) {
+ if (ERROR("SPACING",
+ "space prohibited after that open parenthesis '('\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~
+ s/\(\s+/\(/;
+ }
+ }
+ if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
+ $line !~ /for\s*\(.*;\s+\)/ &&
+ $line !~ /:\s+\)/) {
+ if (ERROR("SPACING",
+ "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~
+ s/\s+\)/\)/;
+ }
+ }
+
+# check unnecessary parentheses around addressof/dereference single $Lvals
+# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
+
+ while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
+ my $var = $1;
+ if (CHK("UNNECESSARY_PARENTHESES",
+ "Unnecessary parentheses around $var\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
+ }
+ }
+
+# check for unnecessary parentheses around function pointer uses
+# ie: (foo->bar)(); should be foo->bar();
+# but not "if (foo->bar) (" to avoid some false positives
+ if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
+ my $var = $2;
+ if (CHK("UNNECESSARY_PARENTHESES",
+ "Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
+ $fix) {
+ my $var2 = deparenthesize($var);
+ $var2 =~ s/\s//g;
+ $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
+ }
+ }
+
+# check for unnecessary parentheses around comparisons in if uses
+# when !drivers/staging or command-line uses --strict
+ if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&
+ $perl_version_ok && defined($stat) &&
+ $stat =~ /(^.\s*if\s*($balanced_parens))/) {
+ my $if_stat = $1;
+ my $test = substr($2, 1, -1);
+ my $herectx;
+ while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) {
+ my $match = $1;
+ # avoid parentheses around potential macro args
+ next if ($match =~ /^\s*\w+\s*$/);
+ if (!defined($herectx)) {
+ $herectx = $here . "\n";
+ my $cnt = statement_rawlines($if_stat);
+ for (my $n = 0; $n < $cnt; $n++) {
+ my $rl = raw_line($linenr, $n);
+ $herectx .= $rl . "\n";
+ last if $rl =~ /^[ \+].*\{/;
+ }
+ }
+ CHK("UNNECESSARY_PARENTHESES",
+ "Unnecessary parentheses around '$match'\n" . $herectx);
+ }
+ }
+
+#goto labels aren't indented, allow a single space however
+ if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
+ !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
+ if (WARN("INDENTED_LABEL",
+ "labels should not be indented\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~
+ s/^(.)\s+/$1/;
+ }
+ }
+
+# return is not a function
+ if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
+ my $spacing = $1;
+ if ($perl_version_ok &&
+ $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
+ my $value = $1;
+ $value = deparenthesize($value);
+ if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
+ ERROR("RETURN_PARENTHESES",
+ "return is not a function, parentheses are not required\n" . $herecurr);
+ }
+ } elsif ($spacing !~ /\s+/) {
+ ERROR("SPACING",
+ "space required before the open parenthesis '('\n" . $herecurr);
+ }
+ }
+
+# unnecessary return in a void function
+# at end-of-function, with the previous line a single leading tab, then return;
+# and the line before that not a goto label target like "out:"
+ if ($sline =~ /^[ \+]}\s*$/ &&
+ $prevline =~ /^\+\treturn\s*;\s*$/ &&
+ $linenr >= 3 &&
+ $lines[$linenr - 3] =~ /^[ +]/ &&
+ $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
+ WARN("RETURN_VOID",
+ "void function return statements are not generally useful\n" . $hereprev);
+ }
+
+# if statements using unnecessary parentheses - ie: if ((foo == bar))
+ if ($perl_version_ok &&
+ $line =~ /\bif\s*((?:\(\s*){2,})/) {
+ my $openparens = $1;
+ my $count = $openparens =~ tr@\(@\(@;
+ my $msg = "";
+ if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
+ my $comp = $4; #Not $1 because of $LvalOrFunc
+ $msg = " - maybe == should be = ?" if ($comp eq "==");
+ WARN("UNNECESSARY_PARENTHESES",
+ "Unnecessary parentheses$msg\n" . $herecurr);
+ }
+ }
+
+# comparisons with a constant or upper case identifier on the left
+# avoid cases like "foo + BAR < baz"
+# only fix matches surrounded by parentheses to avoid incorrect
+# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
+ if ($perl_version_ok &&
+ $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
+ my $lead = $1;
+ my $const = $2;
+ my $comp = $3;
+ my $to = $4;
+ my $newcomp = $comp;
+ if ($lead !~ /(?:$Operators|\.)\s*$/ &&
+ $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
+ WARN("CONSTANT_COMPARISON",
+ "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
+ $fix) {
+ if ($comp eq "<") {
+ $newcomp = ">";
+ } elsif ($comp eq "<=") {
+ $newcomp = ">=";
+ } elsif ($comp eq ">") {
+ $newcomp = "<";
+ } elsif ($comp eq ">=") {
+ $newcomp = "<=";
+ }
+ $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
+ }
+ }
+
+# Return of what appears to be an errno should normally be negative
+ if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
+ my $name = $1;
+ if ($name ne 'EOF' && $name ne 'ERROR') {
+ WARN("USE_NEGATIVE_ERRNO",
+ "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
+ }
+ }
+
+# Need a space before open parenthesis after if, while etc
+ if ($line =~ /\b(if|while|for|switch)\(/) {
+ if (ERROR("SPACING",
+ "space required before the open parenthesis '('\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~
+ s/\b(if|while|for|switch)\(/$1 \(/;
+ }
+ }
+
+# Check for illegal assignment in if conditional -- and check for trailing
+# statements after the conditional.
+ if ($line =~ /do\s*(?!{)/) {
+ ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
+ ctx_statement_block($linenr, $realcnt, 0)
+ if (!defined $stat);
+ my ($stat_next) = ctx_statement_block($line_nr_next,
+ $remain_next, $off_next);
+ $stat_next =~ s/\n./\n /g;
+ ##print "stat<$stat> stat_next<$stat_next>\n";
+
+ if ($stat_next =~ /^\s*while\b/) {
+ # If the statement carries leading newlines,
+ # then count those as offsets.
+ my ($whitespace) =
+ ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
+ my $offset =
+ statement_rawlines($whitespace) - 1;
+
+ $suppress_whiletrailers{$line_nr_next +
+ $offset} = 1;
+ }
+ }
+ if (!defined $suppress_whiletrailers{$linenr} &&
+ defined($stat) && defined($cond) &&
+ $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
+ my ($s, $c) = ($stat, $cond);
+
+ if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
+ ERROR("ASSIGN_IN_IF",
+ "do not use assignment in if condition\n" . $herecurr);
+ }
+
+ # Find out what is on the end of the line after the
+ # conditional.
+ substr($s, 0, length($c), '');
+ $s =~ s/\n.*//g;
+ $s =~ s/$;//g; # Remove any comments
+ if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
+ $c !~ /}\s*while\s*/)
+ {
+ # Find out how long the conditional actually is.
+ my @newlines = ($c =~ /\n/gs);
+ my $cond_lines = 1 + $#newlines;
+ my $stat_real = '';
+
+ $stat_real = raw_line($linenr, $cond_lines)
+ . "\n" if ($cond_lines);
+ if (defined($stat_real) && $cond_lines > 1) {
+ $stat_real = "[...]\n$stat_real";
+ }
+
+ ERROR("TRAILING_STATEMENTS",
+ "trailing statements should be on next line\n" . $herecurr . $stat_real);
+ }
+ }
+
+# Check for bitwise tests written as boolean
+ if ($line =~ /
+ (?:
+ (?:\[|\(|\&\&|\|\|)
+ \s*0[xX][0-9]+\s*
+ (?:\&\&|\|\|)
+ |
+ (?:\&\&|\|\|)
+ \s*0[xX][0-9]+\s*
+ (?:\&\&|\|\||\)|\])
+ )/x)
+ {
+ WARN("HEXADECIMAL_BOOLEAN_TEST",
+ "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
+ }
+
+# if and else should not have general statements after it
+ if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
+ my $s = $1;
+ $s =~ s/$;//g; # Remove any comments
+ if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
+ ERROR("TRAILING_STATEMENTS",
+ "trailing statements should be on next line\n" . $herecurr);
+ }
+ }
+# if should not continue a brace
+ if ($line =~ /}\s*if\b/) {
+ ERROR("TRAILING_STATEMENTS",
+ "trailing statements should be on next line (or did you mean 'else if'?)\n" .
+ $herecurr);
+ }
+# case and default should not have general statements after them
+ if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
+ $line !~ /\G(?:
+ (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
+ \s*return\s+
+ )/xg)
+ {
+ ERROR("TRAILING_STATEMENTS",
+ "trailing statements should be on next line\n" . $herecurr);
+ }
+
+ # Check for }<nl>else {, these must be at the same
+ # indent level to be relevant to each other.
+ if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
+ $previndent == $indent) {
+ if (ERROR("ELSE_AFTER_BRACE",
+ "else should follow close brace '}'\n" . $hereprev) &&
+ $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
+ fix_delete_line($fixlinenr - 1, $prevrawline);
+ fix_delete_line($fixlinenr, $rawline);
+ my $fixedline = $prevrawline;
+ $fixedline =~ s/}\s*$//;
+ if ($fixedline !~ /^\+\s*$/) {
+ fix_insert_line($fixlinenr, $fixedline);
+ }
+ $fixedline = $rawline;
+ $fixedline =~ s/^(.\s*)else/$1} else/;
+ fix_insert_line($fixlinenr, $fixedline);
+ }
+ }
+
+ if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
+ $previndent == $indent) {
+ my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
+
+ # Find out what is on the end of the line after the
+ # conditional.
+ substr($s, 0, length($c), '');
+ $s =~ s/\n.*//g;
+
+ if ($s =~ /^\s*;/) {
+ if (ERROR("WHILE_AFTER_BRACE",
+ "while should follow close brace '}'\n" . $hereprev) &&
+ $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
+ fix_delete_line($fixlinenr - 1, $prevrawline);
+ fix_delete_line($fixlinenr, $rawline);
+ my $fixedline = $prevrawline;
+ my $trailing = $rawline;
+ $trailing =~ s/^\+//;
+ $trailing = trim($trailing);
+ $fixedline =~ s/}\s*$/} $trailing/;
+ fix_insert_line($fixlinenr, $fixedline);
+ }
+ }
+ }
+
+#Specific variable tests
+ while ($line =~ m{($Constant|$Lval)}g) {
+ my $var = $1;
+
+#CamelCase
+ if ($var !~ /^$Constant$/ &&
+ $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
+#Ignore Page<foo> variants
+ $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
+#Ignore SI style variants like nS, mV and dB
+#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE)
+ $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ &&
+#Ignore some three character SI units explicitly, like MiB and KHz
+ $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
+ while ($var =~ m{($Ident)}g) {
+ my $word = $1;
+ next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
+ if ($check) {
+ seed_camelcase_includes();
+ if (!$file && !$camelcase_file_seeded) {
+ seed_camelcase_file($realfile);
+ $camelcase_file_seeded = 1;
+ }
+ }
+ if (!defined $camelcase{$word}) {
+ $camelcase{$word} = 1;
+ CHK("CAMELCASE",
+ "Avoid CamelCase: <$word>\n" . $herecurr);
+ }
+ }
+ }
+ }
+
+#no spaces allowed after \ in define
+ if ($line =~ /\#\s*define.*\\\s+$/) {
+ if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
+ "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\s+$//;
+ }
+ }
+
+# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
+# itself <asm/foo.h> (uses RAW line)
+ if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
+ my $file = "$1.h";
+ my $checkfile = "include/linux/$file";
+ if (-f "$root/$checkfile" &&
+ $realfile ne $checkfile &&
+ $1 !~ /$allowed_asm_includes/)
+ {
+ my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
+ if ($asminclude > 0) {
+ if ($realfile =~ m{^arch/}) {
+ CHK("ARCH_INCLUDE_LINUX",
+ "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
+ } else {
+ WARN("INCLUDE_LINUX",
+ "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
+ }
+ }
+ }
+ }
+
+# multi-statement macros should be enclosed in a do while loop, grab the
+# first statement and ensure its the whole macro if its not enclosed
+# in a known good container
+ if ($realfile !~ m@/vmlinux.lds.h$@ &&
+ $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
+ my $ln = $linenr;
+ my $cnt = $realcnt;
+ my ($off, $dstat, $dcond, $rest);
+ my $ctx = '';
+ my $has_flow_statement = 0;
+ my $has_arg_concat = 0;
+ ($dstat, $dcond, $ln, $cnt, $off) =
+ ctx_statement_block($linenr, $realcnt, 0);
+ $ctx = $dstat;
+ #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
+ #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
+
+ $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
+ $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
+
+ $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
+ my $define_args = $1;
+ my $define_stmt = $dstat;
+ my @def_args = ();
+
+ if (defined $define_args && $define_args ne "") {
+ $define_args = substr($define_args, 1, length($define_args) - 2);
+ $define_args =~ s/\s*//g;
+ $define_args =~ s/\\\+?//g;
+ @def_args = split(",", $define_args);
+ }
+
+ $dstat =~ s/$;//g;
+ $dstat =~ s/\\\n.//g;
+ $dstat =~ s/^\s*//s;
+ $dstat =~ s/\s*$//s;
+
+ # Flatten any parentheses and braces
+ while ($dstat =~ s/\([^\(\)]*\)/1/ ||
+ $dstat =~ s/\{[^\{\}]*\}/1/ ||
+ $dstat =~ s/.\[[^\[\]]*\]/1/)
+ {
+ }
+
+ # Flatten any obvious string concatentation.
+ while ($dstat =~ s/($String)\s*$Ident/$1/ ||
+ $dstat =~ s/$Ident\s*($String)/$1/)
+ {
+ }
+
+ # Make asm volatile uses seem like a generic function
+ $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
+
+ my $exceptions = qr{
+ $Declare|
+ module_param_named|
+ MODULE_PARM_DESC|
+ DECLARE_PER_CPU|
+ DEFINE_PER_CPU|
+ __typeof__\(|
+ union|
+ struct|
+ \.$Ident\s*=\s*|
+ ^\"|\"$|
+ ^\[
+ }x;
+ #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
+
+ $ctx =~ s/\n*$//;
+ my $stmt_cnt = statement_rawlines($ctx);
+ my $herectx = get_stat_here($linenr, $stmt_cnt, $here);
+
+ if ($dstat ne '' &&
+ $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(),
+ $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo();
+ $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
+ $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants
+ $dstat !~ /$exceptions/ &&
+ $dstat !~ /^\.$Ident\s*=/ && # .foo =
+ $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo
+ $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...)
+ $dstat !~ /^for\s*$Constant$/ && # for (...)
+ $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar()
+ $dstat !~ /^do\s*{/ && # do {...
+ $dstat !~ /^\(\{/ && # ({...
+ $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
+ {
+ if ($dstat =~ /^\s*if\b/) {
+ ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
+ "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
+ } elsif ($dstat =~ /;/) {
+ ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
+ "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
+ } else {
+ ERROR("COMPLEX_MACRO",
+ "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
+ }
+
+ }
+
+ # Make $define_stmt single line, comment-free, etc
+ my @stmt_array = split('\n', $define_stmt);
+ my $first = 1;
+ $define_stmt = "";
+ foreach my $l (@stmt_array) {
+ $l =~ s/\\$//;
+ if ($first) {
+ $define_stmt = $l;
+ $first = 0;
+ } elsif ($l =~ /^[\+ ]/) {
+ $define_stmt .= substr($l, 1);
+ }
+ }
+ $define_stmt =~ s/$;//g;
+ $define_stmt =~ s/\s+/ /g;
+ $define_stmt = trim($define_stmt);
+
+# check if any macro arguments are reused (ignore '...' and 'type')
+ foreach my $arg (@def_args) {
+ next if ($arg =~ /\.\.\./);
+ next if ($arg =~ /^type$/i);
+ my $tmp_stmt = $define_stmt;
+ $tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
+ $tmp_stmt =~ s/\#+\s*$arg\b//g;
+ $tmp_stmt =~ s/\b$arg\s*\#\#//g;
+ my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
+ if ($use_cnt > 1) {
+ CHK("MACRO_ARG_REUSE",
+ "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
+ }
+# check if any macro arguments may have other precedence issues
+ if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
+ ((defined($1) && $1 ne ',') ||
+ (defined($2) && $2 ne ','))) {
+ CHK("MACRO_ARG_PRECEDENCE",
+ "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
+ }
+ }
+
+# check for macros with flow control, but without ## concatenation
+# ## concatenation is commonly a macro that defines a function so ignore those
+ if ($has_flow_statement && !$has_arg_concat) {
+ my $cnt = statement_rawlines($ctx);
+ my $herectx = get_stat_here($linenr, $cnt, $here);
+
+ WARN("MACRO_WITH_FLOW_CONTROL",
+ "Macros with flow control statements should be avoided\n" . "$herectx");
+ }
+
+# check for line continuations outside of #defines, preprocessor #, and asm
+
+ } else {
+ if ($prevline !~ /^..*\\$/ &&
+ $line !~ /^\+\s*\#.*\\$/ && # preprocessor
+ $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm
+ $line =~ /^\+.*\\$/) {
+ WARN("LINE_CONTINUATIONS",
+ "Avoid unnecessary line continuations\n" . $herecurr);
+ }
+ }
+
+# do {} while (0) macro tests:
+# single-statement macros do not need to be enclosed in do while (0) loop,
+# macro should not end with a semicolon
+ if ($perl_version_ok &&
+ $realfile !~ m@/vmlinux.lds.h$@ &&
+ $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
+ my $ln = $linenr;
+ my $cnt = $realcnt;
+ my ($off, $dstat, $dcond, $rest);
+ my $ctx = '';
+ ($dstat, $dcond, $ln, $cnt, $off) =
+ ctx_statement_block($linenr, $realcnt, 0);
+ $ctx = $dstat;
+
+ $dstat =~ s/\\\n.//g;
+ $dstat =~ s/$;/ /g;
+
+ if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
+ my $stmts = $2;
+ my $semis = $3;
+
+ $ctx =~ s/\n*$//;
+ my $cnt = statement_rawlines($ctx);
+ my $herectx = get_stat_here($linenr, $cnt, $here);
+
+ if (($stmts =~ tr/;/;/) == 1 &&
+ $stmts !~ /^\s*(if|while|for|switch)\b/) {
+ WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
+ "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
+ }
+ if (defined $semis && $semis ne "") {
+ WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
+ "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
+ }
+ } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
+ $ctx =~ s/\n*$//;
+ my $cnt = statement_rawlines($ctx);
+ my $herectx = get_stat_here($linenr, $cnt, $here);
+
+ WARN("TRAILING_SEMICOLON",
+ "macros should not use a trailing semicolon\n" . "$herectx");
+ }
+ }
+
+# check for redundant bracing round if etc
+ if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
+ my ($level, $endln, @chunks) =
+ ctx_statement_full($linenr, $realcnt, 1);
+ #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
+ #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
+ if ($#chunks > 0 && $level == 0) {
+ my @allowed = ();
+ my $allow = 0;
+ my $seen = 0;
+ my $herectx = $here . "\n";
+ my $ln = $linenr - 1;
+ for my $chunk (@chunks) {
+ my ($cond, $block) = @{$chunk};
+
+ # If the condition carries leading newlines, then count those as offsets.
+ my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
+ my $offset = statement_rawlines($whitespace) - 1;
+
+ $allowed[$allow] = 0;
+ #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
+
+ # We have looked at and allowed this specific line.
+ $suppress_ifbraces{$ln + $offset} = 1;
+
+ $herectx .= "$rawlines[$ln + $offset]\n[...]\n";
+ $ln += statement_rawlines($block) - 1;
+
+ substr($block, 0, length($cond), '');
+
+ $seen++ if ($block =~ /^\s*{/);
+
+ #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
+ if (statement_lines($cond) > 1) {
+ #print "APW: ALLOWED: cond<$cond>\n";
+ $allowed[$allow] = 1;
+ }
+ if ($block =~/\b(?:if|for|while)\b/) {
+ #print "APW: ALLOWED: block<$block>\n";
+ $allowed[$allow] = 1;
+ }
+ if (statement_block_size($block) > 1) {
+ #print "APW: ALLOWED: lines block<$block>\n";
+ $allowed[$allow] = 1;
+ }
+ $allow++;
+ }
+ if ($seen) {
+ my $sum_allowed = 0;
+ foreach (@allowed) {
+ $sum_allowed += $_;
+ }
+ if ($sum_allowed == 0) {
+ WARN("BRACES",
+ "braces {} are not necessary for any arm of this statement\n" . $herectx);
+ } elsif ($sum_allowed != $allow &&
+ $seen != $allow) {
+ CHK("BRACES",
+ "braces {} should be used on all arms of this statement\n" . $herectx);
+ }
+ }
+ }
+ }
+ if (!defined $suppress_ifbraces{$linenr - 1} &&
+ $line =~ /\b(if|while|for|else)\b/) {
+ my $allowed = 0;
+
+ # Check the pre-context.
+ if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
+ #print "APW: ALLOWED: pre<$1>\n";
+ $allowed = 1;
+ }
+
+ my ($level, $endln, @chunks) =
+ ctx_statement_full($linenr, $realcnt, $-[0]);
+
+ # Check the condition.
+ my ($cond, $block) = @{$chunks[0]};
+ #print "CHECKING<$linenr> cond<$cond> block<$block>\n";
+ if (defined $cond) {
+ substr($block, 0, length($cond), '');
+ }
+ if (statement_lines($cond) > 1) {
+ #print "APW: ALLOWED: cond<$cond>\n";
+ $allowed = 1;
+ }
+ if ($block =~/\b(?:if|for|while)\b/) {
+ #print "APW: ALLOWED: block<$block>\n";
+ $allowed = 1;
+ }
+ if (statement_block_size($block) > 1) {
+ #print "APW: ALLOWED: lines block<$block>\n";
+ $allowed = 1;
+ }
+ # Check the post-context.
+ if (defined $chunks[1]) {
+ my ($cond, $block) = @{$chunks[1]};
+ if (defined $cond) {
+ substr($block, 0, length($cond), '');
+ }
+ if ($block =~ /^\s*\{/) {
+ #print "APW: ALLOWED: chunk-1 block<$block>\n";
+ $allowed = 1;
+ }
+ }
+ if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
+ my $cnt = statement_rawlines($block);
+ my $herectx = get_stat_here($linenr, $cnt, $here);
+
+ WARN("BRACES",
+ "braces {} are not necessary for single statement blocks\n" . $herectx);
+ }
+ }
+
+# check for single line unbalanced braces
+ if ($sline =~ /^.\s*\}\s*else\s*$/ ||
+ $sline =~ /^.\s*else\s*\{\s*$/) {
+ CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
+ }
+
+# check for unnecessary blank lines around braces
+ if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
+ if (CHK("BRACES",
+ "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
+ $fix && $prevrawline =~ /^\+/) {
+ fix_delete_line($fixlinenr - 1, $prevrawline);
+ }
+ }
+ if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
+ if (CHK("BRACES",
+ "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
+ $fix) {
+ fix_delete_line($fixlinenr, $rawline);
+ }
+ }
+
+# no volatiles please
+ my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
+ if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
+ WARN("VOLATILE",
+ "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
+ }
+
+# Check for user-visible strings broken across lines, which breaks the ability
+# to grep for the string. Make exceptions when the previous string ends in a
+# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
+# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
+ if ($line =~ /^\+\s*$String/ &&
+ $prevline =~ /"\s*$/ &&
+ $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
+ if (WARN("SPLIT_STRING",
+ "quoted string split across lines\n" . $hereprev) &&
+ $fix &&
+ $prevrawline =~ /^\+.*"\s*$/ &&
+ $last_coalesced_string_linenr != $linenr - 1) {
+ my $extracted_string = get_quoted_string($line, $rawline);
+ my $comma_close = "";
+ if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
+ $comma_close = $1;
+ }
+
+ fix_delete_line($fixlinenr - 1, $prevrawline);
+ fix_delete_line($fixlinenr, $rawline);
+ my $fixedline = $prevrawline;
+ $fixedline =~ s/"\s*$//;
+ $fixedline .= substr($extracted_string, 1) . trim($comma_close);
+ fix_insert_line($fixlinenr - 1, $fixedline);
+ $fixedline = $rawline;
+ $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
+ if ($fixedline !~ /\+\s*$/) {
+ fix_insert_line($fixlinenr, $fixedline);
+ }
+ $last_coalesced_string_linenr = $linenr;
+ }
+ }
+
+# check for missing a space in a string concatenation
+ if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
+ WARN('MISSING_SPACE',
+ "break quoted strings at a space character\n" . $hereprev);
+ }
+
+# check for an embedded function name in a string when the function is known
+# This does not work very well for -f --file checking as it depends on patch
+# context providing the function name or a single line form for in-file
+# function declarations
+ if ($line =~ /^\+.*$String/ &&
+ defined($context_function) &&
+ get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
+ length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
+ WARN("EMBEDDED_FUNCTION_NAME",
+ "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
+ }
+
+# check for spaces before a quoted newline
+ if ($rawline =~ /^.*\".*\s\\n/) {
+ if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
+ "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
+ }
+
+ }
+
+# concatenated string without spaces between elements
+ if ($line =~ /$String[A-Za-z0-9_]/ || $line =~ /[A-Za-z0-9_]$String/) {
+ if (CHK("CONCATENATED_STRING",
+ "Concatenated strings should use spaces between elements\n" . $herecurr) &&
+ $fix) {
+ while ($line =~ /($String)/g) {
+ my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
+ $fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/;
+ $fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/;
+ }
+ }
+ }
+
+# uncoalesced string fragments
+ if ($line =~ /$String\s*"/) {
+ if (WARN("STRING_FRAGMENTS",
+ "Consecutive strings are generally better as a single string\n" . $herecurr) &&
+ $fix) {
+ while ($line =~ /($String)(?=\s*")/g) {
+ my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
+ $fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e;
+ }
+ }
+ }
+
+# check for non-standard and hex prefixed decimal printf formats
+ my $show_L = 1; #don't show the same defect twice
+ my $show_Z = 1;
+ while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
+ my $string = substr($rawline, $-[1], $+[1] - $-[1]);
+ $string =~ s/%%/__/g;
+ # check for %L
+ if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
+ WARN("PRINTF_L",
+ "\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
+ $show_L = 0;
+ }
+ # check for %Z
+ if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
+ WARN("PRINTF_Z",
+ "%Z$1 is non-standard C, use %z$1\n" . $herecurr);
+ $show_Z = 0;
+ }
+ # check for 0x<decimal>
+ if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
+ ERROR("PRINTF_0XDECIMAL",
+ "Prefixing 0x with decimal output is defective\n" . $herecurr);
+ }
+ }
+
+# check for line continuations in quoted strings with odd counts of "
+ if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) {
+ WARN("LINE_CONTINUATIONS",
+ "Avoid line continuations in quoted strings\n" . $herecurr);
+ }
+
+# warn about #if 0
+ if ($line =~ /^.\s*\#\s*if\s+0\b/) {
+ WARN("IF_0",
+ "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr);
+ }
+
+# warn about #if 1
+ if ($line =~ /^.\s*\#\s*if\s+1\b/) {
+ WARN("IF_1",
+ "Consider removing the #if 1 and its #endif\n" . $herecurr);
+ }
+
+# check for needless "if (<foo>) fn(<foo>)" uses
+ if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
+ my $tested = quotemeta($1);
+ my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
+ if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
+ my $func = $1;
+ if (WARN('NEEDLESS_IF',
+ "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
+ $fix) {
+ my $do_fix = 1;
+ my $leading_tabs = "";
+ my $new_leading_tabs = "";
+ if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
+ $leading_tabs = $1;
+ } else {
+ $do_fix = 0;
+ }
+ if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
+ $new_leading_tabs = $1;
+ if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
+ $do_fix = 0;
+ }
+ } else {
+ $do_fix = 0;
+ }
+ if ($do_fix) {
+ fix_delete_line($fixlinenr - 1, $prevrawline);
+ $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
+ }
+ }
+ }
+ }
+
+# check for unnecessary "Out of Memory" messages
+ if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
+ $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
+ (defined $1 || defined $3) &&
+ $linenr > 3) {
+ my $testval = $2;
+ my $testline = $lines[$linenr - 3];
+
+ my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
+# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
+
+ if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ &&
+ $s !~ /\b__GFP_NOWARN\b/ ) {
+ WARN("OOM_MESSAGE",
+ "Possible unnecessary 'out of memory' message\n" . $hereprev);
+ }
+ }
+
+# check for logging functions with KERN_<LEVEL>
+ if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
+ $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
+ my $level = $1;
+ if (WARN("UNNECESSARY_KERN_LEVEL",
+ "Possible unnecessary $level\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\s*$level\s*//;
+ }
+ }
+
+# check for logging continuations
+ if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
+ WARN("LOGGING_CONTINUATION",
+ "Avoid logging continuation uses where feasible\n" . $herecurr);
+ }
+
+# check for mask then right shift without a parentheses
+ if ($perl_version_ok &&
+ $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
+ $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
+ WARN("MASK_THEN_SHIFT",
+ "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
+ }
+
+# check for pointer comparisons to NULL
+ if ($perl_version_ok) {
+ while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
+ my $val = $1;
+ my $equal = "!";
+ $equal = "" if ($4 eq "!=");
+ if (CHK("COMPARISON_TO_NULL",
+ "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
+ }
+ }
+ }
+
+# check for bad placement of section $InitAttribute (e.g.: __initdata)
+ if ($line =~ /(\b$InitAttribute\b)/) {
+ my $attr = $1;
+ if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
+ my $ptr = $1;
+ my $var = $2;
+ if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
+ ERROR("MISPLACED_INIT",
+ "$attr should be placed after $var\n" . $herecurr)) ||
+ ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
+ WARN("MISPLACED_INIT",
+ "$attr should be placed after $var\n" . $herecurr))) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/(\bstatic\s+(?:const\s+)?)(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*([=;])\s*/"$1" . trim(string_find_replace($2, "\\s*$attr\\s*", " ")) . " " . trim(string_find_replace($3, "\\s*$attr\\s*", "")) . " $attr" . ("$4" eq ";" ? ";" : " = ")/e;
+ }
+ }
+ }
+
+# check for $InitAttributeData (ie: __initdata) with const
+ if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
+ my $attr = $1;
+ $attr =~ /($InitAttributePrefix)(.*)/;
+ my $attr_prefix = $1;
+ my $attr_type = $2;
+ if (ERROR("INIT_ATTRIBUTE",
+ "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~
+ s/$InitAttributeData/${attr_prefix}initconst/;
+ }
+ }
+
+# check for $InitAttributeConst (ie: __initconst) without const
+ if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
+ my $attr = $1;
+ if (ERROR("INIT_ATTRIBUTE",
+ "Use of $attr requires a separate use of const\n" . $herecurr) &&
+ $fix) {
+ my $lead = $fixed[$fixlinenr] =~
+ /(^\+\s*(?:static\s+))/;
+ $lead = rtrim($1);
+ $lead = "$lead " if ($lead !~ /^\+$/);
+ $lead = "${lead}const ";
+ $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
+ }
+ }
+
+# check for __read_mostly with const non-pointer (should just be const)
+ if ($line =~ /\b__read_mostly\b/ &&
+ $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
+ if (ERROR("CONST_READ_MOSTLY",
+ "Invalid use of __read_mostly with const type\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
+ }
+ }
+
+# don't use __constant_<foo> functions outside of include/uapi/
+ if ($realfile !~ m@^include/uapi/@ &&
+ $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
+ my $constant_func = $1;
+ my $func = $constant_func;
+ $func =~ s/^__constant_//;
+ if (WARN("CONSTANT_CONVERSION",
+ "$constant_func should be $func\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
+ }
+ }
+
+# prefer usleep_range over udelay
+ if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
+ my $delay = $1;
+ # ignore udelay's < 10, however
+ if (! ($delay < 10) ) {
+ CHK("USLEEP_RANGE",
+ "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr);
+ }
+ if ($delay > 2000) {
+ WARN("LONG_UDELAY",
+ "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
+ }
+ }
+
+# warn about unexpectedly long msleep's
+ if ($line =~ /\bmsleep\s*\((\d+)\);/) {
+ if ($1 < 20) {
+ WARN("MSLEEP",
+ "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr);
+ }
+ }
+
+# check for comparisons of jiffies
+ if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
+ WARN("JIFFIES_COMPARISON",
+ "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
+ }
+
+# check for comparisons of get_jiffies_64()
+ if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
+ WARN("JIFFIES_COMPARISON",
+ "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
+ }
+
+# warn about #ifdefs in C files
+# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
+# print "#ifdef in C files should be avoided\n";
+# print "$herecurr";
+# $clean = 0;
+# }
+
+# warn about spacing in #ifdefs
+ if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
+ if (ERROR("SPACING",
+ "exactly one space required after that #$1\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~
+ s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
+ }
+
+ }
+
+# check for spinlock_t definitions without a comment.
+ if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
+ $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
+ my $which = $1;
+ if (!ctx_has_comment($first_line, $linenr)) {
+ CHK("UNCOMMENTED_DEFINITION",
+ "$1 definition without comment\n" . $herecurr);
+ }
+ }
+# check for memory barriers without a comment.
+
+ my $barriers = qr{
+ mb|
+ rmb|
+ wmb|
+ read_barrier_depends
+ }x;
+ my $barrier_stems = qr{
+ mb__before_atomic|
+ mb__after_atomic|
+ store_release|
+ load_acquire|
+ store_mb|
+ (?:$barriers)
+ }x;
+ my $all_barriers = qr{
+ (?:$barriers)|
+ smp_(?:$barrier_stems)|
+ virt_(?:$barrier_stems)
+ }x;
+
+ if ($line =~ /\b(?:$all_barriers)\s*\(/) {
+ if (!ctx_has_comment($first_line, $linenr)) {
+ WARN("MEMORY_BARRIER",
+ "memory barrier without comment\n" . $herecurr);
+ }
+ }
+
+ my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
+
+ if ($realfile !~ m@^include/asm-generic/@ &&
+ $realfile !~ m@/barrier\.h$@ &&
+ $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
+ $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
+ WARN("MEMORY_BARRIER",
+ "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
+ }
+
+# check for waitqueue_active without a comment.
+ if ($line =~ /\bwaitqueue_active\s*\(/) {
+ if (!ctx_has_comment($first_line, $linenr)) {
+ WARN("WAITQUEUE_ACTIVE",
+ "waitqueue_active without comment\n" . $herecurr);
+ }
+ }
+
+# check for smp_read_barrier_depends and read_barrier_depends
+ if (!$file && $line =~ /\b(smp_|)read_barrier_depends\s*\(/) {
+ WARN("READ_BARRIER_DEPENDS",
+ "$1read_barrier_depends should only be used in READ_ONCE or DEC Alpha code\n" . $herecurr);
+ }
+
+# check of hardware specific defines
+ if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
+ CHK("ARCH_DEFINES",
+ "architecture specific defines should be avoided\n" . $herecurr);
+ }
+
+# check that the storage class is not after a type
+ if ($line =~ /\b($Type)\s+($Storage)\b/) {
+ WARN("STORAGE_CLASS",
+ "storage class '$2' should be located before type '$1'\n" . $herecurr);
+ }
+# Check that the storage class is at the beginning of a declaration
+ if ($line =~ /\b$Storage\b/ &&
+ $line !~ /^.\s*$Storage/ &&
+ $line =~ /^.\s*(.+?)\$Storage\s/ &&
+ $1 !~ /[\,\)]\s*$/) {
+ WARN("STORAGE_CLASS",
+ "storage class should be at the beginning of the declaration\n" . $herecurr);
+ }
+
+# check the location of the inline attribute, that it is between
+# storage class and type.
+ if ($line =~ /\b$Type\s+$Inline\b/ ||
+ $line =~ /\b$Inline\s+$Storage\b/) {
+ ERROR("INLINE_LOCATION",
+ "inline keyword should sit between storage class and type\n" . $herecurr);
+ }
+
+# Check for __inline__ and __inline, prefer inline
+ if ($realfile !~ m@\binclude/uapi/@ &&
+ $line =~ /\b(__inline__|__inline)\b/) {
+ if (WARN("INLINE",
+ "plain inline is preferred over $1\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
+
+ }
+ }
+
+# Check for __attribute__ packed, prefer __packed
+ if ($realfile !~ m@\binclude/uapi/@ &&
+ $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
+ WARN("PREFER_PACKED",
+ "__packed is preferred over __attribute__((packed))\n" . $herecurr);
+ }
+
+# Check for __attribute__ aligned, prefer __aligned
+ if ($realfile !~ m@\binclude/uapi/@ &&
+ $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
+ WARN("PREFER_ALIGNED",
+ "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
+ }
+
+# Check for __attribute__ section, prefer __section
+ if ($realfile !~ m@\binclude/uapi/@ &&
+ $line =~ /\b__attribute__\s*\(\s*\(.*_*section_*\s*\(\s*("[^"]*")/) {
+ my $old = substr($rawline, $-[1], $+[1] - $-[1]);
+ my $new = substr($old, 1, -1);
+ if (WARN("PREFER_SECTION",
+ "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/;
+ }
+ }
+
+# Check for __attribute__ format(printf, prefer __printf
+ if ($realfile !~ m@\binclude/uapi/@ &&
+ $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
+ if (WARN("PREFER_PRINTF",
+ "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex;
+
+ }
+ }
+
+# Check for __attribute__ format(scanf, prefer __scanf
+ if ($realfile !~ m@\binclude/uapi/@ &&
+ $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
+ if (WARN("PREFER_SCANF",
+ "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex;
+ }
+ }
+
+# Check for __attribute__ weak, or __weak declarations (may have link issues)
+ if ($perl_version_ok &&
+ $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
+ ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
+ $line =~ /\b__weak\b/)) {
+ ERROR("WEAK_DECLARATION",
+ "Using weak declarations can have unintended link defects\n" . $herecurr);
+ }
+
+# check for c99 types like uint8_t used outside of uapi/ and tools/
+ if ($realfile !~ m@\binclude/uapi/@ &&
+ $realfile !~ m@\btools/@ &&
+ $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
+ my $type = $1;
+ if ($type =~ /\b($typeC99Typedefs)\b/) {
+ $type = $1;
+ my $kernel_type = 'u';
+ $kernel_type = 's' if ($type =~ /^_*[si]/);
+ $type =~ /(\d+)/;
+ $kernel_type .= $1;
+ if (CHK("PREFER_KERNEL_TYPES",
+ "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
+ }
+ }
+ }
+
+# check for cast of C90 native int or longer types constants
+ if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
+ my $cast = $1;
+ my $const = $2;
+ if (WARN("TYPECAST_INT_CONSTANT",
+ "Unnecessary typecast of c90 int constant\n" . $herecurr) &&
+ $fix) {
+ my $suffix = "";
+ my $newconst = $const;
+ $newconst =~ s/${Int_type}$//;
+ $suffix .= 'U' if ($cast =~ /\bunsigned\b/);
+ if ($cast =~ /\blong\s+long\b/) {
+ $suffix .= 'LL';
+ } elsif ($cast =~ /\blong\b/) {
+ $suffix .= 'L';
+ }
+ $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
+ }
+ }
+
+# check for sizeof(&)
+ if ($line =~ /\bsizeof\s*\(\s*\&/) {
+ WARN("SIZEOF_ADDRESS",
+ "sizeof(& should be avoided\n" . $herecurr);
+ }
+
+# check for sizeof without parenthesis
+ if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
+ if (WARN("SIZEOF_PARENTHESIS",
+ "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
+ }
+ }
+
+# check for struct spinlock declarations
+ if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
+ WARN("USE_SPINLOCK_T",
+ "struct spinlock should be spinlock_t\n" . $herecurr);
+ }
+
+# check for seq_printf uses that could be seq_puts
+ if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
+ my $fmt = get_quoted_string($line, $rawline);
+ $fmt =~ s/%%//g;
+ if ($fmt !~ /%/) {
+ if (WARN("PREFER_SEQ_PUTS",
+ "Prefer seq_puts to seq_printf\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
+ }
+ }
+ }
+
+# check for vsprintf extension %p<foo> misuses
+ if ($perl_version_ok &&
+ defined $stat &&
+ $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
+ $1 !~ /^_*volatile_*$/) {
+ my $stat_real;
+
+ my $lc = $stat =~ tr@\n@@;
+ $lc = $lc + $linenr;
+ for (my $count = $linenr; $count <= $lc; $count++) {
+ my $specifier;
+ my $extension;
+ my $qualifier;
+ my $bad_specifier = "";
+ my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
+ $fmt =~ s/%%//g;
+
+ while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) {
+ $specifier = $1;
+ $extension = $2;
+ $qualifier = $3;
+ if ($extension !~ /[SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||
+ ($extension eq "f" &&
+ defined $qualifier && $qualifier !~ /^w/)) {
+ $bad_specifier = $specifier;
+ last;
+ }
+ if ($extension eq "x" && !defined($stat_real)) {
+ if (!defined($stat_real)) {
+ $stat_real = get_stat_real($linenr, $lc);
+ }
+ WARN("VSPRINTF_SPECIFIER_PX",
+ "Using vsprintf specifier '\%px' potentially exposes the kernel memory layout, if you don't really need the address please consider using '\%p'.\n" . "$here\n$stat_real\n");
+ }
+ }
+ if ($bad_specifier ne "") {
+ my $stat_real = get_stat_real($linenr, $lc);
+ my $ext_type = "Invalid";
+ my $use = "";
+ if ($bad_specifier =~ /p[Ff]/) {
+ $use = " - use %pS instead";
+ $use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
+ }
+
+ WARN("VSPRINTF_POINTER_EXTENSION",
+ "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
+ }
+ }
+ }
+
+# Check for misused memsets
+ if ($perl_version_ok &&
+ defined $stat &&
+ $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
+
+ my $ms_addr = $2;
+ my $ms_val = $7;
+ my $ms_size = $12;
+
+ if ($ms_size =~ /^(0x|)0$/i) {
+ ERROR("MEMSET",
+ "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
+ } elsif ($ms_size =~ /^(0x|)1$/i) {
+ WARN("MEMSET",
+ "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
+ }
+ }
+
+# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
+# if ($perl_version_ok &&
+# defined $stat &&
+# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
+# if (WARN("PREFER_ETHER_ADDR_COPY",
+# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
+# $fix) {
+# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
+# }
+# }
+
+# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
+# if ($perl_version_ok &&
+# defined $stat &&
+# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
+# WARN("PREFER_ETHER_ADDR_EQUAL",
+# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
+# }
+
+# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
+# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
+# if ($perl_version_ok &&
+# defined $stat &&
+# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
+#
+# my $ms_val = $7;
+#
+# if ($ms_val =~ /^(?:0x|)0+$/i) {
+# if (WARN("PREFER_ETH_ZERO_ADDR",
+# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
+# $fix) {
+# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
+# }
+# } elsif ($ms_val =~ /^(?:0xff|255)$/i) {
+# if (WARN("PREFER_ETH_BROADCAST_ADDR",
+# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
+# $fix) {
+# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
+# }
+# }
+# }
+
+# typecasts on min/max could be min_t/max_t
+ if ($perl_version_ok &&
+ defined $stat &&
+ $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
+ if (defined $2 || defined $7) {
+ my $call = $1;
+ my $cast1 = deparenthesize($2);
+ my $arg1 = $3;
+ my $cast2 = deparenthesize($7);
+ my $arg2 = $8;
+ my $cast;
+
+ if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
+ $cast = "$cast1 or $cast2";
+ } elsif ($cast1 ne "") {
+ $cast = $cast1;
+ } else {
+ $cast = $cast2;
+ }
+ WARN("MINMAX",
+ "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
+ }
+ }
+
+# check usleep_range arguments
+ if ($perl_version_ok &&
+ defined $stat &&
+ $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
+ my $min = $1;
+ my $max = $7;
+ if ($min eq $max) {
+ WARN("USLEEP_RANGE",
+ "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
+ } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
+ $min > $max) {
+ WARN("USLEEP_RANGE",
+ "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
+ }
+ }
+
+# check for naked sscanf
+ if ($perl_version_ok &&
+ defined $stat &&
+ $line =~ /\bsscanf\b/ &&
+ ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
+ $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
+ $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
+ my $lc = $stat =~ tr@\n@@;
+ $lc = $lc + $linenr;
+ my $stat_real = get_stat_real($linenr, $lc);
+ WARN("NAKED_SSCANF",
+ "unchecked sscanf return value\n" . "$here\n$stat_real\n");
+ }
+
+# check for simple sscanf that should be kstrto<foo>
+ if ($perl_version_ok &&
+ defined $stat &&
+ $line =~ /\bsscanf\b/) {
+ my $lc = $stat =~ tr@\n@@;
+ $lc = $lc + $linenr;
+ my $stat_real = get_stat_real($linenr, $lc);
+ if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
+ my $format = $6;
+ my $count = $format =~ tr@%@%@;
+ if ($count == 1 &&
+ $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
+ WARN("SSCANF_TO_KSTRTO",
+ "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
+ }
+ }
+ }
+
+# check for new externs in .h files.
+ if ($realfile =~ /\.h$/ &&
+ $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
+ if (CHK("AVOID_EXTERNS",
+ "extern prototypes should be avoided in .h files\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
+ }
+ }
+
+# check for new externs in .c files.
+ if ($realfile =~ /\.c$/ && defined $stat &&
+ $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
+ {
+ my $function_name = $1;
+ my $paren_space = $2;
+
+ my $s = $stat;
+ if (defined $cond) {
+ substr($s, 0, length($cond), '');
+ }
+ if ($s =~ /^\s*;/ &&
+ $function_name ne 'uninitialized_var')
+ {
+ WARN("AVOID_EXTERNS",
+ "externs should be avoided in .c files\n" . $herecurr);
+ }
+
+ if ($paren_space =~ /\n/) {
+ WARN("FUNCTION_ARGUMENTS",
+ "arguments for function declarations should follow identifier\n" . $herecurr);
+ }
+
+ } elsif ($realfile =~ /\.c$/ && defined $stat &&
+ $stat =~ /^.\s*extern\s+/)
+ {
+ WARN("AVOID_EXTERNS",
+ "externs should be avoided in .c files\n" . $herecurr);
+ }
+
+# check for function declarations that have arguments without identifier names
+ if (defined $stat &&
+ $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
+ $1 ne "void") {
+ my $args = trim($1);
+ while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
+ my $arg = trim($1);
+ if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
+ WARN("FUNCTION_ARGUMENTS",
+ "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
+ }
+ }
+ }
+
+# check for function definitions
+ if ($perl_version_ok &&
+ defined $stat &&
+ $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
+ $context_function = $1;
+
+# check for multiline function definition with misplaced open brace
+ my $ok = 0;
+ my $cnt = statement_rawlines($stat);
+ my $herectx = $here . "\n";
+ for (my $n = 0; $n < $cnt; $n++) {
+ my $rl = raw_line($linenr, $n);
+ $herectx .= $rl . "\n";
+ $ok = 1 if ($rl =~ /^[ \+]\{/);
+ $ok = 1 if ($rl =~ /\{/ && $n == 0);
+ last if $rl =~ /^[ \+].*\{/;
+ }
+ if (!$ok) {
+ ERROR("OPEN_BRACE",
+ "open brace '{' following function definitions go on the next line\n" . $herectx);
+ }
+ }
+
+# checks for new __setup's
+ if ($rawline =~ /\b__setup\("([^"]*)"/) {
+ my $name = $1;
+
+ if (!grep(/$name/, @setup_docs)) {
+ CHK("UNDOCUMENTED_SETUP",
+ "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr);
+ }
+ }
+
+# check for pointless casting of alloc functions
+ if ($line =~ /\*\s*\)\s*$allocFunctions\b/) {
+ WARN("UNNECESSARY_CASTS",
+ "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
+ }
+
+# alloc style
+# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
+ if ($perl_version_ok &&
+ $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
+ CHK("ALLOC_SIZEOF_STRUCT",
+ "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
+ }
+
+# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
+ if ($perl_version_ok &&
+ defined $stat &&
+ $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
+ my $oldfunc = $3;
+ my $a1 = $4;
+ my $a2 = $10;
+ my $newfunc = "kmalloc_array";
+ $newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
+ my $r1 = $a1;
+ my $r2 = $a2;
+ if ($a1 =~ /^sizeof\s*\S/) {
+ $r1 = $a2;
+ $r2 = $a1;
+ }
+ if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
+ !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
+ my $cnt = statement_rawlines($stat);
+ my $herectx = get_stat_here($linenr, $cnt, $here);
+
+ if (WARN("ALLOC_WITH_MULTIPLY",
+ "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
+ $cnt == 1 &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e;
+ }
+ }
+ }
+
+# check for krealloc arg reuse
+ if ($perl_version_ok &&
+ $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ &&
+ $1 eq $3) {
+ WARN("KREALLOC_ARG_REUSE",
+ "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
+ }
+
+# check for alloc argument mismatch
+ if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {
+ WARN("ALLOC_ARRAY_ARGS",
+ "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
+ }
+
+# check for multiple semicolons
+ if ($line =~ /;\s*;\s*$/) {
+ if (WARN("ONE_SEMICOLON",
+ "Statements terminations use 1 semicolon\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
+ }
+ }
+
+# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
+ if ($realfile !~ m@^include/uapi/@ &&
+ $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
+ my $ull = "";
+ $ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
+ if (CHK("BIT_MACRO",
+ "Prefer using the BIT$ull macro\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
+ }
+ }
+
+# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
+ if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(CONFIG_[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) {
+ my $config = $1;
+ if (WARN("PREFER_IS_ENABLED",
+ "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
+ }
+ }
+
+# check for case / default statements not preceded by break/fallthrough/switch
+ if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) {
+ my $has_break = 0;
+ my $has_statement = 0;
+ my $count = 0;
+ my $prevline = $linenr;
+ while ($prevline > 1 && ($file || $count < 3) && !$has_break) {
+ $prevline--;
+ my $rline = $rawlines[$prevline - 1];
+ my $fline = $lines[$prevline - 1];
+ last if ($fline =~ /^\@\@/);
+ next if ($fline =~ /^\-/);
+ next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/);
+ $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i);
+ next if ($fline =~ /^.[\s$;]*$/);
+ $has_statement = 1;
+ $count++;
+ $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|exit\s*\(\b|return\b|goto\b|continue\b)/);
+ }
+ if (!$has_break && $has_statement) {
+ WARN("MISSING_BREAK",
+ "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr);
+ }
+ }
+
+# check for switch/default statements without a break;
+ if ($perl_version_ok &&
+ defined $stat &&
+ $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
+ my $cnt = statement_rawlines($stat);
+ my $herectx = get_stat_here($linenr, $cnt, $here);
+
+ WARN("DEFAULT_NO_BREAK",
+ "switch default: should use break\n" . $herectx);
+ }
+
+# check for gcc specific __FUNCTION__
+ if ($line =~ /\b__FUNCTION__\b/) {
+ if (WARN("USE_FUNC",
+ "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
+ }
+ }
+
+# check for uses of __DATE__, __TIME__, __TIMESTAMP__
+ while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
+ ERROR("DATE_TIME",
+ "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
+ }
+
+# check for use of yield()
+ if ($line =~ /\byield\s*\(\s*\)/) {
+ WARN("YIELD",
+ "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr);
+ }
+
+# check for comparisons against true and false
+ if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
+ my $lead = $1;
+ my $arg = $2;
+ my $test = $3;
+ my $otype = $4;
+ my $trail = $5;
+ my $op = "!";
+
+ ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
+
+ my $type = lc($otype);
+ if ($type =~ /^(?:true|false)$/) {
+ if (("$test" eq "==" && "$type" eq "true") ||
+ ("$test" eq "!=" && "$type" eq "false")) {
+ $op = "";
+ }
+
+ CHK("BOOL_COMPARISON",
+ "Using comparison to $otype is error prone\n" . $herecurr);
+
+## maybe suggesting a correct construct would better
+## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
+
+ }
+ }
+
+# check for semaphores initialized locked
+ if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
+ WARN("CONSIDER_COMPLETION",
+ "consider using a completion\n" . $herecurr);
+ }
+
+# recommend kstrto* over simple_strto* and strict_strto*
+ if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
+ WARN("CONSIDER_KSTRTO",
+ "$1 is obsolete, use k$3 instead\n" . $herecurr);
+ }
+
+# check for __initcall(), use device_initcall() explicitly or more appropriate function please
+ if ($line =~ /^.\s*__initcall\s*\(/) {
+ WARN("USE_DEVICE_INITCALL",
+ "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
+ }
+
+# check for spin_is_locked(), suggest lockdep instead
+ if ($line =~ /\bspin_is_locked\(/) {
+ WARN("USE_LOCKDEP",
+ "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr);
+ }
+
+# check for deprecated apis
+ if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) {
+ my $deprecated_api = $1;
+ my $new_api = $deprecated_apis{$deprecated_api};
+ WARN("DEPRECATED_API",
+ "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr);
+ }
+
+# check for various structs that are normally const (ops, kgdb, device_tree)
+# and avoid what seem like struct definitions 'struct foo {'
+ if ($line !~ /\bconst\b/ &&
+ $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
+ WARN("CONST_STRUCT",
+ "struct $1 should normally be const\n" . $herecurr);
+ }
+
+# use of NR_CPUS is usually wrong
+# ignore definitions of NR_CPUS and usage to define arrays as likely right
+ if ($line =~ /\bNR_CPUS\b/ &&
+ $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
+ $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
+ $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
+ $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
+ $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/)
+ {
+ WARN("NR_CPUS",
+ "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
+ }
+
+# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
+ if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
+ ERROR("DEFINE_ARCH_HAS",
+ "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
+ }
+
+# likely/unlikely comparisons similar to "(likely(foo) > 0)"
+ if ($perl_version_ok &&
+ $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
+ WARN("LIKELY_MISUSE",
+ "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
+ }
+
+# nested likely/unlikely calls
+ if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) {
+ WARN("LIKELY_MISUSE",
+ "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr);
+ }
+
+# whine mightly about in_atomic
+ if ($line =~ /\bin_atomic\s*\(/) {
+ if ($realfile =~ m@^drivers/@) {
+ ERROR("IN_ATOMIC",
+ "do not use in_atomic in drivers\n" . $herecurr);
+ } elsif ($realfile !~ m@^kernel/@) {
+ WARN("IN_ATOMIC",
+ "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
+ }
+ }
+
+# check for mutex_trylock_recursive usage
+ if ($line =~ /mutex_trylock_recursive/) {
+ ERROR("LOCKING",
+ "recursive locking is bad, do not use this ever.\n" . $herecurr);
+ }
+
+# check for lockdep_set_novalidate_class
+ if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
+ $line =~ /__lockdep_no_validate__\s*\)/ ) {
+ if ($realfile !~ m@^kernel/lockdep@ &&
+ $realfile !~ m@^include/linux/lockdep@ &&
+ $realfile !~ m@^drivers/base/core@) {
+ ERROR("LOCKDEP",
+ "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
+ }
+ }
+
+ if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
+ $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
+ WARN("EXPORTED_WORLD_WRITABLE",
+ "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
+ }
+
+# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
+# and whether or not function naming is typical and if
+# DEVICE_ATTR permissions uses are unusual too
+ if ($perl_version_ok &&
+ defined $stat &&
+ $stat =~ /\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?\s*(\s*(?:${multi_mode_perms_string_search}|0[0-7]{3,3})\s*)\s*\)?\s*,\s*(\w+)\s*,\s*(\w+)\s*\)/) {
+ my $var = $1;
+ my $perms = $2;
+ my $show = $3;
+ my $store = $4;
+ my $octal_perms = perms_to_octal($perms);
+ if ($show =~ /^${var}_show$/ &&
+ $store =~ /^${var}_store$/ &&
+ $octal_perms eq "0644") {
+ if (WARN("DEVICE_ATTR_RW",
+ "Use DEVICE_ATTR_RW\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*$store\s*\)/DEVICE_ATTR_RW(${var})/;
+ }
+ } elsif ($show =~ /^${var}_show$/ &&
+ $store =~ /^NULL$/ &&
+ $octal_perms eq "0444") {
+ if (WARN("DEVICE_ATTR_RO",
+ "Use DEVICE_ATTR_RO\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*NULL\s*\)/DEVICE_ATTR_RO(${var})/;
+ }
+ } elsif ($show =~ /^NULL$/ &&
+ $store =~ /^${var}_store$/ &&
+ $octal_perms eq "0200") {
+ if (WARN("DEVICE_ATTR_WO",
+ "Use DEVICE_ATTR_WO\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*NULL\s*,\s*$store\s*\)/DEVICE_ATTR_WO(${var})/;
+ }
+ } elsif ($octal_perms eq "0644" ||
+ $octal_perms eq "0444" ||
+ $octal_perms eq "0200") {
+ my $newshow = "$show";
+ $newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show");
+ my $newstore = $store;
+ $newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store");
+ my $rename = "";
+ if ($show ne $newshow) {
+ $rename .= " '$show' to '$newshow'";
+ }
+ if ($store ne $newstore) {
+ $rename .= " '$store' to '$newstore'";
+ }
+ WARN("DEVICE_ATTR_FUNCTIONS",
+ "Consider renaming function(s)$rename\n" . $herecurr);
+ } else {
+ WARN("DEVICE_ATTR_PERMS",
+ "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr);
+ }
+ }
+
+# Mode permission misuses where it seems decimal should be octal
+# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
+# o Ignore module_param*(...) uses with a decimal 0 permission as that has a
+# specific definition of not visible in sysfs.
+# o Ignore proc_create*(...) uses with a decimal 0 permission as that means
+# use the default permissions
+ if ($perl_version_ok &&
+ defined $stat &&
+ $line =~ /$mode_perms_search/) {
+ foreach my $entry (@mode_permission_funcs) {
+ my $func = $entry->[0];
+ my $arg_pos = $entry->[1];
+
+ my $lc = $stat =~ tr@\n@@;
+ $lc = $lc + $linenr;
+ my $stat_real = get_stat_real($linenr, $lc);
+
+ my $skip_args = "";
+ if ($arg_pos > 1) {
+ $arg_pos--;
+ $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
+ }
+ my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
+ if ($stat =~ /$test/) {
+ my $val = $1;
+ $val = $6 if ($skip_args ne "");
+ if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") &&
+ (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
+ ($val =~ /^$Octal$/ && length($val) ne 4))) {
+ ERROR("NON_OCTAL_PERMISSIONS",
+ "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
+ }
+ if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
+ ERROR("EXPORTED_WORLD_WRITABLE",
+ "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
+ }
+ }
+ }
+ }
+
+# check for uses of S_<PERMS> that could be octal for readability
+ while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) {
+ my $oval = $1;
+ my $octal = perms_to_octal($oval);
+ if (WARN("SYMBOLIC_PERMS",
+ "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/;
+ }
+ }
+
+# validate content of MODULE_LICENSE against list from include/linux/module.h
+ if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
+ my $extracted_string = get_quoted_string($line, $rawline);
+ my $valid_licenses = qr{
+ GPL|
+ GPL\ v2|
+ GPL\ and\ additional\ rights|
+ Dual\ BSD/GPL|
+ Dual\ MIT/GPL|
+ Dual\ MPL/GPL|
+ Proprietary
+ }x;
+ if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
+ WARN("MODULE_LICENSE",
+ "unknown module license " . $extracted_string . "\n" . $herecurr);
+ }
+ }
+
+# check for sysctl duplicate constants
+ if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) {
+ WARN("DUPLICATED_SYSCTL_CONST",
+ "duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr);
+ }
+ }
+
+ # If we have no input at all, then there is nothing to report on
+ # so just keep quiet.
+ if ($#rawlines == -1) {
+ exit(0);
+ }
+
+ # In mailback mode only produce a report in the negative, for
+ # things that appear to be patches.
+ if ($mailback && ($clean == 1 || !$is_patch)) {
+ exit(0);
+ }
+
+ # This is not a patch, and we are are in 'no-patch' mode so
+ # just keep quiet.
+ if (!$chk_patch && !$is_patch) {
+ exit(0);
+ }
+
+ if (!$is_patch && $filename !~ /cover-letter\.patch$/) {
+ ERROR("NOT_UNIFIED_DIFF",
+ "Does not appear to be a unified-diff format patch\n");
+ }
+ if ($is_patch && $has_commit_log && $chk_signoff) {
+ if ($signoff == 0) {
+ ERROR("MISSING_SIGN_OFF",
+ "Missing Signed-off-by: line(s)\n");
+ } elsif (!$authorsignoff) {
+ WARN("NO_AUTHOR_SIGN_OFF",
+ "Missing Signed-off-by: line by nominal patch author '$author'\n");
+ }
+ }
+
+ print report_dump();
+ if ($summary && !($clean == 1 && $quiet == 1)) {
+ print "$filename " if ($summary_file);
+ print "total: $cnt_error errors, $cnt_warn warnings, " .
+ (($check)? "$cnt_chk checks, " : "") .
+ "$cnt_lines lines checked\n";
+ }
+
+ if ($quiet == 0) {
+ # If there were any defects found and not already fixing them
+ if (!$clean and !$fix) {
+ print << "EOM"
+
+NOTE: For some of the reported defects, checkpatch may be able to
+ mechanically convert to the typical style using --fix or --fix-inplace.
+EOM
+ }
+ # If there were whitespace errors which cleanpatch can fix
+ # then suggest that.
+ if ($rpt_cleaners) {
+ $rpt_cleaners = 0;
+ print << "EOM"
+
+NOTE: Whitespace errors detected.
+ You may wish to use scripts/cleanpatch or scripts/cleanfile
+EOM
+ }
+ }
+
+ if ($clean == 0 && $fix &&
+ ("@rawlines" ne "@fixed" ||
+ $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
+ my $newfile = $filename;
+ $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
+ my $linecount = 0;
+ my $f;
+
+ @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
+
+ open($f, '>', $newfile)
+ or die "$P: Can't open $newfile for write\n";
+ foreach my $fixed_line (@fixed) {
+ $linecount++;
+ if ($file) {
+ if ($linecount > 3) {
+ $fixed_line =~ s/^\+//;
+ print $f $fixed_line . "\n";
+ }
+ } else {
+ print $f $fixed_line . "\n";
+ }
+ }
+ close($f);
+
+ if (!$quiet) {
+ print << "EOM";
+
+Wrote EXPERIMENTAL --fix correction(s) to '$newfile'
+
+Do _NOT_ trust the results written to this file.
+Do _NOT_ submit these changes without inspecting them for correctness.
+
+This EXPERIMENTAL file is simply a convenience to help rewrite patches.
+No warranties, expressed or implied...
+EOM
+ }
+ }
+
+ if ($quiet == 0) {
+ print "\n";
+ if ($clean == 1) {
+ print "$vname has no obvious style problems and is ready for submission.\n";
+ } else {
+ print "$vname has style problems, please review.\n";
+ }
+ }
+ return $clean;
+}
diff --git a/scripts/const_structs.checkpatch b/scripts/const_structs.checkpatch
new file mode 100644
index 0000000..ac5f126
--- /dev/null
+++ b/scripts/const_structs.checkpatch
@@ -0,0 +1,64 @@
+acpi_dock_ops
+address_space_operations
+backlight_ops
+block_device_operations
+clk_ops
+comedi_lrange
+component_ops
+dentry_operations
+dev_pm_ops
+dma_map_ops
+driver_info
+drm_connector_funcs
+drm_encoder_funcs
+drm_encoder_helper_funcs
+ethtool_ops
+extent_io_ops
+file_lock_operations
+file_operations
+hv_ops
+ide_dma_ops
+ide_port_ops
+inode_operations
+intel_dvo_dev_ops
+irq_domain_ops
+item_operations
+iwl_cfg
+iwl_ops
+kgdb_arch
+kgdb_io
+kset_uevent_ops
+lock_manager_operations
+machine_desc
+microcode_ops
+mlxsw_reg_info
+mtrr_ops
+neigh_ops
+net_device_ops
+nlmsvc_binding
+nvkm_device_chip
+of_device_id
+pci_raw_ops
+pipe_buf_operations
+platform_hibernation_ops
+platform_suspend_ops
+proto_ops
+regmap_access_table
+rpc_pipe_ops
+rtc_class_ops
+sd_desc
+seq_operations
+sirfsoc_padmux
+snd_ac97_build_ops
+snd_soc_component_driver
+soc_pcmcia_socket_ops
+stacktrace_ops
+sysfs_ops
+tty_operations
+uart_ops
+usb_mon_operations
+v4l2_ctrl_ops
+v4l2_ioctl_ops
+vm_operations_struct
+wacom_features
+wd_ops
diff --git a/scripts/guix.scm b/scripts/guix.scm
new file mode 100644
index 0000000..9bc117e
--- /dev/null
+++ b/scripts/guix.scm
@@ -0,0 +1,322 @@
+;;; Copyright © 2020 Denis Carikli <GNUtoo@cyberdimension.org>
+;;;
+;;; This file 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 file 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 GNU Guix. If not, see <http://www.gnu.org/licenses/>.
+;;; The guix.scm file is a convention: A file named guix.scm is
+;;; found in several project source code, either in the top
+;;; directory or in sub-directories like contrib for instance.
+
+;;; The guix.scm files typically contain package definitions that
+;;; are not meant to be used as regular packages but are meant for
+;;; testing or developing on the given project.
+;;;
+;;; Here it enables to build libsamsung-ril under GNU/Linux from the
+;;; files currently present in this repository: Guix first copies all
+;;; the files in this repository as-is and builds them. So if there
+;;; are some local changes that aren't even committed in git yet, they
+;;; will also be picked up and built by Guix. This is very useful to
+;;; do fast compilation tests.
+;;;
+;;; Because of that it's also not adapted to be used as a regular package
+;;; as distributions would typically need to use a given git revision or
+;;; released tarballs instead of potentially locally modified code.
+;;;
+;;; Once you have Guix installed, to build libsamsung-ril with this
+;;; guix.scm file, you can use the 'guix build --file=scripts/guix.scm'
+;;; command.
+
+(use-modules
+ (ice-9 popen)
+ (ice-9 rdelim)
+ (sxml ssax input-parse)
+ ((guix licenses) #:prefix license:)
+ (guix build-system android-ndk)
+ (guix build-system gnu)
+ (guix gexp)
+ (guix git-download)
+ (guix packages)
+ (guix transformations)
+ (gnu packages)
+ (gnu packages android)
+ (gnu packages autotools)
+ (gnu packages disk)
+ (gnu packages linux)
+ (gnu packages llvm)
+ (gnu packages pkg-config)
+ (gnu packages python)
+ (gnu packages python-xyz)
+ (gnu packages tls))
+
+(define %strict-cflags "CFLAGS=-Werror -W -Wall -Wunused -Wunused-function")
+
+(define %libsamsung-ril-commit
+ (let* ((port (open-input-pipe
+ "git --no-pager log --oneline HEAD -1 --format='%H'"))
+ (str (read-line port)))
+ (close-pipe port)
+ str))
+
+(define %local-source
+ (local-file
+ (dirname (dirname (current-filename)))
+ #:recursive? #t))
+
+;; We just need libsamsung-ipc to build libsamsung-ril.
+;; Using the Android.mk instead of Autotools can help spot more issues.
+;; For instance if libsamsung-ril depends on libsamsung-ipc code that is only
+;; built by the Autotools, using the Android.mk might spot that.
+;; Forgetting to update the Android.mk seems more frequent than forgetting
+;; to update the Autotools, because the code is often build tested with the
+;; Autotools while writing it.
+(define-public libsamsung-ipc
+ (package
+ (name "libsamsung-ipc")
+ ;; Note that the hash is ignored here because we use transformations
+ ;; to get the latest git version
+ (version (git-version "0.0" "HEAD"
+ "73b26ca046c7dc2a3de89079203159a0cae83807"))
+ (source
+ (origin
+ (method git-fetch)
+ (uri
+ (git-reference
+ (url
+ "https://git.replicant.us/replicant/hardware_replicant_libsamsung-ipc")
+ ;; Note that the hashes are ignored here because we use transformations
+ ;; to get the latest git version
+ (commit "73b26ca046c7dc2a3de89079203159a0cae83807")))
+ (sha256 (base32 "0icrc6b8hsjvzr6wjhvylq8fkn9s8snm6qf6yvz0lnlnxv0xifgp"))
+ ))
+ (build-system android-ndk-build-system)
+ (inputs
+ `(("android-libutils" ,android-libutils)
+ ("libcrypto" ,openssl)))
+ (arguments
+ `(#:phases
+ (modify-phases
+ %standard-phases
+ (delete 'bootstrap)
+ (add-before
+ 'build 'patch-host
+ (lambda _
+ (substitute* "Android.mk"
+ (("BUILD_SHARED_LIBRARY") "BUILD_HOST_SHARED_LIBRARY")
+ (("BUILD_STATIC_LIBRARY") "BUILD_HOST_STATIC_LIBRARY")
+ (("BUILD_STATIC_EXECUTABLE")
+ "BUILD_HOST_STATIC_EXECUTABLE"))
+ #t)))
+ #:make-flags (list ,%strict-cflags)))
+ (synopsis
+ "libsamsung-ipc is a free software implementation of the Samsung IPC modem
+ protocol")
+ (description
+ "libsamsung-ipc is a free software implementation of the Samsung IPC modem
+ protocol, found in many Samsung smartphones and tablets.")
+ (home-page "https://www.replicant.us")
+ (license license:gpl2+)))
+
+(define-public replicant-6-hardware_ril-headers
+ (package
+ (name "replicant-6-hardware_ril-headers")
+ (version "6.0-0003")
+ (source
+ (origin
+ (method git-fetch)
+ (uri
+ (git-reference
+ (url
+ "https://git.replicant.us/mirrors/LineageOS/android_hardware_ril.git")
+ (commit "f29d36b6b5430d3974b1857f8438d924c2f16a86")))
+ (file-name (git-file-name name version))
+ (sha256 (base32 "1inaz3lyqx3bmn6421yvxpkyj0v8vkslpl8ymxng2s3jm5xwi39g"))))
+ (build-system android-ndk-build-system)
+ (arguments
+ `(#:phases
+ (modify-phases
+ %standard-phases
+ (delete 'bootstrap)
+ (delete 'configure)
+ ;; We only want to packages the headers for now
+ (replace 'install
+ (lambda* (#:key outputs #:allow-other-keys)
+ (let* ((out (assoc-ref outputs "out"))
+ (include (string-append out "/include")))
+ (copy-recursively
+ "include" (string-append out "/include"))
+ #t))))))
+ (synopsis "Headers of the RIL used by Replicant 6.0")
+ (description
+ "Headers of the The Radio Interface Layer (RIL) used by Replicant 6.0
+ The Radio Interface Layer (RIL) daemon is used to abstracts the modem
+ protocols in Android. It typically loads a libril counterpart that actually
+ implement a specific modem protocol, while the RIL daemon itself handles the
+ interface with the Android framework")
+ (home-page "https://www.replicant.us")
+ (license license:asl2.0)))
+
+(define-public replicant-6-libhardware_legacy
+ (package
+ (name "replicant-6-libhardware_legacy")
+ (version "6.0-0003")
+ (source
+ (origin
+ (method git-fetch)
+ (uri
+ (git-reference
+ (url
+ "https://git.replicant.us/replicant/hardware_libhardware_legacy.git")
+ (commit "0a29b8547b892115003c46ae17eae4b609aa9a87")))
+ (file-name (git-file-name name version))
+ (sha256 (base32 "1m8ip09pqw9gjrcqvsj3c7l2mxpaprp3z92sqq7qvp018ayqg1nv"))))
+ (build-system android-ndk-build-system)
+ (inputs
+ `(("android-libcutils" ,android-libcutils)
+ ("android-liblog" ,android-liblog)
+ ("libnl" ,libnl)))
+ (native-inputs
+ `(("android-core" ,(android-platform-system-core
+ (android-platform-version)))))
+ (arguments
+ `(#:make-flags
+ (list
+ (string-append "CFLAGS= "
+ ;; TODO: see the comment below about
+ ;; copying the android-core source code.
+ ;; When this is fixed:
+ ;; - Change the make flag (list above to ,#~(list
+ ;; - Uncomment the following lines:
+ ;; "-I " #$(this-package-native-input "android-core")
+ ;; "/include "
+ ;; - remove the -I ../core/include below:
+ "-I core/include "))
+ #:phases
+ (modify-phases
+ %standard-phases
+ ;; TODO: Guix's android.scm does that too in android-ext4-utils however
+ ;; it might be a good idea to instead package the android-code source
+ ;; code as-is and refer to it instead of just copyring it locally
+ (add-after
+ 'unpack 'unpack-core
+ (lambda* (#:key inputs #:allow-other-keys)
+ (mkdir-p "core")
+ (copy-recursively (assoc-ref inputs "android-core")
+ "core")
+ #t))
+ (delete 'bootstrap)
+ (add-before
+ 'build 'patch-host
+ (lambda _
+ ;; TODO: Cross-compile.
+ (substitute* "Android.mk"
+ (("BUILD_SHARED_LIBRARY") "BUILD_HOST_SHARED_LIBRARY")
+ (("BUILD_STATIC_LIBRARY") "BUILD_HOST_STATIC_LIBRARY")
+ (("BUILD_STATIC_EXECUTABLE")
+ "BUILD_HOST_STATIC_EXECUTABLE"))
+ #t)))))
+ (synopsis
+ "replicant-6-libhardware_legacy is Replicant 6.0's fork of Android's legacy
+ HAL (Hardware Abstraction Layer)")
+ (description
+ "replicant-6-libhardware_legacy is Replicant 6.0's fork of Android's legacy
+ HAL (Hardware Abstraction Layer).
+ At the beginning of Android, breaking the kernel API to support (new) hardware
+ faster was a common practice. This was handled by the use of an hardware
+ abstraction in userspace between the (highly modified) Linux kernel and the
+ Android framework that the Android applications interact with. In addition that
+ abstraction layer also supported userspace drivers for things that are not
+ typically handled by the kernel like modem or GPS protocols.")
+ (home-page "https://www.replicant.us")
+ (license license:asl2.0)))
+
+(define-public libsamsung-ril
+ (package
+ (name "libsamsung-ril")
+ (version (git-version "0.0" "HEAD" %libsamsung-ril-commit))
+ (source %local-source)
+ (build-system android-ndk-build-system)
+ (inputs
+ `(("android-libcutils" ,android-libcutils)
+ ("android-liblog" ,android-liblog)
+ ("android-libutils" ,android-libutils)
+ ("clang" ,clang)
+ ("libcrypto" ,openssl)
+ ("libsamsung-ipc" ,libsamsung-ipc)
+ ("replicant-6-libhardware_legacy" ,replicant-6-libhardware_legacy)))
+ (native-inputs
+ `(("android-core" ,(android-platform-system-core
+ (android-platform-version)))
+ ("replicant-6-hardware_ril-headers" ,replicant-6-hardware_ril-headers)))
+ (arguments
+ `(#:make-flags
+ ,#~(list
+ (string-append
+ "CFLAGS=-W -Wall -Wno-unused "
+ "-DANDROID "
+ "-I core/include "
+ "-I " #$(this-package-input "libsamsung-ipc")
+ "/include/samsung-ipc "
+ "-I " #$(this-package-input "replicant-6-libhardware_legacy")
+ "/include "
+ "-I " #$(this-package-native-input "replicant-6-hardware_ril-headers")
+ "/include ")
+ ;; We need to pass it LOCAL_MODULE=libsamsung-ril, else it only builds
+ ;; the libsrs-client target (and not the libsamsung-ril target nor any of
+ ;; the other tools).
+ ;; TODO: Build all the tools as well
+ "LOCAL_MODULE=libsamsung-ril")
+ #:phases (modify-phases
+ %standard-phases
+ (add-after
+ 'unpack 'unpack-core
+ (lambda*
+ (#:key inputs #:allow-other-keys)
+ (mkdir-p "core")
+ (copy-recursively (assoc-ref inputs "android-core")
+ "core")
+ #t))
+ (delete 'bootstrap)
+ (add-before
+ 'build 'patch-host
+ (lambda _
+ ;; TODO: Cross-compile.
+ (substitute*
+ "Android.mk"
+ (("BUILD_SHARED_LIBRARY") "BUILD_HOST_SHARED_LIBRARY")
+ (("BUILD_STATIC_LIBRARY") "BUILD_HOST_STATIC_LIBRARY")
+ (("BUILD_STATIC_EXECUTABLE")
+ "BUILD_HOST_STATIC_EXECUTABLE"))
+ #t))
+ (add-after
+ 'patch-host
+ 'prepare-build-environment
+ (lambda* (#:key inputs #:allow-other-keys)
+ (setenv "CC" "clang")
+ #t)))))
+ (synopsis
+ "libsamsung-ril is RIL library that uses libsamsung-ipc to implementation
+ the Samsung IPC modem protocol")
+ (description
+ "The Radio Interface Layer (RIL) daemon is used to abstracts the modem
+ protocols in Android. It typically loads a libril counterpart that actually
+ implement a specific modem protocol, while the RIL daemon itself handles the
+ interface with the Android framework. libsamsung-ril is libril library
+ that uses libsamsung-ipc to implementation the Samsung IPC modem protocol,
+ found in many Samsung smartphones and tablets.")
+ (home-page "https://www.replicant.us")
+ (license license:gpl2+)))
+
+(define use-libsamsung-ipc-master
+ (options->transformation
+ '((with-branch . "libsamsung-ipc=master"))))
+
+(list (use-libsamsung-ipc-master libsamsung-ril))
diff --git a/scripts/spelling.txt b/scripts/spelling.txt
new file mode 100644
index 0000000..ffa838f
--- /dev/null
+++ b/scripts/spelling.txt
@@ -0,0 +1,1489 @@
+# Originally from Debian's Lintian tool. Various false positives have been
+# removed, and various additions have been made as they've been discovered
+# in the kernel source.
+#
+# License: GPLv2
+#
+# The format of each line is:
+# mistake||correction
+#
+abandonning||abandoning
+abigious||ambiguous
+abitrate||arbitrate
+abnornally||abnormally
+abnrormal||abnormal
+abord||abort
+aboslute||absolute
+abov||above
+abreviated||abbreviated
+absense||absence
+absolut||absolute
+absoulte||absolute
+acccess||access
+acceess||access
+acceleratoin||acceleration
+accelleration||acceleration
+accesing||accessing
+accesnt||accent
+accessable||accessible
+accesss||access
+accidentaly||accidentally
+accidentually||accidentally
+acclerated||accelerated
+accoding||according
+accomodate||accommodate
+accomodates||accommodates
+accordign||according
+accoring||according
+accout||account
+accquire||acquire
+accquired||acquired
+accross||across
+accumalate||accumulate
+accumalator||accumulator
+acessable||accessible
+acess||access
+acessing||accessing
+achitecture||architecture
+acient||ancient
+acitions||actions
+acitve||active
+acknowldegement||acknowledgment
+acknowledgement||acknowledgment
+ackowledge||acknowledge
+ackowledged||acknowledged
+acording||according
+activete||activate
+actived||activated
+actualy||actually
+acumulating||accumulating
+acumulative||accumulative
+acumulator||accumulator
+adapater||adapter
+addional||additional
+additionaly||additionally
+additonal||additional
+addres||address
+adddress||address
+addreses||addresses
+addresss||address
+addrress||address
+aditional||additional
+aditionally||additionally
+aditionaly||additionally
+adminstrative||administrative
+adress||address
+adresses||addresses
+adrresses||addresses
+advertisment||advertisement
+adviced||advised
+afecting||affecting
+againt||against
+agaist||against
+aggreataon||aggregation
+aggreation||aggregation
+albumns||albums
+alegorical||allegorical
+algined||aligned
+algorith||algorithm
+algorithmical||algorithmically
+algoritm||algorithm
+algoritms||algorithms
+algorithmn||algorithm
+algorrithm||algorithm
+algorritm||algorithm
+aligment||alignment
+alignement||alignment
+allign||align
+alligned||aligned
+alllocate||allocate
+alloated||allocated
+allocatote||allocate
+allocatrd||allocated
+allocte||allocate
+allpication||application
+alocate||allocate
+alogirhtms||algorithms
+alogrithm||algorithm
+alot||a lot
+alow||allow
+alows||allows
+alreay||already
+alredy||already
+altough||although
+alue||value
+ambigious||ambiguous
+ambigous||ambiguous
+amoung||among
+amout||amount
+amplifer||amplifier
+amplifyer||amplifier
+an union||a union
+an user||a user
+an userspace||a userspace
+an one||a one
+analysator||analyzer
+ang||and
+anniversery||anniversary
+annoucement||announcement
+anomolies||anomalies
+anomoly||anomaly
+anway||anyway
+aplication||application
+appearence||appearance
+applicaion||application
+appliction||application
+applictions||applications
+applys||applies
+appplications||applications
+appropiate||appropriate
+appropriatly||appropriately
+approriate||appropriate
+approriately||appropriately
+apropriate||appropriate
+aquainted||acquainted
+aquired||acquired
+aquisition||acquisition
+arbitary||arbitrary
+architechture||architecture
+arguement||argument
+arguements||arguments
+aritmetic||arithmetic
+arne't||aren't
+arraival||arrival
+artifical||artificial
+artillary||artillery
+asign||assign
+asser||assert
+assertation||assertion
+assertting||asserting
+assiged||assigned
+assigment||assignment
+assigments||assignments
+assistent||assistant
+assocation||association
+associcated||associated
+assotiated||associated
+asssert||assert
+assum||assume
+assumtpion||assumption
+asuming||assuming
+asycronous||asynchronous
+asynchnous||asynchronous
+asynchromous||asynchronous
+asymetric||asymmetric
+asymmeric||asymmetric
+atomatically||automatically
+atomicly||atomically
+atempt||attempt
+attachement||attachment
+attched||attached
+attemps||attempts
+attemping||attempting
+attepmpt||attempt
+attnetion||attention
+attruibutes||attributes
+authentification||authentication
+authenicated||authenticated
+automaticaly||automatically
+automaticly||automatically
+automatize||automate
+automatized||automated
+automatizes||automates
+autonymous||autonomous
+auxillary||auxiliary
+auxilliary||auxiliary
+avaiable||available
+avaible||available
+availabe||available
+availabled||available
+availablity||availability
+availaible||available
+availale||available
+availavility||availability
+availble||available
+availiable||available
+availible||available
+avalable||available
+avaliable||available
+aysnc||async
+backgroud||background
+backword||backward
+backwords||backwards
+bahavior||behavior
+bakup||backup
+baloon||balloon
+baloons||balloons
+bandwith||bandwidth
+banlance||balance
+batery||battery
+beacuse||because
+becasue||because
+becomming||becoming
+becuase||because
+beeing||being
+befor||before
+begining||beginning
+beter||better
+betweeen||between
+bianries||binaries
+bitmast||bitmask
+boardcast||broadcast
+borad||board
+boundry||boundary
+brievely||briefly
+brigde||bridge
+broadcase||broadcast
+broadcat||broadcast
+bufufer||buffer
+cacluated||calculated
+caculate||calculate
+caculation||calculation
+cadidate||candidate
+calender||calendar
+calescing||coalescing
+calle||called
+callibration||calibration
+callled||called
+calucate||calculate
+calulate||calculate
+cancelation||cancellation
+cancle||cancel
+capabilites||capabilities
+capabilties||capabilities
+capabilty||capability
+capabitilies||capabilities
+capablity||capability
+capatibilities||capabilities
+capapbilities||capabilities
+caputure||capture
+carefuly||carefully
+cariage||carriage
+catagory||category
+cehck||check
+challange||challenge
+challanges||challenges
+chache||cache
+chanell||channel
+changable||changeable
+chanined||chained
+channle||channel
+channnel||channel
+charachter||character
+charachters||characters
+charactor||character
+charater||character
+charaters||characters
+charcter||character
+chcek||check
+chck||check
+checksumed||checksummed
+checksuming||checksumming
+childern||children
+childs||children
+chiled||child
+chked||checked
+chnage||change
+chnages||changes
+chnnel||channel
+choosen||chosen
+chouse||chose
+circumvernt||circumvent
+claread||cleared
+clared||cleared
+closeing||closing
+clustred||clustered
+cnfiguration||configuration
+coexistance||coexistence
+colescing||coalescing
+collapsable||collapsible
+colorfull||colorful
+comand||command
+comit||commit
+commerical||commercial
+comming||coming
+comminucation||communication
+commited||committed
+commiting||committing
+committ||commit
+commoditiy||commodity
+comsume||consume
+comsumer||consumer
+comsuming||consuming
+compability||compatibility
+compaibility||compatibility
+comparsion||comparison
+compatability||compatibility
+compatable||compatible
+compatibililty||compatibility
+compatibiliy||compatibility
+compatibilty||compatibility
+compatiblity||compatibility
+competion||completion
+compilant||compliant
+compleatly||completely
+completition||completion
+completly||completely
+complient||compliant
+componnents||components
+compoment||component
+comppatible||compatible
+compres||compress
+compresion||compression
+comression||compression
+comunication||communication
+conbination||combination
+conditionaly||conditionally
+conditon||condition
+condtion||condition
+conected||connected
+conector||connector
+connecetd||connected
+configration||configuration
+configuartion||configuration
+configuation||configuration
+configued||configured
+configuratoin||configuration
+configuraton||configuration
+configuretion||configuration
+configutation||configuration
+conider||consider
+conjuction||conjunction
+connectinos||connections
+connnection||connection
+connnections||connections
+consistancy||consistency
+consistant||consistent
+containes||contains
+containts||contains
+contaisn||contains
+contant||contact
+contence||contents
+contiguos||contiguous
+continious||continuous
+continous||continuous
+continously||continuously
+continueing||continuing
+contraints||constraints
+contruct||construct
+contol||control
+contoller||controller
+controled||controlled
+controler||controller
+controll||control
+contruction||construction
+contry||country
+conuntry||country
+convertion||conversion
+convertor||converter
+convienient||convenient
+convinient||convenient
+corected||corrected
+correponding||corresponding
+correponds||corresponds
+correspoding||corresponding
+cotrol||control
+cound||could
+couter||counter
+coutner||counter
+cryptocraphic||cryptographic
+cunter||counter
+curently||currently
+cylic||cyclic
+dafault||default
+deafult||default
+deamon||daemon
+debouce||debounce
+decendant||descendant
+decendants||descendants
+decompres||decompress
+decsribed||described
+decription||description
+dectected||detected
+defailt||default
+deferal||deferral
+deffered||deferred
+defferred||deferred
+definate||definite
+definately||definitely
+defintion||definition
+defintions||definitions
+defualt||default
+defult||default
+deintializing||deinitializing
+deintialize||deinitialize
+deintialized||deinitialized
+deivce||device
+delared||declared
+delare||declare
+delares||declares
+delaring||declaring
+delemiter||delimiter
+delievered||delivered
+demodualtor||demodulator
+demension||dimension
+dependancies||dependencies
+dependancy||dependency
+dependant||dependent
+dependend||dependent
+depreacted||deprecated
+depreacte||deprecate
+desactivate||deactivate
+desciptor||descriptor
+desciptors||descriptors
+descripto||descriptor
+descripton||description
+descrition||description
+descritptor||descriptor
+desctiptor||descriptor
+desriptor||descriptor
+desriptors||descriptors
+desination||destination
+destionation||destination
+destoried||destroyed
+destory||destroy
+destoryed||destroyed
+destorys||destroys
+destroied||destroyed
+detabase||database
+deteced||detected
+develope||develop
+developement||development
+developped||developed
+developpement||development
+developper||developer
+developpment||development
+deveolpment||development
+devided||divided
+deviece||device
+diable||disable
+dicline||decline
+dictionnary||dictionary
+didnt||didn't
+diferent||different
+differrence||difference
+diffrent||different
+differenciate||differentiate
+diffrentiate||differentiate
+difinition||definition
+digial||digital
+dimention||dimension
+dimesions||dimensions
+dispalying||displaying
+diplay||display
+directon||direction
+direectly||directly
+diregard||disregard
+disassocation||disassociation
+disapear||disappear
+disapeared||disappeared
+disappared||disappeared
+disbale||disable
+disbaled||disabled
+disble||disable
+disbled||disabled
+disconnet||disconnect
+discontinous||discontinuous
+disharge||discharge
+disnabled||disabled
+dispertion||dispersion
+dissapears||disappears
+dissconect||disconnect
+distiction||distinction
+divisable||divisible
+divsiors||divisors
+docuentation||documentation
+documantation||documentation
+documentaion||documentation
+documment||document
+doesnt||doesn't
+donwload||download
+donwloading||downloading
+dorp||drop
+dosen||doesn
+downlad||download
+downlads||downloads
+droped||dropped
+droput||dropout
+druing||during
+dynmaic||dynamic
+eanable||enable
+eanble||enable
+easilly||easily
+ecspecially||especially
+edditable||editable
+editting||editing
+efective||effective
+effectivness||effectiveness
+efficently||efficiently
+ehther||ether
+eigth||eight
+elementry||elementary
+eletronic||electronic
+embeded||embedded
+enabledi||enabled
+enbale||enable
+enble||enable
+enchanced||enhanced
+encorporating||incorporating
+encrupted||encrypted
+encrypiton||encryption
+encryptio||encryption
+endianess||endianness
+enhaced||enhanced
+enlightnment||enlightenment
+enqueing||enqueuing
+entires||entries
+entites||entities
+entrys||entries
+enocded||encoded
+enterily||entirely
+enviroiment||environment
+enviroment||environment
+environement||environment
+environent||environment
+eqivalent||equivalent
+equiped||equipped
+equivelant||equivalent
+equivilant||equivalent
+eror||error
+errorr||error
+estbalishment||establishment
+etsablishment||establishment
+etsbalishment||establishment
+excecutable||executable
+exceded||exceeded
+excellant||excellent
+execeeded||exceeded
+execeeds||exceeds
+exeed||exceed
+exeuction||execution
+existance||existence
+existant||existent
+exixt||exist
+exlcude||exclude
+exlcusive||exclusive
+exmaple||example
+expecially||especially
+experies||expires
+explicite||explicit
+explicitely||explicitly
+explict||explicit
+explictely||explicitly
+explictly||explicitly
+expresion||expression
+exprimental||experimental
+extened||extended
+extensability||extensibility
+extention||extension
+extenstion||extension
+extracter||extractor
+faied||failed
+faield||failed
+falied||failed
+faild||failed
+failded||failed
+failer||failure
+faill||fail
+failied||failed
+faillure||failure
+failue||failure
+failuer||failure
+failng||failing
+faireness||fairness
+falied||failed
+faliure||failure
+fallbck||fallback
+familar||familiar
+fatser||faster
+feauture||feature
+feautures||features
+fetaure||feature
+fetaures||features
+fileystem||filesystem
+fimware||firmware
+firmare||firmware
+firmaware||firmware
+firware||firmware
+finanize||finalize
+findn||find
+finilizes||finalizes
+finsih||finish
+flusing||flushing
+folloing||following
+followign||following
+followings||following
+follwing||following
+fonud||found
+forseeable||foreseeable
+forse||force
+fortan||fortran
+forwardig||forwarding
+frambuffer||framebuffer
+framming||framing
+framwork||framework
+frequncy||frequency
+frequancy||frequency
+frome||from
+fucntion||function
+fuction||function
+fuctions||functions
+fullill||fulfill
+funcation||function
+funcion||function
+functionallity||functionality
+functionaly||functionally
+functionnality||functionality
+functonality||functionality
+funtion||function
+funtions||functions
+furthur||further
+futhermore||furthermore
+futrue||future
+gatable||gateable
+gateing||gating
+gauage||gauge
+gaurenteed||guaranteed
+generiously||generously
+genereate||generate
+genereted||generated
+genric||generic
+globel||global
+grabing||grabbing
+grahical||graphical
+grahpical||graphical
+grapic||graphic
+grranted||granted
+guage||gauge
+guarenteed||guaranteed
+guarentee||guarantee
+halfs||halves
+hander||handler
+handfull||handful
+hanlde||handle
+hanled||handled
+happend||happened
+harware||hardware
+heirarchically||hierarchically
+helpfull||helpful
+hexdecimal||hexadecimal
+hybernate||hibernate
+hierachy||hierarchy
+hierarchie||hierarchy
+homogenous||homogeneous
+howver||however
+hsould||should
+hypervior||hypervisor
+hypter||hyper
+identidier||identifier
+iligal||illegal
+illigal||illegal
+illgal||illegal
+iomaped||iomapped
+imblance||imbalance
+immeadiately||immediately
+immedaite||immediate
+immedate||immediate
+immediatelly||immediately
+immediatly||immediately
+immidiate||immediate
+immutible||immutable
+impelentation||implementation
+impementated||implemented
+implemantation||implementation
+implemenation||implementation
+implementaiton||implementation
+implementated||implemented
+implemention||implementation
+implementd||implemented
+implemetation||implementation
+implemntation||implementation
+implentation||implementation
+implmentation||implementation
+implmenting||implementing
+incative||inactive
+incomming||incoming
+incompatabilities||incompatibilities
+incompatable||incompatible
+incompatble||incompatible
+inconsistant||inconsistent
+increas||increase
+incremeted||incremented
+incrment||increment
+inculde||include
+indendation||indentation
+indended||intended
+independant||independent
+independantly||independently
+independed||independent
+indiate||indicate
+indicat||indicate
+inexpect||inexpected
+inferface||interface
+infomation||information
+informatiom||information
+informations||information
+informtion||information
+infromation||information
+ingore||ignore
+inital||initial
+initalized||initialized
+initalised||initialized
+initalise||initialize
+initalize||initialize
+initation||initiation
+initators||initiators
+initialiazation||initialization
+initializationg||initialization
+initializiation||initialization
+initialze||initialize
+initialzed||initialized
+initialzing||initializing
+initilization||initialization
+initilize||initialize
+initliaze||initialize
+inofficial||unofficial
+inrerface||interface
+insititute||institute
+instace||instance
+instal||install
+instanciate||instantiate
+instanciated||instantiated
+insufficent||insufficient
+inteface||interface
+integreated||integrated
+integrety||integrity
+integrey||integrity
+intendet||intended
+intented||intended
+interanl||internal
+interchangable||interchangeable
+interferring||interfering
+interger||integer
+intermittant||intermittent
+internel||internal
+interoprability||interoperability
+interuupt||interrupt
+interupt||interrupt
+interupts||interrupts
+interrface||interface
+interrrupt||interrupt
+interrup||interrupt
+interrups||interrupts
+interruptted||interrupted
+interupted||interrupted
+interupt||interrupt
+intial||initial
+intialisation||initialisation
+intialised||initialised
+intialise||initialise
+intialization||initialization
+intialized||initialized
+intialize||initialize
+intregral||integral
+intrerrupt||interrupt
+intrrupt||interrupt
+intterrupt||interrupt
+intuative||intuitive
+inavlid||invalid
+invaid||invalid
+invaild||invalid
+invailid||invalid
+invald||invalid
+invalde||invalid
+invalide||invalid
+invalidiate||invalidate
+invalud||invalid
+invididual||individual
+invokation||invocation
+invokations||invocations
+ireelevant||irrelevant
+irrelevent||irrelevant
+isnt||isn't
+isssue||issue
+issus||issues
+iternations||iterations
+itertation||iteration
+itslef||itself
+jave||java
+jeffies||jiffies
+jumpimng||jumping
+juse||just
+jus||just
+kown||known
+langage||language
+langauage||language
+langauge||language
+langugage||language
+lauch||launch
+layed||laid
+legnth||length
+leightweight||lightweight
+lengh||length
+lenght||length
+lenth||length
+lesstiff||lesstif
+libaries||libraries
+libary||library
+librairies||libraries
+libraris||libraries
+licenceing||licencing
+logaritmic||logarithmic
+loggging||logging
+loggin||login
+logile||logfile
+loobpack||loopback
+loosing||losing
+losted||lost
+machinary||machinery
+maibox||mailbox
+maintainance||maintenance
+maintainence||maintenance
+maintan||maintain
+makeing||making
+mailformed||malformed
+malplaced||misplaced
+malplace||misplace
+managable||manageable
+managment||management
+mangement||management
+manoeuvering||maneuvering
+manufaucturing||manufacturing
+mappping||mapping
+matchs||matches
+mathimatical||mathematical
+mathimatic||mathematic
+mathimatics||mathematics
+maximium||maximum
+maxium||maximum
+mechamism||mechanism
+meetign||meeting
+memeory||memory
+memmber||member
+memoery||memory
+ment||meant
+mergable||mergeable
+mesage||message
+messags||messages
+messgaes||messages
+messsage||message
+messsages||messages
+metdata||metadata
+micropone||microphone
+microprocesspr||microprocessor
+migrateable||migratable
+milliseonds||milliseconds
+minium||minimum
+minimam||minimum
+miniumum||minimum
+minumum||minimum
+misalinged||misaligned
+miscelleneous||miscellaneous
+misformed||malformed
+mispelled||misspelled
+mispelt||misspelt
+mising||missing
+mismactch||mismatch
+missign||missing
+missmanaged||mismanaged
+missmatch||mismatch
+misssing||missing
+miximum||maximum
+mmnemonic||mnemonic
+mnay||many
+modfiy||modify
+modulues||modules
+momery||memory
+memomry||memory
+monochorome||monochrome
+monochromo||monochrome
+monocrome||monochrome
+mopdule||module
+mroe||more
+mulitplied||multiplied
+multidimensionnal||multidimensional
+multipe||multiple
+multple||multiple
+mumber||number
+muticast||multicast
+mutilcast||multicast
+mutiple||multiple
+mutli||multi
+nams||names
+navagating||navigating
+nead||need
+neccecary||necessary
+neccesary||necessary
+neccessary||necessary
+necesary||necessary
+neded||needed
+negaive||negative
+negoitation||negotiation
+negotation||negotiation
+nerver||never
+nescessary||necessary
+nessessary||necessary
+noticable||noticeable
+notications||notifications
+notifcations||notifications
+notifed||notified
+notity||notify
+numebr||number
+numner||number
+obtaion||obtain
+obusing||abusing
+occassionally||occasionally
+occationally||occasionally
+occurance||occurrence
+occurances||occurrences
+occured||occurred
+occurence||occurrence
+occure||occurred
+occured||occurred
+occuring||occurring
+offser||offset
+offet||offset
+offlaod||offload
+offloded||offloaded
+offseting||offsetting
+omited||omitted
+omiting||omitting
+omitt||omit
+ommiting||omitting
+ommitted||omitted
+onself||oneself
+ony||only
+operatione||operation
+opertaions||operations
+optionnal||optional
+optmizations||optimizations
+orientatied||orientated
+orientied||oriented
+orignal||original
+originial||original
+otherise||otherwise
+ouput||output
+oustanding||outstanding
+overaall||overall
+overhread||overhead
+overlaping||overlapping
+overide||override
+overrided||overridden
+overriden||overridden
+overun||overrun
+overwritting||overwriting
+overwriten||overwritten
+pacakge||package
+pachage||package
+packacge||package
+packege||package
+packge||package
+packtes||packets
+pakage||package
+paket||packet
+pallette||palette
+paln||plan
+paramameters||parameters
+paramaters||parameters
+paramater||parameter
+parametes||parameters
+parametised||parametrised
+paramter||parameter
+paramters||parameters
+parmaters||parameters
+particuarly||particularly
+particularily||particularly
+partion||partition
+partions||partitions
+partiton||partition
+pased||passed
+passin||passing
+pathes||paths
+pecularities||peculiarities
+peformance||performance
+peforming||performing
+peice||piece
+pendantic||pedantic
+peprocessor||preprocessor
+perfoming||performing
+perfomring||performing
+peripherial||peripheral
+permissons||permissions
+peroid||period
+persistance||persistence
+persistant||persistent
+phoneticly||phonetically
+plalform||platform
+platfoem||platform
+platfrom||platform
+plattform||platform
+pleaes||please
+ploting||plotting
+plugable||pluggable
+poinnter||pointer
+pointeur||pointer
+poiter||pointer
+posible||possible
+positon||position
+possibilites||possibilities
+potocol||protocol
+powerfull||powerful
+pramater||parameter
+preamle||preamble
+preample||preamble
+preapre||prepare
+preceeded||preceded
+preceeding||preceding
+preceed||precede
+precendence||precedence
+precission||precision
+preemptable||preemptible
+prefered||preferred
+prefferably||preferably
+premption||preemption
+prepaired||prepared
+preperation||preparation
+pressre||pressure
+primative||primitive
+princliple||principle
+priorty||priority
+privilaged||privileged
+privilage||privilege
+priviledge||privilege
+priviledges||privileges
+probaly||probably
+procceed||proceed
+proccesors||processors
+procesed||processed
+proces||process
+procesing||processing
+processessing||processing
+processess||processes
+processpr||processor
+processsed||processed
+processsing||processing
+procteted||protected
+prodecure||procedure
+progams||programs
+progess||progress
+programers||programmers
+programm||program
+programms||programs
+progresss||progress
+prohibitted||prohibited
+prohibitting||prohibiting
+promiscous||promiscuous
+promps||prompts
+pronnounced||pronounced
+prononciation||pronunciation
+pronouce||pronounce
+pronunce||pronounce
+propery||property
+propigate||propagate
+propigation||propagation
+propogate||propagate
+prosess||process
+protable||portable
+protcol||protocol
+protecion||protection
+protedcted||protected
+protocoll||protocol
+promixity||proximity
+psudo||pseudo
+psuedo||pseudo
+psychadelic||psychedelic
+pwoer||power
+queing||queuing
+quering||querying
+queus||queues
+randomally||randomly
+raoming||roaming
+reasearcher||researcher
+reasearchers||researchers
+reasearch||research
+receieve||receive
+recepient||recipient
+recevied||received
+receving||receiving
+recieved||received
+recieve||receive
+reciever||receiver
+recieves||receives
+recogniced||recognised
+recognizeable||recognizable
+recommanded||recommended
+recyle||recycle
+redircet||redirect
+redirectrion||redirection
+redundacy||redundancy
+reename||rename
+refcounf||refcount
+refence||reference
+refered||referred
+referenace||reference
+refering||referring
+refernces||references
+refernnce||reference
+refrence||reference
+registed||registered
+registerd||registered
+registeration||registration
+registeresd||registered
+registerred||registered
+registes||registers
+registraration||registration
+regsiter||register
+regster||register
+regualar||regular
+reguator||regulator
+regulamentations||regulations
+reigstration||registration
+releated||related
+relevent||relevant
+reloade||reload
+remoote||remote
+remore||remote
+removeable||removable
+repectively||respectively
+replacable||replaceable
+replacments||replacements
+replys||replies
+reponse||response
+representaion||representation
+reqeust||request
+requestied||requested
+requiere||require
+requirment||requirement
+requred||required
+requried||required
+requst||request
+reregisteration||reregistration
+reseting||resetting
+reseved||reserved
+reseverd||reserved
+resizeable||resizable
+resouce||resource
+resouces||resources
+resoures||resources
+responce||response
+resrouce||resource
+ressizes||resizes
+ressource||resource
+ressources||resources
+restesting||retesting
+resumbmitting||resubmitting
+retransmited||retransmitted
+retreived||retrieved
+retreive||retrieve
+retreiving||retrieving
+retrive||retrieve
+retrived||retrieved
+retrun||return
+retun||return
+retuned||returned
+reudce||reduce
+reuest||request
+reuqest||request
+reutnred||returned
+revsion||revision
+rmeoved||removed
+rmeove||remove
+rmeoves||removes
+rountine||routine
+routins||routines
+rquest||request
+runing||running
+runned||ran
+runnning||running
+runtine||runtime
+sacrifying||sacrificing
+safly||safely
+safty||safety
+savable||saveable
+scaleing||scaling
+scaned||scanned
+scaning||scanning
+scarch||search
+schdule||schedule
+seach||search
+searchs||searches
+secquence||sequence
+secund||second
+segement||segment
+semaphone||semaphore
+senario||scenario
+senarios||scenarios
+sentivite||sensitive
+separatly||separately
+sepcify||specify
+seperated||separated
+seperately||separately
+seperate||separate
+seperatly||separately
+seperator||separator
+sepperate||separate
+seqeunce||sequence
+seqeuncer||sequencer
+seqeuencer||sequencer
+sequece||sequence
+sequencial||sequential
+serveral||several
+servive||service
+setts||sets
+settting||setting
+shotdown||shutdown
+shoud||should
+shouldnt||shouldn't
+shoule||should
+shrinked||shrunk
+siginificantly||significantly
+signabl||signal
+similary||similarly
+similiar||similar
+simlar||similar
+simliar||similar
+simpified||simplified
+singaled||signaled
+singal||signal
+singed||signed
+sleeped||slept
+sliped||slipped
+softwares||software
+speach||speech
+specfic||specific
+specfield||specified
+speciefied||specified
+specifc||specific
+specifed||specified
+specificatin||specification
+specificaton||specification
+specifing||specifying
+specifiying||specifying
+speficied||specified
+speicify||specify
+speling||spelling
+spinlcok||spinlock
+spinock||spinlock
+splitted||split
+spreaded||spread
+spurrious||spurious
+sructure||structure
+stablilization||stabilization
+staically||statically
+staion||station
+standardss||standards
+standartization||standardization
+standart||standard
+standy||standby
+stardard||standard
+staticly||statically
+statuss||status
+stoped||stopped
+stoping||stopping
+stoppped||stopped
+straming||streaming
+struc||struct
+structres||structures
+stuct||struct
+strucuture||structure
+stucture||structure
+sturcture||structure
+subdirectoires||subdirectories
+suble||subtle
+substract||subtract
+submition||submission
+suceed||succeed
+succesfully||successfully
+succesful||successful
+successed||succeeded
+successfull||successful
+successfuly||successfully
+sucessfully||successfully
+sucess||success
+superflous||superfluous
+superseeded||superseded
+suplied||supplied
+suported||supported
+suport||support
+supportet||supported
+suppored||supported
+supportin||supporting
+suppoted||supported
+suppported||supported
+suppport||support
+supress||suppress
+surpressed||suppressed
+surpresses||suppresses
+susbsystem||subsystem
+suspeneded||suspended
+suspsend||suspend
+suspicously||suspiciously
+swaping||swapping
+switchs||switches
+swith||switch
+swithable||switchable
+swithc||switch
+swithced||switched
+swithcing||switching
+swithed||switched
+swithing||switching
+swtich||switch
+symetric||symmetric
+synax||syntax
+synchonized||synchronized
+synchronuously||synchronously
+syncronize||synchronize
+syncronized||synchronized
+syncronizing||synchronizing
+syncronus||synchronous
+syste||system
+sytem||system
+sythesis||synthesis
+taht||that
+tansmit||transmit
+targetted||targeted
+targetting||targeting
+taskelt||tasklet
+teh||the
+temorary||temporary
+temproarily||temporarily
+temperture||temperature
+thead||thread
+therfore||therefore
+thier||their
+threds||threads
+threshhold||threshold
+thresold||threshold
+throught||through
+trackling||tracking
+troughput||throughput
+thses||these
+tiggers||triggers
+tiggered||triggered
+tipically||typically
+timeing||timing
+timout||timeout
+tmis||this
+toogle||toggle
+torerable||tolerable
+traking||tracking
+tramsmitted||transmitted
+tramsmit||transmit
+tranasction||transaction
+tranfer||transfer
+transcevier||transceiver
+transciever||transceiver
+transferd||transferred
+transfered||transferred
+transfering||transferring
+transision||transition
+transmittd||transmitted
+transormed||transformed
+trasfer||transfer
+trasmission||transmission
+treshold||threshold
+trigerred||triggered
+trigerring||triggering
+trun||turn
+tunning||tuning
+ture||true
+tyep||type
+udpate||update
+uesd||used
+uknown||unknown
+usupported||unsupported
+uncommited||uncommitted
+unconditionaly||unconditionally
+undeflow||underflow
+underun||underrun
+unecessary||unnecessary
+unexecpted||unexpected
+unexepected||unexpected
+unexpcted||unexpected
+unexpectd||unexpected
+unexpeted||unexpected
+unexpexted||unexpected
+unfortunatelly||unfortunately
+unifiy||unify
+uniterrupted||uninterrupted
+unintialized||uninitialized
+unitialized||uninitialized
+unkmown||unknown
+unknonw||unknown
+unknow||unknown
+unkown||unknown
+unamed||unnamed
+uneeded||unneeded
+unneded||unneeded
+unneccecary||unnecessary
+unneccesary||unnecessary
+unneccessary||unnecessary
+unnecesary||unnecessary
+unneedingly||unnecessarily
+unnsupported||unsupported
+unmached||unmatched
+unregester||unregister
+unresgister||unregister
+unrgesiter||unregister
+unsinged||unsigned
+unstabel||unstable
+unsolicitied||unsolicited
+unsuccessfull||unsuccessful
+unsuported||unsupported
+untill||until
+unuseful||useless
+unvalid||invalid
+upate||update
+upsupported||unsupported
+usefule||useful
+usefull||useful
+usege||usage
+usera||users
+usualy||usually
+usupported||unsupported
+utilites||utilities
+utillities||utilities
+utilties||utilities
+utiltity||utility
+utitity||utility
+utitlty||utility
+vaid||valid
+vaild||valid
+valide||valid
+variantions||variations
+varible||variable
+varient||variant
+vaule||value
+verbse||verbose
+veify||verify
+verisons||versions
+verison||version
+verson||version
+vicefersa||vice-versa
+virtal||virtual
+virtaul||virtual
+virtiual||virtual
+visiters||visitors
+vitual||virtual
+vunerable||vulnerable
+wakeus||wakeups
+wathdog||watchdog
+wating||waiting
+wiat||wait
+wether||whether
+whataver||whatever
+whcih||which
+whenver||whenever
+wheter||whether
+whe||when
+wierd||weird
+wiil||will
+wirte||write
+withing||within
+wnat||want
+workarould||workaround
+writeing||writing
+writting||writing
+wtih||with
+zombe||zombie
+zomebie||zombie
diff --git a/sim.c b/sim.c
index c503b27..6bb0f4c 100644
--- a/sim.c
+++ b/sim.c
@@ -23,17 +23,13 @@
#define LOG_TAG "RIL"
#include <utils/Log.h>
+#include <ril-versions-compat.h>
#include <samsung-ril.h>
#include <utils.h>
#include <sim.h>
-#if RIL_VERSION >= 6
-RIL_RadioState ipc2ril_sec_pin_status_response(struct ipc_sec_pin_status_response_data *data,
- RIL_CardStatus_v6 *card_status)
-#else
-RIL_RadioState ipc2ril_sec_pin_status_response(struct ipc_sec_pin_status_response_data *data,
- RIL_CardStatus *card_status)
-#endif
+enum sim_state ipc2ril_sec_pin_status_response(struct ipc_sec_pin_status_response_data *data,
+ RIL_CardStatus_compat *card_status)
{
RIL_AppStatus app_statuses[] = {
// Absent
@@ -57,12 +53,12 @@ RIL_RadioState ipc2ril_sec_pin_status_response(struct ipc_sec_pin_status_respons
// Perso service provider
{ RIL_APPTYPE_SIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER, NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
};
- RIL_RadioState radio_state;
+ enum sim_state sim_state;
unsigned int index;
unsigned int count;
if (data == NULL || card_status == NULL)
- return 0;
+ return SIM_STATE_ERROR;
count = sizeof(app_statuses) / sizeof(RIL_AppStatus);
@@ -117,20 +113,16 @@ RIL_RadioState ipc2ril_sec_pin_status_response(struct ipc_sec_pin_status_respons
switch (index) {
case 1:
- radio_state = RADIO_STATE_SIM_NOT_READY;
+ sim_state = SIM_STATE_NOT_READY;
break;
case 2:
- radio_state = RADIO_STATE_SIM_READY;
+ sim_state = SIM_STATE_READY;
break;
default:
- radio_state = RADIO_STATE_SIM_LOCKED_OR_ABSENT;
- }
+ sim_state = SIM_STATE_LOCKED_OR_ABSENT;
+ }
-#if RIL_VERSION >= 6
- memset(card_status, 0, sizeof(RIL_CardStatus_v6));
-#else
- memset(card_status, 0, sizeof(RIL_CardStatus));
-#endif
+ memset(card_status, 0, sizeof(RIL_CardStatus_compat));
if (index == 0)
card_status->card_state = RIL_CARDSTATE_ABSENT;
@@ -151,7 +143,7 @@ RIL_RadioState ipc2ril_sec_pin_status_response(struct ipc_sec_pin_status_respons
RIL_LOGD("%s: Selecting status application %d on %d", __func__, index, count);
- return radio_state;
+ return sim_state;
}
unsigned char ril2ipc_sec_facility_type(char *facility)
@@ -201,25 +193,21 @@ int ipc_sec_pin_status(struct ipc_message *message)
{
struct ipc_sec_pin_status_response_data *data;
struct ipc_sec_pin_status_request_data request_data;
-#if RIL_VERSION >= 6
- RIL_CardStatus_v6 card_status;
-#else
- RIL_CardStatus card_status;
-#endif
- RIL_RadioState radio_state;
+ RIL_CardStatus_compat card_status;
+ enum sim_state sim_state;
int rc;
if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_sec_pin_status_response_data))
return -1;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return 0;
data = (struct ipc_sec_pin_status_response_data *) message->data;
- radio_state = ipc2ril_sec_pin_status_response(data, &card_status);
- if (radio_state == 0)
+ sim_state = ipc2ril_sec_pin_status_response(data, &card_status);
+ if (sim_state == SIM_STATE_ERROR)
return 0;
if (card_status.applications[0].app_type == RIL_APPTYPE_SIM && card_status.applications[0].app_state == RIL_APPSTATE_PIN && ril_data->sim_pin != NULL) {
@@ -245,7 +233,7 @@ int ipc_sec_pin_status(struct ipc_message *message)
}
- ril_radio_state_update(radio_state);
+ ril_sim_state_update(sim_state);
if (message->type == IPC_TYPE_RESP && ipc_seq_valid(message->aseq)) {
ril_request_complete(ipc_fmt_request_token(message->aseq), RIL_E_SUCCESS, (void *) &card_status, sizeof(card_status));
@@ -263,15 +251,10 @@ int ril_request_get_sim_status(__attribute__((unused)) void *data,
{
void *card_status_data;
size_t card_status_size;
-#if RIL_VERSION >= 6
- RIL_CardStatus_v6 *card_status;
-#else
- RIL_CardStatus *card_status;
-#endif
struct ril_request *request;
int rc;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -282,13 +265,7 @@ int ril_request_get_sim_status(__attribute__((unused)) void *data,
card_status_size = ril_request_data_size_get(RIL_REQUEST_GET_SIM_STATUS);
card_status_data = ril_request_data_get(RIL_REQUEST_GET_SIM_STATUS);
-#if RIL_VERSION >= 6
- if (card_status_data != NULL && card_status_size >= sizeof(RIL_CardStatus_v6)) {
- card_status = (RIL_CardStatus_v6 *) ril_request_data_get(RIL_REQUEST_GET_SIM_STATUS);
-#else
- if (card_status_data != NULL && card_status_size >= sizeof(RIL_CardStatus)) {
- card_status = (RIL_CardStatus *) ril_request_data_get(RIL_REQUEST_GET_SIM_STATUS);
-#endif
+ if (card_status_data != NULL && card_status_size >= sizeof(RIL_CardStatus_compat)) {
ril_request_complete(token, RIL_E_SUCCESS, card_status_data, card_status_size);
free(card_status_data);
@@ -334,7 +311,7 @@ int ril_request_query_facility_lock(void *data, size_t size, RIL_Token token)
if (data == NULL || size < 4 * sizeof(char *))
goto error;
- rc = ril_radio_state_check(RADIO_STATE_SIM_READY);
+ rc = ril_sim_has_reached_state(SIM_STATE_READY);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -368,7 +345,7 @@ complete:
int ipc_sec_callback(struct ipc_message *message)
{
- struct ipc_sec_lock_infomation_request_data request_data;
+ struct ipc_sec_lock_information_request_data request_data;
struct ipc_gen_phone_res_data *data;
struct ril_request *request = NULL;
void *request_complete_data;
@@ -392,13 +369,13 @@ int ipc_sec_callback(struct ipc_message *message)
ril_request_data_set_uniq(request->request, (void *) data, sizeof(struct ipc_gen_phone_res_data));
- rc = ipc_sec_lock_infomation_setup(&request_data, IPC_SEC_PIN_TYPE_PIN1);
+ rc = ipc_sec_lock_information_setup(&request_data, IPC_SEC_PIN_TYPE_PIN1);
if (rc < 0) {
ril_request_data_free(request->request);
goto error;
}
- rc = ipc_fmt_send(message->aseq, IPC_SEC_LOCK_INFOMATION, IPC_TYPE_GET, (void *) &request_data, sizeof(request_data));
+ rc = ipc_fmt_send(message->aseq, IPC_SEC_LOCK_INFORMATION, IPC_TYPE_GET, (void *) &request_data, sizeof(request_data));
if (rc < 0) {
ril_request_data_free(request->request);
goto error;
@@ -408,13 +385,13 @@ int ipc_sec_callback(struct ipc_message *message)
ril_request_data_set_uniq(request->request, (void *) data, sizeof(struct ipc_gen_phone_res_data));
- rc = ipc_sec_lock_infomation_setup(&request_data, IPC_SEC_PIN_TYPE_PIN2);
+ rc = ipc_sec_lock_information_setup(&request_data, IPC_SEC_PIN_TYPE_PIN2);
if (rc < 0) {
ril_request_data_free(request->request);
goto error;
}
- rc = ipc_fmt_send(message->aseq, IPC_SEC_LOCK_INFOMATION, IPC_TYPE_GET, (void *) &request_data, sizeof(request_data));
+ rc = ipc_fmt_send(message->aseq, IPC_SEC_LOCK_INFORMATION, IPC_TYPE_GET, (void *) &request_data, sizeof(request_data));
if (rc < 0) {
ril_request_data_free(request->request);
goto error;
@@ -451,20 +428,20 @@ int ipc_sec_callback(struct ipc_message *message)
ril_request_data_set_uniq(RIL_REQUEST_SET_FACILITY_LOCK, (void *) data, sizeof(struct ipc_gen_phone_res_data));
if (facility_type == IPC_SEC_FACILITY_TYPE_FD) {
- rc = ipc_sec_lock_infomation_setup(&request_data, IPC_SEC_PIN_TYPE_PIN2);
+ rc = ipc_sec_lock_information_setup(&request_data, IPC_SEC_PIN_TYPE_PIN2);
if (rc < 0) {
ril_request_data_free(request->request);
goto error;
}
} else {
- rc = ipc_sec_lock_infomation_setup(&request_data, IPC_SEC_PIN_TYPE_PIN1);
+ rc = ipc_sec_lock_information_setup(&request_data, IPC_SEC_PIN_TYPE_PIN1);
if (rc < 0) {
ril_request_data_free(request->request);
goto error;
}
}
- rc = ipc_fmt_send(message->aseq, IPC_SEC_LOCK_INFOMATION, IPC_TYPE_GET, (void *) &request_data, sizeof(request_data));
+ rc = ipc_fmt_send(message->aseq, IPC_SEC_LOCK_INFORMATION, IPC_TYPE_GET, (void *) &request_data, sizeof(request_data));
if (rc < 0) {
ril_request_data_free(request->request);
goto error;
@@ -533,7 +510,7 @@ int ril_request_set_facility_lock(void *data, size_t size, RIL_Token token)
if (data == NULL || size < 4 * sizeof(char *))
goto error;
- rc = ril_radio_state_check(RADIO_STATE_SIM_READY);
+ rc = ril_sim_has_reached_state(SIM_STATE_READY);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -611,7 +588,7 @@ int ril_request_enter_sim_pin(void *data, size_t size, RIL_Token token)
if (data == NULL || size < 2 * sizeof(char *) || ril_data == NULL)
goto error;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -668,7 +645,7 @@ int ril_request_enter_sim_puk(void *data, size_t size, RIL_Token token)
if (data == NULL || size < 2 * sizeof(char *))
goto error;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -718,7 +695,7 @@ int ril_request_enter_sim_pin2(void *data, size_t size, RIL_Token token)
if (data == NULL || size < 2 * sizeof(char *))
goto error;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -768,7 +745,7 @@ int ril_request_enter_sim_puk2(void *data, size_t size, RIL_Token token)
if (data == NULL || size < 2 * sizeof(char *))
goto error;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -822,7 +799,7 @@ int ril_request_change_sim_pin(void *data, size_t size, RIL_Token token)
if (request != NULL)
return RIL_REQUEST_UNHANDLED;
- rc = ril_radio_state_check(RADIO_STATE_SIM_READY);
+ rc = ril_sim_has_reached_state(SIM_STATE_READY);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -872,7 +849,7 @@ int ril_request_change_sim_pin2(void *data, size_t size, RIL_Token token)
if (request != NULL)
return RIL_REQUEST_UNHANDLED;
- rc = ril_radio_state_check(RADIO_STATE_SIM_READY);
+ rc = ril_sim_has_reached_state(SIM_STATE_READY);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -911,20 +888,11 @@ complete:
int ipc_sec_rsim_access(struct ipc_message *message)
{
struct ipc_sec_rsim_access_response_header *header;
- struct ipc_sec_rsim_access_usim_response_header *usim_header;
- struct sim_file_response sim_file_response;
struct ril_request *request;
struct ril_client *client;
struct ipc_fmt_data *ipc_fmt_data;
RIL_SIM_IO_Response response;
-#if RIL_VERSION >= 6
- RIL_SIM_IO_v6 *sim_io;
-#else
- RIL_SIM_IO *sim_io;
-#endif
- unsigned char *p;
- unsigned int offset;
- unsigned int i;
+ RIL_SIM_IO_compat *sim_io;
void *data;
size_t size;
@@ -946,18 +914,11 @@ int ipc_sec_rsim_access(struct ipc_message *message)
data = ipc_sec_rsim_access_extract(message->data, message->size);
request = ril_request_find_token(ipc_fmt_request_token(message->aseq));
-#if RIL_VERSION >= 6
- if (request == NULL || request->data == NULL || request->size < sizeof(RIL_SIM_IO_v6))
-#else
- if (request == NULL || request->data == NULL || request->size < sizeof(RIL_SIM_IO))
-#endif
+
+ if (request == NULL || request->data == NULL || request->size < sizeof(RIL_SIM_IO_compat))
return 0;
-#if RIL_VERSION >= 6
- sim_io = (RIL_SIM_IO_v6 *) request->data;
-#else
- sim_io = (RIL_SIM_IO *) request->data;
-#endif
+ sim_io = (RIL_SIM_IO_compat *) request->data;
memset(&response, 0, sizeof(response));
response.sw1 = header->sw1;
@@ -966,86 +927,11 @@ int ipc_sec_rsim_access(struct ipc_message *message)
switch (sim_io->command) {
case SIM_COMMAND_READ_BINARY:
case SIM_COMMAND_READ_RECORD:
- if (header->length == 0)
- break;
-
- response.simResponse = data2string(data, header->length);
- break;
case SIM_COMMAND_GET_RESPONSE:
if (header->length == 0)
break;
- if (ipc_fmt_data->sim_icc_type_data.type == 0x01) {
- response.simResponse = data2string(data, header->length);
- break;
- }
-
- if (header->length < sizeof(struct ipc_sec_rsim_access_usim_response_header))
- break;
-
- usim_header = (struct ipc_sec_rsim_access_usim_response_header *) data;
-
- memset(&sim_file_response, 0, sizeof(sim_file_response));
-
- offset = sizeof(struct ipc_sec_rsim_access_usim_response_header) + usim_header->offset;
- if (offset > header->length)
- break;
-
- offset = usim_header->offset - 2;
- p = (unsigned char *) usim_header + offset;
-
- sim_file_response.file_id[0] = p[0];
- sim_file_response.file_id[1] = p[1];
-
- offset = header->length - 2;
- p = (unsigned char *) usim_header;
-
- while (offset > 2) {
- if (p[offset] == 0x88) {
- offset -= 2;
- break;
- }
-
- offset--;
- }
-
- if (offset <= 2)
- break;
-
- p = (unsigned char *) usim_header + offset;
-
- sim_file_response.file_size[0] = p[0];
- sim_file_response.file_size[1] = p[1];
-
- // Fallback to EF
- sim_file_response.file_type = SIM_FILE_TYPE_EF;
- for (i = 0; i < sim_file_ids_count; i++) {
- if (sim_io->fileid == sim_file_ids[i].file_id) {
- sim_file_response.file_type = sim_file_ids[i].type;
- break;
- }
- }
-
- sim_file_response.access_condition[0] = 0x00;
- sim_file_response.access_condition[1] = 0xff;
- sim_file_response.access_condition[2] = 0xff;
-
- sim_file_response.file_status = 0x01;
- sim_file_response.file_length = 0x02;
-
- switch (usim_header->file_structure) {
- case IPC_SEC_RSIM_FILE_STRUCTURE_TRANSPARENT:
- sim_file_response.file_structure = SIM_FILE_STRUCTURE_TRANSPARENT;
- break;
- case IPC_SEC_RSIM_FILE_STRUCTURE_LINEAR_FIXED:
- default:
- sim_file_response.file_structure = SIM_FILE_STRUCTURE_LINEAR_FIXED;
- break;
- }
-
- sim_file_response.record_length = usim_header->length;
-
- response.simResponse = data2string((void *) &sim_file_response, sizeof(sim_file_response));
+ response.simResponse = data2string(data, header->length);
break;
case SIM_COMMAND_UPDATE_BINARY:
case SIM_COMMAND_UPDATE_RECORD:
@@ -1068,11 +954,7 @@ int ril_request_sim_io(void *data, size_t size, RIL_Token token)
struct ipc_sec_rsim_access_request_header request_header;
struct ipc_sec_pin_status_request_data pin_request_data;
struct ril_request *request;
-#if RIL_VERSION >= 6
- RIL_SIM_IO_v6 *sim_io = NULL;
-#else
- RIL_SIM_IO *sim_io = NULL;
-#endif
+ RIL_SIM_IO_compat *sim_io = NULL;
void *sim_io_data = NULL;
size_t sim_io_size = 0;
void *request_data = NULL;
@@ -1080,16 +962,12 @@ int ril_request_sim_io(void *data, size_t size, RIL_Token token)
int pin_request = 0;
int rc;
-#if RIL_VERSION >= 6
- if (data == NULL || size < sizeof(RIL_SIM_IO_v6))
-#else
- if (data == NULL || size < sizeof(RIL_SIM_IO))
-#endif
+ if (data == NULL || size < sizeof(RIL_SIM_IO_compat))
goto error;
- rc = ril_radio_state_check(RADIO_STATE_SIM_READY);
+ rc = ril_sim_has_reached_state(SIM_STATE_READY);
if (rc < 0) {
- rc = ril_radio_state_check(RADIO_STATE_SIM_LOCKED_OR_ABSENT);
+ rc = ril_sim_has_reached_state(SIM_STATE_LOCKED_OR_ABSENT);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
else
@@ -1100,11 +978,7 @@ int ril_request_sim_io(void *data, size_t size, RIL_Token token)
if (request != NULL)
return RIL_REQUEST_UNHANDLED;
-#if RIL_VERSION >= 6
- sim_io = (RIL_SIM_IO_v6 *) data;
-#else
- sim_io = (RIL_SIM_IO *) data;
-#endif
+ sim_io = (RIL_SIM_IO_compat *) data;
if (sim_io->data != NULL) {
sim_io_size = string2data_size(sim_io->data);
@@ -1241,7 +1115,7 @@ int ipc_sec_sim_icc_type(struct ipc_message *message)
int ipc_sec_lock_infomation(struct ipc_message *message)
{
- struct ipc_sec_lock_infomation_response_data *data;
+ struct ipc_sec_lock_information_response_data *data;
struct ipc_gen_phone_res_data *gen_phone_res;
int requests[] = { RIL_REQUEST_ENTER_SIM_PIN, RIL_REQUEST_CHANGE_SIM_PIN, RIL_REQUEST_ENTER_SIM_PIN2, RIL_REQUEST_CHANGE_SIM_PIN2, RIL_REQUEST_SET_FACILITY_LOCK };
void *gen_phone_res_data = NULL;
@@ -1251,17 +1125,17 @@ int ipc_sec_lock_infomation(struct ipc_message *message)
unsigned int i;
int rc;
- if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_sec_lock_infomation_response_data))
+ if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_sec_lock_information_response_data))
return -1;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return 0;
if (message->type != IPC_TYPE_RESP || !ipc_seq_valid(message->aseq))
return 0;
- data = (struct ipc_sec_lock_infomation_response_data *) message->data;
+ data = (struct ipc_sec_lock_information_response_data *) message->data;
if (data->type != IPC_SEC_PIN_TYPE_PIN1 && data->type != IPC_SEC_PIN_TYPE_PIN2)
return 0;
diff --git a/sms.c b/sms.c
index 1c5d302..373811d 100644
--- a/sms.c
+++ b/sms.c
@@ -205,7 +205,7 @@ int ril_request_send_sms(void *data, size_t size, RIL_Token token)
if (data == NULL || size < 2 * sizeof(char *))
goto error;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -345,7 +345,7 @@ int ril_request_write_sms_to_sim(void *data, size_t size, RIL_Token token)
if (data == NULL || size < sizeof(RIL_SMS_WriteArgs))
goto error;
- rc = ril_radio_state_check(RADIO_STATE_SIM_READY);
+ rc = ril_sim_has_reached_state(SIM_STATE_READY);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -528,7 +528,7 @@ int ril_request_sms_acknowledge(void *data, size_t size, RIL_Token token)
if (data == NULL || size < 2 * sizeof(int))
goto error;
- rc = ril_radio_state_check(RADIO_STATE_SIM_READY);
+ rc = ril_sim_has_reached_state(SIM_STATE_READY);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
diff --git a/srs-client/srs-client.c b/srs-client/srs-client.c
index d16c597..6f3b467 100644
--- a/srs-client/srs-client.c
+++ b/srs-client/srs-client.c
@@ -270,8 +270,6 @@ int srs_client_send(struct srs_client *client, unsigned short command,
if (client == NULL || client->fd < 0)
return -1;
- SRS_CLIENT_LOCK(client);
-
memset(&message, 0, sizeof(message));
message.command = command;
message.data = data;
@@ -288,6 +286,8 @@ int srs_client_send(struct srs_client *client, unsigned short command,
memcpy(p, message.data, message.size);
}
+ SRS_CLIENT_LOCK(client);
+
memset(&timeout, 0, sizeof(timeout));
timeout.tv_usec = 300;
diff --git a/srs.c b/srs.c
index 4a11564..cae57cc 100644
--- a/srs.c
+++ b/srs.c
@@ -17,26 +17,28 @@
* along with Samsung-RIL. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
+#include <signal.h>
+#include <stdlib.h>
+
+#include <sys/eventfd.h>
+#include <sys/select.h>
+#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
-#include <sys/socket.h>
#include <sys/un.h>
-#include <sys/select.h>
-#include <sys/eventfd.h>
#include <arpa/inet.h>
-#include <netinet/in.h>
#include <cutils/sockets.h>
+#include <netinet/in.h>
#define LOG_TAG "RIL-SRS"
#include <utils/Log.h>
#include <hardware_legacy/power.h>
-#include <samsung-ril.h>
-#include <utils.h>
+#include "samsung-ril.h"
+#include "utils.h"
/*
* Utils
@@ -465,7 +467,6 @@ int srs_client_send(struct ril_client *client, struct srs_message *message)
if (data->client_fd < 0)
return -1;
- RIL_CLIENT_LOCK(client);
srs_header_setup(&header, message);
@@ -478,6 +479,8 @@ int srs_client_send(struct ril_client *client, struct srs_message *message)
memcpy(p, message->data, message->size);
}
+ RIL_CLIENT_LOCK(client);
+
srs_log_send(client, message);
memset(&timeout, 0, sizeof(timeout));
diff --git a/ss.c b/ss.c
index 49f3152..4d89fde 100644
--- a/ss.c
+++ b/ss.c
@@ -18,6 +18,9 @@
* along with Samsung-RIL. If not, see <http://www.gnu.org/licenses/>.
*/
+#define _GNU_SOURCE
+#include <stdio.h>
+
#define LOG_TAG "RIL-SS"
#include <utils/Log.h>
@@ -121,7 +124,7 @@ int ril_request_send_ussd(void *data, size_t size, RIL_Token token)
if (data == NULL || size < sizeof(char *))
goto error;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -214,12 +217,14 @@ complete:
return rc;
}
-int ril_request_cancel_ussd(void *data, size_t size, RIL_Token token)
+int ril_request_cancel_ussd(__attribute__((unused)) void *data,
+ __attribute__((unused)) size_t size,
+ RIL_Token token)
{
struct ipc_ss_ussd_header ussd;
int rc;
- rc = ril_radio_state_check(RADIO_STATE_SIM_NOT_READY);
+ rc = ril_radio_has_reached_state(RADIO_STATE_ON);
if (rc < 0)
return RIL_REQUEST_UNHANDLED;
@@ -419,7 +424,6 @@ int ipc_ss_ussd(struct ipc_message *message)
char *ussd_message[2];
int ussd_encoding;
struct ipc_ss_ussd_header *ussd = NULL;
- unsigned char state;
int rc;
if (message == NULL || message->data == NULL || message->size < sizeof(struct ipc_ss_ussd_header))
diff --git a/tools/srs-test.c b/tools/srs-test.c
index ac91f1a..e460c57 100644
--- a/tools/srs-test.c
+++ b/tools/srs-test.c
@@ -38,7 +38,7 @@ void display_help(void)
printf("Commands:\n");
printf(" radio-state [STATE] - set radio state\n");
printf("\n");
- printf("States: off, unavailable, sim-not-ready, sim-locked-absent, sim-ready, on\n");
+ printf("States: off, unavailable, on\n");
}
int radio_state(struct srs_client *client, char *string)
@@ -46,9 +46,6 @@ int radio_state(struct srs_client *client, char *string)
struct radio_state_string radio_state_strings[] = {
{ "off", RADIO_STATE_OFF },
{ "unavailable", RADIO_STATE_UNAVAILABLE },
- { "sim-not-ready", RADIO_STATE_SIM_NOT_READY },
- { "sim-locked-absent", RADIO_STATE_SIM_LOCKED_OR_ABSENT },
- { "sim-ready", RADIO_STATE_SIM_READY },
{ "on", RADIO_STATE_ON },
};
struct srs_test_set_radio_state_data data;
diff --git a/utils.c b/utils.c
index 164812e..cc2e9d9 100644
--- a/utils.c
+++ b/utils.c
@@ -18,12 +18,15 @@
* along with Samsung-RIL. If not, see <http://www.gnu.org/licenses/>.
*/
+#define LOG_TAG "RIL"
+
+#include <ctype.h>
+#include <errno.h>
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
+
#include <sys/eventfd.h>
-#define LOG_TAG "RIL"
#include <utils/Log.h>
#include <samsung-ril.h>
@@ -227,8 +230,12 @@ int eventfd_recv(int fd, eventfd_t *event)
int rc;
rc = eventfd_read(fd, event);
- if (rc < 0)
+ if (rc < 0) {
+ rc = errno;
+ RIL_LOGE("%s: eventfd_read error %d: %s", __func__,
+ rc, strerror(rc));
return -1;
+ }
return 0;
}