xref: /FreeRTOS-Plus-TCP-v3.1.0/GenerateOriginalFiles.py (revision a4124602cc584fa0658448c229f48a459a84fbb1)
1#!/usr/bin/env python3
2
3# Prerequisits: Python 3.7 or greater.
4#
5# To run this script, go to the root of the FreeRTOS+TCP directory; that is the
6# directory in which this script is present. And then invoke it with:
7# `python3 your/path/to/GenerateOriginalFiles.py`
8#
9# After running this script, you will have 9 source files in the root directory
10# and two additional folders namely `include` and `portable``.
11
12
13# Import the shutil library to aid in copying of files and folders to different
14# location.
15import os
16import shutil
17import sys
18
19# FreeRTOS Kernel includes. DO NOT change the order in the list.
20FreeRTOS_Kernel_Includes = [ 'FreeRTOS.h',
21                             'task.h',
22                             'queue.h',
23                             'semphr.h',
24                             'list.h',
25                             'event_groups.h',
26                             'timers.h' ]
27
28# FreeRTOS+TCP include files. DO NOT change the order in the list.
29FreeRTOS_TCP_Includes = [ 'FreeRTOS_IP.h',
30                          'FreeRTOSIPConfigDefaults.h',
31                          'FreeRTOS_IP_Private.h',
32                          'FreeRTOS_IP_Utils.h',
33                          'FreeRTOS_IP_Timers.h',
34                          'FreeRTOS_ARP.h',
35                          'FreeRTOS_DHCP.h',
36                          'FreeRTOS_DNS.h',
37                          'FreeRTOS_DNS_Cache.h',
38                          'FreeRTOS_DNS_Callback.h',
39                          'FreeRTOS_DNS_Globals.h',
40                          'FreeRTOS_DNS_Networking.h',
41                          'FreeRTOS_DNS_Parser.h',
42                          'FreeRTOS_ICMP.h',
43                          'FreeRTOS_Sockets.h',
44                          'FreeRTOS_Stream_Buffer.h',
45                          'FreeRTOS_TCP_IP.h',
46                          'FreeRTOS_TCP_Reception.h',
47                          'FreeRTOS_TCP_State_Handling.h',
48                          'FreeRTOS_TCP_Transmission.h',
49                          'FreeRTOS_TCP_Utils.h',
50                          'FreeRTOS_TCP_WIN.h',
51                          'FreeRTOS_UDP_IP.h',
52                          'FreeRTOS_errno_TCP.h',
53                          'IPTraceMacroDefaults.h',
54                          'NetworkInterface.h',
55                          'NetworkBufferManagement.h' ]
56
57# A dictionary to hold the modules to combine and the destination.
58MODULES_DICT = dict()
59
60# DO NOT MODIFY. The modules to combine to make up the original FreeRTOS_ARP.c
61ARP_modules_to_combine = [ 'source/FreeRTOS_ARP.c' ]
62
63# DO NOT MODIFY. The modules to combine to make up the original FreeRTOS_DHCP.c
64DHCP_modules_to_combine = [ 'source/FreeRTOS_DHCP.c' ]
65
66# DO NOT MODIFY. The modules to combine to make up the original FreeRTOS_DNS.c
67DNS_modules_to_combine = [ 'source/FreeRTOS_DNS.c',
68                           'source/FreeRTOS_DNS_Cache.c',
69                           'source/FreeRTOS_DNS_Callback.c',
70                           'source/FreeRTOS_DNS_Networking.c',
71                           'source/FreeRTOS_DNS_Parser.c' ]
72
73# DO NOT MODIFY. The modules to combine to make up the original FreeRTOS_IP.c
74IP_modules_to_combine = [ 'source/FreeRTOS_ICMP.c',
75                          'source/FreeRTOS_IP.c',
76                          'source/FreeRTOS_IP_Timers.c',
77                          'source/FreeRTOS_IP_Utils.c' ]
78
79# DO NOT MODIFY. The modules to combine to make up the original FreeRTOS_Sockets.c
80Socket_modules_to_combine = [ 'source/FreeRTOS_Sockets.c' ]
81
82# DO NOT MODIFY. The modules to combine to make up the original FreeRTOS_Stream_Buffer.c
83StreamBuffer_modules_to_combine = [ 'source/FreeRTOS_Stream_Buffer.c' ]
84
85# DO NOT MODIFY. The modules to combine to make up the original FreeRTOS_TCP_IP.c
86TCP_modules_to_combine = [ 'source/FreeRTOS_TCP_IP.c',
87                           'source/FreeRTOS_TCP_Reception.c',
88                           'source/FreeRTOS_TCP_State_Handling.c',
89                           'source/FreeRTOS_TCP_Transmission.c',
90                           'source/FreeRTOS_TCP_Utils.c' ]
91
92# DO NOT MODIFY. The modules to combine to make up the original FreeRTOS_TCP_WIN.c
93TCP_WIN_modules_to_combine = [ 'source/FreeRTOS_TCP_WIN.c',
94                               'source/FreeRTOS_Tiny_TCP.c' ]
95
96# DO NOT MODIFY. The modules to combine to make up the original FreeRTOS_UDP_IP.c
97UDP_modules_to_combine = [ 'source/FreeRTOS_UDP_IP.c' ]
98
99# Add all the modules and the destinations to the dictionary.
100MODULES_DICT['FreeRTOS_ARP.c'] = ARP_modules_to_combine
101MODULES_DICT['FreeRTOS_DHCP.c'] = DHCP_modules_to_combine
102MODULES_DICT['FreeRTOS_DNS.c'] = DNS_modules_to_combine
103MODULES_DICT['FreeRTOS_IP.c'] = IP_modules_to_combine
104MODULES_DICT['FreeRTOS_Sockets.c'] = Socket_modules_to_combine
105MODULES_DICT['FreeRTOS_Stream_Buffer.c'] = StreamBuffer_modules_to_combine
106MODULES_DICT['FreeRTOS_TCP_IP.c'] = TCP_modules_to_combine
107MODULES_DICT['FreeRTOS_TCP_WIN.c'] = TCP_WIN_modules_to_combine
108MODULES_DICT['FreeRTOS_UDP_IP.c'] = UDP_modules_to_combine
109
110# Sorting function used to add Kernel includes. This is required as the includes
111# need to adhere to a specific order of inclusion.
112def KernelSortingFunction(element):
113    return FreeRTOS_Kernel_Includes.index(element)
114
115# Sorting function used to add FreeRTOS+TCP includes. This is required as the includes
116# need to adhere to a specific order of inclusion.
117def TCPSortingFunction(element):
118    return FreeRTOS_TCP_Includes.index(element)
119
120# Get all the includes in all the modules to combine first. This function does
121# remove the duplicates but does not sort the includes in any specific order.
122def GetIncludeList(ModulesToCombine):
123    # This list is used for the FreeRTOS+TCP include files.
124    TCP_include_list = list()
125    # This list is used for FreeRTOS Kernel include files.
126    Kernel_include_list = list()
127    # This list is used for standard library include files.
128    StdLib_include_list = list()
129
130    for filename in ModulesToCombine:
131        f = open(filename, "r")
132        for line in f.readlines():
133            if line.lstrip().startswith('#include '):
134                if '<' in line:
135                    #if this is a standard library include
136                    start_token = '<'
137                    end_token = '>'
138                    header = line.split(start_token)[1].split(end_token)[0]
139                    StdLib_include_list.append(header)
140                else:
141                    start_token = '"'
142                    end_token = '"'
143                    header = line.split(start_token)[1]
144
145                    if header in FreeRTOS_TCP_Includes:
146                        TCP_include_list.append(header)
147                    elif header in FreeRTOS_Kernel_Includes:
148                        Kernel_include_list.append(header)
149                    else:
150                        print("ERROR: Found " + header + " which is not in any list!")
151        f.close()
152    return list(set(StdLib_include_list)), list(set(Kernel_include_list)), list(set(TCP_include_list))
153
154# Write the includes in a specific order to the destination file.
155def AddIncludesInFile(modules_to_combine, file_descriptor):
156    StdLib_include_list_unique, Kernel_include_list_unique, TCP_include_list_unique = GetIncludeList(modules_to_combine)
157
158    for include in StdLib_include_list_unique:
159        file_descriptor.write(f'#include <{include}>\n')
160
161    # Sort the Kernel includes in a specific order using KernelSortingFunction.
162    Kernel_include_list_unique.sort(key=KernelSortingFunction)
163    for include in Kernel_include_list_unique:
164        file_descriptor.write(f'#include "{include}"\n')
165
166    # Sort the TCP includes in a specific order using TCPSortingFunction.
167    TCP_include_list_unique.sort(key=TCPSortingFunction)
168    for include in TCP_include_list_unique:
169        file_descriptor.write(f'#include "{include}"\n')
170
171# Function to add the copyright notice to the destination file.
172def AddCopyRightNotice(CopyRightNotice, file_descriptor):
173    for line in CopyRightNotice:
174        file_descriptor.write(f'{line}')
175
176# Function to generate the original modules by adding the copyright notice,
177# includes and source to the destination modules.
178def GenerateOriginalModules():
179    # Flag to note the first iteration.
180    FirstIteration = True
181    # Create a list to hold the multi-line copyright notice.
182    CopyRightNotice = list()
183
184    for module in MODULES_DICT:
185        # Store the copyright notice for future use.
186        if FirstIteration:
187            FirstIteration = False
188            # Open the first module. All modules have copyright notices in them.
189            with open(MODULES_DICT[module][0]) as f:
190                for line in f.readlines():
191                    CopyRightNotice.append(line)
192
193                    if '*/' in line:
194                        # Found the end of commented copyright notice. Break out
195                        # of the loop.
196                        break
197                f.close()
198
199        # Combine modules only if they were split into multiple ones.
200        if len(MODULES_DICT[module]) != 1:
201            with open(module, 'w') as file_to_write:
202                # Add the copyright notice to the destination module.
203                AddCopyRightNotice(CopyRightNotice, file_to_write)
204
205                # Add the include files in the destination module.
206                AddIncludesInFile(MODULES_DICT[module], file_to_write)
207
208                # Add the source from all the modules into the destination
209                # module.
210                for filename in MODULES_DICT[module]:
211                    ready_to_write = False
212                    with open(filename, "r") as f:
213                        for line in f.readlines():
214                            if ready_to_write:
215                                file_to_write.write(f'{line}')
216                            elif not line.lstrip().startswith('#include') and not line.lstrip().startswith(('*', '/*', '*/')):
217                                file_to_write.write(f'{line}')
218                                ready_to_write = True
219                        f.close()
220                file_to_write.close()
221        # Some modules are intact and there is no need to combine.
222        # Just copy them to the root directory.
223        else:
224            shutil.copy2(MODULES_DICT[module][0] ,module)
225
226# Function to copy the portable and include directories into the root of the
227# folder.
228def CopyIncludeAndPortableDirs():
229    # Copy the include directory to the root of the folder.
230    shutil.copytree('source/include', 'include')
231    # Copy the portable directory to the root of the folder.
232    shutil.copytree('source/portable', 'portable')
233
234if __name__ == "__main__":
235    # Change the working directory to the root of repository.
236    os.chdir(os.path.dirname(sys.argv[0]))
237
238    GenerateOriginalModules()
239    CopyIncludeAndPortableDirs()
240