CloverBootloader/Xcode/CloverConfigPlistValidator/src/main.cpp

193 lines
4.9 KiB
C++

//
// main.cpp
// cpp_tests
//
// Created by jief on 23.02.20.
// Copyright © 2020 Jief_Machak. All rights reserved.
//
#include <iostream>
#include <locale.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <getopt.h>
#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;
}
}