1import os
2import sys
3import argparse
4import logging
5import time
6import search_gxps
7import shutil
8import glob
9from compare_two_files import compare_output_files
10from compare_two_files import compare
11from compare_two_files import compare_output_folders
12from set_project_lib_version import set_project_lib_version
13from os.path import basename
14
15sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)) + '\\..\\test_view')
16import test_utils
17
18#count[total, passed, failed]
19count_test=[0,0,0]
20count_generate=[0, 0, 0]
21
22multi_theme_project_names = ["multi_themes_16bpp.gxp", "multi_themes_332rgb.gxp"]
23back_compatible_project_names = [
24"all_widgets_5_2_0",
25"all_widgets_5_2_5",
26"all_widgets_5_3_0",
27"all_widgets_5_3_2",
28"all_widgets_5_3_3",
29"all_widgets_5_3_4",
30"all_widgets_5_4_0",
31"all_widgets_5_4_1",
32"all_widgets_5_4_2",
33"all_widgets_5_5_1",
34"all_widgets_synergy_5_4_2",
35"multi_themes_16bpp_5_5_1",
36"all_widgets_synergy_8bpp_6_1_3"
37]
38
39binres_only_project_names = [
40'demo_guix_binres.gxp',
41'all_widgets_16bpp_rotated_cw_binary.gxp',
42'all_widgets_16bpp_rotated_ccw_binary.gxp',
43'all_widgets_synergy_16bpp_rotated_cw_binary.gxp',
44'all_widgets_synergy_16bpp_rotated_ccw_binary.gxp',
45'all_widgets_8bpp_rotated_cw_binary.gxp',
46'all_widgets_8bpp_rotated_ccw_binary.gxp',
47'all_widgets_synergy_8bpp_rotated_cw_binary.gxp',
48'all_widgets_synergy_8bpp_rotated_ccw_binary.gxp',
49'all_widgets_24xrgb_rotated_cw_binary.gxp',
50'all_widgets_24xrgb_rotated_ccw_binary.gxp',
51'all_widgets_synergy_24xrgb_rotated_cw_binary.gxp',
52'all_widgets_synergy_24xrgb_rotated_ccw_binary.gxp'
53]
54
55msbuild_exe_path = "C:/Windows/Microsoft.NET/Framework64/v4.0.30319/MSBuild.exe"
56guix_lib = "../../../build/win32/msvc_2010/guix.vcxproj"
57
58# compiler command line using gx_api.h in src directory
59std_compile = "cl /c /nologo /I..\\..\\..\\common\\inc /I..\\..\\..\\ports\\win32\\inc /I..\\..\\..\\ports\\win32\\lib\\vs_2019"
60# Set compile level4 to detect compile warning.
61# But ignore warning C4132: const object should be initialized. The reason is about GX_CONST GX_STUDIO_WIDGET xxxx parameters in each specification.c.
62compile_option = "/W4 /wd4132 /wd4100 /wd4244 /WX-"
63
64compile_result =[0,0,0]
65
66#Compile studio
67def studio_compile(project_sln_path):
68    #Ensure solution file exists
69    if not os.path.isfile(project_sln_path):
70        raise Exception('studiox.sln not found. path=' + project_sln_path)
71
72    logging.debug("Building Studio Executable");
73    if os.system("msbuild " + project_sln_path + " /p:Configuration=Release") != 0:
74        logging.error("Studio Build Failed")
75        return(-1)
76    else:
77        logging.debug("Studio Build Successful")
78        return(0)
79
80#Compile guix
81def guix_compile(project_sln_path, configuration):
82    #Ensure solution file exists
83    if not os.path.isfile(project_sln_path):
84        raise Exception('guix.sln not found. path=' + project_sln_path)
85
86    logging.debug("Building Guix library, Configuration=%s", configuration);
87    if os.system("msbuild " + project_sln_path + " /p:Configuration=" + configuration) != 0:
88        logging.error("Guix Build Failed")
89        return(-1)
90    else:
91        logging.debug("Guix Build Successful")
92        return(0)
93
94def test_one_project(studio_release, file):
95        project_pathname = os.path.abspath(file)
96        (project_path, project_name) = os.path.split(project_pathname)
97        project_path += '\\'
98
99        logging.debug("===============================================================================")
100        logging.info("Testing output files for project: %s", project_pathname)
101
102        cmp_result = False
103
104        test_file_list = os.listdir(project_path)
105
106        if project_name == 'folder_output_test.gxp':
107            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -d MAIN_DISPLAY -r MAIN_DISPLAY_resources -s specifications -l English,Japanese")
108            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -d SECONDARY -r SECONDARY_resources -s specifications -l English,Chinese")
109
110        elif (project_name == 'two_displays.gxp' or
111              project_name == 'demo_display_resolution.gxp'):
112            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -d MAIN_DISPLAY -r MAIN_DISPLAY_resources -s specifications")
113            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -d SECONDARY -r SECONDARY_resources -s specifications")
114
115        elif project_name == 'two_displays_binres.gxp':
116            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b -d MAIN_DISPLAY -r MAIN_DISPLAY_resources -s specifications")
117            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b -d SECONDARY -r SECONDARY_resources -s specifications")
118
119        elif project_name in multi_theme_project_names:
120                base_name = os.path.splitext(project_name)[0]
121                #Gen "japanese.bin"
122                os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --no_res_header -r temp_Japanese -l Japanese -t")
123                #Gen "resource.bin": Including theme4, theme5, Spanish
124                os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --no_res_header -r resources -t theme_4, theme_5 -l Spanish")
125                #Gen "japanese_big_endian.bin"
126                os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --big_endian --no_res_header -r temp_Japanese_big_endian -l Japanese -t")
127                #Gen "resource_big_endian.bin"
128                os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --big_endian --no_res_header -r resources_big_endian -t theme_4, theme_5 -l Spanish")
129
130                #Gen "resource.c/.h" and "specifications.c/.h"
131                os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -r resources -s specifications -t theme_1, theme_2, theme_3 -l English, Chinese")
132
133                if project_name == 'multi_themes_16bpp.gxp':
134                    #gen "resource_big_endian.c" and "resource_big_endian.h"
135                    os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n --big_endian -r resources_big_endian -t theme_1, theme_2, theme_3 -l English, Chinese")
136
137        elif project_name == 'multi_themes_32bpp.gxp':
138            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -r resources -s specifications -b")
139            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n --big_endian -r resources_big_endian")
140            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --big_endian --no_res_header -r resources_big_endian")
141        elif project_name == 'multi_themes_8bpp_palette.gxp':
142            #Gen "resource.bin": Including theme4, theme5
143            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --no_res_header -r resources -t theme_4, theme_5 -l")
144            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -r resources -s specifications -t theme_1, theme_2, theme_3")
145        elif project_name == 'multi_themes_16bpp_synergy.gxp':
146            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --no_res_header -r resources -t theme_4, theme_5")
147            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -r resources -s specifications -t theme_1, theme_2, theme_3")
148        elif project_name == 'arabic_glyph_shaping.gxp':
149            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -r resources -s specifications -l English")
150            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --no_res_header -r resources -l Arabic -t")
151        elif project_name == 'thai_glyph_shaping.gxp':
152            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -r resources -s specifications -l English")
153            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --no_res_header -r resources -l Thai -t")
154        elif project_name == 'multi_themes_16bpp_5_5_1.gxp':
155            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -r resources -s specifications -t theme_1, theme_2, theme_3 -l English, Chinese")
156            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --no_res_header -r resources -t theme_4, theme_5, -l Japanese, Spanish")
157        elif project_name == 'kerning_glyph_draw_32bpp_screen.gxp' or  project_name == 'kerning_glyph_in_string_table.gxp':
158            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -r resources -s specifications -t theme_1 -l English")
159            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --no_res_header -r resources -t theme_2")
160        elif project_name == 'binres_theme_static_language.gxp':
161            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --no_res_header -r resources -t theme_1, theme_2 -l")
162            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -r resources -s specifications -t -l English,Spanish")
163        elif project_name == 'bidi_text_draw_32bpp.gxp':
164            #Gen "bidi_text_draw_32bpp_resources.bin"
165            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --no_res_header -r resources")
166            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -r resources -s specifications")
167        elif project_name == 'bidi_text_line_break_static.gxp':
168            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --no_res_header -r resources -t theme_2 -l")
169            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -r resources -s specifications -t theme_1")
170        elif project_name in binres_only_project_names:
171            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b -r resources -s specifications")
172        elif 'big_endian' in project_name:
173            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -r resources -s specifications --big_endian")
174        elif project_name == 'standalone_binres_load_16bpp.gxp':
175            os.system("mkdir " + project_path + "project_output_folder")
176            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n --output_path project_output_folder")
177            os.system("mkdir " + project_path + "xml_output_folder")
178            os.system(os.path.abspath(studio_release) + " -x " + project_path + "font_1bpp.xml -b --output_path   \"xml_output_folder\"   -o log.txt")
179            os.system(os.path.abspath(studio_release) + " -x " + project_path + "font_4bpp.xml -b --output_path xml_output_folder  -o log.txt")
180            os.system(os.path.abspath(studio_release) + " -x " + project_path + "font_8bpp.xml -b --output_path xml_output_folder  -o log.txt")
181            os.system(os.path.abspath(studio_release) + " -x " + project_path + "pixelmap_8bit_palette.xml -b --output_path xml_output_folder -o log.txt")
182            os.system(os.path.abspath(studio_release) + " -x " + project_path + "pixelmap_565rgb.xml -b --output_path xml_output_folder  -o log.txt")
183            os.system(os.path.abspath(studio_release) + " -x " + project_path + "pixelmap_compress_4444argb.xml -b --output_path xml_output_folder  -o log.txt")
184            os.system(os.path.abspath(studio_release) + " -x " + project_path + "pixelmap_compress_alphamap.xml -b --output_path xml_output_folder  -o log.txt")
185            os.system(os.path.abspath(studio_release) + " -x " + project_path + "pixelmap_raw_4444argb.xml -b --output_path xml_output_folder  -o log.txt")
186            os.system(os.path.abspath(studio_release) + " -x " + project_path + "pixelmap_raw_alphamap.xml -b --output_path xml_output_folder  -o log.txt")
187        elif project_name == 'standalone_binres_load_8bpp.gxp':
188            os.system("mkdir " + project_path + "project_output_folder")
189            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n --output_path project_output_folder")
190            os.system("mkdir " + project_path + "xml_output_folder")
191            os.system(os.path.abspath(studio_release) + " -x " + project_path + "pixelmap_folder_1.xml -b --output_path " + project_path + "xml_output_folder -o log.txt")
192            os.system(os.path.abspath(studio_release) + " -x " + project_path + "pixelmap_fish.xml -b --output_path " + project_path + "xml_output_folder  -o log.txt")
193        elif project_name == 'standalone_binres_load_extended_unicode_32bpp.gxp':
194            os.system("mkdir " + project_path + "project_output_folder")
195            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n --output_path project_output_folder")
196            os.system("mkdir " + project_path + "xml_output_folder")
197            os.system(os.path.abspath(studio_release) + " -x " + project_path + "font_pld_italic_1bpp.xml -b --output_path " + project_path + "xml_output_folder -o log.txt")
198            os.system(os.path.abspath(studio_release) + " -x " + project_path + "font_pld_italic_4bpp.xml -b --output_path " + project_path + "xml_output_folder  -o log.txt")
199            os.system(os.path.abspath(studio_release) + " -x " + project_path + "font_pld_italic_8bpp.xml -b --output_path " + project_path + "xml_output_folder  -o log.txt")
200            os.system(os.path.abspath(studio_release) + " -x " + project_path + "pixelmaps.xml -b --output_path " + project_path + "xml_output_folder  -o log.txt")
201        else:
202            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -r resources -s specifications")
203
204        # remove the temporary output files
205        if (project_name == 'standalone_binres_load_16bpp.gxp' or project_name == 'standalone_binres_load_8bpp.gxp' or project_name == 'standalone_binres_load_extended_unicode_32bpp.gxp'):
206            # check if log file is generated
207            if os.path.isfile(project_path + "xml_output_folder\log.txt") == False:
208                cmp_result = False
209                logging.info("Log file is not generated")
210            else:
211                cmp_result = True
212                # remove the log file
213                os.remove(project_path + "xml_output_folder\log.txt")
214
215            if cmp_result == True:
216                cmp_result = compare_output_folders(project_path, project_path + "project_output_folder\\")
217            if cmp_result == True:
218                cmp_result = compare_output_folders(project_path, project_path + "xml_output_folder\\")
219
220            #shutil.rmtree(project_path + "project_output_folder")
221            #shutil.rmtree(project_path + "xml_output_folder")
222        else:
223            cmp_result = compare_output_files(project_path, test_file_list)
224
225            remove_list = []
226            remove_list.append(project_path + 'resources.c')
227            remove_list.append(project_path + 'resources.h')
228            remove_list.append(project_path + 'specifications.c')
229            remove_list.append(project_path + 'specifications.h')
230
231            if project_name in multi_theme_project_names:
232                remove_list.append(project_path + 'resources.c')
233                remove_list.append(project_path + 'resources.h')
234                remove_list.append(project_path + 'resources_big_endian.bin')
235                remove_list.append(project_path + 'resources.bin')
236                remove_list.append(project_path + 'temp_Japanese.bin')
237                remove_list.append(project_path + 'temp_Japanese_big_endian.bin')
238
239                if project_name == 'multi_themes_16bpp.gxp':
240                    remove_list.append(project_path + 'resources_big_endian.c')
241                    remove_list.append(project_path + 'resources_big_endian.h')
242
243            elif project_name == 'multi_themes_32bpp.gxp':
244                remove_list.append(project_path + 'resources.bin')
245                remove_list.append(project_path + 'resources_big_endian.bin')
246                remove_list.append(project_path + 'resources_big_endian.c')
247                remove_list.append(project_path + 'resources_big_endian.h')
248
249            elif (project_name == 'arabic_glyph_shaping.gxp' or
250                project_name == 'thai_glyph_shaping.gxp'):
251                remove_list.append(project_path + 'resources.bin')
252
253            elif (project_name == 'multi_themes_8bpp_palette.gxp' or
254                project_name == 'multi_themes_16bpp_synergy.gxp' or
255                project_name == 'kerning_glyph_draw_32bpp_screen.gxp' or
256                project_name == 'kerning_glyph_in_string_table.gxp' or
257                project_name == 'bidi_text_draw_32bpp.gxp' or
258                project_name == 'bidi_text_line_break_static.gxp' or
259                project_name == 'multi_themes_16bpp_5_5_1.gxp' or
260                project_name == 'binres_theme_static_language.gxp' or
261                project_name in binres_only_project_names):
262                remove_list.append(project_path + 'resources.bin')
263
264            elif project_name == 'folder_output_test.gxp':
265                remove_list.remove(project_path + 'resources.c')
266                remove_list.remove(project_path + 'resources.h')
267                remove_list.append(project_path + 'main_display_resources.c')
268                remove_list.append(project_path + 'main_display_resources.h')
269                remove_list.append(project_path + 'secondary_resources.c')
270                remove_list.append(project_path + 'secondary_resources.h')
271                remove_list.append(project_path + 'specifications.c')
272                remove_list.append(project_path + 'specifications.h')
273                remove_list.append(project_path + 'button_screen_specifications.c')
274                remove_list.append(project_path + 'empty_folder_specifications.c')
275                remove_list.append(project_path + 'indicator_screen_runtime_allocate_specifications.c')
276                remove_list.append(project_path + 'popup_modal_specifications.c')
277                remove_list.append(project_path + 'static_screens_specifications.c')
278
279            elif (project_name == 'two_displays.gxp' or
280                project_name == 'demo_display_resolution.gxp'):
281                remove_list.append(project_path + 'MAIN_DISPLAY_resources.c')
282                remove_list.append(project_path + 'MAIN_DISPLAY_resources.h')
283                remove_list.append(project_path + 'SECONDARY_resources.c')
284                remove_list.append(project_path + 'SECONDARY_resources.h')
285
286            elif project_name == 'two_displays_binres.gxp':
287                remove_list.append(project_path + 'MAIN_DISPLAY_resources.bin')
288                remove_list.append(project_path + 'MAIN_DISPLAY_resources.h')
289                remove_list.append(project_path + 'SECONDARY_resources.bin')
290                remove_list.append(project_path + 'SECONDARY_resources.h')
291
292            for file in remove_list:
293                if os.path.isfile(file):
294                    os.remove(file)
295
296        return cmp_result
297
298# Generate test output file for every gxp projects and
299# compare between default project and new output files.
300def test(gxp_projects, studio_release, write_result = True):
301    init_file = '__init__.py'
302    path = sys.path[0]
303    file = open(path+'\\'+init_file,'a+')
304    file.close()
305
306    if not os.path.isfile(studio_release):
307        raise Exception('guix_studio.exe not found. path=' + studio_release)
308
309    for file in gxp_projects:
310        # count total projects
311        count_test[0] += 1
312        if test_one_project(studio_release, file) == True:
313            # count passed projects
314            count_test[1] += 1
315        else:
316            #count failed projects
317            count_test[2] += 1
318            print("File comparison failed")
319
320    # Write the result.
321    if write_result:
322        write_test_result()
323
324# Regenerate output files for every gxp projects.
325def generate(gxp_projects, studio_release, version, gen_resources, gen_specifications, gen_failures):
326    init_file = '__init__.py'
327    path = sys.path[0]
328    file = open(path+'\\'+init_file,'a+')
329    file.close()
330
331    if not os.path.isfile(studio_release):
332        raise Exception('guix_studio.exe not found. path=' + studio_release)
333
334    for file in gxp_projects:
335        if gen_failures:
336            templist = []
337            templist.append(file)
338            previous_failed_test_count = count_test[2]
339            test(templist, studio_release, False)
340            if count_test[2] == previous_failed_test_count:
341                 continue
342
343        count_generate[0] += 1
344        project_pathname = os.path.abspath(file)
345        project_name = os.path.basename(file)
346        root_name = project_pathname[:-4]
347        dirname = os.path.dirname(project_pathname)
348        base_name = os.path.splitext(project_name)[0]
349
350        logging.info("Generating output files for project %s", project_pathname)
351
352        output_file_lists = []
353
354        gen_options = " "
355
356        if gen_specifications is True:
357            gen_options += "-s "
358            output_file_lists.append(root_name + '_specifications.c')
359            output_file_lists.append(root_name + '_specifications.h')
360
361        if gen_resources is True:
362            gen_options += "-r "
363            if project_name == 'two_displays.gxp' or project_name == 'demo_display_resolution.gxp' or project_name == 'folder_output_test.gxp':
364                output_file_lists.append(root_name + '_MAIN_DISPLAY_resources.c')
365                output_file_lists.append(root_name + '_MAIN_DISPLAY_resources.h')
366                output_file_lists.append(root_name + '_SECONDARY_resources.c')
367                output_file_lists.append(root_name + '_SECONDARY_resources.h')
368            elif project_name == 'two_displays_binres.gxp':
369                output_file_lists.append(root_name + '_MAIN_DISPLAY_resources.bin')
370                output_file_lists.append(root_name + '_MAIN_DISPLAY_resources.h')
371                output_file_lists.append(root_name + '_SECONDARY_resources.bin')
372                output_file_lists.append(root_name + '_SECONDARY_resources.h')
373            elif project_name in multi_theme_project_names:
374                output_file_lists.append(root_name + '_resources.c')
375                output_file_lists.append(root_name + '_resources.h')
376                output_file_lists.append(root_name + '_resources_big_endian.bin')
377                output_file_lists.append(root_name + '_resources.bin')
378                output_file_lists.append(dirname + '\Japanese.bin')
379                output_file_lists.append(dirname + '\Japanese_big_endian.bin')
380
381                if project_name == 'multi_themes_16bpp.gxp':
382                    output_file_lists.append(root_name + '_resources_big_endian.c')
383                    output_file_lists.append(root_name + '_resources_big_endian.h')
384            elif project_name == 'arabic_glyph_shaping.gxp':
385                output_file_lists.append(dirname + '\\arabic_string_res.bin')
386                output_file_lists.append(root_name + '_resources.c')
387                output_file_lists.append(root_name + '_resources.h')
388            elif project_name == 'thai_glyph_shaping.gxp':
389                output_file_lists.append(dirname + '\\thai_string_res.bin')
390                output_file_lists.append(root_name + '_resources.c')
391                output_file_lists.append(root_name + '_resources.h')
392            elif project_name == 'multi_themes_32bpp.gxp':
393                output_file_lists.append(root_name + '_resources.h')
394                output_file_lists.append(root_name + '_resources.bin')
395                output_file_lists.append(root_name + '_resources_big_endian.bin')
396                output_file_lists.append(root_name + '_resources_big_endian.c')
397                output_file_lists.append(root_name + '_resources_big_endian.h')
398
399            elif project_name == 'multi_themes_8bpp_palette.gxp':
400                output_file_lists.append(root_name + '_resources.bin')
401                output_file_lists.append(root_name + '_resources.c')
402                output_file_lists.append(root_name + '_resources.h')
403
404            elif project_name == 'multi_themes_16bpp_synergy.gxp':
405                output_file_lists.append(root_name + '_resources.bin')
406                output_file_lists.append(root_name + '_resources.c')
407                output_file_lists.append(root_name + '_resources.h')
408
409            elif (project_name == 'bidi_text_draw_32bpp.gxp' or
410                  project_name == 'bidi_text_line_break_static.gxp' or
411                  project_name == 'kerning_glyph_in_string_table.gxp' or
412                  project_name == 'kerning_glyph_draw_32bpp_screen.gxp' or
413                  project_name == 'multi_themes_16bpp_5_5_1.gxp' or
414                  project_name == 'binres_theme_static_language.gxp'):
415                output_file_lists.append(root_name + '_resources.bin')
416                output_file_lists.append(root_name + '_resources.c')
417                output_file_lists.append(root_name + '_resources.h')
418            elif project_name in binres_only_project_names:
419                output_file_lists.append(root_name + '_resources.bin')
420                output_file_lists.append(root_name + '_resources.h')
421            elif project_name == 'standalone_binres_load_16bpp.gxp':
422                output_file_lists.append(root_name + '_resources.c')
423                output_file_lists.append(root_name + '_resources.h')
424                output_file_lists.append(dirname + '\\font_1bpp.bin')
425                output_file_lists.append(dirname + '\\font_4bpp.bin')
426                output_file_lists.append(dirname + '\\font_8bpp.bin')
427                output_file_lists.append(dirname + '\\pixelmap_8bit_palette.bin')
428                output_file_lists.append(dirname + '\\pixelmap_565rgb.bin')
429                output_file_lists.append(dirname + '\\pixelmap_compress_4444argb.bin')
430                output_file_lists.append(dirname + '\\pixelmap_compress_alphamap.bin')
431                output_file_lists.append(dirname + '\\pixelmap_raw_4444argb.bin')
432                output_file_lists.append(dirname + '\\pixelmap_raw_alphamap.bin')
433            elif project_name == 'standalone_binres_load_8bpp.gxp':
434                output_file_lists.append(root_name + '_resources.c')
435                output_file_lists.append(root_name + '_resources.h')
436                output_file_lists.append(dirname + '\\pixelmap_folder_1.bin')
437                output_file_lists.append(dirname + '\\pixelmap_fish.bin')
438            elif project_name == 'standalone_binres_load_extended_unicode_32bpp':
439                output_file_lists.append(root_name + '_resources.c')
440                output_file_lists.append(root_name + '_resources.h')
441                output_file_lists.append(dirname + '\\font_old_italic_1bpp.bin')
442                output_file_lists.append(dirname + '\\font_old_italic_4bpp.bin')
443                output_file_lists.append(dirname + '\\font_old_italic_8bpp.bin')
444                output_file_lists.append(dirname + '\\pixelmaps.bin')
445            else:
446                output_file_lists.append(root_name + '_resources.c')
447                output_file_lists.append(root_name + '_resources.h')
448
449        #remove exist output files
450        for file in output_file_lists:
451            if os.path.isfile(file):
452                os.remove(file)
453
454        #regenerate output files
455        if project_name == 'two_displays.gxp':
456            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n" + gen_options + "-d MAIN_DISPLAY")
457            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n" + gen_options  + "-d SECONDARY")
458        elif project_name == 'two_displays_binres.gxp':
459            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b" + gen_options + "-d MAIN_DISPLAY")
460            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b" + gen_options  + "-d SECONDARY")
461        elif project_name in multi_theme_project_names:
462            #generate binary format resource files
463            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --no_res_header -r Japanese -l Japanese -t")
464            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --no_res_header -r -t theme_4, theme_5 -l Spanish")
465            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --big_endian --no_res_header -r Japanese_big_endian -l Japanese -t")
466            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --big_endian --no_res_header -r " + base_name + "_resources_big_endian -t theme_4, theme_5 -l Spanish")
467
468            #generate source format resource and specification files
469            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n" + gen_options + "-t theme_1, theme_2, theme_3 -l English, Chinese")
470
471            if project_name == 'multi_themes_16bpp.gxp':
472                os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n --big_endian -r " + base_name + "_resources_big_endian -t theme_1, theme_2, theme_3 -l English, Chinese")
473        elif project_name == 'arabic_glyph_shaping.gxp':
474                os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -r -s -l English")
475                os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --no_res_header -r arabic_string_res -l Arabic -t")
476        elif project_name == 'thai_glyph_shaping.gxp':
477                os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -r -s -l English")
478                os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --no_res_header -r thai_string_res -l Thai -t")
479        elif project_name == 'multi_themes_16bpp_5_5_1.gxp':
480            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -r -s -t theme_1, theme_2, theme_3 -l English, Chinese")
481            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --no_res_header -r -t theme_4, theme_5, -l Japanese, Spanish")
482        elif project_name == 'multi_themes_32bpp.gxp':
483            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -r -s -b")
484            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n --big_endian -r " + base_name + "_resources_big_endian")
485            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --big_endian --no_res_header -r " + base_name + "_resources_big_endian")
486
487        elif project_name == 'multi_themes_8bpp_palette.gxp':
488            #Gen "resource.bin": Including theme4, theme5
489            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --no_res_header -t theme_4, theme_5 -l")
490            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -t theme_1, theme_2, theme_3")
491
492        elif project_name == 'multi_themes_16bpp_synergy.gxp':
493            #Gen "resource.bin": Including theme4, theme5
494            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --no_res_header -t theme_4, theme_5")
495            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -t theme_1, theme_2, theme_3")
496
497        elif project_name == 'kerning_glyph_draw_32bpp_screen.gxp' or  project_name == 'kerning_glyph_in_string_table.gxp':
498            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -r -s -t theme_1 -l English")
499            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --no_res_header -r -t theme_2")
500
501        elif project_name == 'binres_theme_static_language.gxp':
502            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --no_res_header -r -t theme_1, theme_2 -l")
503            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -t -l English,Spanish")
504
505        elif project_name == 'bidi_text_draw_32bpp.gxp':
506            #Gen "bidi_text_draw_32bpp_resources.bin"
507            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --no_res_header")
508            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n")
509        elif project_name == 'bidi_text_line_break_static.gxp':
510            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -b --no_res_header -t theme_2 -l")
511            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -t theme_1")
512        elif project_name in binres_only_project_names:
513            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -r -s -b")
514        elif 'big_endian' in project_name:
515                os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -r -s --big_endian")
516        elif project_name == 'folder_output_test.gxp':
517            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -d MAIN_DISPLAY -l English,Japanese")
518            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n -d SECONDARY -l English,Chinese")
519        else:
520            os.system(os.path.abspath(studio_release) + " -p " + project_pathname + " -n" + gen_options)
521
522
523        #verify if new output files been created
524
525        success = True
526
527        for file in output_file_lists:
528            if not os.path.isfile(file):
529                print("Failed to generate output file " + file)
530                success = False
531                if file.endswith('_resources.c'):
532                    logging.error('Failed to create resource file ' + file)
533                if file.endswith('_resources.h'):
534                    logging.error('Failed to create resource header ' + file)
535                if file.endswith('.bin'):
536                    logging.error('Failed to create binary resource file' + file)
537                if file.endswith('_specification.c'):
538                    logging.error('Failed to create specification file ' + file)
539                if file.endswith('_specification.h'):
540                    logging.error('Failed to create specification header ' + file)
541
542        if success:
543            count_generate[1] += 1
544        else:
545            count_generate[2] += 1
546
547    #remove the generated object files
548    os.system('del *.obj')
549
550    write_test_result()
551
552def upgrade_projects():
553    logging.debug("*****************************************************")
554    logging.debug("*     Upgrade projects                              *")
555    logging.debug("*                                                   *")
556    logging.debug("*                                                   *")
557    logging.debug("*****************************************************")
558
559    sln_files = search_gxps.sln_file_search('..\\..\\..')
560
561    for file in sln_files:
562        logging.debug('Upgrade ' + file)
563        os.system("devenv /upgrade " + file)
564
565def update_gxp_project(project_files):
566    logging.debug("*****************************************************")
567    logging.debug("*     Update gxp projects                           *")
568    logging.debug("*                                                   *")
569    logging.debug("*                                                   *")
570    logging.debug("*****************************************************")
571
572    for project in project_files:
573        print("Updating project %s\n" %(project))
574        test_utils.open_project(project, 0)
575        test_utils.toolbar_save()
576
577def compile_project(project_files):
578    logging.debug("*****************************************************")
579    logging.debug("*     Compile projects                              *")
580    logging.debug("*                                                   *")
581    logging.debug("*                                                   *")
582    logging.debug("*****************************************************")
583    logging.debug("  Test date: %s", time.asctime())
584    logging.debug("  Test directory: %s", os.getcwd())
585
586    for file in project_files:
587        if "internal_build" in file:
588            logging.debug('Compiling ' + file)
589
590            project_name = os.path.basename(os.path.realpath(file))
591            project_name = os.path.splitext(project_name)[0]
592
593            if (project_name in back_compatible_project_names):
594                continue
595
596            # count total projects
597            count_test[0] += 1
598            if os.system("msbuild /p:Configuration=Debug /p:BuildProjectReferences=false " + file):
599                #count failed projects
600                count_test[2] += 1
601                logging.error("**Error** Compilation failed for project " + os.path.realpath(file))
602            else:
603                # count passed projects
604                count_test[1] += 1
605
606    write_test_result()
607
608def output_file_header():
609    logging.debug("*****************************************************")
610    logging.debug("*           Studio File Generation Test             *")
611    logging.debug("*                                                   *")
612    logging.debug("*                                                   *")
613    logging.debug("*****************************************************")
614    logging.debug("  Test date: %s", time.asctime())
615    logging.debug("  Test directory: %s", os.getcwd())
616
617def write_test_result():
618    logging.debug("********************************************")
619    if count_test[0]:
620       logging.info(" Total Test Projects : %d", count_test[0])
621       logging.info(" Passed : %d", count_test[1])
622       logging.info(" Failed : %d", count_test[2])
623
624    if count_generate[0]:
625       logging.info(" Total Generate Projects : %d", count_generate[0])
626       logging.info(" Passed : %d", count_generate[1])
627       logging.info(" Failed : %d", count_generate[2])
628
629def __main__():
630    #Change the current working directory to the path of this file.
631    current_path = os.path.split(os.path.realpath(__file__))[0]
632    os.chdir(current_path)
633    studio_sln_path = "../../../guix_studio/build/vs_2019/studiox.sln"
634    studio_exe_path = "../../../guix_studio/build/vs_2019/Release/guix_studio.exe"
635    guix_project_path = "../../../ports/win32/build/vs_2019/guix.vcxproj"
636
637    gxp_projects = []
638
639    parser = argparse.ArgumentParser(description = "Test Studio generated output files.")
640    parser.add_argument('-b', action='store_true', dest='build_studio', help='Build Studio')
641    parser.add_argument('--build_guix', action='store_true', dest='build_guix', help='Build Guix Lib')
642    parser.add_argument('-p', action = 'store', dest ='project', help='Specify Studio project')
643    parser.add_argument('-t', action = 'store_true', dest ='test', help='Compare generated output files with golden files')
644    parser.add_argument('-g', action = 'store_true', dest ='generate', help="Generate all golden files and compile them.")
645    parser.add_argument('-r', action = 'store_true', dest ='gen_resources', help="Generate resource golden files and compile them.")
646    parser.add_argument('-s', action = 'store_true', dest ='gen_specifications', help="Generate specifications golden files and compile them.")
647    parser.add_argument('-v', action='store', dest='version', help='Specify guix library version, such as \'5.2.8\'')
648    parser.add_argument('--upgrade', action = 'store_true', dest = 'upgrade', help="Upgrade sln files.")
649    parser.add_argument('--compile_project', action = 'store_true', dest = 'compile_project', help="Compile project.")
650    parser.add_argument('--update_gxp_project', action = 'store_true', dest = 'update_gxp_project', help="Update gxp project.")
651    parser.add_argument('--gen_failures', action = 'store_true', dest = 'gen_failures', help="Used with -g/-r/-s to generate golden files only for failed tests.")
652    parser.add_argument('--debug', action = 'store_true', dest = 'debug', help="Print the debug logs to console.")
653    parser.add_argument('--samples', action = 'store_true', dest ='samples', help='Specify Studio projects under \"samples\" folder')
654    parser.add_argument('--tutorials', action = 'store_true', dest ='tutorials', help='Specify Studio projects under \"tutorials\" folder')
655    parser.add_argument('--internal_examples', action = 'store_true', dest ='internal_examples', help='Specify Studio projects under \"examples_internal\" folder')
656
657    args = parser.parse_args()
658
659    Format = '%(message)s'
660    logging.basicConfig(filename='output_files_test_log.txt', filemode = 'w', level=logging.DEBUG, format = Format)
661
662    #If using '--debug', set logging level to DEBUG to print all the logs(debug, info, warning and error message).
663    if args.debug:
664        logging_level = logging.DEBUG
665    else:
666        #Default logging level is INFO, will not print debug message.
667        logging_level = logging.INFO
668
669    console = logging.StreamHandler()
670    console.setLevel(logging_level)
671    formater = logging.Formatter(Format)
672    console.setFormatter(formater)
673    logging.getLogger('').addHandler(console)
674
675    # Upgrade sln files
676    if args.upgrade is True:
677        upgrade_projects()
678
679    # Build studio
680    if args.build_studio:
681        build_result = studio_compile(studio_sln_path)
682        if build_result != 0:
683            exit(-1)
684
685    if args.project is None:
686        if (args.samples is False and
687            args.tutorials is False and
688            args.internal_examples is False):
689           args.samples = True
690           args.tutorials = True
691           args.internal_examples = True
692
693        gxp_projects = search_gxps.project_search('../../../', args.samples, args.tutorials, args.internal_examples)
694        print("\nFound %d projects\n" %(len(gxp_projects)))
695    else:
696        gxp_projects.append(args.project)
697
698    # Update GUIX library version in Studio project files
699    if args.version:
700        set_project_lib_version(gxp_projects, args.version)
701
702    # Update gxp projects
703    if args.update_gxp_project:
704        if not test_utils.find_studio_handles():
705            test_utils.run_studio()
706            if not test_utils.find_studio_handles():
707                raise Exception("Unable to start and find Studio application")
708        update_gxp_project(gxp_projects)
709
710    if args.compile_project:
711        project_files = []
712        if args.project is None:
713            project_files = search_gxps.sln_file_search('..\\..\\..')
714        else:
715            project_files.append(args.project)
716
717        compile_project(project_files)
718        if count_test[2] != 0:
719            exit(-1)
720        else:
721            exit(0)
722    else:
723        output_file_header()
724
725    if args.build_guix:
726        build_result = guix_compile(guix_project_path, "Debug")
727        build_result += guix_compile(guix_project_path, "Debug_GUIX_5_4_0_COMPATIBILITY")
728        build_result += guix_compile(guix_project_path, "Debug_GX_DYNAMIC_BIDI_TEXT_SUPPORT")
729        build_result += guix_compile(guix_project_path, "Debug_GX_PALETTE_MODE_AA_TEXT_COLORS16")
730        build_result += guix_compile(guix_project_path, "Debug_GX_MOUSE_SUPPORT")
731        build_result += guix_compile(guix_project_path, "Debug_GX_FONT_KERNING_SUPPORT")
732        build_result += guix_compile(guix_project_path, "Debug_GX_SYNERGY_FONT_FORMAT_SUPPORT")
733        build_result += guix_compile(guix_project_path, "Debug_GX_DISABLE_BRUSH_ALPHA_SUPPORT")
734        build_result += guix_compile(guix_project_path, "Debug_GX_EXTENDED_UNICODE_SUPPORT")
735        if build_result != 0:
736            exit(-1)
737
738    if args.generate is True:
739        args.gen_resources = True
740        args.gen_specifications = True
741
742    #compile the source files
743    if args.gen_resources is True or args.gen_specifications is True:
744        if args.gen_failures:
745            print("Test projects and generate golden files for failed tests.")
746        else:
747            print("Generate new golden files and compile them.")
748        generate(gxp_projects, studio_exe_path, None, args.gen_resources, args.gen_specifications, args.gen_failures)
749
750    else:
751        if args.test is True:
752            test(gxp_projects, studio_exe_path)
753            if count_test[2] != 0:
754                exit(-1)
755            else:
756                exit(0)
757
758
759__main__()
760
761