summaryrefslogtreecommitdiff
path: root/src/scripts/check-definitions.py
blob: ace70786b92d0ec463d74fee4f198985885f5716 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/usr/bin/env python
# Licensed to the .NET Foundation under one or more agreements.
# The .NET Foundation licenses this file to you under the MIT license.
# See the LICENSE file in the project root for more information.
#
# check-definitions.py
#  This script checks the consistency between compiler definitions
# of the native part of CoreCLR and managed part (mscorlib.dll) of
# CoreCLR
#
# Usage:
#   $ ./check-definitions.py Definition_File String_of_Definitions [String_of_Ignored_Definitions]
#
#      Definition_File: the filename of a file containing the list of
#          compiler definitions of CMAKE, seperated by line.
#          (Mandatory)
#      String_of_Definitions: the list of managed code compiler
#          definitions, seperated by semicolon without spaces.
#          (Mandatory)
#      String_of_Ignored_Definitions: the list of compiler definitions
#          to be suppressed from emitting warnings, seperated by semicolon without spaces.
#          (Optional)
#
# (c) 2016 MyungJoo Ham <myungjoo.ham@samsung.com>

from __future__ import print_function

import sys
import re

debug = 0

# For the native part, return the sorted definition array.
def loadDefinitionFile(filename):
    result = []
    f = open(filename, 'r')
    for line in f:
        theLine = line.rstrip("\r\n").strip()
        if (len(theLine) > 0):
            result.append(theLine)

    f.close()
    result = sorted(result)
    return result


# For the managed part, return the sorted definition array.
def loadDefinitionString(string):
    splitted = string.split(';')
    result = []
    for line in splitted:
       theLine = line.strip()
       if (len(theLine) > 0):
           result.append(theLine)

    result = sorted(result)
    return result


def getDiff(arrNative, arrManaged):
    result = [[], []]
    iF = 0 # From file (native)
    nF = len(arrNative)

    iS = 0 # From string (managed)
    nS = len(arrManaged)

    while (iS < nS) and (iF < nF):
        if (arrNative[iF] == arrManaged[iS]):
            if (debug == 1):
                print("Both have " + arrNative[iF])
            iF = iF + 1
            iS = iS + 1
        elif (arrNative[iF] == (arrManaged[iS] + "=1")):
            if (debug == 1):
                print("Both have " + arrNative[iF] + "(=1)")
            iF = iF + 1
            iS = iS + 1
        elif (arrNative[iF] < arrManaged[iS]):
            if (debug == 1):
                print("--- Managed Omitted " + arrNative[iF])
            result[1].append(arrNative[iF])
            iF = iF + 1
        elif (arrNative[iF] > arrManaged[iS]):
            if (debug == 1):
                print("+++ Managed Added " + arrManaged[iS])
            result[0].append(arrManaged[iS])
            iS = iS + 1

    if (iS < nS):
        while iS < nS:
            if (debug == 1):
                print("+++ Managed Added " + arrManaged[iS])
            result[0].append(arrManaged[iS])
            iS = iS + 1
    elif (iF < nF):
        while iF < nF:
            if (debug == 1):
                print("--- Managed Omitted " + arrNative[iF])
            result[1].append(arrNative[iF])
            iF = iF + 1
    return result


def printPotentiallyCritical(arrDefinitions, referencedFilename, arrIgnore):
    f = open(referencedFilename, 'r')
    content = f.read()
    f.close()
    for keyword in arrDefinitions:
        skip = 0

        if (keyword[-2:] == "=1"):
            key = keyword[:-2]
        else:
            key = keyword

        if re.search("[^\\w]"+key+"[^\\w]", content):
            for ign in arrIgnore:
                if key == ign:
                    skip = 1
                    break
            if skip == 0:
                print(keyword)

# MAIN SCRIPT
if len(sys.argv) < 3:
    print("\nUsage:")
    print("$ check-definitions.py [Definition file] [String of definitions]")
    print("    Definition file contains the list of cmake (native) compiler definitions")
    print("      seperated by line.")
    print("    String of definitions contains the list of csproj (managed) definitions")
    print("      seperated by semicolons.")
    sys.exit(-1)

filename = sys.argv[1]
string = sys.argv[2]

arrayNative = loadDefinitionFile(filename)
arrayManaged = loadDefinitionString(string)
arrayIgnore = []

if len(sys.argv) > 3:
    arrayIgnore = loadDefinitionString(sys.argv[3])

arrays = getDiff(arrayNative, arrayManaged)
# arrays[0] = array of added in managed
# arrays[1] = array of omitted in managed (added in native)

print("Potentially Dangerous Compiler Definitions in clrdefinitions.cmake (omitted in native build):")
printPotentiallyCritical(arrays[0], "../../clrdefinitions.cmake", arrayIgnore)

print("Potentially Dangerous Compiler Definitions in clr.defines.targets (omitted in managed build):")
printPotentiallyCritical(arrays[1], "../../clr.defines.targets", arrayIgnore)

print("Definition Check Completed.")