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