From d32fbab1181c16e479cba1cf71386974330e7ea9 Mon Sep 17 00:00:00 2001 From: TheVice Date: Mon, 27 Apr 2020 04:59:19 +0300 Subject: [PATCH] [file_system] moved copy/move tasks to own unit file. Fixed issue at 'directory_enumerate_file_system_entries_wchar_t' function: if output encoding requested non UTF8, finish pointer do not refreshed to up-to-date data and fail return may provided in same case where with UTF8 output encoding function return success. [interpreter] at 'interpreter_get_value_for_argument' function make sure that returned empty string is really means empty and code that provided such do not requested to be added as function return value. In this case for some of test cases from the tests.xml requested addition changes. At the string::empty function actually script code used as input, that actually mean - empty value. For some reason get-host-name may not set at some environments so that test case also upgraded. [copy_move] changed signature of 'copy_evaluate_task' and 'move_evaluate_task' functions. Only cases with different input and output encodings and that used nested elements of copy and move tasks not covered. [tests.xml] at 'loadfile sample' removed expected to use code - at other tests used such for, here left unchanged use property::get-value function to cover last one too. [tests_project] expected base directory from test environment is interpreting before compare to returned value. --- CMakeLists.txt | 8 + copy_move.c | 648 ++++++++++++++++++++++++++++++++++++++++++++++ copy_move.h | 25 ++ file_system.c | 183 +------------ file_system.h | 6 - interpreter.c | 26 +- tests.xml | 292 ++++++++++++++++++++- tests_project.cpp | 18 +- 8 files changed, 1005 insertions(+), 201 deletions(-) create mode 100644 copy_move.c create mode 100644 copy_move.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 222fd9f..cf04b71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,8 @@ add_library(ant4c STATIC "${CMAKE_SOURCE_DIR}/common.h" "${CMAKE_SOURCE_DIR}/conversion.c" "${CMAKE_SOURCE_DIR}/conversion.h" + "${CMAKE_SOURCE_DIR}/copy_move.c" + "${CMAKE_SOURCE_DIR}/copy_move.h" "${CMAKE_SOURCE_DIR}/date_time.c" "${CMAKE_SOURCE_DIR}/date_time.h" "${CMAKE_SOURCE_DIR}/echo.c" @@ -69,20 +71,26 @@ add_library(ant4c STATIC add_executable(ant4c_app "${CMAKE_SOURCE_DIR}/main.c") +# add_library(ant4c_lib SHARED +# "${CMAKE_SOURCE_DIR}/main.c") + #if (MSVC OR MINGW) # add_compile_definitions(ant4c UNICODE _UNICODE) # add_compile_definitions(ant4c_app UNICODE _UNICODE) #endif() target_link_libraries(ant4c_app ant4c) +# target_link_libraries(ant4c_lib ant4c) if(DEFINED PROGRAM_VERSION) target_compile_definitions(ant4c PRIVATE -DPROGRAM_VERSION=${PROGRAM_VERSION}) target_compile_definitions(ant4c_app PRIVATE -DPROGRAM_VERSION=${PROGRAM_VERSION}) + # target_compile_definitions(ant4c_lib PRIVATE -DPROGRAM_VERSION=${PROGRAM_VERSION}) endif() if(NOT MSVC) target_link_libraries(ant4c_app m) + # target_link_libraries(ant4c_lib m) endif() set(SOURCES_OF_EXEC_APP "${CMAKE_SOURCE_DIR}/tests_exec_app.c") diff --git a/copy_move.c b/copy_move.c new file mode 100644 index 0000000..1c70871 --- /dev/null +++ b/copy_move.c @@ -0,0 +1,648 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 https://github.com/TheVice/ + * + */ + +#include "copy_move.h" +#include "buffer.h" +#include "common.h" +#include "conversion.h" +#include "file_system.h" +#include "load_file.h" +#include "path.h" +#include "project.h" +#include "range.h" +#include "string_unit.h" +#include "text_encoding.h" + +#include + +#define COPY_MOVE_DIR 0 +#define COPY_MOVE_FILE 1 +#define COPY_MOVE_TO_DIR 2 +#define COPY_MOVE_TO_FILE 3 +#define COPY_MOVE_FLATTEN 4 +#define COPY_MOVE_OVER_WRITE 5 +#define COPY_MOVE_INPUT_ENCODING 6 +#define COPY_MOVE_OUTPUT_ENCODING 7 +#define COPY_MOVE_INCLUDE_EMPTY_DIRS 8 + +static const uint8_t* copy_move_attributes[] = +{ + (const uint8_t*)"dir", + (const uint8_t*)"file", + (const uint8_t*)"todir", + (const uint8_t*)"tofile", + (const uint8_t*)"flatten", + (const uint8_t*)"overwrite", + (const uint8_t*)"inputencoding", + (const uint8_t*)"outputencoding", + (const uint8_t*)"includeemptydirs" +}; + +static const uint8_t copy_move_attributes_lengths[] = { 3, 4, 5, 6, 7, 9, 13, 14, 16 }; + +uint8_t copy_move_get_attributes_and_arguments_for_task( + const uint8_t*** task_attributes, const uint8_t** task_attributes_lengths, + uint8_t* task_attributes_count, struct buffer* task_arguments) +{ + return common_get_attributes_and_arguments_for_task( + copy_move_attributes, copy_move_attributes_lengths, + COUNT_OF(copy_move_attributes), + task_attributes, task_attributes_lengths, + task_attributes_count, task_arguments); +} + +enum file_system_tasks { file_system_copy_task, file_system_move_task }; + +uint8_t copy_move_file_with_encoding( + uint8_t task_id, const uint8_t* source, const uint8_t* target, + uint16_t input_encoding, uint8_t output_encoding, uint8_t verbose) +{ + (void)task_id; + (void)source; + (void)target; + (void)input_encoding; + (void)output_encoding; + (void)verbose; + /*TODO:*/ + return 0; +} + +uint8_t copy_move_file(uint8_t task_id, const uint8_t* source, + const uint8_t** out_files, uint8_t count, + uint16_t input_encoding, uint8_t output_encoding, + uint8_t over_write, uint8_t verbose) +{ + if (NULL == source || + NULL == out_files) + { + return 0; + } + + for (uint8_t i = 0; i < count; ++i) + { + if (NULL == out_files[i]) + { + continue; + } + + if (over_write) + { + if (file_exists(out_files[i]) && + !file_delete(out_files[i])) + { + return 0; + } + } + else + { + if (file_exists(out_files[i])) + { + continue; + } + } + + uint8_t result = 0; + + if (input_encoding == output_encoding || + Default == input_encoding || + Default == output_encoding) + { + result = file_system_copy_task == task_id ? + file_copy(source, out_files[i]) : + file_move(source, out_files[i]); + } + else + { + result = copy_move_file_with_encoding( + task_id, source, out_files[i], + input_encoding, output_encoding, verbose); + } + + if (!result) + { + return 0; + } + } + + return 1; +} + +uint8_t copy_move_read_over_write(struct buffer* task_arguments, uint8_t* over_write, uint8_t verbose) +{ + struct buffer* over_write_in_a_buffer = buffer_buffer_data(task_arguments, COPY_MOVE_OVER_WRITE); + (*over_write) = (uint8_t)buffer_size(over_write_in_a_buffer); + + if (*over_write) + { + if (!bool_parse(buffer_data(over_write_in_a_buffer, 0), *over_write, over_write) || + !buffer_resize(over_write_in_a_buffer, 0)) + { + return 0; + } + } + + (void)verbose; + return 1; +} + +uint8_t copy_move_read_encodings(struct buffer* task_arguments, + uint16_t* input_encoding, uint8_t* output_encoding, + uint8_t verbose) +{ + if (NULL == task_arguments || + NULL == input_encoding || + NULL == output_encoding) + { + return 0; + } + + struct buffer* input_encoding_in_a_buffer = buffer_buffer_data( + task_arguments, COPY_MOVE_INPUT_ENCODING); + + (*input_encoding) = (uint16_t)buffer_size(input_encoding_in_a_buffer); + + if (*input_encoding) + { + (*input_encoding) = load_file_get_encoding(input_encoding_in_a_buffer); + + if (FILE_ENCODING_UNKNOWN == (*input_encoding)) + { + return 0; + } + } + else + { + (*input_encoding) = Default; + } + + const struct buffer* output_encoding_in_a_buffer = buffer_buffer_data( + task_arguments, COPY_MOVE_OUTPUT_ENCODING); + (*output_encoding) = (uint8_t)buffer_size(output_encoding_in_a_buffer); + + if (*output_encoding) + { + const uint8_t* ptr = buffer_data(output_encoding_in_a_buffer, 0); + (*output_encoding) = text_encoding_get_one(ptr, ptr + (*output_encoding)); + + if (TEXT_ENCODING_UNKNOWN == (*output_encoding)) + { + return 0; + } + } + else + { + (*output_encoding) = Default; + } + + (void)verbose; + return 1; +} + +uint8_t copy_move_file_evaluate_task( + const struct range* source_file, uint8_t task_id, + uint16_t input_encoding, uint8_t output_encoding, uint8_t over_write, + struct buffer* task_arguments, uint8_t verbose) +{ + if (range_is_null_or_empty(source_file) || + NULL == task_arguments) + { + return 0; + } + + const uint8_t* out_files[2]; + out_files[0] = out_files[1] = NULL; + /**/ + struct buffer* to_dir_in_a_buffer = buffer_buffer_data(task_arguments, COPY_MOVE_TO_DIR); + + if (buffer_size(to_dir_in_a_buffer)) + { + struct range target_file; + + if (!path_get_file_name(source_file->start, source_file->finish, &target_file)) + { + return 0; + } + + if (!path_combine_in_place(to_dir_in_a_buffer, 0, target_file.start, target_file.finish) || + !buffer_push_back(to_dir_in_a_buffer, 0)) + { + return 0; + } + + out_files[0] = buffer_data(to_dir_in_a_buffer, 0); + + if (string_equal(source_file->start, source_file->finish, + out_files[0], out_files[0] + buffer_size(to_dir_in_a_buffer))) + { + out_files[0] = NULL; + } + } + + struct buffer* to_file_in_a_buffer = buffer_buffer_data(task_arguments, COPY_MOVE_TO_FILE); + + if (buffer_size(to_file_in_a_buffer)) + { + if (!buffer_push_back(to_file_in_a_buffer, 0)) + { + return 0; + } + + out_files[1] = buffer_data(to_file_in_a_buffer, 0); + + if (string_equal(source_file->start, source_file->finish, + out_files[1], out_files[1] + buffer_size(to_file_in_a_buffer))) + { + out_files[1] = NULL; + } + } + + if (NULL != out_files[0] && + NULL != out_files[1]) + { + if (string_equal( + out_files[0], out_files[0] + buffer_size(to_dir_in_a_buffer), + out_files[1], out_files[1] + buffer_size(to_file_in_a_buffer))) + { + out_files[1] = NULL; + } + } + + return copy_move_file(task_id, source_file->start, + out_files, COUNT_OF(out_files), + input_encoding, output_encoding, + over_write, verbose); +} + +uint8_t copy_move_dir_evaluate_task( + struct buffer* dir_in_a_buffer, uint8_t task_id, + uint16_t input_encoding, uint8_t output_encoding, uint8_t over_write, + struct buffer* task_arguments, uint8_t verbose) +{ + if (NULL == dir_in_a_buffer || + NULL == task_arguments) + { + return 0; + } + + struct buffer* flatten_in_a_buffer = buffer_buffer_data(task_arguments, COPY_MOVE_FLATTEN); + + uint8_t flatten = (uint8_t)buffer_size(flatten_in_a_buffer); + + if (flatten) + { + if (!bool_parse(buffer_data(flatten_in_a_buffer, 0), flatten, &flatten)) + { + return 0; + } + } + + const ptrdiff_t dir_in_a_buffer_size = buffer_size(dir_in_a_buffer); +#ifdef _WIN32 + static const uint8_t* wild_card = (const uint8_t*)"*\0"; + + if (!path_combine_in_place(dir_in_a_buffer, 0, wild_card, wild_card + 2)) + { + return 0; + } + +#else + + if (!buffer_push_back(dir_in_a_buffer, 0)) + { + return 0; + } + +#endif + + if (!buffer_resize(flatten_in_a_buffer, 0) || + !directory_enumerate_file_system_entries(dir_in_a_buffer, 1, 1, flatten_in_a_buffer)) + { + return 0; + } + + const uint8_t* start = buffer_data(flatten_in_a_buffer, 0); + const uint8_t* finish = start + buffer_size(flatten_in_a_buffer); + /**/ + static const uint8_t zero = 0; + /**/ + struct buffer* to_dir_in_a_buffer = buffer_buffer_data(task_arguments, COPY_MOVE_TO_DIR); + const ptrdiff_t to_dir_path_size = buffer_size(to_dir_in_a_buffer); + + if (flatten) + { + while (start < finish) + { + const uint8_t* pos = find_any_symbol_like_or_not_like_that(start, finish, &zero, 1, 1, 1); + struct range file_name; + + if (!path_get_file_name(start, pos, &file_name)) + { + return 0; + } + + if (!path_combine_in_place(to_dir_in_a_buffer, 0, file_name.start, file_name.finish) || + !buffer_push_back(to_dir_in_a_buffer, 0)) + { + return 0; + } + + BUFFER_TO_RANGE(file_name, to_dir_in_a_buffer); + + if (!copy_move_file( + task_id, start, &(file_name.start), 1, + input_encoding, output_encoding, + over_write, verbose)) + { + return 0; + } + + if (!buffer_resize(to_dir_in_a_buffer, to_dir_path_size)) + { + return 0; + } + + start = pos + 1; + } + + return 1; + } + + while (start < finish) + { + const uint8_t* pos = find_any_symbol_like_or_not_like_that(start, finish, &zero, 1, 1, 1); + start += dir_in_a_buffer_size; + + if (range_in_parts_is_null_or_empty(start, pos)) + { + return 0; + } + + if (!path_combine_in_place(to_dir_in_a_buffer, 0, start, pos) || + !buffer_push_back(to_dir_in_a_buffer, 0)) + { + return 0; + } + + struct range directory_name; + + BUFFER_TO_RANGE(directory_name, to_dir_in_a_buffer); + + if (!path_get_directory_name( + directory_name.start, directory_name.finish, &directory_name)) + { + return 0; + } + + const uint8_t delimiter = *(directory_name.finish); + uint8_t* ptr = buffer_data(to_dir_in_a_buffer, directory_name.finish - directory_name.start); + *ptr = '\0'; + + if (!directory_exists(directory_name.start) && + !directory_create(directory_name.start)) + { + return 0; + } + + + *ptr = delimiter; + start -= dir_in_a_buffer_size; + + if (!copy_move_file( + task_id, start, &(directory_name.start), 1, + input_encoding, output_encoding, + over_write, verbose)) + { + return 0; + } + + if (!buffer_resize(to_dir_in_a_buffer, to_dir_path_size)) + { + return 0; + } + + start = pos + 1; + } + + struct buffer* include_empty_dirs_in_a_buffer = buffer_buffer_data( + task_arguments, COPY_MOVE_INCLUDE_EMPTY_DIRS); + + uint8_t include_empty_dirs = (uint8_t)buffer_size(include_empty_dirs_in_a_buffer); + + if (include_empty_dirs) + { + if (!bool_parse( + buffer_data(include_empty_dirs_in_a_buffer, 0), include_empty_dirs, &include_empty_dirs)) + { + return 0; + } + } + else + { + include_empty_dirs = 1; + } + + if (1 == include_empty_dirs) + { + if (!buffer_resize(flatten_in_a_buffer, 0) || + !directory_enumerate_file_system_entries(dir_in_a_buffer, 0, 1, flatten_in_a_buffer)) + { + return 0; + } + + start = buffer_data(flatten_in_a_buffer, 0); + finish = start + buffer_size(flatten_in_a_buffer); + + while (start < finish) + { + const uint8_t* pos = find_any_symbol_like_or_not_like_that(start, finish, &zero, 1, 1, 1); + start += dir_in_a_buffer_size; + + if (range_in_parts_is_null_or_empty(start, pos)) + { + return 0; + } + + if (!path_combine_in_place(to_dir_in_a_buffer, 0, start, pos) || + !buffer_push_back(to_dir_in_a_buffer, 0)) + { + return 0; + } + + start = buffer_data(to_dir_in_a_buffer, 0); + + if (!directory_exists(start) && + !directory_create(start)) + { + return 0; + } + + if (!buffer_resize(to_dir_in_a_buffer, to_dir_path_size)) + { + return 0; + } + + start = pos + 1; + } + } + + return 1; +} + +uint8_t copy_move_evaluate_task( + const void* the_project, const void* the_target, + uint8_t task_id, struct buffer* task_arguments, uint8_t verbose) +{ + if (NULL == task_arguments) + { + return 0; + } + + uint16_t input_encoding = Default; + uint8_t output_encoding = Default; + + if (!copy_move_read_encodings( + task_arguments, &input_encoding, &output_encoding, verbose)) + { + return 0; + } + + uint8_t over_write = 0; + + if (!copy_move_read_over_write(task_arguments, &over_write, verbose)) + { + return 0; + } + + struct buffer* to_dir_in_a_buffer = buffer_buffer_data(task_arguments, COPY_MOVE_TO_DIR); + + const ptrdiff_t to_dir_path_size = buffer_size(to_dir_in_a_buffer); + + if (to_dir_path_size) + { + if (!buffer_push_back(to_dir_in_a_buffer, 0)) + { + return 0; + } + + const uint8_t* to_dir_path = buffer_data(to_dir_in_a_buffer, 0); + + if (!path_combine_in_place(to_dir_in_a_buffer, 0, NULL, NULL) || + file_exists(to_dir_path)) + { + return 0; + } + + if (!directory_exists(to_dir_path) && + !directory_create(to_dir_path)) + { + return 0; + } + + if (!buffer_resize(to_dir_in_a_buffer, to_dir_path_size)) + { + return 0; + } + } + + struct buffer* dir_in_a_buffer = buffer_buffer_data(task_arguments, COPY_MOVE_DIR); + + const ptrdiff_t dir_in_a_buffer_size = buffer_size(dir_in_a_buffer); + + if (dir_in_a_buffer_size) + { + if (!buffer_push_back(dir_in_a_buffer, 0) || + !directory_exists(buffer_data(dir_in_a_buffer, 0))) + { + return 0; + } + + if (!to_dir_path_size) + { + if (!project_get_current_directory(the_project, the_target, to_dir_in_a_buffer, 0, verbose)) + { + return 0; + } + } + + if (!buffer_resize(dir_in_a_buffer, dir_in_a_buffer_size)) + { + return 0; + } + + struct range in; + + BUFFER_TO_RANGE(in, dir_in_a_buffer); + + struct range out; + + BUFFER_TO_RANGE(out, to_dir_in_a_buffer); + + if (string_equal(in.start, in.finish, out.start, out.finish)) + { + return 1; + } + + if (!copy_move_dir_evaluate_task( + dir_in_a_buffer, task_id, input_encoding, output_encoding, over_write, task_arguments, verbose)) + { + return 0; + } + } + + struct buffer* file_in_a_buffer = buffer_buffer_data(task_arguments, COPY_MOVE_FILE); + + if (buffer_size(file_in_a_buffer)) + { + if (!buffer_push_back(file_in_a_buffer, 0) || + !file_exists(buffer_data(file_in_a_buffer, 0))) + { + return 0; + } + + const struct buffer* to_file_in_a_buffer = buffer_buffer_data(task_arguments, COPY_MOVE_TO_FILE); + const ptrdiff_t to_file_path_size = buffer_size(to_file_in_a_buffer); + + if (!to_dir_path_size && + !to_file_path_size) + { + if (!project_get_current_directory(the_project, the_target, to_dir_in_a_buffer, 0, verbose)) + { + return 0; + } + } + + struct range source; + + BUFFER_TO_RANGE(source, file_in_a_buffer); + + if (!copy_move_file_evaluate_task( + &source, task_id, input_encoding, output_encoding, over_write, task_arguments, verbose)) + { + return 0; + } + } + + return 1; +} + +uint8_t copy_evaluate_task( + const void* the_project, const void* the_target, + struct buffer* task_arguments, uint8_t verbose) +{ + return copy_move_evaluate_task( + the_project, the_target, + file_system_copy_task, task_arguments, verbose); +} + +uint8_t move_evaluate_task( + const void* the_project, const void* the_target, + struct buffer* task_arguments, uint8_t verbose) +{ + return copy_move_evaluate_task( + the_project, the_target, + file_system_move_task, task_arguments, verbose); +} diff --git a/copy_move.h b/copy_move.h new file mode 100644 index 0000000..bf6fba7 --- /dev/null +++ b/copy_move.h @@ -0,0 +1,25 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 https://github.com/TheVice/ + * + */ + +#ifndef _COPY_MOVE_H_ +#define _COPY_MOVE_H_ + +#include + +struct buffer; + +uint8_t copy_move_get_attributes_and_arguments_for_task( + const uint8_t*** task_attributes, const uint8_t** task_attributes_lengths, + uint8_t* task_attributes_count, struct buffer* task_arguments); +uint8_t copy_evaluate_task( + const void* the_project, const void* the_target, + struct buffer* task_arguments, uint8_t verbose); +uint8_t move_evaluate_task( + const void* the_project, const void* the_target, + struct buffer* task_arguments, uint8_t verbose); + +#endif diff --git a/file_system.c b/file_system.c index 45b3e76..866eb7b 100644 --- a/file_system.c +++ b/file_system.c @@ -141,6 +141,7 @@ uint8_t directory_enumerate_file_system_entries_wchar_t( if (NULL == pattern || all_entries < entry_type || (0 != recurse && 1 != recurse) || + (UTF8 != output_encoding && UTF16LE != output_encoding) || NULL == output) { return 0; @@ -244,10 +245,11 @@ uint8_t directory_enumerate_file_system_entries_wchar_t( continue; } + finish = (const wchar_t*)(buffer_data(pattern, 0) + sizeof(wchar_t) * new_index); + if (UTF8 == output_encoding) { start = buffer_wchar_t_data(pattern, 0); - finish = (const wchar_t*)(buffer_data(pattern, 0) + sizeof(wchar_t) * new_index); file_system_set_position_after_pre_root_wchar_t(&start); if (!text_encoding_UTF16LE_to_UTF8(start, finish, output) || @@ -2898,182 +2900,3 @@ uint8_t touch_evaluate_task(struct buffer* task_arguments, uint8_t verbose) return file_set_last_write_time(buffer_data(file_path_in_buffer, 0), seconds); } - -#define COPY_MOVE_DIR 0 -#define COPY_MOVE_FILE 1 -#define COPY_MOVE_TO_DIR 2 -#define COPY_MOVE_TO_FILE 3 -#define COPY_MOVE_FLATTEN 4 -#define COPY_MOVE_OVER_WRITE 5 -#define COPY_MOVE_INPUT_ENCODING 6 -#define COPY_MOVE_OUTPUT_ENCODING 7 -#define COPY_MOVE_INCLUDE_EMPTY_DIRS 8 - -static const uint8_t* copy_move_attributes[] = -{ - (const uint8_t*)"dir", - (const uint8_t*)"file", - (const uint8_t*)"todir", - (const uint8_t*)"tofile", - (const uint8_t*)"flatten", - (const uint8_t*)"overwrite", - (const uint8_t*)"inputencoding", - (const uint8_t*)"outputencoding", - (const uint8_t*)"includeemptydirs" -}; - -static const uint8_t copy_move_attributes_lengths[] = { 3, 4, 5, 6, 7, 9, 13, 14, 16 }; - -uint8_t copy_move_get_attributes_and_arguments_for_task( - const uint8_t*** task_attributes, const uint8_t** task_attributes_lengths, - uint8_t* task_attributes_count, struct buffer* task_arguments) -{ - return common_get_attributes_and_arguments_for_task( - copy_move_attributes, copy_move_attributes_lengths, - COUNT_OF(copy_move_attributes), - task_attributes, task_attributes_lengths, - task_attributes_count, task_arguments); -} - -enum file_system_tasks { file_system_copy_task, file_system_move_task }; - -uint8_t copy_move_file_evaluate_task(struct buffer* file_in_a_buffer, uint8_t task_id, - struct buffer* task_arguments, uint8_t verbose) -{ - (void)verbose; - /**/ - struct range source_file; - BUFFER_TO_RANGE(source_file, file_in_a_buffer); - /**/ - struct range target_file; - target_file.start = target_file.finish = NULL; - /**/ - struct buffer* to_dir_in_a_buffer = buffer_buffer_data(task_arguments, COPY_MOVE_TO_DIR); - const ptrdiff_t to_dir_path_size = buffer_size(to_dir_in_a_buffer); - - if (to_dir_path_size) - { - if (!path_get_file_name(source_file.start, source_file.finish, &target_file)) - { - return 0; - } - - if (!path_combine_in_place(to_dir_in_a_buffer, 0, target_file.start, target_file.finish) || - !buffer_push_back(to_dir_in_a_buffer, 0)) - { - return 0; - } - - target_file.start = buffer_data(to_dir_in_a_buffer, 0); - target_file.finish = NULL; - } - - struct buffer* to_file_in_a_buffer = buffer_buffer_data(task_arguments, COPY_MOVE_TO_FILE); - - const ptrdiff_t to_file_path_size = buffer_size(to_file_in_a_buffer); - - if (to_file_path_size) - { - if (!buffer_push_back(to_file_in_a_buffer, 0)) - { - return 0; - } - - target_file.finish = buffer_data(to_file_in_a_buffer, 0); - } - - if (!to_dir_in_a_buffer && - !to_file_path_size) - { - /*TODO:*/ - return 0; - } - - for (uint8_t i = 0; i < 2; ++i) - { - const uint8_t* target_file_ptr = i ? target_file.finish : target_file.start; - - if (NULL == target_file_ptr) - { - continue; - } - - const uint8_t result = file_system_copy_task == task_id ? - file_copy(source_file.start, target_file_ptr) : - file_move(source_file.start, target_file_ptr); - - if (!result) - { - return 0; - } - } - - return 1; -} - -uint8_t copy_move_evaluate_task(uint8_t task_id, struct buffer* task_arguments, uint8_t verbose) -{ - if (NULL == task_arguments) - { - return 0; - } - - struct buffer* to_dir_in_a_buffer = buffer_buffer_data(task_arguments, COPY_MOVE_TO_DIR); - - const ptrdiff_t to_dir_path_size = buffer_size(to_dir_in_a_buffer); - - if (to_dir_path_size) - { - if (!buffer_push_back(to_dir_in_a_buffer, 0)) - { - return 0; - } - - const uint8_t* to_dir_path = buffer_data(to_dir_in_a_buffer, 0); - - if (!path_combine_in_place(to_dir_in_a_buffer, 0, NULL, NULL) || - file_exists(to_dir_path)) - { - return 0; - } - - if (!directory_exists(to_dir_path) && - !directory_create(to_dir_path)) - { - return 0; - } - - if (!buffer_resize(to_dir_in_a_buffer, to_dir_path_size)) - { - return 0; - } - } - - struct buffer* file_in_a_buffer = buffer_buffer_data(task_arguments, COPY_MOVE_FILE); - - if (buffer_size(file_in_a_buffer)) - { - if (!buffer_push_back(file_in_a_buffer, 0) || - !file_exists(buffer_data(file_in_a_buffer, 0))) - { - return 0; - } - - if (!copy_move_file_evaluate_task(file_in_a_buffer, task_id, task_arguments, verbose)) - { - return 0; - } - } - - return 1; -} - -uint8_t copy_evaluate_task(struct buffer* task_arguments, uint8_t verbose) -{ - return copy_move_evaluate_task(file_system_copy_task, task_arguments, verbose); -} - -uint8_t move_evaluate_task(struct buffer* task_arguments, uint8_t verbose) -{ - return copy_move_evaluate_task(file_system_move_task, task_arguments, verbose); -} diff --git a/file_system.h b/file_system.h index 969cdea..169d665 100644 --- a/file_system.h +++ b/file_system.h @@ -144,10 +144,4 @@ uint8_t touch_get_attributes_and_arguments_for_task( uint8_t* task_attributes_count, struct buffer* task_arguments); uint8_t touch_evaluate_task(struct buffer* task_arguments, uint8_t verbose); -uint8_t copy_move_get_attributes_and_arguments_for_task( - const uint8_t*** task_attributes, const uint8_t** task_attributes_lengths, - uint8_t* task_attributes_count, struct buffer* task_arguments); -uint8_t copy_evaluate_task(struct buffer* task_arguments, uint8_t verbose); -uint8_t move_evaluate_task(struct buffer* task_arguments, uint8_t verbose); - #endif diff --git a/interpreter.c b/interpreter.c index eb9184d..546d2ce 100644 --- a/interpreter.c +++ b/interpreter.c @@ -9,6 +9,7 @@ #include "buffer.h" #include "common.h" #include "conversion.h" +#include "copy_move.h" #include "date_time.h" #include "echo.h" #include "environment.h" @@ -336,12 +337,23 @@ uint8_t interpreter_get_value_for_argument( } else { - if (!buffer_resize(&value, 0) || - !string_un_quote(argument_area) || - !buffer_append_data_from_range(&value, argument_area)) + const ptrdiff_t index_1 = string_index_of( + argument_area->start, argument_area->finish, namespace_border, + namespace_border + NAMESPACE_BORDER_LENGTH); + const ptrdiff_t index_2 = -1 == index_1 ? index_1 : + string_last_index_of( + argument_area->start, argument_area->finish, namespace_border, + namespace_border + NAMESPACE_BORDER_LENGTH); + + if (-1 == index_1 || index_1 != index_2) { - buffer_release(&value); - return 0; + if (!buffer_resize(&value, 0) || + !string_un_quote(argument_area) || + !buffer_append_data_from_range(&value, argument_area)) + { + buffer_release(&value); + return 0; + } } } } @@ -1725,7 +1737,7 @@ uint8_t interpreter_evaluate_task(void* the_project, const void* the_target, uin break; } - task_attributes_count = copy_evaluate_task(&task_arguments, verbose); + task_attributes_count = copy_evaluate_task(the_project, the_target, &task_arguments, verbose); break; case delete_task: @@ -1961,7 +1973,7 @@ uint8_t interpreter_evaluate_task(void* the_project, const void* the_target, uin break; } - task_attributes_count = move_evaluate_task(&task_arguments, verbose); + task_attributes_count = move_evaluate_task(the_project, the_target, &task_arguments, verbose); break; case program_task: diff --git a/tests.xml b/tests.xml index 57fa94f..f3e7221 100644 --- a/tests.xml +++ b/tests.xml @@ -1394,7 +1394,7 @@ ${string::empty( environment::get-folder-path('MyComputer') )} - False + True 1 @@ -1618,14 +1618,14 @@ ${string::empty( environment::get-folder-path('LocalizedResources') )} - False + True 1 ${string::empty( environment::get-folder-path('CommonOemLinks') )} - False + True 1 @@ -1636,8 +1636,8 @@ 1 - ${string::empty(environment::get-machine-name())} - False + ${math::less(string::get-length(environment::get-machine-name()), 255)} + True 1 @@ -4189,7 +4189,6 @@ Hello! Do you know that last-index-of('ABAB', 'B') is ${string::last-index-of('A - @@ -5031,6 +5030,287 @@ Hello! Do you know that last-index-of('ABAB', 'B') is ${string::last-index-of('A 1 Copy/move file sample 2. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + 1 + Copy/move file sample 3. + ${path::get-temp-path()} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + 1 + Copy/move file sample 4. + + + + + + + + + + + + + + + + ]]> + 1 + Copy/move file sample 5. + ${path::get-temp-path()} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + 1 + Copy/move file sample 6. + ${path::get-temp-path()} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + 1 + Copy/move folder sample 1. + ${path::get-temp-path()} + + + + + + + + + + ]]> + 1 + Copy/move folder sample 2. + ${path::get-temp-path()} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + 1 + Copy/move folder sample 3. + ${path::get-temp-path()} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + 1 + Copy/move folder sample 4. + ${path::get-temp-path()} + diff --git a/tests_project.cpp b/tests_project.cpp index d1e240d..6273e68 100644 --- a/tests_project.cpp +++ b/tests_project.cpp @@ -12,6 +12,7 @@ extern "C" { #include "common.h" #include "conversion.h" #include "file_system.h" +#include "interpreter.h" #include "load_file.h" #include "path.h" #include "project.h" @@ -108,6 +109,7 @@ TEST_F(TestProject, project_load_from_content) std::cout << "[ RUN ]" << std::endl; // const std::string content(node.node().select_node("content").node().child_value()); + struct range content_in_range; const auto project_help = (uint8_t)INT_PARSE( node.node().select_node("project_help").node().child_value()); const auto expected_return = (uint8_t)INT_PARSE( @@ -115,11 +117,23 @@ TEST_F(TestProject, project_load_from_content) const std::string expected_name(node.node().select_node("name").node().child_value()); const std::string expected_default_target(node.node().select_node("default").node().child_value()); const std::string target_to_run(node.node().select_node("target_to_run").node().child_value()); - const std::string expected_base_directory(node.node().select_node("base_directory").node().child_value()); + // + std::string expected_base_directory(node.node().select_node("base_directory").node().child_value()); + + if (!expected_base_directory.empty()) + { + ASSERT_TRUE(buffer_resize(&output, 0)) + << buffer_free(&output); + content_in_range = string_to_range(expected_base_directory); + ASSERT_TRUE(interpreter_evaluate_code(NULL, NULL, &content_in_range, &output, verbose)) + << buffer_free(&output); + expected_base_directory = buffer_to_string(&output); + } + const auto properties = node.node().select_nodes("property"); const auto targets = node.node().select_nodes("target"); // - const auto content_in_range(string_to_range(content)); + content_in_range = string_to_range(content); ASSERT_EQ(content.empty(), range_is_null_or_empty(&content_in_range)) << buffer_free(&output); //