Subversion Repositories Kolibri OS

Rev

Rev 9367 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 9367 Rev 9377
Line 1... Line 1...
1
# Copyright Magomed Kostoev
1
# Copyright Magomed Kostoev
2
# Published under MIT license
2
# Published under MIT license
Line -... Line 3...
-
 
3
 
3
 
4
block_beginner2finisher = {
4
class Rule:
5
    "(": ")",
-
 
6
    "{": "}",
-
 
7
    "\"": "\"",
5
    pass
8
}
6
 
9
 
7
def get_config(config_name):
10
def get_to(src, ptr, c, backwards = False):
8
    if config_name == "KPACK_CMD":
11
    while src[ptr] != c:
9
        # Just never pack the file for now
12
        if not backwards:
10
        return ""
13
            ptr += 1
11
    else:
14
        else:
12
        print(f"Unknown config name: {config_name}")
15
            ptr -= 1
Line -... Line 16...
-
 
16
    return ptr
-
 
17
 
-
 
18
# Assuming we are at beginning of some block (string,
-
 
19
# parenthesed expression, {}-like thing), get to end
-
 
20
# of the block (also handles the blocks openned in the
13
        exit(-1)
21
# way to the block ending character. So it's not just
-
 
22
# stupid searching for block closing character.
-
 
23
def get_to_block_finisher(src, ptr):
14
 
24
    assert(src[ptr] in block_beginner2finisher)
-
 
25
 
-
 
26
    block_beginner = src[ptr]
-
 
27
    ptr += 1
-
 
28
    while src[ptr] != block_beginner2finisher[block_beginner]:
-
 
29
        # If any block starts here - get to its end and then continue
15
def skip_whitespaces(src, ptr):
30
        if src[ptr] in block_beginner2finisher:
16
    while len(src) > ptr and src[ptr] == " ":
31
            ptr = get_to_block_finisher(src, ptr)
Line 17... Line -...
17
        ptr += 1
-
 
18
    return ptr
-
 
19
 
-
 
20
# Returns True if @src has @string starting from @ptr index
-
 
21
def match_string(src, ptr, string):
-
 
22
    if len(src) <= ptr + len(string):
-
 
23
        return False
-
 
24
    for i in range(len(string)):
-
 
25
        if src[ptr + i] != string[i]:
-
 
26
            return False
32
        ptr += 1
27
    return True
-
 
28
 
-
 
29
def parse_tup_getconfig(src, ptr):
-
 
30
    # Skip get straight to the argument
33
    return ptr
31
    ptr += len("tup.getconfig(")
-
 
32
    ptr = skip_whitespaces(src, ptr)
-
 
33
    if src[ptr] != "\"":
-
 
34
        print("Expected \"config name\" as tup.getconfig parameter")
-
 
35
        exit()
-
 
36
    (config_name, ptr) = parse_string(src, ptr)
34
 
37
    ptr = skip_whitespaces(src, ptr)
-
 
38
    # Skip closing parenthese of the tup.getconfig call
-
 
Line -... Line 35...
-
 
35
def get_strnig(src, ptr):
39
    assert(src[ptr] == ")")
36
    # Strings starts with "\""
40
    ptr += 1
37
    assert(src[ptr] == "\"")
41
    return (get_config(config_name), ptr)
-
 
42
 
38
 
43
def parse_string(src, ptr):
39
    result = ""
44
    ptr += 1
40
    # Skip first "\"" of the string
45
    string = ""
-
 
46
    while src[ptr] != "\"":
-
 
47
        string += src[ptr]
-
 
48
        ptr += 1
-
 
49
    # Skip the closing "\""
-
 
50
    ptr += 1
-
 
51
    ptr = skip_whitespaces(src, ptr)
-
 
52
    # Check if we have concatination here
-
 
53
    if match_string(src, ptr, ".."):
-
 
54
        # Skip the ".."
-
 
55
        ptr += 2
-
 
56
        # The expression parsing should result in a string
-
 
57
        (string_to_add, ptr) = parse_expression(src, ptr)
-
 
58
        # Concat our string to the resulting string
-
 
59
        string += string_to_add
-
 
60
    return (string, ptr)
-
 
61
 
-
 
62
def parse_expression(src, ptr):
-
 
63
    ptr = skip_whitespaces(src, ptr)
-
 
64
    result = "WAT?!"
-
 
65
    if src[ptr] == "\"":
-
 
66
        (result, ptr) = parse_string(src, ptr)
-
 
67
    elif match_string(src, ptr, "tup.getconfig("):
-
 
68
        (result, ptr) = parse_tup_getconfig(src, ptr)
-
 
69
    else:
-
 
70
        print(f"Can't handle anything starting with '{src[ptr]}'")
-
 
71
        exit(-1)
-
 
72
    ptr = skip_whitespaces(src, ptr)
-
 
73
    return (result, ptr)
-
 
74
 
-
 
75
def expect_comma(src, ptr):
-
 
76
    comma_skept = False
-
 
77
    ptr = skip_whitespaces(src, ptr)
-
 
78
    if src[ptr] == ",":
-
 
79
        ptr += 1
-
 
80
        return (True, ptr)
-
 
81
    else:
-
 
82
        return (False, ptr)
-
 
83
 
-
 
84
def parse_arguments(src, ptr):
-
 
85
    result = []
-
 
86
    # Parse first argument
-
 
87
    (argument, ptr) = parse_expression(src, ptr)
-
 
88
    result.append(argument)
-
 
89
    (comma_encoutered, ptr) = expect_comma(src, ptr)
-
 
90
    # Parse the second argument if it's there
-
 
91
    if comma_encoutered:
-
 
92
        (argument, ptr) = parse_expression(src, ptr)
-
 
93
        result.append(argument)
-
 
94
        (comma_encoutered, ptr) = expect_comma(src, ptr)
-
 
95
    # Parse third argument if it's there
41
    ptr += 1
Line 96... Line 42...
96
    if comma_encoutered:
42
    while src[ptr] != "\"":
97
        (argument, ptr) = parse_expression(src, ptr)
43
        result += src[ptr]
98
        result.append(argument)
44
        ptr += 1
99
    return result
45
    return result
100
 
46
 
101
def parse_rule(src, ptr):
47
def parse_rule_output(src, ptr):
102
    # Get straight to the first argument
-
 
103
    ptr += len("tup.rule(")
-
 
104
    # Parse the arguments
48
    # Get straight to the first argument
105
    args = parse_arguments(src, ptr)
49
    ptr += len("tup.rule")
106
    # Build the rule object
-
 
107
    result = Rule()
50
    # Get to parenthese
108
    if len(args) == 3:
-
 
109
        result.input = args[0]
-
 
110
        result.command = args[1]
-
 
111
        result.output = args[2]
51
    ptr = get_to(src, ptr, "(")
112
        # Replace %f with input file in rule's command
52
    # Get to the closing parenthese
113
        if type(result.input == str):
53
    ptr = get_to_block_finisher(src, ptr)
114
            result.command = result.command.replace("%f", result.input)
-
 
115
        else:
-
 
116
            print("Command building with non-string tup.rule's first argument"
-
 
117
                + " isn't implemented")
54
    # We are at closing parenthese of argument list
118
            exit()
-
 
119
        # Replace %o with output file in rule's command
55
    # And the last argument is always output file
120
        if type(result.output == str):
-
 
121
            result.command = result.command.replace("%o", result.output)
-
 
122
        else:
-
 
123
            print("Command building with non-string tup.rule's first argument"
-
 
124
                + " isn't implemented")
-
 
125
            exit()
-
 
126
    elif len(args) == 2:
-
 
127
        result.input = []
-
 
128
        result.command = args[0]
56
    # Let's get to closing "\"" of the output file name
129
        result.output = args[1]
-
 
130
    else:
-
 
131
        print(f"tup.rule can only take 2 or 3 arguments, not {len(args)}")
-
 
132
        exit(-1)
-
 
133
    # Unify the API - return arrays as input and output
57
    ptr = get_to(src, ptr, "\"", backwards = True)
134
    if type(result.input) == str:
-
 
135
        result.input = [ result.input ]
-
 
136
    else:
-
 
137
        assert(type(result.input) == list)
58
    # Get into the string
Line 138... Line 59...
138
    if type(result.output) == str:
59
    ptr -= 1
139
        result.output = [ result.output ]
60
    # Then get to the beginning of the string
140
    else:
61
    ptr = get_to(src, ptr, "\"", backwards = True)
141
        assert(type(result.output) == list)
62
    # Now we can read the string
142
    return result
63
    return get_strnig(src, ptr)
143
 
64
 
144
def parse(file_name):
65
def parse_tupfile_outputs(file_name):
145
    rules = []
66
    outputs = []
146
    with open(file_name) as f:
67
    with open(file_name) as f:
147
        tupfile = f.read()
68
        tupfile = f.read()