// // main.cpp // cpp_tests // // Created by jief on 23.02.20. // Copyright © 2020 Jief_Machak. All rights reserved. // #include #include #include #include #include #include #include #include #include "../../../rEFIt_UEFI/Platform/CloverVersion.h" #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif #ifndef MAX #define MAX(a,b) ((a) > (b) ? (a) : (b)) #endif ssize_t read_all(int fd, void* buf, size_t size) { size_t nbluTotal = 0; while ( nbluTotal < size ) { ssize_t nblu = read(fd, ((uint8_t*)buf)+nbluTotal, MIN(65536, size-nbluTotal)); if ( nblu < 0 ) return -1; if ( nblu == 0 ) { if ( nbluTotal != size ) { // Read only nbluTotal bytes instead of size return -1; } return nbluTotal; } nbluTotal += nblu; } return size; } #include "../../../rEFIt_UEFI/Settings/ConfigPlist/ConfigPlistClass.h" void usage() { fprintf(stderr, "Usage ConfigPlistValidator [-h|--help] [-v|--version] [--info] [-p|--productname=] path_to_config.plist\n"); exit(1); } extern "C" int main(int argc, char * const argv[]) { (void)argc; (void)argv; setlocale(LC_ALL, "en_US"); // to allow printf unicode char int c; int info_flag = 0; XString8 ProductName; while (1) { static struct option long_options[] = { /* These options set a flag. */ {"info", no_argument, &info_flag, 1}, {"productname", required_argument, 0, 'p'}, {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'v'}, {0, 0, 0, 0} }; /* getopt_long stores the option index here. */ int option_index = 0; c = getopt_long (argc, argv, "productname:info:hv", long_options, &option_index); /* Detect the end of the options. */ if (c == -1) break; switch (c) { case 0: break; case 'p': ProductName.takeValueFrom(optarg); break; case 'h': usage(); case 'v': fprintf(stderr, "ConfigPlistValidator for '%s'\n", gRevisionStr); fprintf(stderr, "Build id is '%s'\n", gBuildId.c_str()); break; case '?': /* getopt_long already printed an error message. */ break; default: fprintf(stderr, "Bug in argument parsing.\n"); return 2; } } if (optind == argc) return 1; if (optind < argc-1 ) { usage(); } const char* path = argv[optind]; #ifdef JIEF_DEBUG path = "config-nowarning-noerror.plist"; path = "config-test2.plist"; path = "/JiefLand/5.Devel/Clover/user config/mifjpn/2021-10-22/config.plist"; path = "/Volumes/CL_EFI_VMDK/EFI/CLOVER/config.plist"; //path = "/Volumes/CL_EFI_VMDK/EFI/CLOVER/smbios.plist"; #endif struct stat st; int ret = stat(path, &st); if ( ret != 0 ) { fprintf(stderr, "Cannot stat file '%s'\n", path); return 1; } char* buf = (char*)malloc(st.st_size+1); int fd = open(path, O_RDONLY); if ( fd < 0 ) { fprintf(stderr, "Cannot open file '%s'. Errno %s\n", path, strerror(errno)); return 1; } ssize_t nblu = read_all(fd, buf, st.st_size); if ( nblu != st.st_size ) { fprintf(stderr, "Cannot read file '%s'. Errno %s\n", path, strerror(errno)); return 1; } buf[st.st_size] = 0; // should not be needed. ConfigPlistClass configPlistTest; XmlLiteParser xmlLiteParser; xmlLiteParser.init(buf, st.st_size); if ( ProductName.notEmpty() ) { // if a ProductName is specified in plist, this will be ignored. configPlistTest.SMBIOS.defaultMacModel = GetModelFromString(ProductName); if ( configPlistTest.SMBIOS.defaultMacModel == MaxMacModel ) { printf("Warning: ProductName specified in command line (%s) doesn't exist. Command line option ignored.\n", ProductName.c_str()); } } configPlistTest.parse(&xmlLiteParser, LString8("")); if ( ProductName.notEmpty() && configPlistTest.getSMBIOS().getProductName().isDefined() ) { if ( ProductName != configPlistTest.getSMBIOS().getProductName().value() ) { printf("Warning: ProductName is specified in command line AND in plist, to a different value. Command line option ignored.\n"); } } bool b = true; for ( size_t idx = 0 ; idx < xmlLiteParser.getXmlParserMessageArray().size() ; idx++ ) { const XmlParserMessage& xmlMsg = xmlLiteParser.getXmlParserMessageArray()[idx]; if ( xmlMsg.type != XmlParserMessageType::info ) { printf("%s\n", xmlMsg.getFormattedMsg().c_str()); b = false; }else if ( info_flag ) { printf("%s\n", xmlMsg.getFormattedMsg().c_str()); } } if ( b ) { if ( xmlLiteParser.getXmlParserInfoMessageCount() > 0 ) { printf("Your plist looks good. Well done!\n"); }else{ printf("Your plist looks so wonderful. Well done!\n"); } return 0; }else{ return 1; } }