The pointer is a double pointer in the memory function and as such the NULL check should be performed in f_memory.
Add print source and header files to all programs.
Stub out the necessary changes regarding the new setting data type in all programs.
Move file stream functions into their own files.
Add missing file stream lock and unlock functions.
Add F_okay and F_okay_not status codes.
Get utf8, status_code, and fss_status_code working with new program design (including the new settings data type).
build_sources_library directory.c directory/common.c private-directory.c
build_sources_library environment.c
build_sources_library execute.c
-build_sources_library file.c private-file.c file/common.c
+build_sources_library file.c private-file.c file/common.c file/stream.c
build_sources_library fss.c private-fss.c fss/common.c fss/named.c fss/nest.c fss/set.c
build_sources_library iki.c iki/common.c iki/data.c private-iki.c iki/private-data.c
build_sources_library limit.c limit/set.c limit/value.c limit/private-set.c limit/private-value.c
build_sources_headers directory.h directory/common.h directory/type.h
build_sources_headers environment.h environment/common.h
build_sources_headers execute.h execute/common.h
-build_sources_headers file.h file/common.h
+build_sources_headers file.h file/common.h file/stream.h
build_sources_headers fss.h fss/comment.h fss/common.h fss/delimit.h fss/named.h fss/nest.h fss/quote.h fss/set.h
build_sources_headers iki.h iki/common.h iki/data.h
build_sources_headers limit.h limit/set.h limit/value.h
build_sources_library iki.c private-iki.c
build_sources_library path.c
build_sources_library print.c
-build_sources_library program.c program/common.c private-program.c
+build_sources_library program.c program/common.c program/print.c private-program.c
build_sources_library status_string.c
build_sources_headers control_group.h
build_sources_headers iki.h
build_sources_headers path.h
build_sources_headers print.h
-build_sources_headers program.h program/common.h
+build_sources_headers program.h program/common.h program/print.h
build_sources_headers status_string.h
build_script yes
build_sources_library level_0/directory.c level_0/directory/common.c level_0/private-directory.c
build_sources_library level_0/environment.c
build_sources_library level_0/execute.c
-build_sources_library level_0/file.c level_0/private-file.c level_0/file/common.c
+build_sources_library level_0/file.c level_0/private-file.c level_0/file/common.c level_0/file/stream.c
build_sources_library level_0/fss.c level_0/private-fss.c level_0/fss/common.c level_0/fss/named.c level_0/fss/nest.c level_0/fss/set.c
build_sources_library level_0/iki.c level_0/iki/common.c level_0/iki/data.c level_0/private-iki.c level_0/iki/private-data.c
build_sources_library level_0/limit.c level_0/limit/set.c level_0/limit/value.c level_0/limit/private-set.c level_0/limit/private-value.c
build_sources_library level_2/iki.c level_2/private-iki.c
build_sources_library level_2/path.c
build_sources_library level_2/print.c
-build_sources_library level_2/program.c level_2/program/common.c level_2/private-program.c
+build_sources_library level_2/program.c level_2/program/common.c level_2/program/print.c level_2/private-program.c
build_sources_library level_2/status_string.c
build_sources_library-monolithic level_0/thread.c level_0/private-thread.c level_0/thread/attribute.c level_0/thread/barrier.c level_0/thread/barrier_attribute.c level_0/thread/condition.c level_0/thread/condition_attribute.c level_0/thread/id.c level_0/thread/key.c level_0/thread/lock.c level_0/thread/lock_attribute.c level_0/thread/mutex.c level_0/thread/mutex_attribute.c level_0/thread/once.c level_0/thread/semaphore.c level_0/thread/set.c level_0/thread/spin.c
build_sources_headers level_0/directory.h level_0/directory/common.h level_0/directory/type.h
build_sources_headers level_0/environment.h level_0/environment/common.h
build_sources_headers level_0/execute.h level_0/execute/common.h
-build_sources_headers level_0/file.h level_0/file/common.h
+build_sources_headers level_0/file.h level_0/file/common.h level_0/file/stream.h
build_sources_headers level_0/fss.h level_0/fss/comment.h level_0/fss/common.h level_0/fss/delimit.h level_0/fss/named.h level_0/fss/nest.h level_0/fss/quote.h level_0/fss/set.h
build_sources_headers level_0/iki.h level_0/iki/common.h level_0/iki/data.h
build_sources_headers level_0/limit.h level_0/limit/set.h level_0/limit/value.h
build_sources_headers level_2/iki.h
build_sources_headers level_2/path.h
build_sources_headers level_2/print.h
-build_sources_headers level_2/program.h level_2/program/common.h
+build_sources_headers level_2/program.h level_2/program/common.h level_2/program/print.h
build_sources_headers level_2/status_string.h
build_sources_headers-monolithic level_0/thread.h level_0/thread/attribute.h level_0/thread/barrier.h level_0/thread/barrier_attribute.h level_0/thread/condition.h level_0/thread/condition_attribute.h level_0/thread/id.h level_0/thread/key.h level_0/thread/lock.h level_0/thread/lock_attribute.h level_0/thread/mutex.h level_0/thread/mutex_attribute.h level_0/thread/once.h level_0/thread/semaphore.h level_0/thread/set.h level_0/thread/spin.h
}
#endif // _di_f_file_stat_by_id_
-#ifndef _di_f_file_stream_close_
- f_status_t f_file_stream_close(f_file_t * const file) {
- #ifndef _di_level_0_parameter_checking_
- if (!file) return F_status_set_error(F_parameter);
- #endif // _di_level_0_parameter_checking_
-
- if (!file->stream) return F_stream_not;
-
- if (fclose(file->stream) == EOF) {
-
- // According to man pages, further access to a stream on error results in undefined behavior.
- file->stream = 0;
-
- if (errno == EACCES) return F_status_set_error(F_access_denied);
- if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
- if (errno == EBADF) return F_status_set_error(F_file_descriptor);
- if (errno == EFBIG) return F_status_set_error(F_file_overflow);
- if (errno == EDEADLK) return F_status_set_error(F_deadlock);
- if (errno == EDESTADDRREQ) return F_status_set_error(F_socket_not);
- if (errno == EDQUOT) return F_status_set_error(F_space_not);
- if (errno == EFAULT) return F_status_set_error(F_buffer);
- if (errno == EINTR) return F_status_set_error(F_interrupt);
- if (errno == EINVAL) return F_status_set_error(F_parameter);
- if (errno == EIO) return F_status_set_error(F_input_output);
- if (errno == EMFILE) return F_status_set_error(F_file_descriptor_max);
- if (errno == ENOLCK) return F_status_set_error(F_lock);
- if (errno == ENOSPC) return F_status_set_error(F_space_not);
- if (errno == ENOTDIR) return F_status_set_error(F_file_type_not_directory);
- if (errno == EPERM) return F_status_set_error(F_prohibited);
- if (errno == EPIPE) return F_status_set_error(F_pipe_not);
-
- return F_status_set_error(F_file_close);
- }
-
- file->stream = 0;
-
- return F_none;
- }
-#endif // _di_f_file_stream_close_
-
-#ifndef _di_f_file_stream_flush_
- f_status_t f_file_stream_flush(const f_file_t file) {
-
- if (!file.stream) return F_stream_not;
-
- // Only 0 is considered a success and so any non-zero value could be an error.
- if (fflush(file.stream) != 0) {
- if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
- if (errno == EBADF) return F_status_set_error(F_file_descriptor);
- if (errno == EFAULT) return F_status_set_error(F_buffer);
- if (errno == EINTR) return F_status_set_error(F_interrupt);
- if (errno == EINVAL) return F_status_set_error(F_parameter);
- if (errno == EIO) return F_status_set_error(F_input_output);
- if (errno == EISDIR) return F_status_set_error(F_file_type_directory);
-
- return F_status_set_error(F_file_synchronize);
- }
-
- return F_none;
- }
-#endif // _di_f_file_stream_flush_
-
-#ifndef _di_f_file_stream_open_
- f_status_t f_file_stream_open(const f_string_static_t path, const f_string_static_t mode, f_file_t * const file) {
- #ifndef _di_level_0_parameter_checking_
- if (!file) return F_status_set_error(F_parameter);
- #endif // _di_level_0_parameter_checking_
-
- if (!path.used) return F_data_not;
-
- if (mode.used) {
- file->stream = fopen(path.string, mode.string);
- }
- else {
- file->stream = fopen(path.string, private_f_file_stream_open_mode_determine(file->flag));
- }
-
- if (!file->stream) {
- if (errno == EACCES) return F_status_set_error(F_access_denied);
- if (errno == EDQUOT) return F_status_set_error(F_filesystem_quota_block);
- if (errno == EEXIST) return F_status_set_error(F_file_found);
- if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
- if (errno == EFAULT) return F_status_set_error(F_buffer);
- if (errno == EFBIG || errno == EOVERFLOW) return F_status_set_error(F_number_overflow);
- if (errno == EINTR) return F_status_set_error(F_interrupt);
- if (errno == EINVAL) return F_status_set_error(F_parameter);
- if (errno == ELOOP) return F_status_set_error(F_loop);
- if (errno == ENFILE) return F_status_set_error(F_file_open_max);
- if (errno == ENOENT) return F_status_set_error(F_file_found_not);
- if (errno == ENOTDIR) return F_status_set_error(F_file_type_not_directory);
- if (errno == ENOMEM) return F_status_set_error(F_memory_not);
- if (errno == ENOSPC) return F_status_set_error(F_space_not);
- if (errno == EPERM) return F_status_set_error(F_prohibited);
- if (errno == EROFS) return F_status_set_error(F_read_only);
- if (errno == ETXTBSY) return F_status_set_error(F_busy);
- if (errno == EISDIR) return F_status_set_error(F_directory);
- if (errno == EOPNOTSUPP) return F_status_set_error(F_supported_not);
-
- return F_status_set_error(F_failure);
- }
-
- return F_none;
- }
-#endif // _di_f_file_stream_open_
-
-#ifndef _di_f_file_stream_open_descriptor_
- f_status_t f_file_stream_open_descriptor(const f_string_static_t mode, f_file_t * const file) {
- #ifndef _di_level_0_parameter_checking_
- if (!file) return F_status_set_error(F_parameter);
- #endif // _di_level_0_parameter_checking_
-
- if (file->id == -1) return F_file_descriptor_not;
-
- if (mode.used) {
- file->stream = fdopen(file->id, private_f_file_stream_open_mode_determine(file->flag));
- }
- else {
- file->stream = fdopen(file->id, mode.string);
- }
-
- if (!file->stream) {
- if (errno == EACCES) return F_status_set_error(F_access_denied);
- if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
- if (errno == EBADF) return F_status_set_error(F_file_descriptor);
- if (errno == EFBIG) return F_status_set_error(F_file_overflow);
- if (errno == EDEADLK) return F_status_set_error(F_deadlock);
- if (errno == EDESTADDRREQ) return F_status_set_error(F_socket_not);
- if (errno == EDQUOT) return F_status_set_error(F_space_not);
- if (errno == EFAULT) return F_status_set_error(F_buffer);
- if (errno == EINTR) return F_status_set_error(F_interrupt);
- if (errno == EINVAL) return F_status_set_error(F_parameter);
- if (errno == EIO) return F_status_set_error(F_input_output);
- if (errno == EMFILE) return F_status_set_error(F_file_descriptor_max);
- if (errno == ENODEV) return F_status_set_error(F_device_not);
- if (errno == ENOLCK) return F_status_set_error(F_lock);
- if (errno == ENOMEM) return F_status_set_error(F_memory_not);
- if (errno == ENOSPC) return F_status_set_error(F_space_not);
- if (errno == ENOTDIR) return F_status_set_error(F_file_type_not_directory);
- if (errno == EPERM) return F_status_set_error(F_prohibited);
- if (errno == EPIPE) return F_status_set_error(F_pipe_not);
-
- return F_status_set_error(F_failure);
- }
-
- return F_none;
- }
-#endif // _di_f_file_stream_open_descriptor_
-
-#ifndef _di_f_file_stream_read_
- f_status_t f_file_stream_read(const f_file_t file, f_string_dynamic_t * const buffer) {
- #ifndef _di_level_0_parameter_checking_
- if (!file.size_read) return F_status_set_error(F_parameter);
- if (!buffer) return F_status_set_error(F_parameter);
- #endif // _di_level_0_parameter_checking_
-
- if (!file.stream) return F_stream_not;
-
- flockfile(file.stream);
-
- if (feof_unlocked(file.stream)) {
- funlockfile(file.stream);
-
- return F_none_eof;
- }
-
- if (ferror_unlocked(file.stream)) {
- funlockfile(file.stream);
-
- return F_status_set_error(F_error);
- }
-
- f_status_t status = F_none;
- size_t size_read = 0;
-
- do {
- status = f_string_dynamic_increase_by(file.size_read, buffer);
-
- if (F_status_is_error(status)) {
- funlockfile(file.stream);
-
- return status;
- }
-
- size_read = fread_unlocked(buffer->string + buffer->used, sizeof(f_char_t), file.size_read, file.stream);
-
- if (ferror_unlocked(file.stream)) {
- funlockfile(file.stream);
-
- return F_status_set_error(F_file_read);
- }
-
- buffer->used += size_read;
-
- } while (size_read == file.size_read && !feof_unlocked(file.stream));
-
- funlockfile(file.stream);
-
- return F_none_eof;
- }
-#endif // _di_f_file_stream_read_
-
-#ifndef _di_f_file_stream_read_block_
- f_status_t f_file_stream_read_block(const f_file_t file, f_string_dynamic_t * const buffer) {
- #ifndef _di_level_0_parameter_checking_
- if (!file.size_read) return F_status_set_error(F_parameter);
- if (!buffer) return F_status_set_error(F_parameter);
- #endif // _di_level_0_parameter_checking_
-
- if (!file.stream) return F_stream_not;
-
- flockfile(file.stream);
-
- if (feof_unlocked(file.stream)) {
- funlockfile(file.stream);
-
- return F_none_eof;
- }
-
- if (ferror_unlocked(file.stream)) {
- funlockfile(file.stream);
-
- return F_status_set_error(F_error);
- }
-
- {
- const f_status_t status = f_string_dynamic_increase_by(file.size_read, buffer);
-
- if (F_status_is_error(status)) {
- funlockfile(file.stream);
-
- return status;
- }
- }
-
- const size_t size_read = fread_unlocked(buffer->string + buffer->used, sizeof(f_char_t), file.size_read, file.stream);
-
- if (ferror_unlocked(file.stream)) {
- funlockfile(file.stream);
-
- return F_status_set_error(F_file_read);
- }
-
- if (size_read) {
- buffer->used += size_read;
- }
-
- if (feof_unlocked(file.stream)) {
- funlockfile(file.stream);
-
- return F_none_eof;
- }
-
- funlockfile(file.stream);
-
- return F_none;
- }
-#endif // _di_f_file_stream_read_block_
-
-#ifndef _di_f_file_stream_read_until_
- f_status_t f_file_stream_read_until(const f_file_t file, const f_array_length_t total, f_string_dynamic_t * const buffer) {
- #ifndef _di_level_0_parameter_checking_
- if (!file.size_read) return F_status_set_error(F_parameter);
- if (!buffer) return F_status_set_error(F_parameter);
- #endif // _di_level_0_parameter_checking_
-
- if (!file.stream) return F_stream_not;
- if (!total) return F_data_not;
-
- flockfile(file.stream);
-
- if (feof_unlocked(file.stream)) {
- funlockfile(file.stream);
-
- return F_none_eof;
- }
-
- if (ferror_unlocked(file.stream)) {
- funlockfile(file.stream);
-
- return F_status_set_error(F_error);
- }
-
- {
- const f_status_t status = f_string_dynamic_increase_by(total, buffer);
-
- if (F_status_is_error(status)) {
- funlockfile(file.stream);
-
- return F_none_eof;
- }
- }
-
- f_array_length_t buffer_size = file.size_read;
- f_array_length_t buffer_count = 0;
-
- size_t size_read = 0;
-
- for (;;) {
-
- if (buffer_count + buffer_size > total) {
- buffer_size = total - buffer_count;
- }
-
- size_read = fread_unlocked(buffer->string + buffer->used, sizeof(f_char_t), buffer_size, file.stream);
-
- if (ferror_unlocked(file.stream)) {
- funlockfile(file.stream);
-
- return F_status_set_error(F_file_read);
- }
-
- buffer->used += size_read;
-
- if (feof_unlocked(file.stream)) {
- funlockfile(file.stream);
-
- return F_none_eof;
- }
-
- buffer_count += size_read;
-
- if (buffer_count >= total) break;
- } // for
-
- funlockfile(file.stream);
-
- return F_none_stop;
- }
-#endif // _di_f_file_stream_read_until_
-
-#ifndef _di_f_file_stream_reopen_
- f_status_t f_file_stream_reopen(const f_string_static_t path, const f_string_static_t mode, f_file_t * const file) {
- #ifndef _di_level_0_parameter_checking_
- if (!file) return F_status_set_error(F_parameter);
- #endif // _di_level_0_parameter_checking_
-
- if (!path.used && !mode.used) return F_data_not;
-
- FILE *result = 0;
-
- if (mode.used) {
- result = freopen(path.used ? path.string : 0, mode.string, file->stream);
- }
- else {
- result = freopen(path.used ? path.string : 0, private_f_file_stream_open_mode_determine(file->flag), file->stream);
- }
-
- if (!result) {
- if (errno == EACCES) return F_status_set_error(F_access_denied);
- if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
- if (errno == EBADF) return F_status_set_error(F_file_descriptor);
- if (errno == EFBIG) return F_status_set_error(F_file_overflow);
- if (errno == EDEADLK) return F_status_set_error(F_deadlock);
- if (errno == EDESTADDRREQ) return F_status_set_error(F_socket_not);
- if (errno == EDQUOT) return F_status_set_error(F_space_not);
- if (errno == EFAULT) return F_status_set_error(F_buffer);
- if (errno == EINTR) return F_status_set_error(F_interrupt);
- if (errno == EINVAL) return F_status_set_error(F_parameter);
- if (errno == EIO) return F_status_set_error(F_input_output);
- if (errno == EMFILE) return F_status_set_error(F_file_descriptor_max);
- if (errno == ENOLCK) return F_status_set_error(F_lock);
- if (errno == ENOSPC) return F_status_set_error(F_space_not);
- if (errno == ENOTDIR) return F_status_set_error(F_file_type_not_directory);
- if (errno == EPERM) return F_status_set_error(F_prohibited);
- if (errno == EPIPE) return F_status_set_error(F_pipe_not);
-
- return F_status_set_error(F_failure);
- }
-
- file->stream = result;
-
- return F_none;
- }
-#endif // _di_f_file_stream_reopen_
-
-#ifndef _di_f_file_stream_write_
- f_status_t f_file_stream_write(const f_file_t file, const f_string_static_t buffer, f_array_length_t * const written) {
-
- if (!file.stream || !buffer.used || !file.size_write) {
- if (written) {
- *written = 0;
- }
-
- return file.stream ? F_data_not : F_stream_not;
- }
-
- if (written) {
- const f_status_t status = private_f_file_stream_write_until(file, buffer, buffer.used, written);
-
- if (status == F_none && *written == buffer.used) return F_none_eos;
- }
- else {
- f_array_length_t written_local = 0;
-
- const f_status_t status = private_f_file_stream_write_until(file, buffer, buffer.used, &written_local);
-
- if (status == F_none && written_local == buffer.used) return F_none_eos;
- }
-
- return F_none;
- }
-#endif // _di_f_file_stream_write_
-
-#ifndef _di_f_file_stream_write_block_
- f_status_t f_file_stream_write_block(const f_file_t file, const f_string_static_t buffer, f_array_length_t * const written) {
-
- if (!file.stream || !buffer.used || !file.size_write) {
- if (written) {
- *written = 0;
- }
-
- return file.stream ? F_data_not : F_stream_not;
- }
-
- const f_array_length_t write_max = file.size_write > buffer.used ? buffer.used : file.size_write;
-
- if (written) {
- const f_status_t status = private_f_file_stream_write_until(file, buffer, write_max, written);
-
- if (status == F_none) {
- if (*written == buffer.used) return F_none_eos;
- if (*written == write_max) return F_none_stop;
- }
- }
- else {
- f_array_length_t written_local = 0;
-
- const f_status_t status = private_f_file_stream_write_until(file, buffer, write_max, &written_local);
-
- if (status == F_none) {
- if (written_local == buffer.used) return F_none_eos;
- if (written_local == write_max) return F_none_stop;
- }
- }
-
- return F_none;
- }
-#endif // _di_f_file_stream_write_block_
-
-#ifndef _di_f_file_stream_write_until_
- f_status_t f_file_stream_write_until(const f_file_t file, const f_string_static_t buffer, const f_array_length_t total, f_array_length_t * const written) {
-
- if (!file.stream || !buffer.used || !total || !file.size_write) {
- if (written) {
- *written = 0;
- }
-
- return file.stream ? F_data_not : F_stream_not;
- }
-
- const f_array_length_t write_max = total > buffer.used ? buffer.used : total;
-
- if (written) {
- const f_status_t status = private_f_file_stream_write_until(file, buffer, write_max, written);
-
- if (status == F_none) {
- if (*written == buffer.used) return F_none_eos;
- if (*written == write_max) return F_none_stop;
- }
- }
- else {
- f_array_length_t written_local = 0;
-
- const f_status_t status = private_f_file_stream_write_until(file, buffer, buffer.used, &written_local);
-
- if (status == F_none) {
- if (written_local == buffer.used) return F_none_eos;
- if (written_local == write_max) return F_none_stop;
- }
- }
-
- return F_none;
- }
-#endif // _di_f_file_stream_write_until_
-
-#ifndef _di_f_file_stream_write_range_
- f_status_t f_file_stream_write_range(const f_file_t file, const f_string_static_t buffer, const f_string_range_t range, f_array_length_t * const written) {
-
- if (!file.stream || !buffer.used || range.start > range.stop || range.start >= buffer.used || !file.size_write) {
- if (written) {
- *written = 0;
- }
-
- return file.stream ? F_data_not : F_stream_not;
- }
-
- const f_array_length_t write_max = (range.stop - range.start) + 1 > buffer.used ? buffer.used : (range.stop - range.start) + 1;
-
- if (written) {
- const f_string_static_t buffer_adjusted = macro_f_string_static_t_initialize(buffer.string + range.start, 0, buffer.used - range.start);
-
- const f_status_t status = private_f_file_stream_write_until(file, buffer_adjusted, write_max, written);
-
- if (status == F_none) {
- if (range.start + *written == buffer.used) return F_none_eos;
- if (range.start + *written == write_max) return F_none_stop;
- }
- }
- else {
- const f_string_static_t buffer_adjusted = macro_f_string_static_t_initialize(buffer.string + range.start, 0, buffer.used - range.start);
- f_array_length_t written_local = 0;
-
- const f_status_t status = private_f_file_stream_write_until(file, buffer_adjusted, write_max, &written_local);
-
- if (status == F_none) {
- if (range.start + written_local == buffer.used) return F_none_eos;
- if (range.start + written_local == write_max) return F_none_stop;
- }
- }
-
- return F_none;
- }
-#endif // _di_f_file_stream_write_range_
-
#ifndef _di_f_file_touch_
f_status_t f_file_touch(const f_string_static_t path, const mode_t mode, const bool dereference) {
*
* Provides structures and data types for a file I/O.
* Provides operations for opening/closing files.
- *
- * @fixme Currently this uses makedev(3) to create devices, which is non-standard.
- * The documentation for mknod(2) isn't clear on how to make major/minor based block and character devices.
- * Find out how to implement this and elliminate the use of the non-standard makedev(3) call.
*/
#ifndef _F_file_h
#define _F_file_h
// FLL-0 file includes.
#include <fll/level_0/file/common.h>
+#include <fll/level_0/file/stream.h>
#ifdef __cplusplus
extern "C" {
#endif // _di_f_file_stat_by_id_
/**
- * Close an open file stream.
- *
- * @param file
- * The file information.
- * The file.stream is set to NULL, on both success or on failure.
- *
- * @return
- * F_none on success.
- * F_stream_not if file.stream is NULL.
- *
- * F_access_denied (with error bit) on access denied.
- * F_block (with error bit) if the action would block and non-blocking is set on the stream.
- * F_buffer (with error bit) if the buffer is invalid.
- * F_deadlock (with error bit) if operation would cause a deadlock.
- * F_file_descriptor (with error bit) if file descriptor is invalid.
- * F_file_descriptor_max (with error bit) if max file descriptors is reached.
- * F_file_overflow (with error bit) if the write exceeds some implementation defined maximum file size.
- * F_file_type_not_directory (with error bit) if F_NOTIFY was specified and file.id is not a directory.
- * F_input_output (with error bit) on I/O error.
- * F_interrupt (with error bit) when program received an interrupt signal, halting operation.
- * F_lock (with error bit) if failed to lock, such as lock table is full or too many open segments.
- * F_parameter (with error bit) if a parameter is invalid.
- * F_pipe_not (with error bit) if the stream is a pipe or a socket but the pipe or socket is already closed.
- * F_space_not (with error bit) if file system is out of space (or file system quota is reached).
- * F_socket_not (with error bit) if the datagram socket in which a peer has not been set (for socket related streams).
- *
- * F_file_close (with error bit) on any other error.
- *
- * @see fclose()
- */
-#ifndef _di_f_file_stream_close_
- extern f_status_t f_file_stream_close(f_file_t * const file);
-#endif // _di_f_file_stream_close_
-
-/**
- * Flush a file stream.
- *
- * @param file
- * The file information.
- * The file.id is updated with the file descriptor, if necessary and able.
- *
- * @return
- * F_none is returned on success.
- * F_stream_not if file.stream is NULL.
- * F_file_descriptor_not if file.id is -1.
- *
- * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation.
- * F_buffer (with error bit) if the buffer is invalid.
- * F_file_closed (with error bit) if file is not open.
- * F_file_descriptor (with error bit) if the file descriptor is invalid.
- * F_file_type_directory (with error bit) if file descriptor represents a directory.
- * F_input_output (with error bit) on I/O error.
- * F_interrupt (with error bit) if interrupt was received.
- *
- * F_file_synchronize (with error bit) on any other error.
- *
- * @see fflush()
- */
-#ifndef _di_f_file_stream_flush_
- extern f_status_t f_file_stream_flush(const f_file_t file);
-#endif // _di_f_file_stream_flush_
-
-/**
- * Open a file stream.
- *
- * The file descriptor is retrieved on success, if necessary and able.
- *
- * If the file stream is open, it is closed before re-opening.
- *
- * This is often used for changing the file pointed to by standard streams such as stdout.
- *
- * @param path
- * The file path.
- * @param mode
- * The file modes do use when opening, as an fopen() file mode string.
- * Set mode.used to 0 to determine mode from file.flags (falling back to read only as a failsafe).
- * If neither truncate nor append are specified in write only mode, then the failsafe is to append.
- *
- * File Modes (fopen() file modes vs open file modes):
- * - "r": O_RDONLY.
- * - "w": O_WRONLY | O_CREAT | O_TRUNC.
- * - "a": O_WRONLY | O_CREAT | O_APPEND.
- * - "r+": O_RDWR.
- * - "w+": O_RDWR | O_CREAT | O_TRUNC.
- * - "a+": O_RDWR | O_CREAT | O_APPEND.
- * @param file
- * The file information.
- * The file.stream is updated if necessary.
- * The file.id is updated with the file descriptor, if necessary and able.
- *
- * @return
- * F_none is returned on success.
- * F_data_not if both path.used is 0.
- *
- * F_access_denied (with error bit) on access denied.
- * F_buffer (with error bit) if the buffer is invalid.
- * F_busy (with error bit) if file system is too busy to perform write.
- * F_file_descriptor (with error bit) if unable to load the file descriptor.
- * F_file_found_not (with error bit) if the file was not found.
- * F_file_open_max (with error bit) when system-wide max open files is reached.
- * F_file_type_not_directory (with error bit) if F_NOTIFY was specified and file.id is not a directory.
- * F_filesystem_quota_block (with error bit) if file system's disk blocks or inodes are exhausted.
- * F_interrupt (with error bit) when program received an interrupt signal, halting operation.
- * F_loop (with error bit) on loop error.
- * F_memory_not (with error bit) if out of memory.
- * F_name (with error bit) on path name is too long.
- * F_number_overflow (with error bit) on overflow error.
- * F_parameter (with error bit) if a parameter is invalid.
- * F_prohibited (with error bit) if file system does not allow for making changes.
- * F_read_only (with error bit) if file is read-only.
- * F_supported_not (with error bit) fo unsupported file types.
- * F_failure (with error bit) for any other error.
- *
- * @see fopen()
- */
-#ifndef _di_f_file_stream_open_
- extern f_status_t f_file_stream_open(const f_string_static_t path, const f_string_static_t mode, f_file_t * const file);
-#endif // _di_f_file_stream_open_
-
-/**
- * Open a file stream from a file descriptor.
- *
- * @param mode
- * The file modes do use when opening.
- * Set mode.used to 0 to determine mode from file.flags (falling back to read only as a failsafe).
- * If neither truncate nor append are not specified in write only mode, then the failsafe is to append.
- * This should match the modes used to open the file descriptor as it relates to the stream modes.
- * @param file
- * The file with a valid file descriptor (file.id).
- *
- * @return
- * F_none is returned on success.
- * F_file_descriptor_not if file.id is -1.
- *
- * F_access_denied (with error bit) on access denied.
- * F_block (with error bit) if the action would block and non-blocking is set on the stream.
- * F_buffer (with error bit) if the buffer is invalid.
- * F_deadlock (with error bit) if operation would cause a deadlock.
- * F_file_descriptor (with error bit) if file descriptor is invalid.
- * F_file_descriptor_max (with error bit) if max file descriptors is reached.
- * F_file_overflow (with error bit) if the write exceeds some implementation defined maximum file size.
- * F_file_type_not_directory (with error bit) if F_NOTIFY was specified and file.id is not a directory.
- * F_interrupt (with error bit) when program received an interrupt signal, halting operation.
- * F_lock (with error bit) if failed to lock, such as lock table is full or too many open segments.
- * F_parameter (with error bit) if a parameter is invalid.
- * F_pipe_not (with error bit) if the stream is a pipe or a socket but the pipe or socket is already closed.
- * F_prohibited (with error bit) if file system does not allow for making changes.
- * F_socket_not (with error bit) if socket is not connected.
- * F_space_not (with error bit) if the file system is out of space (or file system quota is reached).
- *
- * @see fdopen()
- */
-#ifndef _di_f_file_stream_open_descriptor_
- extern f_status_t f_file_stream_open_descriptor(const f_string_static_t mode, f_file_t * const file);
-#endif // _di_f_file_stream_open_descriptor_
-
-/**
- * Read until EOF is reached.
- *
- * To check how much was read into the buffer, record buffer->used before execution and compare to buffer->used after execution.
- *
- * @param file
- * The file to read.
- * The file.size_read represents the amount to process at a given time.
- * @param buffer
- * The buffer the file is being read into.
- * The contents of the file is appended into this buffer.
- *
- * @return
- * F_none_eof on success and EOF was reached.
- * F_stream_not if file.stream is NULL.
- *
- * F_block (with error bit) if file descriptor is set to non-block and the read would result in a blocking operation.
- * F_buffer (with error bit) if the buffer is invalid.
- * F_error (with error bit) if the file is already in the error state at the start of this function.
- * F_file_closed (with error bit) if file is not open.
- * F_file_descriptor (with error bit) if the file descriptor is invalid.
- * F_file_type_directory (with error bit) if file descriptor represents a directory.
- * F_input_output (with error bit) on I/O error.
- * F_interrupt (with error bit) if interrupt was received.
- * F_parameter (with error bit) if a parameter is invalid.
- *
- * @see flockfile()
- * @see feof_unlocked()
- * @see ferror_unlocked()
- * @see fread_unlocked()
- * @see funlockfile()
- */
-#ifndef _di_f_file_stream_read_
- extern f_status_t f_file_stream_read(const f_file_t file, f_string_dynamic_t * const buffer);
-#endif // _di_f_file_stream_read_
-
-/**
- * Read until a single block is filled or EOF is reached.
- *
- * To determine how much was read into the buffer, record buffer->used before execution and compare to buffer->used after execution.
- *
- * @param file
- * The file to read.
- * The file.size_read represents the amount to process at a given time.
- * @param buffer
- * The buffer the file is being read into.
- * The contents of the file is appended into this buffer.
- *
- * @return
- * F_none on success.
- * F_none_eof on success and EOF was reached.
- * F_stream_not if file.stream is NULL.
- *
- * F_error (with error bit) if the file is already in the error state at the start of this function.
- * F_file_closed (with error bit) if the file is closed.
- * F_file_read (with error bit) on file read error.
- * F_parameter (with error bit) if a parameter is invalid.
- *
- * @see feof_unlocked()
- * @see ferror_unlocked()
- * @see flockfile()
- * @see fread()
- * @see funlockfile()
- */
-#ifndef _di_f_file_stream_read_block_
- extern f_status_t f_file_stream_read_block(const f_file_t file, f_string_dynamic_t * const buffer);
-#endif // _di_f_file_stream_read_block_
-
-/**
- * Read until a given number or EOF is reached, storing it in the buffer.
- *
- * To check how much was read into the buffer, record buffer->used before execution and compare to buffer->used after execution.
- *
- * This is different from simply using the file.size_read.
- * The file.size_read represents the amount to process at a given time.
- * The total represents the maximum number of file.size_read to process.
- * For example, if file.size_read is 16 and total is 128, then this function would need to be called 8 times until total is reached.
- *
- * @param file
- * The file to read.
- * The file.size_read represents the amount to process at a given time.
- * @param total
- * The total bytes to read, unless EOF is reached first.
- * @param buffer
- * The buffer the file is being read into.
- *
- * @return
- * F_none_eof on success and EOF was reached.
- * F_none_stop on success and total was reached.
- * F_data_not if total is 0.
- * F_stream_not if file.stream is NULL.
- *
- * F_error (with error bit) if the file is already in the error state at the start of this function.
- * F_file_closed (with error bit) if the file is closed.
- * F_file_read (with error bit) on file read error.
- * F_parameter (with error bit) if a parameter is invalid.
- *
- * Errors (with error bit) from: f_string_dynamic_increase_by().
- *
- * @see feof_unlocked()
- * @see ferror_unlocked()
- * @see flockfile()
- * @see fread_unlocked()
- * @see funlockfile()
- *
- * @see f_string_dynamic_increase_by()
- */
-#ifndef _di_f_file_stream_read_until_
- extern f_status_t f_file_stream_read_until(const f_file_t file, const f_array_length_t total, f_string_dynamic_t * const buffer);
-#endif // _di_f_file_stream_read_until_
-
-/**
- * Re-open a file stream.
- *
- * This allows for re-using an existing file stream and possibly file-descriptor.
- *
- * The file descriptor is retrieved on success, if necessary and able.
- *
- * @param path
- * The file path.
- * Set path.used to 0 with a non-empty mode (mode.used > 0) to only change the mode of the existing stream.
- * @param mode
- * The file modes do use when opening.
- * Set to 0 to determine mode from file.flags (falling back to read only as a failsafe).
- * If neither truncate nor append are not specified in write only mode, then the failsafe is to append.
- * @param file
- * The file information.
- * The file.stream is updated, if necessary.
- *
- * @return
- * F_none is returned on success.
- * F_data_not if both path.used and mode.used are 0.
- *
- * F_access_denied (with error bit) on access denied.
- * F_buffer (with error bit) if the buffer is invalid.
- * F_busy (with error bit) if file system is too busy to perform write.
- * F_file_descriptor (with error bit) if unable to load the file descriptor.
- * F_file_found_not (with error bit) if the file was not found.
- * F_file_open_max (with error bit) when system-wide max open files is reached.
- * F_file_type_not_directory (with error bit) if F_NOTIFY was specified and file.id is not a directory.
- * F_filesystem_quota_block (with error bit) if file system's disk blocks or inodes are exhausted.
- * F_interrupt (with error bit) when program received an interrupt signal, halting operation.
- * F_loop (with error bit) on loop error.
- * F_memory_not (with error bit) if out of memory.
- * F_name (with error bit) on path name is too long.
- * F_number_overflow (with error bit) on overflow error.
- * F_parameter (with error bit) if a parameter is invalid.
- * F_prohibited (with error bit) if file system does not allow for making changes.
- * F_read_only (with error bit) if file is read-only.
- * F_supported_not (with error bit) fo unsupported file types.
- * F_failure (with error bit) for any other error.
- *
- * @see fileno()
- * @see freopen()
- */
-#ifndef _di_f_file_stream_reopen_
- extern f_status_t f_file_stream_reopen(const f_string_static_t path, const f_string_static_t mode, f_file_t * const file);
-#endif // _di_f_file_stream_reopen_
-
-/**
- * Write until entire buffer is written.
- *
- * @param file
- * The file to write to.
- * The file must already be open.
- * The file.size_write represents the amount to process at a given time.
- * @param buffer
- * The buffer to write to the file.
- * @param written
- * (optional) The total bytes written.
- * Set to NULL to not use.
- *
- * @return
- * F_none on success.
- * F_none_eof when the file stream is at the end of the file.
- * F_none_stop on success but no data was written (written == 0) (not an error and often happens if file type is not a regular file).
- * F_data_not on success but buffer.used is 0.
- * F_stream_not if file.stream is NULL.
- *
- * F_file_write (with error bit) on error during file write.
- * F_parameter (with error bit) if a parameter is invalid.
- *
- * F_file_write (with error bit) on any other error.
- *
- * @see ferror_unlocked()
- * @see flockfile()
- * @see fwrite_unlocked()
- * @see funlockfile()
- */
-#ifndef _di_f_file_stream_write_
- extern f_status_t f_file_stream_write(const f_file_t file, const f_string_static_t buffer, f_array_length_t * const written);
-#endif // _di_f_file_stream_write_
-
-/**
- * Write until a single block is filled or entire buffer is written.
- *
- * To check how much was write into the buffer, record buffer->used before execution and compare to buffer->used after execution.
- *
- * @param file
- * The file to write to.
- * The file must already be open.
- * The file.size_write represents the amount to process at a given time.
- * @param buffer
- * The buffer to write to the file.
- * @param written
- * (optional) The total bytes written.
- * Set to NULL to not use.
- *
- * @return
- * F_none on success.
- * F_none_eof when the file stream is at the end of the file.
- * F_none_stop on success but no data was written (written == 0) (not an error and often happens if file type is not a regular file).
- * F_data_not on success but buffer.used is 0.
- * F_stream_not if file.stream is NULL.
- *
- * F_file_write (with error bit) on error during file write.
- * F_parameter (with error bit) if a parameter is invalid.
- *
- * F_file_write (with error bit) on any other error.
- *
- * @see flockfile()
- * @see fwrite_unlocked()
- * @see ferror_unlocked()
- * @see funlockfile()
- */
-#ifndef _di_f_file_stream_write_block_
- extern f_status_t f_file_stream_write_block(const f_file_t file, const f_string_static_t buffer, f_array_length_t * const written);
-#endif // _di_f_file_stream_write_block_
-
-/**
- * Write until a given number or entire buffer is written.
- *
- * @param file
- * The file to write to.
- * The file must already be open.
- * The file.size_write represents the amount to process at a given time.
- * @param buffer
- * The buffer to write to the file.
- * @param total
- * The total bytes to write, unless end of buffer is reached first.
- * @param written
- * (optional) The total bytes written.
- * Set to NULL to not use..
- *
- * @return
- * F_none on success.
- * F_none_eof when the file stream is at the end of the file.
- * F_none_eos on success but range.stop exceeded buffer.used (only wrote up to buffer.used).
- * F_none_stop on success but no data was written (written == 0) (not an error and often happens if file type is not a regular file).
- * F_data_not on success but either buffer.used or total is 0.
- * F_stream_not if file.stream is NULL.
- *
- * F_file_write (with error bit) on error during file write.
- * F_parameter (with error bit) if a parameter is invalid.
- *
- * F_file_write (with error bit) on any other error.
- *
- * @see flockfile()
- * @see fwrite_unlocked()
- * @see ferror_unlocked()
- * @see funlockfile()
- */
-#ifndef _di_f_file_stream_write_until_
- extern f_status_t f_file_stream_write_until(const f_file_t file, const f_string_static_t buffer, const f_array_length_t total, f_array_length_t * const written);
-#endif // _di_f_file_stream_write_until_
-
-/**
- * Write a given range within the buffer.
- *
- * @param file
- * The file to write to.
- * The file.size_write represents the amount to process at a given time.
- * @param buffer
- * The buffer to write to the file.
- * @param range
- * An inclusive start an stop range within the buffer to read.
- * @param written
- * (optional) The total bytes written.
- * Set to NULL to not use.
- *
- * @return
- * F_none on success.
- * F_none_stop on success but no data was written (written == 0) (not an error and often happens if file type is not a regular file).
- * F_none_eos on success but range.stop exceeded buffer.used (only wrote up to buffer.used).
- * F_stream_not if file.stream is NULL.
- *
- * F_file_write (with error bit) on error during file write.
- * F_parameter (with error bit) if a parameter is invalid.
- *
- * @see fwrite_unlocked()
- */
-#ifndef _di_f_file_stream_write_range_
- extern f_status_t f_file_stream_write_range(const f_file_t file, const f_string_static_t buffer, const f_string_range_t range, f_array_length_t * const written);
-#endif // _di_f_file_stream_write_range_
-
-
-/**
* Update the files access and modification timestamp, creating the file if it does not already exist.
*
* When the file is created, it is created as a regular file.
} // extern "C"
#endif
-#endif // _F_file_h
+#endif // _F_file_common_h
--- /dev/null
+#include "../file.h"
+#include "stream.h"
+#include "../private-file.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_f_file_stream_close_
+ f_status_t f_file_stream_close(f_file_t * const file) {
+ #ifndef _di_level_0_parameter_checking_
+ if (!file) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ if (!file->stream) return F_stream_not;
+
+ if (fclose(file->stream) == EOF) {
+
+ // According to man pages, further access to a stream on error results in undefined behavior.
+ file->stream = 0;
+
+ if (errno == EACCES) return F_status_set_error(F_access_denied);
+ if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
+ if (errno == EBADF) return F_status_set_error(F_file_descriptor);
+ if (errno == EFBIG) return F_status_set_error(F_file_overflow);
+ if (errno == EDEADLK) return F_status_set_error(F_deadlock);
+ if (errno == EDESTADDRREQ) return F_status_set_error(F_socket_not);
+ if (errno == EDQUOT) return F_status_set_error(F_space_not);
+ if (errno == EFAULT) return F_status_set_error(F_buffer);
+ if (errno == EINTR) return F_status_set_error(F_interrupt);
+ if (errno == EINVAL) return F_status_set_error(F_parameter);
+ if (errno == EIO) return F_status_set_error(F_input_output);
+ if (errno == EMFILE) return F_status_set_error(F_file_descriptor_max);
+ if (errno == ENOLCK) return F_status_set_error(F_lock);
+ if (errno == ENOSPC) return F_status_set_error(F_space_not);
+ if (errno == ENOTDIR) return F_status_set_error(F_file_type_not_directory);
+ if (errno == EPERM) return F_status_set_error(F_prohibited);
+ if (errno == EPIPE) return F_status_set_error(F_pipe_not);
+
+ return F_status_set_error(F_file_close);
+ }
+
+ file->stream = 0;
+
+ return F_none;
+ }
+#endif // _di_f_file_stream_close_
+
+#ifndef _di_f_file_stream_flush_
+ f_status_t f_file_stream_flush(const f_file_t file) {
+
+ if (!file.stream) return F_stream_not;
+
+ // Only 0 is considered a success and so any non-zero value could be an error.
+ if (fflush(file.stream) != 0) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
+ if (errno == EBADF) return F_status_set_error(F_file_descriptor);
+ if (errno == EFAULT) return F_status_set_error(F_buffer);
+ if (errno == EINTR) return F_status_set_error(F_interrupt);
+ if (errno == EINVAL) return F_status_set_error(F_parameter);
+ if (errno == EIO) return F_status_set_error(F_input_output);
+ if (errno == EISDIR) return F_status_set_error(F_file_type_directory);
+
+ return F_status_set_error(F_file_synchronize);
+ }
+
+ return F_none;
+ }
+#endif // _di_f_file_stream_flush_
+
+#ifndef _di_f_file_stream_lock_
+ f_status_t f_file_stream_lock(const f_file_t file) {
+
+ if (!file.stream) return F_stream_not;
+
+ flockfile(file.stream);
+
+ return F_none;
+ }
+#endif // _di_f_file_stream_lock_
+
+#ifndef _di_f_file_stream_lock_try_
+ f_status_t f_file_stream_lock_try(const f_file_t file) {
+
+ if (!file.stream) return F_stream_not;
+
+ if (ftrylockfile(file.stream)) return F_busy;
+
+ return F_none;
+ }
+#endif // _di_f_file_stream_lock_try_
+
+#ifndef _di_f_file_stream_open_
+ f_status_t f_file_stream_open(const f_string_static_t path, const f_string_static_t mode, f_file_t * const file) {
+ #ifndef _di_level_0_parameter_checking_
+ if (!file) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ if (!path.used) return F_data_not;
+
+ if (mode.used) {
+ file->stream = fopen(path.string, mode.string);
+ }
+ else {
+ file->stream = fopen(path.string, private_f_file_stream_open_mode_determine(file->flag));
+ }
+
+ if (!file->stream) {
+ if (errno == EACCES) return F_status_set_error(F_access_denied);
+ if (errno == EDQUOT) return F_status_set_error(F_filesystem_quota_block);
+ if (errno == EEXIST) return F_status_set_error(F_file_found);
+ if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
+ if (errno == EFAULT) return F_status_set_error(F_buffer);
+ if (errno == EFBIG || errno == EOVERFLOW) return F_status_set_error(F_number_overflow);
+ if (errno == EINTR) return F_status_set_error(F_interrupt);
+ if (errno == EINVAL) return F_status_set_error(F_parameter);
+ if (errno == ELOOP) return F_status_set_error(F_loop);
+ if (errno == ENFILE) return F_status_set_error(F_file_open_max);
+ if (errno == ENOENT) return F_status_set_error(F_file_found_not);
+ if (errno == ENOTDIR) return F_status_set_error(F_file_type_not_directory);
+ if (errno == ENOMEM) return F_status_set_error(F_memory_not);
+ if (errno == ENOSPC) return F_status_set_error(F_space_not);
+ if (errno == EPERM) return F_status_set_error(F_prohibited);
+ if (errno == EROFS) return F_status_set_error(F_read_only);
+ if (errno == ETXTBSY) return F_status_set_error(F_busy);
+ if (errno == EISDIR) return F_status_set_error(F_directory);
+ if (errno == EOPNOTSUPP) return F_status_set_error(F_supported_not);
+
+ return F_status_set_error(F_failure);
+ }
+
+ return F_none;
+ }
+#endif // _di_f_file_stream_open_
+
+#ifndef _di_f_file_stream_open_descriptor_
+ f_status_t f_file_stream_open_descriptor(const f_string_static_t mode, f_file_t * const file) {
+ #ifndef _di_level_0_parameter_checking_
+ if (!file) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ if (file->id == -1) return F_file_descriptor_not;
+
+ if (mode.used) {
+ file->stream = fdopen(file->id, private_f_file_stream_open_mode_determine(file->flag));
+ }
+ else {
+ file->stream = fdopen(file->id, mode.string);
+ }
+
+ if (!file->stream) {
+ if (errno == EACCES) return F_status_set_error(F_access_denied);
+ if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
+ if (errno == EBADF) return F_status_set_error(F_file_descriptor);
+ if (errno == EFBIG) return F_status_set_error(F_file_overflow);
+ if (errno == EDEADLK) return F_status_set_error(F_deadlock);
+ if (errno == EDESTADDRREQ) return F_status_set_error(F_socket_not);
+ if (errno == EDQUOT) return F_status_set_error(F_space_not);
+ if (errno == EFAULT) return F_status_set_error(F_buffer);
+ if (errno == EINTR) return F_status_set_error(F_interrupt);
+ if (errno == EINVAL) return F_status_set_error(F_parameter);
+ if (errno == EIO) return F_status_set_error(F_input_output);
+ if (errno == EMFILE) return F_status_set_error(F_file_descriptor_max);
+ if (errno == ENODEV) return F_status_set_error(F_device_not);
+ if (errno == ENOLCK) return F_status_set_error(F_lock);
+ if (errno == ENOMEM) return F_status_set_error(F_memory_not);
+ if (errno == ENOSPC) return F_status_set_error(F_space_not);
+ if (errno == ENOTDIR) return F_status_set_error(F_file_type_not_directory);
+ if (errno == EPERM) return F_status_set_error(F_prohibited);
+ if (errno == EPIPE) return F_status_set_error(F_pipe_not);
+
+ return F_status_set_error(F_failure);
+ }
+
+ return F_none;
+ }
+#endif // _di_f_file_stream_open_descriptor_
+
+#ifndef _di_f_file_stream_read_
+ f_status_t f_file_stream_read(const f_file_t file, f_string_dynamic_t * const buffer) {
+ #ifndef _di_level_0_parameter_checking_
+ if (!file.size_read) return F_status_set_error(F_parameter);
+ if (!buffer) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ if (!file.stream) return F_stream_not;
+
+ flockfile(file.stream);
+
+ if (feof_unlocked(file.stream)) {
+ funlockfile(file.stream);
+
+ return F_none_eof;
+ }
+
+ if (ferror_unlocked(file.stream)) {
+ funlockfile(file.stream);
+
+ return F_status_set_error(F_error);
+ }
+
+ f_status_t status = F_none;
+ size_t size_read = 0;
+
+ do {
+ status = f_string_dynamic_increase_by(file.size_read, buffer);
+
+ if (F_status_is_error(status)) {
+ funlockfile(file.stream);
+
+ return status;
+ }
+
+ size_read = fread_unlocked(buffer->string + buffer->used, sizeof(f_char_t), file.size_read, file.stream);
+
+ if (ferror_unlocked(file.stream)) {
+ funlockfile(file.stream);
+
+ return F_status_set_error(F_file_read);
+ }
+
+ buffer->used += size_read;
+
+ } while (size_read == file.size_read && !feof_unlocked(file.stream));
+
+ funlockfile(file.stream);
+
+ return F_none_eof;
+ }
+#endif // _di_f_file_stream_read_
+
+#ifndef _di_f_file_stream_read_block_
+ f_status_t f_file_stream_read_block(const f_file_t file, f_string_dynamic_t * const buffer) {
+ #ifndef _di_level_0_parameter_checking_
+ if (!file.size_read) return F_status_set_error(F_parameter);
+ if (!buffer) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ if (!file.stream) return F_stream_not;
+
+ flockfile(file.stream);
+
+ if (feof_unlocked(file.stream)) {
+ funlockfile(file.stream);
+
+ return F_none_eof;
+ }
+
+ if (ferror_unlocked(file.stream)) {
+ funlockfile(file.stream);
+
+ return F_status_set_error(F_error);
+ }
+
+ {
+ const f_status_t status = f_string_dynamic_increase_by(file.size_read, buffer);
+
+ if (F_status_is_error(status)) {
+ funlockfile(file.stream);
+
+ return status;
+ }
+ }
+
+ const size_t size_read = fread_unlocked(buffer->string + buffer->used, sizeof(f_char_t), file.size_read, file.stream);
+
+ if (ferror_unlocked(file.stream)) {
+ funlockfile(file.stream);
+
+ return F_status_set_error(F_file_read);
+ }
+
+ if (size_read) {
+ buffer->used += size_read;
+ }
+
+ if (feof_unlocked(file.stream)) {
+ funlockfile(file.stream);
+
+ return F_none_eof;
+ }
+
+ funlockfile(file.stream);
+
+ return F_none;
+ }
+#endif // _di_f_file_stream_read_block_
+
+#ifndef _di_f_file_stream_read_until_
+ f_status_t f_file_stream_read_until(const f_file_t file, const f_array_length_t total, f_string_dynamic_t * const buffer) {
+ #ifndef _di_level_0_parameter_checking_
+ if (!file.size_read) return F_status_set_error(F_parameter);
+ if (!buffer) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ if (!file.stream) return F_stream_not;
+ if (!total) return F_data_not;
+
+ flockfile(file.stream);
+
+ if (feof_unlocked(file.stream)) {
+ funlockfile(file.stream);
+
+ return F_none_eof;
+ }
+
+ if (ferror_unlocked(file.stream)) {
+ funlockfile(file.stream);
+
+ return F_status_set_error(F_error);
+ }
+
+ {
+ const f_status_t status = f_string_dynamic_increase_by(total, buffer);
+
+ if (F_status_is_error(status)) {
+ funlockfile(file.stream);
+
+ return F_none_eof;
+ }
+ }
+
+ f_array_length_t buffer_size = file.size_read;
+ f_array_length_t buffer_count = 0;
+
+ size_t size_read = 0;
+
+ for (;;) {
+
+ if (buffer_count + buffer_size > total) {
+ buffer_size = total - buffer_count;
+ }
+
+ size_read = fread_unlocked(buffer->string + buffer->used, sizeof(f_char_t), buffer_size, file.stream);
+
+ if (ferror_unlocked(file.stream)) {
+ funlockfile(file.stream);
+
+ return F_status_set_error(F_file_read);
+ }
+
+ buffer->used += size_read;
+
+ if (feof_unlocked(file.stream)) {
+ funlockfile(file.stream);
+
+ return F_none_eof;
+ }
+
+ buffer_count += size_read;
+
+ if (buffer_count >= total) break;
+ } // for
+
+ funlockfile(file.stream);
+
+ return F_none_stop;
+ }
+#endif // _di_f_file_stream_read_until_
+
+#ifndef _di_f_file_stream_reopen_
+ f_status_t f_file_stream_reopen(const f_string_static_t path, const f_string_static_t mode, f_file_t * const file) {
+ #ifndef _di_level_0_parameter_checking_
+ if (!file) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ if (!path.used && !mode.used) return F_data_not;
+
+ FILE *result = 0;
+
+ if (mode.used) {
+ result = freopen(path.used ? path.string : 0, mode.string, file->stream);
+ }
+ else {
+ result = freopen(path.used ? path.string : 0, private_f_file_stream_open_mode_determine(file->flag), file->stream);
+ }
+
+ if (!result) {
+ if (errno == EACCES) return F_status_set_error(F_access_denied);
+ if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
+ if (errno == EBADF) return F_status_set_error(F_file_descriptor);
+ if (errno == EFBIG) return F_status_set_error(F_file_overflow);
+ if (errno == EDEADLK) return F_status_set_error(F_deadlock);
+ if (errno == EDESTADDRREQ) return F_status_set_error(F_socket_not);
+ if (errno == EDQUOT) return F_status_set_error(F_space_not);
+ if (errno == EFAULT) return F_status_set_error(F_buffer);
+ if (errno == EINTR) return F_status_set_error(F_interrupt);
+ if (errno == EINVAL) return F_status_set_error(F_parameter);
+ if (errno == EIO) return F_status_set_error(F_input_output);
+ if (errno == EMFILE) return F_status_set_error(F_file_descriptor_max);
+ if (errno == ENOLCK) return F_status_set_error(F_lock);
+ if (errno == ENOSPC) return F_status_set_error(F_space_not);
+ if (errno == ENOTDIR) return F_status_set_error(F_file_type_not_directory);
+ if (errno == EPERM) return F_status_set_error(F_prohibited);
+ if (errno == EPIPE) return F_status_set_error(F_pipe_not);
+
+ return F_status_set_error(F_failure);
+ }
+
+ file->stream = result;
+
+ return F_none;
+ }
+#endif // _di_f_file_stream_reopen_
+
+#ifndef _di_f_file_stream_unlock_
+ f_status_t f_file_stream_unlock(const f_file_t file) {
+
+ if (!file.stream) return F_stream_not;
+
+ funlockfile(file.stream);
+
+ return F_none;
+ }
+#endif // _di_f_file_stream_unlock_
+
+#ifndef _di_f_file_stream_write_
+ f_status_t f_file_stream_write(const f_file_t file, const f_string_static_t buffer, f_array_length_t * const written) {
+
+ if (!file.stream || !buffer.used || !file.size_write) {
+ if (written) {
+ *written = 0;
+ }
+
+ return file.stream ? F_data_not : F_stream_not;
+ }
+
+ if (written) {
+ const f_status_t status = private_f_file_stream_write_until(file, buffer, buffer.used, written);
+
+ if (status == F_none && *written == buffer.used) return F_none_eos;
+ }
+ else {
+ f_array_length_t written_local = 0;
+
+ const f_status_t status = private_f_file_stream_write_until(file, buffer, buffer.used, &written_local);
+
+ if (status == F_none && written_local == buffer.used) return F_none_eos;
+ }
+
+ return F_none;
+ }
+#endif // _di_f_file_stream_write_
+
+#ifndef _di_f_file_stream_write_block_
+ f_status_t f_file_stream_write_block(const f_file_t file, const f_string_static_t buffer, f_array_length_t * const written) {
+
+ if (!file.stream || !buffer.used || !file.size_write) {
+ if (written) {
+ *written = 0;
+ }
+
+ return file.stream ? F_data_not : F_stream_not;
+ }
+
+ const f_array_length_t write_max = file.size_write > buffer.used ? buffer.used : file.size_write;
+
+ if (written) {
+ const f_status_t status = private_f_file_stream_write_until(file, buffer, write_max, written);
+
+ if (status == F_none) {
+ if (*written == buffer.used) return F_none_eos;
+ if (*written == write_max) return F_none_stop;
+ }
+ }
+ else {
+ f_array_length_t written_local = 0;
+
+ const f_status_t status = private_f_file_stream_write_until(file, buffer, write_max, &written_local);
+
+ if (status == F_none) {
+ if (written_local == buffer.used) return F_none_eos;
+ if (written_local == write_max) return F_none_stop;
+ }
+ }
+
+ return F_none;
+ }
+#endif // _di_f_file_stream_write_block_
+
+#ifndef _di_f_file_stream_write_until_
+ f_status_t f_file_stream_write_until(const f_file_t file, const f_string_static_t buffer, const f_array_length_t total, f_array_length_t * const written) {
+
+ if (!file.stream || !buffer.used || !total || !file.size_write) {
+ if (written) {
+ *written = 0;
+ }
+
+ return file.stream ? F_data_not : F_stream_not;
+ }
+
+ const f_array_length_t write_max = total > buffer.used ? buffer.used : total;
+
+ if (written) {
+ const f_status_t status = private_f_file_stream_write_until(file, buffer, write_max, written);
+
+ if (status == F_none) {
+ if (*written == buffer.used) return F_none_eos;
+ if (*written == write_max) return F_none_stop;
+ }
+ }
+ else {
+ f_array_length_t written_local = 0;
+
+ const f_status_t status = private_f_file_stream_write_until(file, buffer, buffer.used, &written_local);
+
+ if (status == F_none) {
+ if (written_local == buffer.used) return F_none_eos;
+ if (written_local == write_max) return F_none_stop;
+ }
+ }
+
+ return F_none;
+ }
+#endif // _di_f_file_stream_write_until_
+
+#ifndef _di_f_file_stream_write_range_
+ f_status_t f_file_stream_write_range(const f_file_t file, const f_string_static_t buffer, const f_string_range_t range, f_array_length_t * const written) {
+
+ if (!file.stream || !buffer.used || range.start > range.stop || range.start >= buffer.used || !file.size_write) {
+ if (written) {
+ *written = 0;
+ }
+
+ return file.stream ? F_data_not : F_stream_not;
+ }
+
+ const f_array_length_t write_max = (range.stop - range.start) + 1 > buffer.used ? buffer.used : (range.stop - range.start) + 1;
+
+ if (written) {
+ const f_string_static_t buffer_adjusted = macro_f_string_static_t_initialize(buffer.string + range.start, 0, buffer.used - range.start);
+
+ const f_status_t status = private_f_file_stream_write_until(file, buffer_adjusted, write_max, written);
+
+ if (status == F_none) {
+ if (range.start + *written == buffer.used) return F_none_eos;
+ if (range.start + *written == write_max) return F_none_stop;
+ }
+ }
+ else {
+ const f_string_static_t buffer_adjusted = macro_f_string_static_t_initialize(buffer.string + range.start, 0, buffer.used - range.start);
+ f_array_length_t written_local = 0;
+
+ const f_status_t status = private_f_file_stream_write_until(file, buffer_adjusted, write_max, &written_local);
+
+ if (status == F_none) {
+ if (range.start + written_local == buffer.used) return F_none_eos;
+ if (range.start + written_local == write_max) return F_none_stop;
+ }
+ }
+
+ return F_none;
+ }
+#endif // _di_f_file_stream_write_range_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 0
+ *
+ * Project: File
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Defines common data to be used for/by project file.
+ *
+ * This is auto-included by file.h and should not need to be explicitly included.
+ */
+#ifndef _F_file_stream_h
+#define _F_file_stream_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Close an open file stream.
+ *
+ * @param file
+ * The file information.
+ * The file.stream is set to NULL, on both success or on failure.
+ *
+ * @return
+ * F_none on success.
+ * F_stream_not if file.stream is NULL.
+ *
+ * F_access_denied (with error bit) on access denied.
+ * F_block (with error bit) if the action would block and non-blocking is set on the stream.
+ * F_buffer (with error bit) if the buffer is invalid.
+ * F_deadlock (with error bit) if operation would cause a deadlock.
+ * F_file_descriptor (with error bit) if file descriptor is invalid.
+ * F_file_descriptor_max (with error bit) if max file descriptors is reached.
+ * F_file_overflow (with error bit) if the write exceeds some implementation defined maximum file size.
+ * F_file_type_not_directory (with error bit) if F_NOTIFY was specified and file.id is not a directory.
+ * F_input_output (with error bit) on I/O error.
+ * F_interrupt (with error bit) when program received an interrupt signal, halting operation.
+ * F_lock (with error bit) if failed to lock, such as lock table is full or too many open segments.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_pipe_not (with error bit) if the stream is a pipe or a socket but the pipe or socket is already closed.
+ * F_space_not (with error bit) if file system is out of space (or file system quota is reached).
+ * F_socket_not (with error bit) if the datagram socket in which a peer has not been set (for socket related streams).
+ *
+ * F_file_close (with error bit) on any other error.
+ *
+ * @see fclose()
+ */
+#ifndef _di_f_file_stream_close_
+ extern f_status_t f_file_stream_close(f_file_t * const file);
+#endif // _di_f_file_stream_close_
+
+/**
+ * Flush a file stream.
+ *
+ * @param file
+ * The file information.
+ * The file.id is updated with the file descriptor, if necessary and able.
+ *
+ * @return
+ * F_none is returned on success.
+ * F_stream_not if file.stream is NULL.
+ * F_file_descriptor_not if file.id is -1.
+ *
+ * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation.
+ * F_buffer (with error bit) if the buffer is invalid.
+ * F_file_closed (with error bit) if file is not open.
+ * F_file_descriptor (with error bit) if the file descriptor is invalid.
+ * F_file_type_directory (with error bit) if file descriptor represents a directory.
+ * F_input_output (with error bit) on I/O error.
+ * F_interrupt (with error bit) if interrupt was received.
+ *
+ * F_file_synchronize (with error bit) on any other error.
+ *
+ * @see fflush()
+ */
+#ifndef _di_f_file_stream_flush_
+ extern f_status_t f_file_stream_flush(const f_file_t file);
+#endif // _di_f_file_stream_flush_
+
+/**
+ * Lock a file stream.
+ *
+ * As per flockfile(), this waits (blocks) until the file stream is available to lock again.
+ *
+ * @param file
+ * The file to lock.
+ *
+ * @return
+ * F_none on success.
+ * F_stream_not if file.stream is NULL.
+ *
+ * @see flockfile()
+ */
+#ifndef _di_f_file_stream_lock_
+ extern f_status_t f_file_stream_lock(const f_file_t file);
+#endif // _di_f_file_stream_lock_
+
+/**
+ * Try to lock a file stream.
+ *
+ * As per flockfile(), this does not wait (does not block) when the file stream is already locked.
+ *
+ * @param file
+ * The file to lock.
+ *
+ * @return
+ * F_none on success.
+ * F_busy on success, but the file.stream is already locked.
+ * F_stream_not if file.stream is NULL.
+ *
+ * @see ftrylockfile()
+ */
+#ifndef _di_f_file_stream_lock_try_
+ extern f_status_t f_file_stream_lock_try(const f_file_t file);
+#endif // _di_f_file_stream_lock_try_
+
+/**
+ * Open a file stream.
+ *
+ * The file descriptor is retrieved on success, if necessary and able.
+ *
+ * If the file stream is open, it is closed before re-opening.
+ *
+ * This is often used for changing the file pointed to by standard streams such as stdout.
+ *
+ * @param path
+ * The file path.
+ * @param mode
+ * The file modes do use when opening, as an fopen() file mode string.
+ * Set mode.used to 0 to determine mode from file.flags (falling back to read only as a failsafe).
+ * If neither truncate nor append are specified in write only mode, then the failsafe is to append.
+ *
+ * File Modes (fopen() file modes vs open file modes):
+ * - "r": O_RDONLY.
+ * - "w": O_WRONLY | O_CREAT | O_TRUNC.
+ * - "a": O_WRONLY | O_CREAT | O_APPEND.
+ * - "r+": O_RDWR.
+ * - "w+": O_RDWR | O_CREAT | O_TRUNC.
+ * - "a+": O_RDWR | O_CREAT | O_APPEND.
+ * @param file
+ * The file information.
+ * The file.stream is updated if necessary.
+ * The file.id is updated with the file descriptor, if necessary and able.
+ *
+ * @return
+ * F_none is returned on success.
+ * F_data_not if both path.used is 0.
+ *
+ * F_access_denied (with error bit) on access denied.
+ * F_buffer (with error bit) if the buffer is invalid.
+ * F_busy (with error bit) if file system is too busy to perform write.
+ * F_file_descriptor (with error bit) if unable to load the file descriptor.
+ * F_file_found_not (with error bit) if the file was not found.
+ * F_file_open_max (with error bit) when system-wide max open files is reached.
+ * F_file_type_not_directory (with error bit) if F_NOTIFY was specified and file.id is not a directory.
+ * F_filesystem_quota_block (with error bit) if file system's disk blocks or inodes are exhausted.
+ * F_interrupt (with error bit) when program received an interrupt signal, halting operation.
+ * F_loop (with error bit) on loop error.
+ * F_memory_not (with error bit) if out of memory.
+ * F_name (with error bit) on path name is too long.
+ * F_number_overflow (with error bit) on overflow error.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_prohibited (with error bit) if file system does not allow for making changes.
+ * F_read_only (with error bit) if file is read-only.
+ * F_supported_not (with error bit) fo unsupported file types.
+ * F_failure (with error bit) for any other error.
+ *
+ * @see fopen()
+ */
+#ifndef _di_f_file_stream_open_
+ extern f_status_t f_file_stream_open(const f_string_static_t path, const f_string_static_t mode, f_file_t * const file);
+#endif // _di_f_file_stream_open_
+
+/**
+ * Open a file stream from a file descriptor.
+ *
+ * @param mode
+ * The file modes do use when opening.
+ * Set mode.used to 0 to determine mode from file.flags (falling back to read only as a failsafe).
+ * If neither truncate nor append are not specified in write only mode, then the failsafe is to append.
+ * This should match the modes used to open the file descriptor as it relates to the stream modes.
+ * @param file
+ * The file with a valid file descriptor (file.id).
+ *
+ * @return
+ * F_none is returned on success.
+ * F_file_descriptor_not if file.id is -1.
+ *
+ * F_access_denied (with error bit) on access denied.
+ * F_block (with error bit) if the action would block and non-blocking is set on the stream.
+ * F_buffer (with error bit) if the buffer is invalid.
+ * F_deadlock (with error bit) if operation would cause a deadlock.
+ * F_file_descriptor (with error bit) if file descriptor is invalid.
+ * F_file_descriptor_max (with error bit) if max file descriptors is reached.
+ * F_file_overflow (with error bit) if the write exceeds some implementation defined maximum file size.
+ * F_file_type_not_directory (with error bit) if F_NOTIFY was specified and file.id is not a directory.
+ * F_interrupt (with error bit) when program received an interrupt signal, halting operation.
+ * F_lock (with error bit) if failed to lock, such as lock table is full or too many open segments.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_pipe_not (with error bit) if the stream is a pipe or a socket but the pipe or socket is already closed.
+ * F_prohibited (with error bit) if file system does not allow for making changes.
+ * F_socket_not (with error bit) if socket is not connected.
+ * F_space_not (with error bit) if the file system is out of space (or file system quota is reached).
+ *
+ * @see fdopen()
+ */
+#ifndef _di_f_file_stream_open_descriptor_
+ extern f_status_t f_file_stream_open_descriptor(const f_string_static_t mode, f_file_t * const file);
+#endif // _di_f_file_stream_open_descriptor_
+
+/**
+ * Read until EOF is reached.
+ *
+ * To check how much was read into the buffer, record buffer->used before execution and compare to buffer->used after execution.
+ *
+ * @param file
+ * The file to read.
+ * The file.size_read represents the amount to process at a given time.
+ * @param buffer
+ * The buffer the file is being read into.
+ * The contents of the file is appended into this buffer.
+ *
+ * @return
+ * F_none_eof on success and EOF was reached.
+ * F_stream_not if file.stream is NULL.
+ *
+ * F_block (with error bit) if file descriptor is set to non-block and the read would result in a blocking operation.
+ * F_buffer (with error bit) if the buffer is invalid.
+ * F_error (with error bit) if the file is already in the error state at the start of this function.
+ * F_file_closed (with error bit) if file is not open.
+ * F_file_descriptor (with error bit) if the file descriptor is invalid.
+ * F_file_type_directory (with error bit) if file descriptor represents a directory.
+ * F_input_output (with error bit) on I/O error.
+ * F_interrupt (with error bit) if interrupt was received.
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * @see flockfile()
+ * @see feof_unlocked()
+ * @see ferror_unlocked()
+ * @see fread_unlocked()
+ * @see funlockfile()
+ */
+#ifndef _di_f_file_stream_read_
+ extern f_status_t f_file_stream_read(const f_file_t file, f_string_dynamic_t * const buffer);
+#endif // _di_f_file_stream_read_
+
+/**
+ * Read until a single block is filled or EOF is reached.
+ *
+ * To determine how much was read into the buffer, record buffer->used before execution and compare to buffer->used after execution.
+ *
+ * @param file
+ * The file to read.
+ * The file.size_read represents the amount to process at a given time.
+ * @param buffer
+ * The buffer the file is being read into.
+ * The contents of the file is appended into this buffer.
+ *
+ * @return
+ * F_none on success.
+ * F_none_eof on success and EOF was reached.
+ * F_stream_not if file.stream is NULL.
+ *
+ * F_error (with error bit) if the file is already in the error state at the start of this function.
+ * F_file_closed (with error bit) if the file is closed.
+ * F_file_read (with error bit) on file read error.
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * @see feof_unlocked()
+ * @see ferror_unlocked()
+ * @see flockfile()
+ * @see fread()
+ * @see funlockfile()
+ */
+#ifndef _di_f_file_stream_read_block_
+ extern f_status_t f_file_stream_read_block(const f_file_t file, f_string_dynamic_t * const buffer);
+#endif // _di_f_file_stream_read_block_
+
+/**
+ * Read until a given number or EOF is reached, storing it in the buffer.
+ *
+ * To check how much was read into the buffer, record buffer->used before execution and compare to buffer->used after execution.
+ *
+ * This is different from simply using the file.size_read.
+ * The file.size_read represents the amount to process at a given time.
+ * The total represents the maximum number of file.size_read to process.
+ * For example, if file.size_read is 16 and total is 128, then this function would need to be called 8 times until total is reached.
+ *
+ * @param file
+ * The file to read.
+ * The file.size_read represents the amount to process at a given time.
+ * @param total
+ * The total bytes to read, unless EOF is reached first.
+ * @param buffer
+ * The buffer the file is being read into.
+ *
+ * @return
+ * F_none_eof on success and EOF was reached.
+ * F_none_stop on success and total was reached.
+ * F_data_not if total is 0.
+ * F_stream_not if file.stream is NULL.
+ *
+ * F_error (with error bit) if the file is already in the error state at the start of this function.
+ * F_file_closed (with error bit) if the file is closed.
+ * F_file_read (with error bit) on file read error.
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: f_string_dynamic_increase_by().
+ *
+ * @see feof_unlocked()
+ * @see ferror_unlocked()
+ * @see flockfile()
+ * @see fread_unlocked()
+ * @see funlockfile()
+ *
+ * @see f_string_dynamic_increase_by()
+ */
+#ifndef _di_f_file_stream_read_until_
+ extern f_status_t f_file_stream_read_until(const f_file_t file, const f_array_length_t total, f_string_dynamic_t * const buffer);
+#endif // _di_f_file_stream_read_until_
+
+/**
+ * Re-open a file stream.
+ *
+ * This allows for re-using an existing file stream and possibly file-descriptor.
+ *
+ * The file descriptor is retrieved on success, if necessary and able.
+ *
+ * @param path
+ * The file path.
+ * Set path.used to 0 with a non-empty mode (mode.used > 0) to only change the mode of the existing stream.
+ * @param mode
+ * The file modes do use when opening.
+ * Set to 0 to determine mode from file.flags (falling back to read only as a failsafe).
+ * If neither truncate nor append are not specified in write only mode, then the failsafe is to append.
+ * @param file
+ * The file information.
+ * The file.stream is updated, if necessary.
+ *
+ * @return
+ * F_none is returned on success.
+ * F_data_not if both path.used and mode.used are 0.
+ *
+ * F_access_denied (with error bit) on access denied.
+ * F_buffer (with error bit) if the buffer is invalid.
+ * F_busy (with error bit) if file system is too busy to perform write.
+ * F_file_descriptor (with error bit) if unable to load the file descriptor.
+ * F_file_found_not (with error bit) if the file was not found.
+ * F_file_open_max (with error bit) when system-wide max open files is reached.
+ * F_file_type_not_directory (with error bit) if F_NOTIFY was specified and file.id is not a directory.
+ * F_filesystem_quota_block (with error bit) if file system's disk blocks or inodes are exhausted.
+ * F_interrupt (with error bit) when program received an interrupt signal, halting operation.
+ * F_loop (with error bit) on loop error.
+ * F_memory_not (with error bit) if out of memory.
+ * F_name (with error bit) on path name is too long.
+ * F_number_overflow (with error bit) on overflow error.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_prohibited (with error bit) if file system does not allow for making changes.
+ * F_read_only (with error bit) if file is read-only.
+ * F_supported_not (with error bit) fo unsupported file types.
+ * F_failure (with error bit) for any other error.
+ *
+ * @see fileno()
+ * @see freopen()
+ */
+#ifndef _di_f_file_stream_reopen_
+ extern f_status_t f_file_stream_reopen(const f_string_static_t path, const f_string_static_t mode, f_file_t * const file);
+#endif // _di_f_file_stream_reopen_
+
+/**
+ * Unlock a locked file stream.
+ *
+ * @param file
+ * The file to unlock.
+ *
+ * @return
+ * F_none on success.
+ * F_stream_not if file.stream is NULL.
+ *
+ * @see funlockfile()
+ */
+#ifndef _di_f_file_stream_unlock_
+ extern f_status_t f_file_stream_unlock(const f_file_t file) ;
+#endif // _di_f_file_stream_unlock_
+
+/**
+ * Write until entire buffer is written.
+ *
+ * @param file
+ * The file to write to.
+ * The file must already be open.
+ * The file.size_write represents the amount to process at a given time.
+ * @param buffer
+ * The buffer to write to the file.
+ * @param written
+ * (optional) The total bytes written.
+ * Set to NULL to not use.
+ *
+ * @return
+ * F_none on success.
+ * F_none_eof when the file stream is at the end of the file.
+ * F_none_stop on success but no data was written (written == 0) (not an error and often happens if file type is not a regular file).
+ * F_data_not on success but buffer.used is 0.
+ * F_stream_not if file.stream is NULL.
+ *
+ * F_file_write (with error bit) on error during file write.
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * F_file_write (with error bit) on any other error.
+ *
+ * @see ferror_unlocked()
+ * @see flockfile()
+ * @see fwrite_unlocked()
+ * @see funlockfile()
+ */
+#ifndef _di_f_file_stream_write_
+ extern f_status_t f_file_stream_write(const f_file_t file, const f_string_static_t buffer, f_array_length_t * const written);
+#endif // _di_f_file_stream_write_
+
+/**
+ * Write until a single block is filled or entire buffer is written.
+ *
+ * To check how much was write into the buffer, record buffer->used before execution and compare to buffer->used after execution.
+ *
+ * @param file
+ * The file to write to.
+ * The file must already be open.
+ * The file.size_write represents the amount to process at a given time.
+ * @param buffer
+ * The buffer to write to the file.
+ * @param written
+ * (optional) The total bytes written.
+ * Set to NULL to not use.
+ *
+ * @return
+ * F_none on success.
+ * F_none_eof when the file stream is at the end of the file.
+ * F_none_stop on success but no data was written (written == 0) (not an error and often happens if file type is not a regular file).
+ * F_data_not on success but buffer.used is 0.
+ * F_stream_not if file.stream is NULL.
+ *
+ * F_file_write (with error bit) on error during file write.
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * F_file_write (with error bit) on any other error.
+ *
+ * @see flockfile()
+ * @see fwrite_unlocked()
+ * @see ferror_unlocked()
+ * @see funlockfile()
+ */
+#ifndef _di_f_file_stream_write_block_
+ extern f_status_t f_file_stream_write_block(const f_file_t file, const f_string_static_t buffer, f_array_length_t * const written);
+#endif // _di_f_file_stream_write_block_
+
+/**
+ * Write until a given number or entire buffer is written.
+ *
+ * @param file
+ * The file to write to.
+ * The file must already be open.
+ * The file.size_write represents the amount to process at a given time.
+ * @param buffer
+ * The buffer to write to the file.
+ * @param total
+ * The total bytes to write, unless end of buffer is reached first.
+ * @param written
+ * (optional) The total bytes written.
+ * Set to NULL to not use..
+ *
+ * @return
+ * F_none on success.
+ * F_none_eof when the file stream is at the end of the file.
+ * F_none_eos on success but range.stop exceeded buffer.used (only wrote up to buffer.used).
+ * F_none_stop on success but no data was written (written == 0) (not an error and often happens if file type is not a regular file).
+ * F_data_not on success but either buffer.used or total is 0.
+ * F_stream_not if file.stream is NULL.
+ *
+ * F_file_write (with error bit) on error during file write.
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * F_file_write (with error bit) on any other error.
+ *
+ * @see flockfile()
+ * @see fwrite_unlocked()
+ * @see ferror_unlocked()
+ * @see funlockfile()
+ */
+#ifndef _di_f_file_stream_write_until_
+ extern f_status_t f_file_stream_write_until(const f_file_t file, const f_string_static_t buffer, const f_array_length_t total, f_array_length_t * const written);
+#endif // _di_f_file_stream_write_until_
+
+/**
+ * Write a given range within the buffer.
+ *
+ * @param file
+ * The file to write to.
+ * The file.size_write represents the amount to process at a given time.
+ * @param buffer
+ * The buffer to write to the file.
+ * @param range
+ * An inclusive start an stop range within the buffer to read.
+ * @param written
+ * (optional) The total bytes written.
+ * Set to NULL to not use.
+ *
+ * @return
+ * F_none on success.
+ * F_none_stop on success but no data was written (written == 0) (not an error and often happens if file type is not a regular file).
+ * F_none_eos on success but range.stop exceeded buffer.used (only wrote up to buffer.used).
+ * F_stream_not if file.stream is NULL.
+ *
+ * F_file_write (with error bit) on error during file write.
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * @see fwrite_unlocked()
+ */
+#ifndef _di_f_file_stream_write_range_
+ extern f_status_t f_file_stream_write_range(const f_file_t file, const f_string_static_t buffer, const f_string_range_t range, f_array_length_t * const written);
+#endif // _di_f_file_stream_write_range_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _F_file_stream_h
build_libraries -lc
build_libraries-individual -lf_memory -lf_string
-build_sources_library file.c private-file.c file/common.c
+build_sources_library file.c private-file.c file/common.c file/stream.c
-build_sources_headers file.h file/common.h
+build_sources_headers file.h file/common.h file/stream.h
build_script yes
build_shared yes
build_libraries -lc
build_libraries-individual -lf_memory -lf_string
-build_sources_library file.c file/common.c private-file.c ../../tests/unit/c/mock-file.c
+build_sources_library file.c file/common.c file/stream.c private-file.c ../../tests/unit/c/mock-file.c
-build_sources_headers file.h file/common.h file/type.h
+build_sources_headers file.h file/common.h file/stream.h file/type.h
build_script yes
build_shared yes
f_status_t f_memory_new_aligned(const size_t length, const size_t alignment, void ** const pointer) {
#ifndef _di_level_0_parameter_checking_
if (!alignment) return F_status_set_error(F_parameter);
+ if (!pointer) return F_status_set_error(F_parameter);
#endif // _di_level_0_parameter_checking_
// Prevent double-allocations and unnecessary frees.
F_no_not,
F_object,
F_object_not,
+ F_okay,
+ F_okay_not,
F_once,
F_once_not,
F_option,
const f_string_static_t f_status_no_not_s = macro_f_string_static_t_initialize(F_status_no_not_s, 0, F_status_no_not_s_length);
const f_string_static_t f_status_object_s = macro_f_string_static_t_initialize(F_status_object_s, 0, F_status_object_s_length);
const f_string_static_t f_status_object_not_s = macro_f_string_static_t_initialize(F_status_object_not_s, 0, F_status_object_not_s_length);
+ const f_string_static_t f_status_okay_s = macro_f_string_static_t_initialize(F_status_okay_s, 0, F_status_okay_s_length);
+ const f_string_static_t f_status_okay_not_s = macro_f_string_static_t_initialize(F_status_okay_not_s, 0, F_status_okay_not_s_length);
const f_string_static_t f_status_once_s = macro_f_string_static_t_initialize(F_status_once_s, 0, F_status_once_s_length);
const f_string_static_t f_status_once_not_s = macro_f_string_static_t_initialize(F_status_once_not_s, 0, F_status_once_not_s_length);
const f_string_static_t f_status_option_s = macro_f_string_static_t_initialize(F_status_option_s, 0, F_status_option_s_length);
break;
+ case F_okay:
+ *name = f_status_okay_s;
+
+ break;
+
+ case F_okay_not:
+ *name = f_status_okay_not_s;
+
+ break;
+
case F_once:
*name = f_status_once_s;
#define F_status_no_not_s "F_no_not"
#define F_status_object_s "F_object"
#define F_status_object_not_s "F_object_not"
+ #define F_status_okay_s "F_okay"
+ #define F_status_okay_not_s "F_okay_not"
#define F_status_once_s "F_once"
#define F_status_once_not_s "F_once_not"
#define F_status_option_s "F_option"
#define F_status_no_not_s_length 8
#define F_status_object_s_length 8
#define F_status_object_not_s_length 12
+ #define F_status_okay_s_length 6
+ #define F_status_okay_not_s_length 10
#define F_status_once_s_length 6
#define F_status_once_not_s_length 10
#define F_status_option_s_length 8
extern const f_string_static_t f_status_no_not_s;
extern const f_string_static_t f_status_object_s;
extern const f_string_static_t f_status_object_not_s;
+ extern const f_string_static_t f_status_okay_s;
+ extern const f_string_static_t f_status_okay_not_s;
extern const f_string_static_t f_status_once_s;
extern const f_string_static_t f_status_once_not_s;
extern const f_string_static_t f_status_option_s;
F_no_not,
F_object,
F_object_not,
+ F_okay,
+ F_okay_not,
F_once,
F_once_not,
F_option,
f_status_no_not_s,
f_status_object_s,
f_status_object_not_s,
+ f_status_okay_s,
+ f_status_okay_not_s,
f_status_once_s,
f_status_once_not_s,
f_status_option_s,
f_status_status_code_last_s,
};
- for (uint16_t i = 0; i < 589; ++i) {
+ for (uint16_t i = 0; i < 591; ++i) {
f_string_static_t result = f_string_static_t_initialize;
#endif
#if !defined(_di_fll_program_print_help_option_) || !defined(_di_fll_program_print_help_option_standard_)
- f_status_t private_fll_program_print_help_option(const f_file_t output, const f_color_context_t context, const f_string_static_t option_short, const f_string_static_t option_long, const f_string_static_t symbol_short, const f_string_static_t symbol_long, const char *description) {
+ f_status_t private_fll_program_print_help_option(const fl_print_t print, const f_string_static_t option_short, const f_string_static_t option_long, const f_string_static_t symbol_short, const f_string_static_t symbol_long, const char *description) {
- fl_print_format("%r %Q%[%Q%]", output.stream, f_string_eol_s, symbol_short, context.set.standout, option_short, context.set.standout);
- fl_print_format(", %Q%[%Q%] %S", output.stream, symbol_long, context.set.standout, option_long, context.set.standout, description);
+ fl_print_format("%r %Q%[%Q%]", print.to.stream, f_string_eol_s, symbol_short, print.set->standout, option_short, print.set->standout);
+ fl_print_format(", %Q%[%Q%] %S", print.to.stream, symbol_long, print.set->standout, option_long, print.set->standout, description);
return F_none;
}
*
* This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called.
*
- * @param output
- * The file stream to output to.
- * @param context
- * The color context.
+ * @param print
+ * The output structure to print to.
* @param option_short
* The short name of the option.
* @param option_long
* @see fll_program_print_help_option_standard()
*/
#if !defined(_di_fll_program_print_help_option_) || !defined(_di_fll_program_print_help_option_standard_)
- extern f_status_t private_fll_program_print_help_option(const f_file_t output, const f_color_context_t context, const f_string_static_t option_short, const f_string_static_t option_long, const f_string_static_t symbol_short, const f_string_static_t symbol_long, const char *description) F_attribute_visibility_internal_d;
+ extern f_status_t private_fll_program_print_help_option(const fl_print_t print, const f_string_static_t option_short, const f_string_static_t option_long, const f_string_static_t symbol_short, const f_string_static_t symbol_long, const char *description) F_attribute_visibility_internal_d;
#endif // !defined(_di_fll_program_print_help_option_) || !defined(_di_fll_program_print_help_option_standard_)
/**
extern "C" {
#endif
-#ifndef _di_fll_program_print_help_header_
- f_status_t fll_program_print_help_header(const f_file_t output, const f_color_context_t context, const f_string_static_t name, const f_string_static_t version) {
-
- fl_print_format(" %[%Q%]%r", output.stream, context.set.title, name, context.set.title, f_string_eol_s);
- fl_print_format(" %[Version %Q%]%r", output.stream, context.set.notable, version, context.set.notable, f_string_eol_s);
-
- fl_print_format("%r %[Available Options:%] ", output.stream, f_string_eol_s, context.set.important, context.set.important);
-
- return F_none;
- }
-#endif // _di_fll_program_print_help_header_
-
-#ifndef _di_fll_program_print_help_option_
- f_status_t fll_program_print_help_option(const f_file_t output, const f_color_context_t context, const f_string_static_t option_short, const f_string_static_t option_long, const f_string_static_t symbol_short, const f_string_static_t symbol_long, const char *description) {
-
- return private_fll_program_print_help_option(output, context, option_short, option_long, symbol_short, symbol_long, description);
- }
-#endif // _di_fll_program_print_help_option_
-
-#ifndef _di_fll_program_print_help_option_standard_
- f_status_t fll_program_print_help_option_standard(const f_file_t output, const f_color_context_t context) {
-
- private_fll_program_print_help_option(output, context, f_console_standard_short_help_s, f_console_standard_long_help_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print this help message.");
- private_fll_program_print_help_option(output, context, f_console_standard_short_dark_s, f_console_standard_long_dark_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Output using colors that show up better on dark backgrounds.");
- private_fll_program_print_help_option(output, context, f_console_standard_short_light_s, f_console_standard_long_light_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Output using colors that show up better on light backgrounds.");
- private_fll_program_print_help_option(output, context, f_console_standard_short_no_color_s, f_console_standard_long_no_color_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Do not print using color.");
- private_fll_program_print_help_option(output, context, f_console_standard_short_quiet_s, f_console_standard_long_quiet_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Decrease verbosity, silencing most output.");
- private_fll_program_print_help_option(output, context, f_console_standard_short_error_s, f_console_standard_long_error_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Decrease verbosity, using only error output.");
- private_fll_program_print_help_option(output, context, f_console_standard_short_normal_s, f_console_standard_long_normal_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Set verbosity to normal.");
- private_fll_program_print_help_option(output, context, f_console_standard_short_verbose_s, f_console_standard_long_verbose_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Increase verbosity beyond normal output.");
- private_fll_program_print_help_option(output, context, f_console_standard_short_debug_s, f_console_standard_long_debug_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Enable debugging, significantly increasing verbosity beyond normal output.");
- private_fll_program_print_help_option(output, context, f_console_standard_short_version_s, f_console_standard_long_version_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Print only the version number.");
- private_fll_program_print_help_option(output, context, f_console_standard_short_line_first_no_s, f_console_standard_long_line_first_no_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, "Disable printing of first line.");
- private_fll_program_print_help_option(output, context, f_console_standard_short_line_last_no_s, f_console_standard_long_line_last_no_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Disable printing of last line.");
-
- return F_none;
- }
-#endif // _di_fll_program_print_help_option_standard_
-
-#ifndef _di_fll_program_print_help_option_long_
- f_status_t fll_program_print_help_option_long(const f_file_t output, const f_color_context_t context, const f_string_static_t option_long, const f_string_static_t symbol_long, const char *description) {
-
- fl_print_format("%r %Q%[%Q%] %S", output.stream, f_string_eol_s, symbol_long, context.set.standout, option_long, context.set.standout, description);
-
- return F_none;
- }
-#endif // _di_fll_program_print_help_option_long_
-
-#ifndef _di_fll_program_print_help_option_other_
- f_status_t fll_program_print_help_option_other(const f_file_t output, const f_color_context_t context, const f_string_static_t option_other, const char *description) {
-
- fl_print_format("%r %[%Q%] %S", output.stream, f_string_eol_s, context.set.standout, option_other, context.set.standout, description);
-
- return F_none;
- }
-#endif // _di_fll_program_print_help_option_other_
-
-#ifndef _di_fll_program_print_help_usage_
- f_status_t fll_program_print_help_usage(const f_file_t output, const f_color_context_t context, const f_string_static_t name, const f_string_static_t parameters) {
-
- fl_print_format("%r%r %[Usage:%]%r", output.stream, f_string_eol_s, f_string_eol_s, context.set.important, context.set.important, f_string_eol_s);
-
- fl_print_format(" %[%Q%]", output.stream, context.set.standout, name, context.set.standout);
- fl_print_format(" %[[%] options %[]%]", output.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable);
-
- if (parameters.used) {
- fl_print_format(" %[[%] %Q %[]%]", output.stream, context.set.notable, context.set.notable, parameters, context.set.notable, context.set.notable);
- }
-
- f_print_dynamic_raw(f_string_eol_s, output.stream);
-
- return F_none;
- }
-#endif // _di_fll_program_print_help_usage_
-
-#ifndef _di_fll_program_print_version_
- f_status_t fll_program_print_version(const f_file_t output, const f_string_static_t version) {
-
- f_print_dynamic(version, output.stream);
- f_print_dynamic_raw(f_string_eol_s, output.stream);
-
- return F_none;
- }
-#endif // _di_fll_program_print_version_
-
#ifndef _di_fll_program_parameter_process_context_
f_status_t fll_program_parameter_process_context(const f_uint16s_t choices, const uint8_t modes[], const bool right, fll_program_data_t * const main) {
#ifndef _di_fll_program_parameter_long_print_cannot_use_with_
f_status_t fll_program_parameter_long_print_cannot_use_with(const fl_print_t print, const f_string_static_t first, const f_string_static_t second) {
- flockfile(print.to.stream);
+ f_file_stream_lock(print.to);
- fl_print_format("%r%[%QCannot specify the '%]", print.to.stream, f_string_eol_s, print.context, print.prefix, print.context);
+ fl_print_format("%[%QCannot specify the '%]", print.to.stream, print.context, print.prefix, print.context);
fl_print_format("%[%r%r%]", print.to.stream, print.notable, f_console_symbol_long_enable_s, first, print.notable);
fl_print_format("%[' parameter with the '%]", print.to.stream, print.context, print.context);
fl_print_format("%[%r%r%]", print.to.stream, print.notable, f_console_symbol_long_enable_s, second, print.notable);
fl_print_format("%[' parameter.%]%r", print.to.stream, print.context, print.context, f_string_eol_s);
- funlockfile(print.to.stream);
+ f_file_stream_unlock(print.to);
return F_none;
}
// FLL-2 program includes.
#include <fll/level_2/program/common.h>
+#include <fll/level_2/program/print.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
- * Print standard help header.
- *
- * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called.
- *
- * @param output
- * The file stream to output to.
- * @param context
- * The color context.
- * @param name
- * The name of the program.
- * @param version
- * The version number of the program.
- *
- * @return
- * F_none on success.
- *
- * @see f_print_terminated()
- * @see fl_print_format()
- */
-#ifndef _di_fll_program_print_help_header_
- extern f_status_t fll_program_print_help_header(const f_file_t output, const f_color_context_t context, const f_string_static_t name, const f_string_static_t version);
-#endif // _di_fll_program_print_help_header_
-
-/**
- * Print standard help option.
- *
- * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called.
- *
- * @param output
- * The file stream to output to.
- * @param context
- * The color context.
- * @param option_short
- * The short name of the option.
- * @param option_long
- * The long name of the option.
- * @param symbol_short
- * The short symbol of the option.
- * @param symbol_long
- * The long symbol of the option.
- * @param description
- * A desciption associated with the option.
- *
- * @return
- * F_none on success.
- *
- * @see f_print_terminated()
- * @see fl_print_format()
- */
-#ifndef _di_fll_program_print_help_option_
- extern f_status_t fll_program_print_help_option(const f_file_t output, const f_color_context_t context, const f_string_static_t option_short, const f_string_static_t option_long, const f_string_static_t symbol_short, const f_string_static_t symbol_long, const char *description);
-#endif // _di_fll_program_print_help_option_
-
-/**
- * Print standard help option (long option only).
- *
- * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called.
- *
- * @param output
- * The file stream to output to.
- * @param context
- * The color context.
- * @param option_long
- * The long name of the option.
- * @param symbol_long
- * The long symbol of the option.
- * @param description
- * A desciption associated with the option.
- *
- * @return
- * F_none on success.
- *
- * @see f_print_terminated()
- * @see fl_print_format()
- */
-#ifndef _di_fll_program_print_help_option_long_
- extern f_status_t fll_program_print_help_option_long(const f_file_t output, const f_color_context_t context, const f_string_static_t option_long, const f_string_static_t symbol_long, const char *description);
-#endif // _di_fll_program_print_help_option_long_
-
-/**
- * Print standard help option (other option only).
- *
- * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called.
- *
- * @param output
- * The file stream to output to.
- * @param context
- * The color context.
- * @param option_other
- * The other name of the option.
- * @param description
- * A desciption associated with the option.
- *
- * @return
- * F_none on success.
- *
- * @see f_print_terminated()
- * @see fl_print_format()
- */
-#ifndef _di_fll_program_print_help_option_other_
- extern f_status_t fll_program_print_help_option_other(const f_file_t output, const f_color_context_t context, const f_string_static_t option_other, const char *description);
-#endif // _di_fll_program_print_help_option_other_
-
-/**
- * Print all standard help options.
- *
- * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called.
- *
- * @param output
- * The file stream to output to.
- * @param context
- * The color context.
- *
- * @return
- * F_none on success.
- *
- * @see f_print_terminated()
- * @see fl_print_format()
- */
-#ifndef _di_fll_program_print_help_option_standard_
- extern f_status_t fll_program_print_help_option_standard(const f_file_t output, const f_color_context_t context);
-#endif // _di_fll_program_print_help_option_standard_
-
-/**
- * Print standard help usage.
- *
- * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called.
- *
- * @param output
- * The file stream to output to.
- * @param context
- * The color context.
- * @param name
- * The name of the program.
- * @param parameters
- * (optional) The non-option parameters to be displayed inside the brackets.
- * Set the first array value to EOS to disable printing of parameters.
- * Set parameters.used to 0 to disable.
- *
- * @return
- * F_none on success.
- *
- * @see f_print_terminated()
- * @see fl_print_format()
- */
-#ifndef _di_fll_program_print_help_usage_
- extern f_status_t fll_program_print_help_usage(const f_file_t output, const f_color_context_t context, const f_string_static_t name, const f_string_static_t parameters);
-#endif // _di_fll_program_print_help_usage_
-
-/**
- * Print the program version.
- *
- * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called.
- *
- * @param output
- * The file stream to output to.
- * @param version
- * The version number of the program.
- *
- * @return
- * F_none on success.
- *
- * @see fl_print_format()
- */
-#ifndef _di_fll_program_print_version_
- extern f_status_t fll_program_print_version(const f_file_t output, const f_string_static_t version);
-#endif // _di_fll_program_print_version_
-
-/**
* Determine the color context from the parameters and then set the color context based on the choice.
*
* This will allow for the color context and the color sets to be safely used when colors are disabled.
*
* @param main
* The main program data.
+ * The main->signal must be used to designate blocked signals.
*
* @return
* A positive number representing a valid signal on signal received.
--- /dev/null
+#include "../program.h"
+#include "../private-program.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fll_program_print_help_header_
+ f_status_t fll_program_print_help_header(const fl_print_t print, const f_string_static_t name, const f_string_static_t version) {
+
+ fl_print_format(" %[%Q%]%r", print.to.stream, print.set->title, name, print.set->title, f_string_eol_s);
+ fl_print_format(" %[Version %Q%]%r", print.to.stream, print.set->notable, version, print.set->notable, f_string_eol_s);
+
+ fl_print_format("%r %[Available Options:%] ", print.to.stream, f_string_eol_s, print.set->important, print.set->important);
+
+ return F_none;
+ }
+#endif // _di_fll_program_print_help_header_
+
+#ifndef _di_fll_program_print_help_option_
+ f_status_t fll_program_print_help_option(const fl_print_t print, const f_string_static_t option_short, const f_string_static_t option_long, const f_string_static_t symbol_short, const f_string_static_t symbol_long, const char *description) {
+
+ return private_fll_program_print_help_option(print, option_short, option_long, symbol_short, symbol_long, description);
+ }
+#endif // _di_fll_program_print_help_option_
+
+#ifndef _di_fll_program_print_help_option_standard_
+ f_status_t fll_program_print_help_option_standard(const fl_print_t print) {
+
+ private_fll_program_print_help_option(print, f_console_standard_short_help_s, f_console_standard_long_help_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print this help message.");
+ private_fll_program_print_help_option(print, f_console_standard_short_dark_s, f_console_standard_long_dark_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Output using colors that show up better on dark backgrounds.");
+ private_fll_program_print_help_option(print, f_console_standard_short_light_s, f_console_standard_long_light_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Output using colors that show up better on light backgrounds.");
+ private_fll_program_print_help_option(print, f_console_standard_short_no_color_s, f_console_standard_long_no_color_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Do not print using color.");
+ private_fll_program_print_help_option(print, f_console_standard_short_quiet_s, f_console_standard_long_quiet_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Decrease verbosity, silencing most print.to.");
+ private_fll_program_print_help_option(print, f_console_standard_short_error_s, f_console_standard_long_error_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Decrease verbosity, using only error print.to.");
+ private_fll_program_print_help_option(print, f_console_standard_short_normal_s, f_console_standard_long_normal_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Set verbosity to normal.");
+ private_fll_program_print_help_option(print, f_console_standard_short_verbose_s, f_console_standard_long_verbose_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Increase verbosity beyond normal print.to.");
+ private_fll_program_print_help_option(print, f_console_standard_short_debug_s, f_console_standard_long_debug_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Enable debugging, significantly increasing verbosity beyond normal print.to.");
+ private_fll_program_print_help_option(print, f_console_standard_short_version_s, f_console_standard_long_version_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Print only the version number.");
+ private_fll_program_print_help_option(print, f_console_standard_short_line_first_no_s, f_console_standard_long_line_first_no_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, "Disable printing of first line.");
+ private_fll_program_print_help_option(print, f_console_standard_short_line_last_no_s, f_console_standard_long_line_last_no_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Disable printing of last line.");
+
+ return F_none;
+ }
+#endif // _di_fll_program_print_help_option_standard_
+
+#ifndef _di_fll_program_print_help_option_long_
+ f_status_t fll_program_print_help_option_long(const fl_print_t print, const f_string_static_t option_long, const f_string_static_t symbol_long, const char *description) {
+
+ fl_print_format("%r %Q%[%Q%] %S", print.to.stream, f_string_eol_s, symbol_long, print.set->standout, option_long, print.set->standout, description);
+
+ return F_none;
+ }
+#endif // _di_fll_program_print_help_option_long_
+
+#ifndef _di_fll_program_print_help_option_other_
+ f_status_t fll_program_print_help_option_other(const fl_print_t print, const f_string_static_t option_other, const char *description) {
+
+ fl_print_format("%r %[%Q%] %S", print.to.stream, f_string_eol_s, print.set->standout, option_other, print.set->standout, description);
+
+ return F_none;
+ }
+#endif // _di_fll_program_print_help_option_other_
+
+#ifndef _di_fll_program_print_help_usage_
+ f_status_t fll_program_print_help_usage(const fl_print_t print, const f_string_static_t name, const f_string_static_t parameters) {
+
+ fl_print_format("%r%r %[Usage:%]%r", print.to.stream, f_string_eol_s, f_string_eol_s, print.set->important, print.set->important, f_string_eol_s);
+
+ fl_print_format(" %[%Q%]", print.to.stream, print.set->standout, name, print.set->standout);
+ fl_print_format(" %[[%] options %[]%]", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable);
+
+ if (parameters.used) {
+ fl_print_format(" %[[%] %Q %[]%]", print.to.stream, print.set->notable, print.set->notable, parameters, print.set->notable, print.set->notable);
+ }
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ return F_none;
+ }
+#endif // _di_fll_program_print_help_usage_
+
+#ifndef _di_fll_program_print_signal_received_
+ f_status_t fll_program_print_signal_received(const fl_print_t print, const f_string_static_t line_first, const f_status_t signal) {
+
+ if (print.verbosity != f_console_verbosity_verbose_e && print.verbosity != f_console_verbosity_debug_e) {
+ return F_output_not;
+ }
+
+ flockfile(print.to.stream);
+
+ // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
+ f_file_stream_flush(print.to);
+
+ fl_print_format("%]%r%[Received signal code %]", print.to.stream, print.set->reset, line_first, print.set->warning, print.set->warning);
+ fl_print_format("%[%i%]", print.to.stream, print.set->notable, signal, print.set->notable);
+ fl_print_format("%[.%]%r", print.to.stream, print.set->warning, print.set->warning, f_string_eol_s);
+
+ funlockfile(print.to.stream);
+
+ return F_none;
+ }
+#endif // _di_fll_program_print_signal_received_
+
+#ifndef _di_fll_program_print_version_
+ f_status_t fll_program_print_version(const fl_print_t print, const f_string_static_t version) {
+
+ f_print_dynamic(version, print.to.stream);
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ return F_none;
+ }
+#endif // _di_fll_program_print_version_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 2
+ *
+ * Project: Program
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Defines common data to be used for/by project program.
+ *
+ * This is auto-included by program.h and should not need to be explicitly included.
+ */
+#ifndef _FLL_program_print_h
+#define _FLL_program_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print standard help header.
+ *
+ * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called.
+ *
+ * @param print
+ * The output structure to print to.
+ * This requires print.set to be non-NULL.
+ * @param name
+ * The name of the program.
+ * @param version
+ * The version number of the program.
+ *
+ * @return
+ * F_none on success.
+ *
+ * @see f_print_terminated()
+ * @see fl_print_format()
+ */
+#ifndef _di_fll_program_print_help_header_
+ extern f_status_t fll_program_print_help_header(const fl_print_t print, const f_string_static_t name, const f_string_static_t version);
+#endif // _di_fll_program_print_help_header_
+
+/**
+ * Print standard help option.
+ *
+ * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called.
+ *
+ * @param print
+ * The output structure to print to.
+ * This requires print.set to be non-NULL.
+ * @param option_short
+ * The short name of the option.
+ * @param option_long
+ * The long name of the option.
+ * @param symbol_short
+ * The short symbol of the option.
+ * @param symbol_long
+ * The long symbol of the option.
+ * @param description
+ * A desciption associated with the option.
+ *
+ * @return
+ * F_none on success.
+ *
+ * @see f_print_terminated()
+ * @see fl_print_format()
+ */
+#ifndef _di_fll_program_print_help_option_
+ extern f_status_t fll_program_print_help_option(const fl_print_t print, const f_string_static_t option_short, const f_string_static_t option_long, const f_string_static_t symbol_short, const f_string_static_t symbol_long, const char *description);
+#endif // _di_fll_program_print_help_option_
+
+/**
+ * Print standard help option (long option only).
+ *
+ * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called.
+ *
+ * @param print
+ * The output structure to print to.
+ * This requires print.set to be non-NULL.
+ * @param option_long
+ * The long name of the option.
+ * @param symbol_long
+ * The long symbol of the option.
+ * @param description
+ * A desciption associated with the option.
+ *
+ * @return
+ * F_none on success.
+ *
+ * @see f_print_terminated()
+ * @see fl_print_format()
+ */
+#ifndef _di_fll_program_print_help_option_long_
+ extern f_status_t fll_program_print_help_option_long(const fl_print_t print, const f_string_static_t option_long, const f_string_static_t symbol_long, const char *description);
+#endif // _di_fll_program_print_help_option_long_
+
+/**
+ * Print standard help option (other option only).
+ *
+ * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called.
+ *
+ * @param print
+ * The output structure to print to.
+ * This requires print.set to be non-NULL.
+ * @param option_other
+ * The other name of the option.
+ * @param description
+ * A desciption associated with the option.
+ *
+ * @return
+ * F_none on success.
+ *
+ * @see f_print_terminated()
+ * @see fl_print_format()
+ */
+#ifndef _di_fll_program_print_help_option_other_
+ extern f_status_t fll_program_print_help_option_other(const fl_print_t print, const f_string_static_t option_other, const char *description);
+#endif // _di_fll_program_print_help_option_other_
+
+/**
+ * Print all standard help options.
+ *
+ * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called.
+ *
+ * @param print
+ * The output structure to print to.
+ * This requires print.set to be non-NULL.
+ * @param context
+ * The color context.
+ *
+ * @return
+ * F_none on success.
+ *
+ * @see f_print_terminated()
+ * @see fl_print_format()
+ */
+#ifndef _di_fll_program_print_help_option_standard_
+ extern f_status_t fll_program_print_help_option_standard(const fl_print_t print);
+#endif // _di_fll_program_print_help_option_standard_
+
+/**
+ * Print standard help usage.
+ *
+ * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called.
+ *
+ * @param print
+ * The output structure to print to.
+ * This requires print.set to be non-NULL.
+ * @param name
+ * The name of the program.
+ * @param parameters
+ * (optional) The non-option parameters to be displayed inside the brackets.
+ * Set the first array value to EOS to disable printing of parameters.
+ * Set parameters.used to 0 to disable.
+ *
+ * @return
+ * F_none on success.
+ *
+ * @see f_print_terminated()
+ * @see fl_print_format()
+ */
+#ifndef _di_fll_program_print_help_usage_
+ extern f_status_t fll_program_print_help_usage(const fl_print_t print, const f_string_static_t name, const f_string_static_t parameters);
+#endif // _di_fll_program_print_help_usage_
+
+/**
+ * Print a message about a process signal being recieved, such as an interrupt signal, as a warning.
+ *
+ * This is only printed when verbosity is set to verbose or debug.
+ *
+ * @param print
+ * The output structure to print to.
+ * This requires print.set to be non-NULL.
+ * @param line_first
+ * The first line character, which is expected to be set to either f_string_eol_s or f_string_empty_s.
+ * @param signal
+ * The signal code received.
+ *
+ * @return
+ * F_none on success.
+ * F_output_not on success, but no printing is performed.
+ */
+#ifndef _di_fll_program_print_signal_received_
+ extern f_status_t fll_program_print_signal_received(const fl_print_t print, const f_string_static_t line_first, const f_status_t signal);
+#endif // _di_fll_program_print_signal_received_
+
+/**
+ * Print the program version.
+ *
+ * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called.
+ *
+ * @param print
+ * The output structure to print to.
+ * This requires print.set to be non-NULL.
+ * @param version
+ * The version number of the program.
+ *
+ * @return
+ * F_none on success.
+ *
+ * @see fl_print_format()
+ */
+#ifndef _di_fll_program_print_version_
+ extern f_status_t fll_program_print_version(const fl_print_t print, const f_string_static_t version);
+#endif // _di_fll_program_print_version_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _FLL_program_print_h
build_libraries -lc
build_libraries-individual -lfl_print -lfl_string -lf_color -lf_console -lf_conversion -lf_file -lf_memory -lf_print -lf_signal -lf_string -lf_type_array -lf_utf
-build_sources_library program.c program/common.c private-program.c
+build_sources_library program.c program/common.c program/print.c private-program.c
-build_sources_headers program.h program/common.h
+build_sources_headers program.h program/common.h program/print.h
build_script yes
build_shared yes
F_no_not,
F_object,
F_object_not,
+ F_okay,
+ F_okay_not,
F_once,
F_once_not,
F_option,
f_status_no_not_s,
f_status_object_s,
f_status_object_not_s,
+ f_status_okay_s,
+ f_status_okay_not_s,
f_status_once_s,
f_status_once_not_s,
f_status_option_s,
f_status_status_code_last_s,
};
- for (uint16_t i = 0; i < 589; ++i) {
+ for (uint16_t i = 0; i < 591; ++i) {
f_status_t result = F_none;
extern "C" {
#endif
-#ifndef _di_byte_dump_print_help_
- f_status_t byte_dump_print_help(const f_file_t file, const f_color_context_t context) {
-
- flockfile(file.stream);
-
- //if (!(setting->flag & XXX_main_flag_line_first_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- fll_program_print_help_header(file, context, byte_dump_program_name_long_s, byte_dump_program_version_s);
-
- fll_program_print_help_option_standard(file, context);
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, byte_dump_short_binary_s, byte_dump_long_binary_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Display binary representation.");
- fll_program_print_help_option(file, context, byte_dump_short_decimal_s, byte_dump_long_decimal_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Display decimal representation.");
- fll_program_print_help_option(file, context, byte_dump_short_duodecimal_s, byte_dump_long_duodecimal_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Display duodecimal representation.");
- fll_program_print_help_option(file, context, byte_dump_short_hexidecimal_s, byte_dump_long_hexidecimal_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Display hexadecimal representation.");
- fll_program_print_help_option(file, context, byte_dump_short_octal_s, byte_dump_long_octal_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Display octal representation.");
- fll_program_print_help_option(file, context, byte_dump_short_unicode_s, byte_dump_long_unicode_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Display using Unicode representation for valid Unicode (like: U+0000).");
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, byte_dump_short_first_s, byte_dump_long_first_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Start reading at this byte offset.");
- fll_program_print_help_option(file, context, byte_dump_short_last_s, byte_dump_long_last_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Stop reading at this (inclusive) byte offset.");
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, byte_dump_short_narrow_s, byte_dump_long_narrow_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use narrow display, resulting in 1*width reducing size of the text columns.");
- fll_program_print_help_option(file, context, byte_dump_short_placeholder_s, byte_dump_long_placeholder_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Use a placeholder character instead of a space for placeholders.");
- fll_program_print_help_option(file, context, byte_dump_short_text_s, byte_dump_long_text_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Include a column of text when displaying the bytes.");
- fll_program_print_help_option(file, context, byte_dump_short_wide_s, byte_dump_long_wide_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use wide display, resulting in 2*width allowing for space for wide characters in the text columns.");
- fll_program_print_help_option(file, context, byte_dump_short_width_s, byte_dump_long_width_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Set number of columns of Bytes to display.");
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fl_print_format(" %[Special Options:%] ", file.stream, context.set.important, context.set.important);
-
- fll_program_print_help_option_long(file, context, byte_dump_long_normal_s, f_console_symbol_long_enable_s, " Display UTF-8 symbols for ASCII control codes.");
- fll_program_print_help_option_long(file, context, byte_dump_long_simple_s, f_console_symbol_long_enable_s, " Display spaces for ASCII control codes.");
- fll_program_print_help_option_long(file, context, byte_dump_long_classic_s, f_console_symbol_long_enable_s, "Display periods for ASCII control codes.");
-
- fll_program_print_help_usage(file, context, byte_dump_program_name_s, fll_program_parameter_filenames_s);
-
- //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- fl_print_format(" When using the %[%r%r%] option, some UTF-8 characters may be replaced by your instance and cause display alignment issues.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, byte_dump_long_text_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" Special UTF-8 characters and non-spacing UTF-8 characters may be replaced with a space (or a placeholder when the %[%r%r%] option is used).%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, byte_dump_long_placeholder_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" UTF-8 \"Combining\" characters might have a space appended to allow a proper display but this may cause copy and paste issues.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When %[%r%r%] is used, any UTF-8 sequences will still be printed in full should any part is found within the requested range.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, byte_dump_long_last_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When using the %[%r%r%] option, invalid Unicode will fallback to being displayed using one of the other modes.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, byte_dump_long_unicode_s, context.set.notable, f_string_eol_s);
-
- //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- f_file_stream_flush(file);
- funlockfile(file.stream);
-
- return F_none;
- }
-#endif // _di_byte_dump_print_help_
-
#ifndef _di_byte_dump_main_
- f_status_t byte_dump_main(fll_program_data_t * const main, const f_console_arguments_t arguments) {
+ f_status_t byte_dump_main(fll_program_data_t * const main, byte_dump_setting_t * const setting) {
f_status_t status = F_none;
status = F_none;
if (main->parameters.array[byte_dump_parameter_help_e].result == f_console_result_found_e) {
- byte_dump_print_help(main->output.to, main->context);
+ byte_dump_print_help(setting, main->message);
return F_none;
}
if (main->parameters.array[byte_dump_parameter_version_e].result == f_console_result_found_e) {
- fll_program_print_version(main->output.to, byte_dump_program_version_s);
+ fll_program_print_version(main->message, byte_dump_program_version_s);
return F_none;
}
#endif
/**
- * Print help.
- *
- * @param file
- * The file to print to.
- * @param context
- * The color context settings.
- *
- * @return
- * F_none on success.
- *
- * @see byte_dump_main()
- */
-#ifndef _di_byte_dump_print_help_
- extern f_status_t byte_dump_print_help(const f_file_t file, const f_color_context_t context);
-#endif // _di_byte_dump_print_help_
-
-/**
* Execute main program.
*
* @param main
* Status codes (with error bit) are returned on any problem.
*/
#ifndef _di_byte_dump_main_
- extern f_status_t byte_dump_main(fll_program_data_t * const main, const f_console_arguments_t arguments);
+ extern f_status_t byte_dump_main(fll_program_data_t * const main, byte_dump_setting_t * const setting);
#endif // _di_byte_dump_main_
+/**
+ * Delete the program main setting data.
+ *
+ * @param setting
+ * The program main setting data.
+ * This does not alter setting.status.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_byte_dump_setting_delete_
+ extern f_status_t byte_dump_setting_delete(byte_dump_setting_t * const setting);
+#endif // _di_byte_dump_setting_delete_
+
+/**
+ * Perform the standard program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately retuns without doing anything.
+ *
+ * @param arguments
+ * The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ *
+ * This alters setting.status:
+ * F_none on success.
+ *
+ * Errors (with error bit) from: f_console_parameter_process().
+ * Errors (with error bit) from: fll_program_parameter_process_context().
+ *
+ * @see f_console_parameter_process()
+ * @see fll_program_parameter_process_context()
+ */
+#ifndef _di_byte_dump_setting_load_
+ extern void byte_dump_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, byte_dump_setting_t * const setting);
+#endif // _di_byte_dump_setting_load_
+
+/**
+ * Perform the standard program setting unload process.
+ *
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * All buffers are deallocated.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: utf8_setting_delete().
+ *
+ * @see utf8_setting_delete()
+ */
+#ifndef _di_byte_dump_setting_unload_
+ extern f_status_t byte_dump_setting_unload(fll_program_data_t * const main, byte_dump_setting_t * const setting);
+#endif // _di_byte_dump_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
const f_string_static_t byte_dump_long_classic_s = macro_f_string_static_t_initialize(BYTE_DUMP_long_classic_s, 0, BYTE_DUMP_long_classic_s_length);
#endif // _di_byte_dump_parameters_
+#ifndef _di_byte_dump_setting_delete_
+ f_status_t byte_dump_setting_delete(byte_dump_setting_t * const setting) {
+
+ if (!setting) return F_status_set_error(F_parameter);
+
+ return F_none;
+ }
+#endif // _di_byte_dump_setting_delete_
+
+#ifndef _di_byte_dump_setting_load_
+ void byte_dump_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, byte_dump_setting_t * const setting) {
+
+ if (!main || !setting) return;
+
+ // Load parameters.
+ setting->status = f_console_parameter_process(arguments, &main->parameters);
+ if (F_status_is_error(setting->status)) return;
+
+ {
+ f_array_length_t choice = 0;
+ f_uint16s_t choices = f_uint16s_t_initialize;
+
+ // Identify and prioritize "color context" parameters.
+ {
+ uint16_t choices_array[3] = { byte_dump_parameter_no_color_e, byte_dump_parameter_light_e, byte_dump_parameter_dark_e };
+ choices.array = choices_array;
+ choices.used = 3;
+
+ const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
+
+ setting->status = fll_program_parameter_process_context(choices, modes, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ byte_dump_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_context", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[byte_dump_parameter_line_first_no_e].result == f_console_result_found_e) {
+ setting->line_first = f_string_empty_s;
+ }
+ else {
+ setting->line_first = f_string_eol_s;
+ }
+
+ if (main->parameters.array[byte_dump_parameter_line_last_no_e].result == f_console_result_found_e) {
+ setting->line_last = f_string_empty_s;
+ }
+ else {
+ setting->line_last = f_string_eol_s;
+ }
+
+ // Identify and prioritize "verbosity" parameters.
+ {
+ uint16_t choices_array[5] = { byte_dump_parameter_verbosity_quiet_e, byte_dump_parameter_verbosity_error_e, byte_dump_parameter_verbosity_verbose_e, byte_dump_parameter_verbosity_debug_e, byte_dump_parameter_verbosity_normal_e };
+ choices.array = choices_array;
+ choices.used = 5;
+
+ const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+
+ setting->status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ byte_dump_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_verbosity", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[byte_dump_parameter_help_e].result == f_console_result_found_e) {
+ setting->flag |= byte_dump_main_flag_help_e;
+
+ return;
+ }
+
+ if (main->parameters.array[byte_dump_parameter_version_e].result == f_console_result_found_e) {
+ setting->flag |= byte_dump_main_flag_version_e;
+
+ return;
+ }
+
+ // Identify and prioritize "from" mode parameters.
+ {
+ uint16_t choices_array[2] = { byte_dump_parameter_from_bytesequence_e, byte_dump_parameter_from_codepoint_e };
+ choices.array = choices_array;
+ choices.used = 2;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ byte_dump_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == byte_dump_parameter_from_bytesequence_e) {
+ if (setting->mode & byte_dump_mode_from_codepoint_e) {
+ setting->mode -= byte_dump_mode_from_codepoint_e;
+ }
+
+ setting->mode |= byte_dump_mode_from_bytesequence_e;
+ }
+ else if (choices.array[choice] == byte_dump_parameter_from_codepoint_e) {
+ if (setting->mode & byte_dump_mode_from_bytesequence_e) {
+ setting->mode -= byte_dump_mode_from_bytesequence_e;
+ }
+
+ setting->mode |= byte_dump_mode_from_codepoint_e;
+ }
+ }
+
+ // Identify and prioritize "to" mode parameters.
+ {
+ uint16_t choices_array[4] = { byte_dump_parameter_to_bytesequence_e, byte_dump_parameter_to_codepoint_e, byte_dump_parameter_to_combining_e, byte_dump_parameter_to_width_e };
+ choices.array = choices_array;
+ choices.used = 4;
+ choice = 1;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ byte_dump_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == byte_dump_parameter_to_bytesequence_e) {
+ if (setting->mode & byte_dump_mode_to_codepoint_e) {
+ setting->mode -= byte_dump_mode_to_codepoint_e;
+ }
+
+ if (setting->mode & byte_dump_mode_to_combining_e) {
+ setting->mode -= byte_dump_mode_to_combining_e;
+ }
+
+ if (setting->mode & byte_dump_mode_to_width_e) {
+ setting->mode -= byte_dump_mode_to_width_e;
+ }
+
+ setting->mode |= byte_dump_mode_to_bytesequence_e;
+ }
+ else if (choices.array[choice] == byte_dump_parameter_to_codepoint_e) {
+ if (setting->mode & byte_dump_mode_to_bytesequence_e) {
+ setting->mode -= byte_dump_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & byte_dump_mode_to_combining_e) {
+ setting->mode -= byte_dump_mode_to_combining_e;
+ }
+
+ if (setting->mode & byte_dump_mode_to_width_e) {
+ setting->mode -= byte_dump_mode_to_width_e;
+ }
+
+ setting->mode |= byte_dump_mode_to_codepoint_e;
+ }
+ else if (choices.array[choice] == byte_dump_parameter_to_combining_e) {
+ if (setting->mode & byte_dump_mode_to_bytesequence_e) {
+ setting->mode -= byte_dump_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & byte_dump_mode_to_codepoint_e) {
+ setting->mode -= byte_dump_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[byte_dump_parameter_to_width_e].result == f_console_result_found_e) {
+ setting->mode |= byte_dump_mode_to_width_e;
+ }
+
+ setting->mode |= byte_dump_mode_to_combining_e;
+ }
+ else if (choices.array[choice] == byte_dump_parameter_to_width_e) {
+ if (setting->mode & byte_dump_mode_to_bytesequence_e) {
+ setting->mode -= byte_dump_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & byte_dump_mode_to_codepoint_e) {
+ setting->mode -= byte_dump_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[byte_dump_parameter_to_combining_e].result == f_console_result_found_e) {
+ setting->mode |= byte_dump_mode_to_combining_e;
+ }
+
+ setting->mode |= byte_dump_mode_to_width_e;
+ }
+ }
+ }
+
+ f_string_static_t * const args = main->parameters.arguments.array;
+
+ if (main->parameters.array[byte_dump_parameter_to_file_e].result == f_console_result_additional_e) {
+ if (main->parameters.array[byte_dump_parameter_to_file_e].values.used > 1) {
+ byte_dump_print_error_parameter_file_to_too_many(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+
+ if (args[main->parameters.array[byte_dump_parameter_to_file_e].values.array[0]].used) {
+ setting->path_files_to.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(1, &setting->path_files_to);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_to.array[setting->path_files_to.used].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[main->parameters.array[byte_dump_parameter_to_file_e].values.array[0]], &setting->path_files_to.array[0]);
+ if (F_status_is_error(setting->status)) return;
+
+ ++setting->path_files_to.used;
+
+ setting->status = f_file_stream_open(args[main->parameters.array[byte_dump_parameter_to_file_e].values.array[0]], f_file_open_mode_append_s, &main->output.to);
+
+ if (F_status_is_error(setting->status)) {
+ fll_error_file_print(main->error, F_status_set_fine(setting->status), "f_file_stream_open", F_true, args[main->parameters.array[byte_dump_parameter_to_file_e].values.array[0]], f_file_operation_open_s, fll_error_file_type_file_e);
+
+ return;
+ }
+
+ setting->flag |= byte_dump_main_flag_file_to_e;
+ }
+ else {
+ byte_dump_print_error_parameter_file_name_empty(main, setting, main->parameters.array[byte_dump_parameter_to_file_e].values.array[0]);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+ else if (main->parameters.array[byte_dump_parameter_to_file_e].result == f_console_result_found_e) {
+ byte_dump_print_error_no_value(main, setting, byte_dump_long_to_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ main->output.to = main->message.to;
+
+ if (setting->flag & byte_dump_main_flag_file_to_e) {
+ setting->flag -= byte_dump_main_flag_file_to_e;
+ }
+ }
+
+ if (main->parameters.array[byte_dump_parameter_from_file_e].result == f_console_result_additional_e) {
+ setting->path_files_from.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(main->parameters.array[byte_dump_parameter_from_file_e].values.used, &setting->path_files_from);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_from.used = main->parameters.array[byte_dump_parameter_from_file_e].values.used;
+
+ f_array_length_t i = 0;
+ f_array_length_t index = 0;
+
+ for (; i < setting->path_files_from.used; ++i) {
+
+ index = main->parameters.array[byte_dump_parameter_from_file_e].values.array[i];
+ setting->path_files_from.array[i].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[index], &setting->path_files_from.array[i]);
+ if (F_status_is_error(setting->status)) return;
+
+ if (args[index].used) {
+ if (f_file_exists(args[index], F_true) != F_true) {
+ byte_dump_print_error_parameter_file_not_found(main, setting, F_true, args[index]);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_file_found_not);
+ }
+ }
+ }
+ else {
+ byte_dump_print_error_parameter_file_name_empty(main, setting, index);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_parameter);
+ }
+ }
+ } // for
+
+ if (F_status_is_error(setting->status)) return;
+
+ setting->flag |= byte_dump_main_flag_file_from_e;
+ }
+ else if (main->parameters.array[byte_dump_parameter_from_file_e].result == f_console_result_found_e) {
+ byte_dump_print_error_no_value(main, setting, byte_dump_long_from_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ if (setting->flag & byte_dump_main_flag_file_from_e) {
+ setting->flag -= byte_dump_main_flag_file_from_e;
+ }
+ }
+
+ if (F_status_is_error(setting->status)) return;
+
+ if (main->parameters.array[byte_dump_parameter_from_file_e].result == f_console_result_none_e && !((main->pipe & fll_program_data_pipe_input_e) || main->parameters.remaining.used)) {
+ byte_dump_print_error_no_from(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+ }
+
+ if (!(setting->mode & byte_dump_mode_to_bytesequence_e)) {
+ if (main->parameters.array[byte_dump_parameter_separate_e].result == f_console_result_found_e || main->parameters.array[byte_dump_parameter_headers_e].result == f_console_result_found_e) {
+ setting->prepend = byte_dump_string_prepend_padding_s;
+ setting->append = f_string_eol_s;
+ }
+ else {
+ setting->prepend = f_string_space_s;
+ }
+ }
+
+ if (main->parameters.array[byte_dump_parameter_headers_e].result == f_console_result_found_e) {
+ setting->flag |= byte_dump_main_flag_header_e;
+ }
+
+ if (main->parameters.array[byte_dump_parameter_separate_e].result == f_console_result_found_e) {
+ setting->flag |= byte_dump_main_flag_separate_e;
+ }
+
+ if (main->parameters.array[byte_dump_parameter_strip_invalid_e].result == f_console_result_found_e) {
+ setting->flag |= byte_dump_main_flag_strip_invalid_e;
+ }
+
+ setting->valid_not = main->message.set->error;
+ }
+#endif // _di_byte_dump_setting_load_
+
+#ifndef _di_byte_dump_setting_unload_
+ f_status_t byte_dump_setting_unload(fll_program_data_t * const main, byte_dump_setting_t * const setting) {
+
+ if (!main || !setting) return F_status_set_error(F_parameter);
+
+ byte_dump_setting_delete(setting);
+
+ return F_none;
+ }
+#endif // _di_byte_dump_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
#define byte_dump_total_parameters_d 28
#endif // _di_byte_dump_parameters_
+/**
+ * Flags used to represent flags passed to the main function.
+ *
+ * byte_dump_main_flag_*_e:
+ * - none: No modes in use.
+ * - file_from: Using a specified source file.
+ * - file_to: Using a specified destination file.
+ * - help: Print help.
+ * - header: Enable printing of headers.
+ * - separate: Enable printing of separators.
+ * - strip_invalid: Using strip invalid character mode.
+ * - verify: Using verify mode.
+ * - version: Print version.
+ */
+#ifndef _di_byte_dump_main_flag_e_
+ enum {
+ byte_dump_main_flag_none_e = 0x0,
+ byte_dump_main_flag_file_from_e = 0x1,
+ byte_dump_main_flag_file_to_e = 0x2,
+ byte_dump_main_flag_header_e = 0x4,
+ byte_dump_main_flag_help_e = 0x8,
+ byte_dump_main_flag_separate_e = 0x10,
+ byte_dump_main_flag_strip_invalid_e = 0x20,
+ byte_dump_main_flag_verify_e = 0x40,
+ byte_dump_main_flag_version_e = 0x80,
+ };
+#endif // _di_byte_dump_main_flag_e_
+
+/**
+ * The byte dump main program settings.
+ *
+ * This is passed to the program-specific main entry point to designate program settings.
+ * These program settings are often processed from the program arguments (often called the command line arguments).
+ *
+ * flag: Flags passed to the main function.
+ *
+ * status: The main status code, generally used by the load settings and main functions.
+ *
+ * line_first: A string expected to represent either "\n" or NULL to allow for easy handling of when to print first new line or not.
+ * line_last: A string expected to represent either "\n" or NULL to allow for easy handling of when to print last new line or not.
+ */
+#ifndef _di_byte_dump_setting_t_
+ typedef struct {
+ uint16_t flag;
+
+ f_status_t status;
+
+ f_string_static_t line_first;
+ f_string_static_t line_last;
+ } byte_dump_setting_t;
+
+ #define byte_dump_setting_t_initialize \
+ { \
+ byte_dump_main_flag_none_e, \
+ F_none, \
+ f_string_static_t_initialize, \
+ f_string_static_t_initialize, \
+ }
+#endif // _di_byte_dump_setting_t_
+
#ifdef __cplusplus
} // extern "C"
#endif
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
fll_program_data_t data = fll_program_data_t_initialize;
+ byte_dump_setting_t setting = byte_dump_setting_t_initialize;
f_console_parameter_t parameters[] = byte_dump_console_parameter_t_initialize;
data.parameters.array = parameters;
data.parameters.used = byte_dump_total_parameters_d;
+ data.environment = envp;
if (f_pipe_input_exists()) {
data.pipe = fll_program_data_pipe_input_e;
fll_program_standard_set_up(&data);
- const f_status_t status = byte_dump_main(&data, arguments);
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+
+ byte_dump_setting_load(arguments, &data, &setting);
+ }
+
+ byte_dump_main(&data, &setting);
+
+ byte_dump_setting_unload(&data, &setting);
fll_program_data_delete(&data);
fll_program_standard_set_down(&data);
- if (F_status_is_error(status)) return 1;
-
- return 0;
+ return F_status_is_error(status) ? 1 : 0;
}
--- /dev/null
+#include "byte_dump.h"
+#include "private-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_byte_dump_print_help_
+ f_status_t byte_dump_print_help(byte_dump_setting_t * const setting, const fl_print_t print) {
+
+ f_file_stream_lock(print.to);
+
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+
+ fll_program_print_help_header(print, byte_dump_program_name_long_s, byte_dump_program_version_s);
+
+ fll_program_print_help_option_standard(print);
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, byte_dump_short_binary_s, byte_dump_long_binary_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Display binary representation.");
+ fll_program_print_help_option(print, byte_dump_short_decimal_s, byte_dump_long_decimal_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Display decimal representation.");
+ fll_program_print_help_option(print, byte_dump_short_duodecimal_s, byte_dump_long_duodecimal_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Display duodecimal representation.");
+ fll_program_print_help_option(print, byte_dump_short_hexidecimal_s, byte_dump_long_hexidecimal_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Display hexadecimal representation.");
+ fll_program_print_help_option(print, byte_dump_short_octal_s, byte_dump_long_octal_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Display octal representation.");
+ fll_program_print_help_option(print, byte_dump_short_unicode_s, byte_dump_long_unicode_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Display using Unicode representation for valid Unicode (like: U+0000).");
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, byte_dump_short_first_s, byte_dump_long_first_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Start reading at this byte offset.");
+ fll_program_print_help_option(print, byte_dump_short_last_s, byte_dump_long_last_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Stop reading at this (inclusive) byte offset.");
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, byte_dump_short_narrow_s, byte_dump_long_narrow_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use narrow display, resulting in 1*width reducing size of the text columns.");
+ fll_program_print_help_option(print, byte_dump_short_placeholder_s, byte_dump_long_placeholder_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Use a placeholder character instead of a space for placeholders.");
+ fll_program_print_help_option(print, byte_dump_short_text_s, byte_dump_long_text_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Include a column of text when displaying the bytes.");
+ fll_program_print_help_option(print, byte_dump_short_wide_s, byte_dump_long_wide_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use wide display, resulting in 2*width allowing for space for wide characters in the text columns.");
+ fll_program_print_help_option(print, byte_dump_short_width_s, byte_dump_long_width_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Set number of columns of Bytes to display.");
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fl_print_format(" %[Special Options:%] ", print.to.stream, context.set.important, context.set.important);
+
+ fll_program_print_help_option_long(print.to, context, byte_dump_long_normal_s, f_console_symbol_long_enable_s, " Display UTF-8 symbols for ASCII control codes.");
+ fll_program_print_help_option_long(print.to, context, byte_dump_long_simple_s, f_console_symbol_long_enable_s, " Display spaces for ASCII control codes.");
+ fll_program_print_help_option_long(print.to, context, byte_dump_long_classic_s, f_console_symbol_long_enable_s, "Display periods for ASCII control codes.");
+
+ fll_program_print_help_usage(print, byte_dump_program_name_s, fll_program_parameter_filenames_s);
+
+ //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+ //}
+
+ fl_print_format(" When using the %[%r%r%] option, some UTF-8 characters may be replaced by your instance and cause display alignment issues.%r%r", print.to.stream, context.set.notable, f_console_symbol_long_enable_s, byte_dump_long_text_s, context.set.notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" Special UTF-8 characters and non-spacing UTF-8 characters may be replaced with a space (or a placeholder when the %[%r%r%] option is used).%r%r", print.to.stream, context.set.notable, f_console_symbol_long_enable_s, byte_dump_long_placeholder_s, context.set.notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" UTF-8 \"Combining\" characters might have a space appended to allow a proper display but this may cause copy and paste issues.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When %[%r%r%] is used, any UTF-8 sequences will still be printed in full should any part is found within the requested range.%r%r", print.to.stream, context.set.notable, f_console_symbol_long_enable_s, byte_dump_long_last_s, context.set.notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When using the %[%r%r%] option, invalid Unicode will fallback to being displayed using one of the other modes.%r", print.to.stream, context.set.notable, f_console_symbol_long_enable_s, byte_dump_long_unicode_s, context.set.notable, f_string_eol_s);
+
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+
+ f_file_stream_flush(output);
+ f_file_stream_unlock(print.to);
+
+ return F_none;
+ }
+#endif // _di_byte_dump_print_help_
+
+#ifndef _di_byte_dump_print_line_first_
+ void byte_dump_print_line_first(byte_dump_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ }
+#endif // _di_byte_dump_print_line_first_
+
+#ifndef _di_byte_dump_print_line_last_
+ void byte_dump_print_line_last(byte_dump_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+ if (print.verbosity == f_console_verbosity_error_e && !F_status_is_error(setting->status)) return;
+ if (setting->flag & byte_dump_main_flag_verify_e) return;
+ if ((setting->flag & byte_dump_main_flag_file_to_e) && !F_status_is_error(setting->status)) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ }
+#endif // _di_byte_dump_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: UTF-8
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _byte_dump_print_h
+#define _byte_dump_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print help.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param output
+ * The file to print to.
+ * @param context
+ * The color context settings.
+ *
+ * @return
+ * F_none on success.
+ *
+ * @see byte_dump_main()
+ */
+#ifndef _di_byte_dump_print_help_
+ extern f_status_t byte_dump_print_help(byte_dump_setting_t * const setting, const fl_print_t print);
+#endif // _di_byte_dump_print_help_
+
+/**
+ * Print first new line, unless verbosity says otherwise.
+ *
+ * This is generally either the first line in the program or the first line printed before an error message.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_byte_dump_print_line_first_
+ extern void byte_dump_print_line_first(byte_dump_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_byte_dump_print_line_first_
+
+/**
+ * Print last new line when the main is complete, unless verbosity says otherwise.
+ *
+ * This is generally the very last line printed in the program.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_byte_dump_print_line_last_
+ extern void byte_dump_print_line_last(byte_dump_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_byte_dump_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _byte_dump_print_h
if (!((++data->main->signal_check) % byte_dump_signal_check_d)) {
if (fll_program_standard_signal_received(data->main)) {
- byte_dump_print_signal_received(data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
extern "C" {
#endif
-#ifndef _di_byte_dump_print_signal_received_
- void byte_dump_print_signal_received(byte_dump_data_t * const data) {
-
- if (data->main->warning.verbosity != f_console_verbosity_verbose_e && data->main->warning.verbosity != f_console_verbosity_debug_e) return;
-
- // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
- fflush(data->main->warning.to.stream);
-
- flockfile(data->main->warning.to.stream);
-
- fl_print_format("%]%r%r%[Received signal code %]", data->main->warning.to.stream, data->main->context.set.reset, f_string_eol_s, f_string_eol_s, data->main->context.set.warning, data->main->context.set.warning);
- fl_print_format("%[%i%]", data->main->warning.to.stream, data->main->context.set.notable, data->main->signal_received, data->main->context.set.notable);
- fl_print_format("%[.%]%r", data->main->warning.to.stream, data->main->context.set.warning, data->main->context.set.warning, f_string_eol_s);
-
- funlockfile(data->main->warning.to.stream);
- }
-#endif // _di_byte_dump_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
}
#endif // _di_byte_previous_cell_
-/**
- * Print a message about a process signal being recieved, such as an interrupt signal.
- *
- * @param main
- * The main program data.
- */
-#ifndef _di_byte_dump_print_signal_received_
- extern void byte_dump_print_signal_received(byte_dump_data_t * const data) F_attribute_visibility_internal_d;
-#endif // _di_byte_dump_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library byte_dump.c common.c private-common.c private-byte_dump.c
+build_sources_library byte_dump.c common.c print.c private-common.c private-byte_dump.c
build_sources_program main.c
-build_sources_headers byte_dump.h common.h
+build_sources_headers byte_dump.h common.h print.h
build_script yes
build_shared yes
}
#endif // _di_control_payload_type_name_
+#ifndef _di_control_setting_delete_
+ f_status_t control_setting_delete(control_setting_t * const setting) {
+
+ if (!setting) return F_status_set_error(F_parameter);
+
+ return F_none;
+ }
+#endif // _di_control_setting_delete_
+
+#ifndef _di_control_setting_load_
+ void control_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, control_setting_t * const setting) {
+
+ if (!main || !setting) return;
+
+ // Load parameters.
+ setting->status = f_console_parameter_process(arguments, &main->parameters);
+ if (F_status_is_error(setting->status)) return;
+
+ {
+ f_array_length_t choice = 0;
+ f_uint16s_t choices = f_uint16s_t_initialize;
+
+ // Identify and prioritize "color context" parameters.
+ {
+ uint16_t choices_array[3] = { control_parameter_no_color_e, control_parameter_light_e, control_parameter_dark_e };
+ choices.array = choices_array;
+ choices.used = 3;
+
+ const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
+
+ setting->status = fll_program_parameter_process_context(choices, modes, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ control_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_context", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[control_parameter_line_first_no_e].result == f_console_result_found_e) {
+ setting->line_first = f_string_empty_s;
+ }
+ else {
+ setting->line_first = f_string_eol_s;
+ }
+
+ if (main->parameters.array[control_parameter_line_last_no_e].result == f_console_result_found_e) {
+ setting->line_last = f_string_empty_s;
+ }
+ else {
+ setting->line_last = f_string_eol_s;
+ }
+
+ // Identify and prioritize "verbosity" parameters.
+ {
+ uint16_t choices_array[5] = { control_parameter_verbosity_quiet_e, control_parameter_verbosity_error_e, control_parameter_verbosity_verbose_e, control_parameter_verbosity_debug_e, control_parameter_verbosity_normal_e };
+ choices.array = choices_array;
+ choices.used = 5;
+
+ const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+
+ setting->status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ control_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_verbosity", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[control_parameter_help_e].result == f_console_result_found_e) {
+ setting->flag |= control_main_flag_help_e;
+
+ return;
+ }
+
+ if (main->parameters.array[control_parameter_version_e].result == f_console_result_found_e) {
+ setting->flag |= control_main_flag_version_e;
+
+ return;
+ }
+
+ // Identify and prioritize "from" mode parameters.
+ {
+ uint16_t choices_array[2] = { control_parameter_from_bytesequence_e, control_parameter_from_codepoint_e };
+ choices.array = choices_array;
+ choices.used = 2;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ control_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == control_parameter_from_bytesequence_e) {
+ if (setting->mode & control_mode_from_codepoint_e) {
+ setting->mode -= control_mode_from_codepoint_e;
+ }
+
+ setting->mode |= control_mode_from_bytesequence_e;
+ }
+ else if (choices.array[choice] == control_parameter_from_codepoint_e) {
+ if (setting->mode & control_mode_from_bytesequence_e) {
+ setting->mode -= control_mode_from_bytesequence_e;
+ }
+
+ setting->mode |= control_mode_from_codepoint_e;
+ }
+ }
+
+ // Identify and prioritize "to" mode parameters.
+ {
+ uint16_t choices_array[4] = { control_parameter_to_bytesequence_e, control_parameter_to_codepoint_e, control_parameter_to_combining_e, control_parameter_to_width_e };
+ choices.array = choices_array;
+ choices.used = 4;
+ choice = 1;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ control_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == control_parameter_to_bytesequence_e) {
+ if (setting->mode & control_mode_to_codepoint_e) {
+ setting->mode -= control_mode_to_codepoint_e;
+ }
+
+ if (setting->mode & control_mode_to_combining_e) {
+ setting->mode -= control_mode_to_combining_e;
+ }
+
+ if (setting->mode & control_mode_to_width_e) {
+ setting->mode -= control_mode_to_width_e;
+ }
+
+ setting->mode |= control_mode_to_bytesequence_e;
+ }
+ else if (choices.array[choice] == control_parameter_to_codepoint_e) {
+ if (setting->mode & control_mode_to_bytesequence_e) {
+ setting->mode -= control_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & control_mode_to_combining_e) {
+ setting->mode -= control_mode_to_combining_e;
+ }
+
+ if (setting->mode & control_mode_to_width_e) {
+ setting->mode -= control_mode_to_width_e;
+ }
+
+ setting->mode |= control_mode_to_codepoint_e;
+ }
+ else if (choices.array[choice] == control_parameter_to_combining_e) {
+ if (setting->mode & control_mode_to_bytesequence_e) {
+ setting->mode -= control_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & control_mode_to_codepoint_e) {
+ setting->mode -= control_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[control_parameter_to_width_e].result == f_console_result_found_e) {
+ setting->mode |= control_mode_to_width_e;
+ }
+
+ setting->mode |= control_mode_to_combining_e;
+ }
+ else if (choices.array[choice] == control_parameter_to_width_e) {
+ if (setting->mode & control_mode_to_bytesequence_e) {
+ setting->mode -= control_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & control_mode_to_codepoint_e) {
+ setting->mode -= control_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[control_parameter_to_combining_e].result == f_console_result_found_e) {
+ setting->mode |= control_mode_to_combining_e;
+ }
+
+ setting->mode |= control_mode_to_width_e;
+ }
+ }
+ }
+
+ f_string_static_t * const args = main->parameters.arguments.array;
+
+ if (main->parameters.array[control_parameter_to_file_e].result == f_console_result_additional_e) {
+ if (main->parameters.array[control_parameter_to_file_e].values.used > 1) {
+ control_print_error_parameter_file_to_too_many(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+
+ if (args[main->parameters.array[control_parameter_to_file_e].values.array[0]].used) {
+ setting->path_files_to.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(1, &setting->path_files_to);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_to.array[setting->path_files_to.used].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[main->parameters.array[control_parameter_to_file_e].values.array[0]], &setting->path_files_to.array[0]);
+ if (F_status_is_error(setting->status)) return;
+
+ ++setting->path_files_to.used;
+
+ setting->status = f_file_stream_open(args[main->parameters.array[control_parameter_to_file_e].values.array[0]], f_file_open_mode_append_s, &main->output.to);
+
+ if (F_status_is_error(setting->status)) {
+ fll_error_file_print(main->error, F_status_set_fine(setting->status), "f_file_stream_open", F_true, args[main->parameters.array[control_parameter_to_file_e].values.array[0]], f_file_operation_open_s, fll_error_file_type_file_e);
+
+ return;
+ }
+
+ setting->flag |= control_main_flag_file_to_e;
+ }
+ else {
+ control_print_error_parameter_file_name_empty(main, setting, main->parameters.array[control_parameter_to_file_e].values.array[0]);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+ else if (main->parameters.array[control_parameter_to_file_e].result == f_console_result_found_e) {
+ control_print_error_no_value(main, setting, control_long_to_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ main->output.to = main->message.to;
+
+ if (setting->flag & control_main_flag_file_to_e) {
+ setting->flag -= control_main_flag_file_to_e;
+ }
+ }
+
+ if (main->parameters.array[control_parameter_from_file_e].result == f_console_result_additional_e) {
+ setting->path_files_from.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(main->parameters.array[control_parameter_from_file_e].values.used, &setting->path_files_from);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_from.used = main->parameters.array[control_parameter_from_file_e].values.used;
+
+ f_array_length_t i = 0;
+ f_array_length_t index = 0;
+
+ for (; i < setting->path_files_from.used; ++i) {
+
+ index = main->parameters.array[control_parameter_from_file_e].values.array[i];
+ setting->path_files_from.array[i].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[index], &setting->path_files_from.array[i]);
+ if (F_status_is_error(setting->status)) return;
+
+ if (args[index].used) {
+ if (f_file_exists(args[index], F_true) != F_true) {
+ control_print_error_parameter_file_not_found(main, setting, F_true, args[index]);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_file_found_not);
+ }
+ }
+ }
+ else {
+ control_print_error_parameter_file_name_empty(main, setting, index);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_parameter);
+ }
+ }
+ } // for
+
+ if (F_status_is_error(setting->status)) return;
+
+ setting->flag |= control_main_flag_file_from_e;
+ }
+ else if (main->parameters.array[control_parameter_from_file_e].result == f_console_result_found_e) {
+ control_print_error_no_value(main, setting, control_long_from_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ if (setting->flag & control_main_flag_file_from_e) {
+ setting->flag -= control_main_flag_file_from_e;
+ }
+ }
+
+ if (F_status_is_error(setting->status)) return;
+
+ if (main->parameters.array[control_parameter_from_file_e].result == f_console_result_none_e && !((main->pipe & fll_program_data_pipe_input_e) || main->parameters.remaining.used)) {
+ control_print_error_no_from(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+ }
+
+ if (!(setting->mode & control_mode_to_bytesequence_e)) {
+ if (main->parameters.array[control_parameter_separate_e].result == f_console_result_found_e || main->parameters.array[control_parameter_headers_e].result == f_console_result_found_e) {
+ setting->prepend = control_string_prepend_padding_s;
+ setting->append = f_string_eol_s;
+ }
+ else {
+ setting->prepend = f_string_space_s;
+ }
+ }
+
+ if (main->parameters.array[control_parameter_headers_e].result == f_console_result_found_e) {
+ setting->flag |= control_main_flag_header_e;
+ }
+
+ if (main->parameters.array[control_parameter_separate_e].result == f_console_result_found_e) {
+ setting->flag |= control_main_flag_separate_e;
+ }
+
+ if (main->parameters.array[control_parameter_strip_invalid_e].result == f_console_result_found_e) {
+ setting->flag |= control_main_flag_strip_invalid_e;
+ }
+
+ setting->valid_not = main->message.set->error;
+ }
+#endif // _di_control_setting_load_
+
+#ifndef _di_control_setting_unload_
+ f_status_t control_setting_unload(fll_program_data_t * const main, control_setting_t * const setting) {
+
+ if (!main || !setting) return F_status_set_error(F_parameter);
+
+ control_setting_delete(setting);
+
+ return F_none;
+ }
+#endif // _di_control_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
#endif // _di_control_payload_types_
/**
+ * Flags used to represent flags passed to the main function.
+ *
+ * control_main_flag_*_e:
+ * - none: No modes in use.
+ * - file_from: Using a specified source file.
+ * - file_to: Using a specified destination file.
+ * - help: Print help.
+ * - header: Enable printing of headers.
+ * - separate: Enable printing of separators.
+ * - strip_invalid: Using strip invalid character mode.
+ * - verify: Using verify mode.
+ * - version: Print version.
+ */
+#ifndef _di_control_main_flag_e_
+ enum {
+ control_main_flag_none_e = 0x0,
+ control_main_flag_file_from_e = 0x1,
+ control_main_flag_file_to_e = 0x2,
+ control_main_flag_header_e = 0x4,
+ control_main_flag_help_e = 0x8,
+ control_main_flag_separate_e = 0x10,
+ control_main_flag_strip_invalid_e = 0x20,
+ control_main_flag_verify_e = 0x40,
+ control_main_flag_version_e = 0x80,
+ };
+#endif // _di_control_main_flag_e_
+
+/**
+ * The control main program settings.
+ *
+ * This is passed to the program-specific main entry point to designate program settings.
+ * These program settings are often processed from the program arguments (often called the command line arguments).
+ *
+ * flag: Flags passed to the main function.
+ *
+ * status: The main status code, generally used by the load settings and main functions.
+ *
+ * line_first: A string expected to represent either "\n" or NULL to allow for easy handling of when to print first new line or not.
+ * line_last: A string expected to represent either "\n" or NULL to allow for easy handling of when to print last new line or not.
+ */
+#ifndef _di_control_setting_t_
+ typedef struct {
+ uint16_t flag;
+
+ f_status_t status;
+
+ f_string_static_t line_first;
+ f_string_static_t line_last;
+ } control_setting_t;
+
+ #define control_setting_t_initialize \
+ { \
+ control_main_flag_none_e, \
+ F_none, \
+ f_string_static_t_initialize, \
+ f_string_static_t_initialize, \
+ }
+#endif // _di_control_setting_t_
+
+/**
* Identify the action code the given name represents.
*
* @param action
extern f_string_static_t control_payload_type_name(const uint8_t type);
#endif // _di_control_payload_type_name_
+/**
+ * Delete the program main setting data.
+ *
+ * @param setting
+ * The program main setting data.
+ * This does not alter setting.status.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_control_setting_delete_
+ extern f_status_t control_setting_delete(control_setting_t * const setting);
+#endif // _di_control_setting_delete_
+
+/**
+ * Perform the standard program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately retuns without doing anything.
+ *
+ * @param arguments
+ * The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ *
+ * This alters setting.status:
+ * F_none on success.
+ *
+ * Errors (with error bit) from: f_console_parameter_process().
+ * Errors (with error bit) from: fll_program_parameter_process_context().
+ *
+ * @see f_console_parameter_process()
+ * @see fll_program_parameter_process_context()
+ */
+#ifndef _di_control_setting_load_
+ extern void control_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, control_setting_t * const setting);
+#endif // _di_control_setting_load_
+
+/**
+ * Perform the standard program setting unload process.
+ *
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * All buffers are deallocated.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: utf8_setting_delete().
+ *
+ * @see utf8_setting_delete()
+ */
+#ifndef _di_control_setting_unload_
+ extern f_status_t control_setting_unload(fll_program_data_t * const main, control_setting_t * const setting);
+#endif // _di_control_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern "C" {
#endif
-#ifndef _di_control_print_help_
- f_status_t control_print_help(const fll_program_data_t * const main) {
-
- flockfile(main->output.to.stream);
-
- //if (!(setting->flag & XXX_main_flag_line_first_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- fll_program_print_help_header(main->output.to, main->context, control_program_name_long_s, control_program_version_s);
-
- fll_program_print_help_option_standard(main->output.to, context);
-
- f_print_dynamic_raw(f_string_eol_s, main->output.to.stream);
-
- fll_program_print_help_option(main->output.to, main->context, control_short_name_s, control_long_name_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify the name of the controller socket file.");
- fll_program_print_help_option(main->output.to, main->context, control_short_return_s, control_long_return_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print a message about the response packet.");
- fll_program_print_help_option(main->output.to, main->context, control_short_settings_s, control_long_settings_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Specify a directory path or a full path to the control settings file.");
- fll_program_print_help_option(main->output.to, main->context, control_short_socket_s, control_long_socket_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a directory path or a full path to the controller socket file.");
-
- fll_program_print_help_usage(main->output.to, main->context, control_program_name_s, control_action_s);
-
- fl_print_format("%r When the %[%r%r%] parameter represents a directory path then the file name is generated from either the", main->output.to.stream, f_string_eol_s, main->context.set.notable, f_console_symbol_long_enable_s, control_long_socket_s, main->context.set.notable);
- fl_print_format(" %[%r%r%] parameter or from the control settings file.%r%r", main->output.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, control_long_name_s, main->context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" A rule action allows for either the full rule path, such as '%[boot/root%]'", main->output.to.stream, main->context.set.notable, main->context.set.notable);
- fl_print_format(" as a single parameter or two parameters with the first representing the rule directory path '%[boot%]'", main->output.to.stream, main->context.set.notable, main->context.set.notable);
- fl_print_format(" and the second representing the rule base name '%[root%]'.%r%r", main->output.to.stream, main->context.set.notable, main->context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The %[%r%r%] parameter is intended to be used for scripting and is of the form \"response [type] [action] [status]\".%r", main->output.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, control_long_return_s, main->context.set.notable, f_string_eol_s);
- fl_print_format(" Be sure to use the %[%r%r%] parameter to suppress output when using this in scripting.%r", main->output.to.stream, main->context.set.notable, f_console_symbol_long_disable_s, f_console_standard_long_quiet_s, main->context.set.notable, f_string_eol_s);
- fl_print_format(" No response is returned on program errors, especially those errors that prevent communicating to the controller.%r", main->output.to.stream, f_string_eol_s);
-
- //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, main->output.to.stream);
- //}
-
- f_file_stream_flush(main->output.to.stream);
- funlockfile(main->output.to.stream);
-
- return F_none;
- }
-#endif // _di_control_print_help_
-
#ifndef _di_control_main_
- f_status_t control_main(fll_program_data_t * const main, const f_console_arguments_t arguments) {
+ f_status_t control_main(fll_program_data_t * const main, control_setting_t * const setting) {
f_status_t status = F_none;
}
if (main->parameters.array[control_parameter_version_e].result == f_console_result_found_e) {
- fll_program_print_version(main->output.to, control_program_version_s);
+ fll_program_print_version(main->message, control_program_version_s);
return F_none;
}
#endif
/**
- * Print help.
- *
- * @param main
- * The main program data.
- *
- * @return
- * F_none on success.
- *
- * @see control_main()
- */
-#ifndef _di_control_print_help_
- extern f_status_t control_print_help(const fll_program_data_t * const main);
-#endif // _di_control_print_help_
-
-/**
* Execute main program.
*
* If main.signal is non-zero, then this blocks and handles the following signals:
* Status codes (with error bit) are returned on any problem.
*/
#ifndef _di_control_main_
- extern f_status_t control_main(fll_program_data_t * const main, const f_console_arguments_t arguments);
+ extern f_status_t control_main(fll_program_data_t * const main, control_setting_t * const setting);
#endif // _di_control_main_
#ifdef __cplusplus
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
fll_program_data_t data = fll_program_data_t_initialize;
+ control_setting_t setting = control_setting_t_initialize;
f_console_parameter_t parameters[] = control_console_parameter_t_initialize;
data.parameters.array = parameters;
data.parameters.used = control_total_parameters_d;
+ data.environment = envp;
if (f_pipe_input_exists()) {
data.pipe = fll_program_data_pipe_input_e;
fll_program_standard_set_up(&data);
- const f_status_t status = control_main(&data, arguments);
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+
+ control_setting_load(arguments, &data, &setting);
+ }
+
+ control_main(&data, &setting);
+
+ control_setting_unload(&data, &setting);
fll_program_data_delete(&data);
fll_program_standard_set_down(&data);
- if (F_status_is_error(status)) return 1;
-
- return 0;
+ return F_status_is_error(status) ? 1 : 0;
}
--- /dev/null
+#include "control.h"
+#include "private-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_control_print_help_
+ f_status_t control_print_help(control_setting_t * const setting, const fl_print_t print) {
+
+ f_file_stream_lock(print.to);
+
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+
+ fll_program_print_help_header(print, control_program_name_long_s, control_program_version_s);
+
+ fll_program_print_help_option_standard(main->output.to, context);
+
+ f_print_dynamic_raw(f_string_eol_s, main->output.to.stream);
+
+ fll_program_print_help_option(print, control_short_name_s, control_long_name_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify the name of the controller socket file.");
+ fll_program_print_help_option(print, control_short_return_s, control_long_return_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print a message about the response packet.");
+ fll_program_print_help_option(print, control_short_settings_s, control_long_settings_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Specify a directory path or a full path to the control settings file.");
+ fll_program_print_help_option(print, control_short_socket_s, control_long_socket_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a directory path or a full path to the controller socket file.");
+
+ fll_program_print_help_usage(print, control_program_name_s, control_action_s);
+
+ fl_print_format("%r When the %[%r%r%] parameter represents a directory path then the file name is generated from either the", print.to.stream, f_string_eol_s, print.set->notable, f_console_symbol_long_enable_s, control_long_socket_s, print.set->notable);
+ fl_print_format(" %[%r%r%] parameter or from the control settings file.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, control_long_name_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" A rule action allows for either the full rule path, such as '%[boot/root%]'", print.to.stream, print.set->notable, print.set->notable);
+ fl_print_format(" as a single parameter or two parameters with the first representing the rule directory path '%[boot%]'", print.to.stream, print.set->notable, print.set->notable);
+ fl_print_format(" and the second representing the rule base name '%[root%]'.%r%r", print.to.stream, print.set->notable, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The %[%r%r%] parameter is intended to be used for scripting and is of the form \"response [type] [action] [status]\".%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, control_long_return_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" Be sure to use the %[%r%r%] parameter to suppress output when using this in scripting.%r", print.to.stream, print.set->notable, f_console_symbol_long_disable_s, f_console_standard_long_quiet_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" No response is returned on program errors, especially those errors that prevent communicating to the controller.%r", print.to.stream, f_string_eol_s);
+
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+
+ f_file_stream_flush(print.to);
+ f_file_stream_unlock(print.to);
+
+ return F_none;
+ }
+#endif // _di_control_print_help_
+
+#ifndef _di_control_print_line_first_
+ void control_print_line_first(control_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ }
+#endif // _di_control_print_line_first_
+
+#ifndef _di_control_print_line_last_
+ void control_print_line_last(control_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+ if (print.verbosity == f_console_verbosity_error_e && !F_status_is_error(setting->status)) return;
+ if (setting->flag & control_main_flag_verify_e) return;
+ if ((setting->flag & control_main_flag_file_to_e) && !F_status_is_error(setting->status)) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ }
+#endif // _di_control_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: UTF-8
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _control_print_h
+#define _control_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print help.
+ *
+ * @param main
+ * The main program data.
+ *
+ * @return
+ * F_none on success.
+ *
+ * @see control_main()
+ */
+#ifndef _di_control_print_help_
+ extern f_status_t control_print_help(const fll_program_data_t * const main);
+#endif // _di_control_print_help_
+
+/**
+ * Print first new line, unless verbosity says otherwise.
+ *
+ * This is generally either the first line in the program or the first line printed before an error message.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_control_print_line_first_
+ extern void control_print_line_first(control_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_control_print_line_first_
+
+/**
+ * Print last new line when the main is complete, unless verbosity says otherwise.
+ *
+ * This is generally the very last line printed in the program.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_control_print_line_last_
+ extern void control_print_line_last(control_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_control_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _control_print_h
}
#endif // _di_control_print_error_socket_file_not_
-#ifndef _di_control_print_signal_received_
- void control_print_signal_received(const fll_program_data_t * const main, const f_status_t signal) {
-
- if (main->warning.verbosity != f_console_verbosity_verbose_e && main->warning.verbosity != f_console_verbosity_debug_e) return;
-
- // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
- fflush(main->warning.to.stream);
-
- flockfile(main->warning.to.stream);
-
- fl_print_format("%]%r%r%[Received signal code%] ", main->warning.to.stream, main->context.set.reset, f_string_eol_s, f_string_eol_s, main->context.set.warning, main->context.set.warning);
- fl_print_format("%[%i%]", main->warning.to.stream, main->context.set.notable, signal, main->context.set.notable);
- fl_print_format("%[.%]%r", main->warning.to.stream, main->context.set.warning, main->context.set.warning, f_string_eol_s);
-
- funlockfile(main->warning.to.stream);
- }
-#endif // _di_control_print_signal_received_
-
#ifndef _di_control_print_warning_packet_header_duplicate_object_
void control_print_warning_packet_header_duplicate_object(const fll_program_data_t * const main, const f_string_static_t response_header) {
#endif // _di_control_print_error_socket_file_not_
/**
- * Print a message about a process signal being recieved, such as an interrupt signal.
- *
- * @param main
- * The main program data.
- * @param signal
- * The signal received.
- */
-#ifndef _di_control_print_signal_received_
- extern void control_print_signal_received(const fll_program_data_t * const main, const f_status_t signal) F_attribute_visibility_internal_d;
-#endif // _di_control_print_signal_received_
-
-/**
* Print a warning message about a response header being repeated (when debugging).
*
* This program currently does not support multiple headers for any given valid header Object.
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library control.c common.c private-common.c private-control.c private-print.c
+build_sources_library control.c common.c print.c private-common.c private-control.c private-print.c
build_sources_program main.c
-build_sources_headers control.h common.h
+build_sources_headers control.h common.h print.h
build_script yes
build_shared yes
}
#endif // _di_controller_rule_setting_limit_type_name_
+#ifndef _di_controller_setting_delete_
+ f_status_t controller_setting_delete(controller_setting_t * const setting) {
+
+ if (!setting) return F_status_set_error(F_parameter);
+
+ return F_none;
+ }
+#endif // _di_controller_setting_delete_
+
+#ifndef _di_controller_setting_load_
+ void controller_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, controller_setting_t * const setting) {
+
+ if (!main || !setting) return;
+
+ // Load parameters.
+ setting->status = f_console_parameter_process(arguments, &main->parameters);
+ if (F_status_is_error(setting->status)) return;
+
+ {
+ f_array_length_t choice = 0;
+ f_uint16s_t choices = f_uint16s_t_initialize;
+
+ // Identify and prioritize "color context" parameters.
+ {
+ uint16_t choices_array[3] = { controller_parameter_no_color_e, controller_parameter_light_e, controller_parameter_dark_e };
+ choices.array = choices_array;
+ choices.used = 3;
+
+ const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
+
+ setting->status = fll_program_parameter_process_context(choices, modes, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ controller_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_context", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[controller_parameter_line_first_no_e].result == f_console_result_found_e) {
+ setting->line_first = f_string_empty_s;
+ }
+ else {
+ setting->line_first = f_string_eol_s;
+ }
+
+ if (main->parameters.array[controller_parameter_line_last_no_e].result == f_console_result_found_e) {
+ setting->line_last = f_string_empty_s;
+ }
+ else {
+ setting->line_last = f_string_eol_s;
+ }
+
+ // Identify and prioritize "verbosity" parameters.
+ {
+ uint16_t choices_array[5] = { controller_parameter_verbosity_quiet_e, controller_parameter_verbosity_error_e, controller_parameter_verbosity_verbose_e, controller_parameter_verbosity_debug_e, controller_parameter_verbosity_normal_e };
+ choices.array = choices_array;
+ choices.used = 5;
+
+ const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+
+ setting->status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ controller_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_verbosity", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[controller_parameter_help_e].result == f_console_result_found_e) {
+ setting->flag |= controller_main_flag_help_e;
+
+ return;
+ }
+
+ if (main->parameters.array[controller_parameter_version_e].result == f_console_result_found_e) {
+ setting->flag |= controller_main_flag_version_e;
+
+ return;
+ }
+
+ // Identify and prioritize "from" mode parameters.
+ {
+ uint16_t choices_array[2] = { controller_parameter_from_bytesequence_e, controller_parameter_from_codepoint_e };
+ choices.array = choices_array;
+ choices.used = 2;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ controller_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == controller_parameter_from_bytesequence_e) {
+ if (setting->mode & controller_mode_from_codepoint_e) {
+ setting->mode -= controller_mode_from_codepoint_e;
+ }
+
+ setting->mode |= controller_mode_from_bytesequence_e;
+ }
+ else if (choices.array[choice] == controller_parameter_from_codepoint_e) {
+ if (setting->mode & controller_mode_from_bytesequence_e) {
+ setting->mode -= controller_mode_from_bytesequence_e;
+ }
+
+ setting->mode |= controller_mode_from_codepoint_e;
+ }
+ }
+
+ // Identify and prioritize "to" mode parameters.
+ {
+ uint16_t choices_array[4] = { controller_parameter_to_bytesequence_e, controller_parameter_to_codepoint_e, controller_parameter_to_combining_e, controller_parameter_to_width_e };
+ choices.array = choices_array;
+ choices.used = 4;
+ choice = 1;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ controller_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == controller_parameter_to_bytesequence_e) {
+ if (setting->mode & controller_mode_to_codepoint_e) {
+ setting->mode -= controller_mode_to_codepoint_e;
+ }
+
+ if (setting->mode & controller_mode_to_combining_e) {
+ setting->mode -= controller_mode_to_combining_e;
+ }
+
+ if (setting->mode & controller_mode_to_width_e) {
+ setting->mode -= controller_mode_to_width_e;
+ }
+
+ setting->mode |= controller_mode_to_bytesequence_e;
+ }
+ else if (choices.array[choice] == controller_parameter_to_codepoint_e) {
+ if (setting->mode & controller_mode_to_bytesequence_e) {
+ setting->mode -= controller_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & controller_mode_to_combining_e) {
+ setting->mode -= controller_mode_to_combining_e;
+ }
+
+ if (setting->mode & controller_mode_to_width_e) {
+ setting->mode -= controller_mode_to_width_e;
+ }
+
+ setting->mode |= controller_mode_to_codepoint_e;
+ }
+ else if (choices.array[choice] == controller_parameter_to_combining_e) {
+ if (setting->mode & controller_mode_to_bytesequence_e) {
+ setting->mode -= controller_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & controller_mode_to_codepoint_e) {
+ setting->mode -= controller_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[controller_parameter_to_width_e].result == f_console_result_found_e) {
+ setting->mode |= controller_mode_to_width_e;
+ }
+
+ setting->mode |= controller_mode_to_combining_e;
+ }
+ else if (choices.array[choice] == controller_parameter_to_width_e) {
+ if (setting->mode & controller_mode_to_bytesequence_e) {
+ setting->mode -= controller_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & controller_mode_to_codepoint_e) {
+ setting->mode -= controller_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[controller_parameter_to_combining_e].result == f_console_result_found_e) {
+ setting->mode |= controller_mode_to_combining_e;
+ }
+
+ setting->mode |= controller_mode_to_width_e;
+ }
+ }
+ }
+
+ f_string_static_t * const args = main->parameters.arguments.array;
+
+ if (main->parameters.array[controller_parameter_to_file_e].result == f_console_result_additional_e) {
+ if (main->parameters.array[controller_parameter_to_file_e].values.used > 1) {
+ controller_print_error_parameter_file_to_too_many(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+
+ if (args[main->parameters.array[controller_parameter_to_file_e].values.array[0]].used) {
+ setting->path_files_to.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(1, &setting->path_files_to);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_to.array[setting->path_files_to.used].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[main->parameters.array[controller_parameter_to_file_e].values.array[0]], &setting->path_files_to.array[0]);
+ if (F_status_is_error(setting->status)) return;
+
+ ++setting->path_files_to.used;
+
+ setting->status = f_file_stream_open(args[main->parameters.array[controller_parameter_to_file_e].values.array[0]], f_file_open_mode_append_s, &main->output.to);
+
+ if (F_status_is_error(setting->status)) {
+ fll_error_file_print(main->error, F_status_set_fine(setting->status), "f_file_stream_open", F_true, args[main->parameters.array[controller_parameter_to_file_e].values.array[0]], f_file_operation_open_s, fll_error_file_type_file_e);
+
+ return;
+ }
+
+ setting->flag |= controller_main_flag_file_to_e;
+ }
+ else {
+ controller_print_error_parameter_file_name_empty(main, setting, main->parameters.array[controller_parameter_to_file_e].values.array[0]);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+ else if (main->parameters.array[controller_parameter_to_file_e].result == f_console_result_found_e) {
+ controller_print_error_no_value(main, setting, controller_long_to_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ main->output.to = main->message.to;
+
+ if (setting->flag & controller_main_flag_file_to_e) {
+ setting->flag -= controller_main_flag_file_to_e;
+ }
+ }
+
+ if (main->parameters.array[controller_parameter_from_file_e].result == f_console_result_additional_e) {
+ setting->path_files_from.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(main->parameters.array[controller_parameter_from_file_e].values.used, &setting->path_files_from);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_from.used = main->parameters.array[controller_parameter_from_file_e].values.used;
+
+ f_array_length_t i = 0;
+ f_array_length_t index = 0;
+
+ for (; i < setting->path_files_from.used; ++i) {
+
+ index = main->parameters.array[controller_parameter_from_file_e].values.array[i];
+ setting->path_files_from.array[i].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[index], &setting->path_files_from.array[i]);
+ if (F_status_is_error(setting->status)) return;
+
+ if (args[index].used) {
+ if (f_file_exists(args[index], F_true) != F_true) {
+ controller_print_error_parameter_file_not_found(main, setting, F_true, args[index]);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_file_found_not);
+ }
+ }
+ }
+ else {
+ controller_print_error_parameter_file_name_empty(main, setting, index);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_parameter);
+ }
+ }
+ } // for
+
+ if (F_status_is_error(setting->status)) return;
+
+ setting->flag |= controller_main_flag_file_from_e;
+ }
+ else if (main->parameters.array[controller_parameter_from_file_e].result == f_console_result_found_e) {
+ controller_print_error_no_value(main, setting, controller_long_from_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ if (setting->flag & controller_main_flag_file_from_e) {
+ setting->flag -= controller_main_flag_file_from_e;
+ }
+ }
+
+ if (F_status_is_error(setting->status)) return;
+
+ if (main->parameters.array[controller_parameter_from_file_e].result == f_console_result_none_e && !((main->pipe & fll_program_data_pipe_input_e) || main->parameters.remaining.used)) {
+ controller_print_error_no_from(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+ }
+
+ if (!(setting->mode & controller_mode_to_bytesequence_e)) {
+ if (main->parameters.array[controller_parameter_separate_e].result == f_console_result_found_e || main->parameters.array[controller_parameter_headers_e].result == f_console_result_found_e) {
+ setting->prepend = controller_string_prepend_padding_s;
+ setting->append = f_string_eol_s;
+ }
+ else {
+ setting->prepend = f_string_space_s;
+ }
+ }
+
+ if (main->parameters.array[controller_parameter_headers_e].result == f_console_result_found_e) {
+ setting->flag |= controller_main_flag_header_e;
+ }
+
+ if (main->parameters.array[controller_parameter_separate_e].result == f_console_result_found_e) {
+ setting->flag |= controller_main_flag_separate_e;
+ }
+
+ if (main->parameters.array[controller_parameter_strip_invalid_e].result == f_console_result_found_e) {
+ setting->flag |= controller_main_flag_strip_invalid_e;
+ }
+
+ setting->valid_not = main->message.set->error;
+ }
+#endif // _di_controller_setting_load_
+
+#ifndef _di_controller_setting_unload_
+ f_status_t controller_setting_unload(fll_program_data_t * const main, controller_setting_t * const setting) {
+
+ if (!main || !setting) return F_status_set_error(F_parameter);
+
+ controller_setting_delete(setting);
+
+ return F_none;
+ }
+#endif // _di_controller_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
#endif // _di_controller_resource_limit_t_
/**
+ * Flags used to represent flags passed to the main function.
+ *
+ * controller_main_flag_*_e:
+ * - none: No modes in use.
+ * - file_from: Using a specified source file.
+ * - file_to: Using a specified destination file.
+ * - help: Print help.
+ * - header: Enable printing of headers.
+ * - separate: Enable printing of separators.
+ * - strip_invalid: Using strip invalid character mode.
+ * - verify: Using verify mode.
+ * - version: Print version.
+ */
+#ifndef _di_controller_main_flag_e_
+ enum {
+ controller_main_flag_none_e = 0x0,
+ controller_main_flag_file_from_e = 0x1,
+ controller_main_flag_file_to_e = 0x2,
+ controller_main_flag_header_e = 0x4,
+ controller_main_flag_help_e = 0x8,
+ controller_main_flag_separate_e = 0x10,
+ controller_main_flag_strip_invalid_e = 0x20,
+ controller_main_flag_verify_e = 0x40,
+ controller_main_flag_version_e = 0x80,
+ };
+#endif // _di_controller_main_flag_e_
+
+/**
+ * The controller main program settings.
+ *
+ * This is passed to the program-specific main entry point to designate program settings.
+ * These program settings are often processed from the program arguments (often called the command line arguments).
+ *
+ * flag: Flags passed to the main function.
+ *
+ * status: The main status code, generally used by the load settings and main functions.
+ *
+ * line_first: A string expected to represent either "\n" or NULL to allow for easy handling of when to print first new line or not.
+ * line_last: A string expected to represent either "\n" or NULL to allow for easy handling of when to print last new line or not.
+ */
+#ifndef _di_controller_setting_t_
+ typedef struct {
+ uint16_t flag;
+
+ f_status_t status;
+
+ f_string_static_t line_first;
+ f_string_static_t line_last;
+ } controller_setting_t;
+
+ #define controller_setting_t_initialize \
+ { \
+ controller_main_flag_none_e, \
+ F_none, \
+ f_string_static_t_initialize, \
+ f_string_static_t_initialize, \
+ }
+#endif // _di_controller_setting_t_
+
+/**
* Identify the payload code the given name represents.
*
* @param payload
extern f_string_static_t controller_rule_setting_limit_type_name(const uint8_t type);
#endif // di_controller_rule_setting_limit_type_name_
+/**
+ * Delete the program main setting data.
+ *
+ * @param setting
+ * The program main setting data.
+ * This does not alter setting.status.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_controller_setting_delete_
+ extern f_status_t controller_setting_delete(controller_setting_t * const setting);
+#endif // _di_controller_setting_delete_
+
+/**
+ * Perform the standard program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately retuns without doing anything.
+ *
+ * @param arguments
+ * The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ *
+ * This alters setting.status:
+ * F_none on success.
+ *
+ * Errors (with error bit) from: f_console_parameter_process().
+ * Errors (with error bit) from: fll_program_parameter_process_context().
+ *
+ * @see f_console_parameter_process()
+ * @see fll_program_parameter_process_context()
+ */
+#ifndef _di_controller_setting_load_
+ extern void controller_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, controller_setting_t * const setting);
+#endif // _di_controller_setting_load_
+
+/**
+ * Perform the standard program setting unload process.
+ *
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * All buffers are deallocated.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: utf8_setting_delete().
+ *
+ * @see utf8_setting_delete()
+ */
+#ifndef _di_controller_setting_unload_
+ extern f_status_t controller_setting_unload(fll_program_data_t * const main, controller_setting_t * const setting);
+#endif // _di_controller_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern "C" {
#endif
-#ifndef _di_controller_print_help_
- f_status_t controller_print_help(controller_main_t * const main) {
-
- controller_lock_print(main->output.to, 0);
-
- //if (!(setting->flag & XXX_main_flag_line_first_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- fll_program_print_help_header(main->output.to, main->context, *main->program_name_long, controller_program_version_s);
-
- fll_program_print_help_option_standard(main->output.to, context);
-
- f_print_dynamic_raw(f_string_eol_s, main->output.to.stream);
-
- fll_program_print_help_option(main->output.to, main->context, controller_short_cgroup_s, controller_long_cgroup_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a custom control group file path, such as '" F_control_group_path_system_prefix_s F_control_group_path_system_default_s "'.");
- fll_program_print_help_option(main->output.to, main->context, controller_short_daemon_s, controller_long_daemon_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Run in daemon only mode (do not process the entry).");
- fll_program_print_help_option(main->output.to, main->context, controller_short_init_s, controller_long_init_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The program will run as an init replacement.");
- fll_program_print_help_option(main->output.to, main->context, controller_short_interruptible_s, controller_long_interruptible_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Designate that this program can be interrupted by a signal.");
- fll_program_print_help_option(main->output.to, main->context, controller_short_pid_s, controller_long_pid_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a custom pid file path, such as 'controller/run/default.pid'.");
- fll_program_print_help_option(main->output.to, main->context, controller_short_settings_s, controller_long_settings_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a custom settings path, such as 'controller/'.");
- fll_program_print_help_option(main->output.to, main->context, controller_short_simulate_s, controller_long_simulate_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Run as a simulation.");
- fll_program_print_help_option(main->output.to, main->context, controller_short_socket_s, controller_long_socket_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a custom socket file path, such as 'controller/run/default.socket'.");
- fll_program_print_help_option(main->output.to, main->context, controller_short_uninterruptible_s, controller_long_uninterruptible_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Designate that this program cannot be interrupted by a signal.");
- fll_program_print_help_option(main->output.to, main->context, controller_short_validate_s, controller_long_validate_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Validate the settings (entry and rules) without running (does not simulate).");
-
- fll_program_print_help_usage(main->output.to, main->context, *main->program_name, controller_entry_s);
-
- fl_print_format("%r When both the %[%r%r%] parameter and the", main->output.to.stream, f_string_eol_s, main->context.set.notable, f_console_symbol_long_enable_s, controller_long_simulate_s, main->context.set.notable);
- fl_print_format(" %[%r%r%] parameter are specified, then additional information on each would be executed rule is printed but no simulation is performed.%r%r", main->output.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, controller_long_validate_s, main->context.set.notable, f_string_eol_s, f_string_eol_s);
-
- const f_string_static_t interruptable = main->as_init ? controller_long_uninterruptible_s : controller_long_interruptible_s;
-
- fl_print_format(" The default interrupt behavior is to operate as if the %[%r%r%] parameter is passed.%r%r", main->output.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, interruptable, main->context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" Specify an empty string for the %[%r%r%] parameter to disable pid file creation for this program.%r", main->output.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, controller_long_pid_s, main->context.set.notable, f_string_eol_s);
-
- //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, main->output.to.stream);
- //}
-
- controller_unlock_print_flush(main->output.to, 0);
-
- return F_none;
- }
-#endif // _di_controller_print_help_
-
#ifndef _di_controller_main_
f_status_t controller_main(controller_main_t * const main, const f_console_arguments_t arguments) {
if (main->parameters.array[controller_parameter_version_e].result == f_console_result_found_e) {
controller_lock_print(main->output.to, 0);
- fll_program_print_version(main->output.to, controller_program_version_s);
+ fll_program_print_version(main->message, controller_program_version_s);
controller_unlock_print_flush(main->output.to, 0);
#endif
/**
- * Print help.
- *
- * @param main
- * The main program data.
- *
- * @return
- * F_none on success.
- *
- * @see controller_main()
- */
-#ifndef _di_controller_print_help_
- extern f_status_t controller_print_help(controller_main_t * const main);
-#endif // _di_controller_print_help_
-
-/**
* Execute main program.
*
* Be sure to call controller_main_delete() after executing this.
}
#endif // _di_controller_print_error_file_
-#ifndef _di_controller_print_signal_received_
- void controller_print_signal_received(controller_main_t * const main, const f_status_t signal) {
-
- if (main->warning.verbosity != f_console_verbosity_verbose_e && main->warning.verbosity != f_console_verbosity_debug_e) return;
-
- // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
- fflush(main->warning.to.stream);
-
- flockfile(main->warning.to.stream);
-
- fl_print_format("%]%r%r%[Received signal code %]", main->warning.to.stream, main->context.set.reset, f_string_eol_s, f_string_eol_s, main->context.set.warning, main->context.set.warning);
- fl_print_format("%[%i%]", main->warning.to.stream, main->context.set.notable, signal, main->context.set.notable);
- fl_print_format("%[.%]%r", main->warning.to.stream, main->context.set.warning, main->context.set.warning, f_string_eol_s);
-
- funlockfile(main->warning.to.stream);
- }
-#endif // _di_controller_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
extern void controller_print_error_file(controller_thread_t * const thread, const fl_print_t print, const f_status_t status, const char *function, const bool fallback, const f_string_static_t name, const f_string_static_t operation, const uint8_t type) F_attribute_visibility_internal_d;
#endif // _di_controller_print_error_file_
-/**
- * Print a message about a process signal being recieved, such as an interrupt signal.
- *
- * @param main
- * The main program data.
- * @param signal
- * The signal received.
- */
-#ifndef _di_controller_print_signal_received_
- extern void controller_print_signal_received(controller_main_t * const main, const f_status_t signal) F_attribute_visibility_internal_d;
-#endif // _di_controller_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
f_thread_mutex_lock(&thread->lock.print);
}
- flockfile(to.stream);
+ f_file_stream_lock(to);
}
#endif // _di_controller_lock_print_
#ifndef _di_controller_unlock_print_flush_
void controller_unlock_print_flush(const f_file_t to, controller_thread_t * const thread) {
- f_file_stream_flush(to.stream);
- funlockfile(to.stream);
+ f_file_stream_flush(to);
+ f_file_stream_unlock(to);
if (thread) {
f_thread_mutex_unlock(&thread->lock.print);
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
- controller_main_t data = controller_main_t_initialize;
+ fll_program_data_t data = fll_program_data_t_initialize;
+ controller_setting_t setting = controller_setting_t_initialize;
f_console_parameter_t parameters[] = controller_console_parameter_t_initialize;
data.parameters.array = parameters;
data.parameters.used = controller_total_parameters_d;
+ data.environment = envp;
if (f_pipe_input_exists()) {
data.pipe = fll_program_data_pipe_input_e;
data.as_init = F_false;
#endif // _controller_as_init_
- const f_status_t status = controller_main(&data, arguments);
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+
+ controller_setting_load(arguments, &data, &setting);
+ }
+
+ controller_main(&data, &setting);
+
+ controller_setting_unload(&data, &setting);
controller_main_delete(&data);
exit(data.child);
}
- if (F_status_is_error(status)) return 1;
-
- return 0;
+ return F_status_is_error(status) ? 1 : 0;
}
--- /dev/null
+#include "controller.h"
+#include "private-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_controller_print_help_
+ f_status_t controller_print_help(controller_setting_t * const setting, const fl_print_t print) {
+
+ controller_lock_print(print.to, 0);
+
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+
+ fll_program_print_help_header(print, *main->program_name_long, controller_program_version_s);
+
+ fll_program_print_help_option_standard(print.to, context);
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, controller_short_cgroup_s, controller_long_cgroup_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a custom control group file path, such as '" F_control_group_path_system_prefix_s F_control_group_path_system_default_s "'.");
+ fll_program_print_help_option(print, controller_short_daemon_s, controller_long_daemon_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Run in daemon only mode (do not process the entry).");
+ fll_program_print_help_option(print, controller_short_init_s, controller_long_init_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The program will run as an init replacement.");
+ fll_program_print_help_option(print, controller_short_interruptible_s, controller_long_interruptible_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Designate that this program can be interrupted by a signal.");
+ fll_program_print_help_option(print, controller_short_pid_s, controller_long_pid_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a custom pid file path, such as 'controller/run/default.pid'.");
+ fll_program_print_help_option(print, controller_short_settings_s, controller_long_settings_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a custom settings path, such as 'controller/'.");
+ fll_program_print_help_option(print, controller_short_simulate_s, controller_long_simulate_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Run as a simulation.");
+ fll_program_print_help_option(print, controller_short_socket_s, controller_long_socket_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a custom socket file path, such as 'controller/run/default.socket'.");
+ fll_program_print_help_option(print, controller_short_uninterruptible_s, controller_long_uninterruptible_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Designate that this program cannot be interrupted by a signal.");
+ fll_program_print_help_option(print, controller_short_validate_s, controller_long_validate_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Validate the settings (entry and rules) without running (does not simulate).");
+
+ fll_program_print_help_usage(print, *main->program_name, controller_entry_s);
+
+ fl_print_format("%r When both the %[%r%r%] parameter and the", print.to.stream, f_string_eol_s, print.set->notable, f_console_symbol_long_enable_s, controller_long_simulate_s, print.set->notable);
+ fl_print_format(" %[%r%r%] parameter are specified, then additional information on each would be executed rule is printed but no simulation is performed.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, controller_long_validate_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ const f_string_static_t interruptable = main->as_init ? controller_long_uninterruptible_s : controller_long_interruptible_s;
+
+ fl_print_format(" The default interrupt behavior is to operate as if the %[%r%r%] parameter is passed.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, interruptable, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" Specify an empty string for the %[%r%r%] parameter to disable pid file creation for this program.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, controller_long_pid_s, print.set->notable, f_string_eol_s);
+
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+
+ controller_unlock_print_flush(print.to, 0);
+
+ return F_none;
+ }
+#endif // _di_controller_print_help_
+
+#ifndef _di_controller_print_line_first_
+ void controller_print_line_first(controller_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ }
+#endif // _di_controller_print_line_first_
+
+#ifndef _di_controller_print_line_last_
+ void controller_print_line_last(controller_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+ if (print.verbosity == f_console_verbosity_error_e && !F_status_is_error(setting->status)) return;
+ if (setting->flag & controller_main_flag_verify_e) return;
+ if ((setting->flag & controller_main_flag_file_to_e) && !F_status_is_error(setting->status)) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ }
+#endif // _di_controller_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: UTF-8
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _controller_print_h
+#define _controller_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print help.
+ *
+ * @param main
+ * The main program data.
+ *
+ * @return
+ * F_none on success.
+ *
+ * @see controller_main()
+ */
+#ifndef _di_controller_print_help_
+ extern f_status_t controller_print_help(controller_main_t * const main);
+#endif // _di_controller_print_help_
+
+/**
+ * Print first new line, unless verbosity says otherwise.
+ *
+ * This is generally either the first line in the program or the first line printed before an error message.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_controller_print_line_first_
+ extern void controller_print_line_first(controller_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_controller_print_line_first_
+
+/**
+ * Print last new line when the main is complete, unless verbosity says otherwise.
+ *
+ * This is generally the very last line printed in the program.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_controller_print_line_last_
+ extern void controller_print_line_last(controller_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_controller_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _controller_print_h
}
if (F_status_set_fine(status) == F_interrupt) {
- controller_print_signal_received(main, thread.signal);
+ fll_program_print_signal_received(main->warning, setting->line_first, thread.signal);
if (main->output.verbosity != f_console_verbosity_quiet_e) {
fll_print_dynamic_raw(f_string_eol_s, main->output.to.stream);
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library controller.c common.c
+build_sources_library controller.c common.c print.c
build_sources_library common/private-common.c common/private-cache.c common/private-control.c common/private-entry.c common/private-lock.c common/private-process.c common/private-rule.c common/private-setting.c common/private-thread.c
build_sources_library control/private-control.c control/private-control_print.c
build_sources_library controller/private-controller.c controller/private-controller_print.c
build_sources_program main.c main-common.c
-build_sources_headers controller.h common.h
+build_sources_headers controller.h common.h print.h
build_sources_setting entries example rules
const f_string_static_t fake_other_operation_skeleton_s = macro_f_string_static_t_initialize(FAKE_other_operation_skeleton_s, 0, FAKE_other_operation_skeleton_s_length);
#endif // _di_fake_parameters_
+#ifndef _di_fake_setting_delete_
+ f_status_t fake_setting_delete(fake_setting_t * const setting) {
+
+ if (!setting) return F_status_set_error(F_parameter);
+
+ return F_none;
+ }
+#endif // _di_fake_setting_delete_
+
+#ifndef _di_fake_setting_load_
+ void fake_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fake_setting_t * const setting) {
+
+ if (!main || !setting) return;
+
+ // Load parameters.
+ setting->status = f_console_parameter_process(arguments, &main->parameters);
+ if (F_status_is_error(setting->status)) return;
+
+ {
+ f_array_length_t choice = 0;
+ f_uint16s_t choices = f_uint16s_t_initialize;
+
+ // Identify and prioritize "color context" parameters.
+ {
+ uint16_t choices_array[3] = { fake_parameter_no_color_e, fake_parameter_light_e, fake_parameter_dark_e };
+ choices.array = choices_array;
+ choices.used = 3;
+
+ const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
+
+ setting->status = fll_program_parameter_process_context(choices, modes, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fake_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_context", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fake_parameter_line_first_no_e].result == f_console_result_found_e) {
+ setting->line_first = f_string_empty_s;
+ }
+ else {
+ setting->line_first = f_string_eol_s;
+ }
+
+ if (main->parameters.array[fake_parameter_line_last_no_e].result == f_console_result_found_e) {
+ setting->line_last = f_string_empty_s;
+ }
+ else {
+ setting->line_last = f_string_eol_s;
+ }
+
+ // Identify and prioritize "verbosity" parameters.
+ {
+ uint16_t choices_array[5] = { fake_parameter_verbosity_quiet_e, fake_parameter_verbosity_error_e, fake_parameter_verbosity_verbose_e, fake_parameter_verbosity_debug_e, fake_parameter_verbosity_normal_e };
+ choices.array = choices_array;
+ choices.used = 5;
+
+ const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+
+ setting->status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fake_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_verbosity", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fake_parameter_help_e].result == f_console_result_found_e) {
+ setting->flag |= fake_main_flag_help_e;
+
+ return;
+ }
+
+ if (main->parameters.array[fake_parameter_version_e].result == f_console_result_found_e) {
+ setting->flag |= fake_main_flag_version_e;
+
+ return;
+ }
+
+ // Identify and prioritize "from" mode parameters.
+ {
+ uint16_t choices_array[2] = { fake_parameter_from_bytesequence_e, fake_parameter_from_codepoint_e };
+ choices.array = choices_array;
+ choices.used = 2;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fake_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fake_parameter_from_bytesequence_e) {
+ if (setting->mode & fake_mode_from_codepoint_e) {
+ setting->mode -= fake_mode_from_codepoint_e;
+ }
+
+ setting->mode |= fake_mode_from_bytesequence_e;
+ }
+ else if (choices.array[choice] == fake_parameter_from_codepoint_e) {
+ if (setting->mode & fake_mode_from_bytesequence_e) {
+ setting->mode -= fake_mode_from_bytesequence_e;
+ }
+
+ setting->mode |= fake_mode_from_codepoint_e;
+ }
+ }
+
+ // Identify and prioritize "to" mode parameters.
+ {
+ uint16_t choices_array[4] = { fake_parameter_to_bytesequence_e, fake_parameter_to_codepoint_e, fake_parameter_to_combining_e, fake_parameter_to_width_e };
+ choices.array = choices_array;
+ choices.used = 4;
+ choice = 1;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fake_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fake_parameter_to_bytesequence_e) {
+ if (setting->mode & fake_mode_to_codepoint_e) {
+ setting->mode -= fake_mode_to_codepoint_e;
+ }
+
+ if (setting->mode & fake_mode_to_combining_e) {
+ setting->mode -= fake_mode_to_combining_e;
+ }
+
+ if (setting->mode & fake_mode_to_width_e) {
+ setting->mode -= fake_mode_to_width_e;
+ }
+
+ setting->mode |= fake_mode_to_bytesequence_e;
+ }
+ else if (choices.array[choice] == fake_parameter_to_codepoint_e) {
+ if (setting->mode & fake_mode_to_bytesequence_e) {
+ setting->mode -= fake_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fake_mode_to_combining_e) {
+ setting->mode -= fake_mode_to_combining_e;
+ }
+
+ if (setting->mode & fake_mode_to_width_e) {
+ setting->mode -= fake_mode_to_width_e;
+ }
+
+ setting->mode |= fake_mode_to_codepoint_e;
+ }
+ else if (choices.array[choice] == fake_parameter_to_combining_e) {
+ if (setting->mode & fake_mode_to_bytesequence_e) {
+ setting->mode -= fake_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fake_mode_to_codepoint_e) {
+ setting->mode -= fake_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fake_parameter_to_width_e].result == f_console_result_found_e) {
+ setting->mode |= fake_mode_to_width_e;
+ }
+
+ setting->mode |= fake_mode_to_combining_e;
+ }
+ else if (choices.array[choice] == fake_parameter_to_width_e) {
+ if (setting->mode & fake_mode_to_bytesequence_e) {
+ setting->mode -= fake_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fake_mode_to_codepoint_e) {
+ setting->mode -= fake_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fake_parameter_to_combining_e].result == f_console_result_found_e) {
+ setting->mode |= fake_mode_to_combining_e;
+ }
+
+ setting->mode |= fake_mode_to_width_e;
+ }
+ }
+ }
+
+ f_string_static_t * const args = main->parameters.arguments.array;
+
+ if (main->parameters.array[fake_parameter_to_file_e].result == f_console_result_additional_e) {
+ if (main->parameters.array[fake_parameter_to_file_e].values.used > 1) {
+ fake_print_error_parameter_file_to_too_many(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+
+ if (args[main->parameters.array[fake_parameter_to_file_e].values.array[0]].used) {
+ setting->path_files_to.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(1, &setting->path_files_to);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_to.array[setting->path_files_to.used].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[main->parameters.array[fake_parameter_to_file_e].values.array[0]], &setting->path_files_to.array[0]);
+ if (F_status_is_error(setting->status)) return;
+
+ ++setting->path_files_to.used;
+
+ setting->status = f_file_stream_open(args[main->parameters.array[fake_parameter_to_file_e].values.array[0]], f_file_open_mode_append_s, &main->output.to);
+
+ if (F_status_is_error(setting->status)) {
+ fll_error_file_print(main->error, F_status_set_fine(setting->status), "f_file_stream_open", F_true, args[main->parameters.array[fake_parameter_to_file_e].values.array[0]], f_file_operation_open_s, fll_error_file_type_file_e);
+
+ return;
+ }
+
+ setting->flag |= fake_main_flag_file_to_e;
+ }
+ else {
+ fake_print_error_parameter_file_name_empty(main, setting, main->parameters.array[fake_parameter_to_file_e].values.array[0]);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+ else if (main->parameters.array[fake_parameter_to_file_e].result == f_console_result_found_e) {
+ fake_print_error_no_value(main, setting, fake_long_to_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ main->output.to = main->message.to;
+
+ if (setting->flag & fake_main_flag_file_to_e) {
+ setting->flag -= fake_main_flag_file_to_e;
+ }
+ }
+
+ if (main->parameters.array[fake_parameter_from_file_e].result == f_console_result_additional_e) {
+ setting->path_files_from.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(main->parameters.array[fake_parameter_from_file_e].values.used, &setting->path_files_from);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_from.used = main->parameters.array[fake_parameter_from_file_e].values.used;
+
+ f_array_length_t i = 0;
+ f_array_length_t index = 0;
+
+ for (; i < setting->path_files_from.used; ++i) {
+
+ index = main->parameters.array[fake_parameter_from_file_e].values.array[i];
+ setting->path_files_from.array[i].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[index], &setting->path_files_from.array[i]);
+ if (F_status_is_error(setting->status)) return;
+
+ if (args[index].used) {
+ if (f_file_exists(args[index], F_true) != F_true) {
+ fake_print_error_parameter_file_not_found(main, setting, F_true, args[index]);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_file_found_not);
+ }
+ }
+ }
+ else {
+ fake_print_error_parameter_file_name_empty(main, setting, index);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_parameter);
+ }
+ }
+ } // for
+
+ if (F_status_is_error(setting->status)) return;
+
+ setting->flag |= fake_main_flag_file_from_e;
+ }
+ else if (main->parameters.array[fake_parameter_from_file_e].result == f_console_result_found_e) {
+ fake_print_error_no_value(main, setting, fake_long_from_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ if (setting->flag & fake_main_flag_file_from_e) {
+ setting->flag -= fake_main_flag_file_from_e;
+ }
+ }
+
+ if (F_status_is_error(setting->status)) return;
+
+ if (main->parameters.array[fake_parameter_from_file_e].result == f_console_result_none_e && !((main->pipe & fll_program_data_pipe_input_e) || main->parameters.remaining.used)) {
+ fake_print_error_no_from(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+ }
+
+ if (!(setting->mode & fake_mode_to_bytesequence_e)) {
+ if (main->parameters.array[fake_parameter_separate_e].result == f_console_result_found_e || main->parameters.array[fake_parameter_headers_e].result == f_console_result_found_e) {
+ setting->prepend = fake_string_prepend_padding_s;
+ setting->append = f_string_eol_s;
+ }
+ else {
+ setting->prepend = f_string_space_s;
+ }
+ }
+
+ if (main->parameters.array[fake_parameter_headers_e].result == f_console_result_found_e) {
+ setting->flag |= fake_main_flag_header_e;
+ }
+
+ if (main->parameters.array[fake_parameter_separate_e].result == f_console_result_found_e) {
+ setting->flag |= fake_main_flag_separate_e;
+ }
+
+ if (main->parameters.array[fake_parameter_strip_invalid_e].result == f_console_result_found_e) {
+ setting->flag |= fake_main_flag_strip_invalid_e;
+ }
+
+ setting->valid_not = main->message.set->error;
+ }
+#endif // _di_fake_setting_load_
+
+#ifndef _di_fake_setting_unload_
+ f_status_t fake_setting_unload(fll_program_data_t * const main, fake_setting_t * const setting) {
+
+ if (!main || !setting) return F_status_set_error(F_parameter);
+
+ fake_setting_delete(setting);
+
+ return F_none;
+ }
+#endif // _di_fake_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
#define fake_total_parameters_d 31
#endif // _di_fake_parameters_
+/**
+ * Flags used to represent flags passed to the main function.
+ *
+ * fake_main_flag_*_e:
+ * - none: No modes in use.
+ * - file_from: Using a specified source file.
+ * - file_to: Using a specified destination file.
+ * - help: Print help.
+ * - header: Enable printing of headers.
+ * - separate: Enable printing of separators.
+ * - strip_invalid: Using strip invalid character mode.
+ * - verify: Using verify mode.
+ * - version: Print version.
+ */
+#ifndef _di_fake_main_flag_e_
+ enum {
+ fake_main_flag_none_e = 0x0,
+ fake_main_flag_file_from_e = 0x1,
+ fake_main_flag_file_to_e = 0x2,
+ fake_main_flag_header_e = 0x4,
+ fake_main_flag_help_e = 0x8,
+ fake_main_flag_separate_e = 0x10,
+ fake_main_flag_strip_invalid_e = 0x20,
+ fake_main_flag_verify_e = 0x40,
+ fake_main_flag_version_e = 0x80,
+ };
+#endif // _di_fake_main_flag_e_
+
+/**
+ * The fake main program settings.
+ *
+ * This is passed to the program-specific main entry point to designate program settings.
+ * These program settings are often processed from the program arguments (often called the command line arguments).
+ *
+ * flag: Flags passed to the main function.
+ *
+ * status: The main status code, generally used by the load settings and main functions.
+ *
+ * line_first: A string expected to represent either "\n" or NULL to allow for easy handling of when to print first new line or not.
+ * line_last: A string expected to represent either "\n" or NULL to allow for easy handling of when to print last new line or not.
+ */
+#ifndef _di_fake_setting_t_
+ typedef struct {
+ uint16_t flag;
+
+ f_status_t status;
+
+ f_string_static_t line_first;
+ f_string_static_t line_last;
+ } fake_setting_t;
+
+ #define fake_setting_t_initialize \
+ { \
+ fake_main_flag_none_e, \
+ F_none, \
+ f_string_static_t_initialize, \
+ f_string_static_t_initialize, \
+ }
+#endif // _di_fake_setting_t_
+
+/**
+ * Delete the program main setting data.
+ *
+ * @param setting
+ * The program main setting data.
+ * This does not alter setting.status.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fake_setting_delete_
+ extern f_status_t fake_setting_delete(fake_setting_t * const setting);
+#endif // _di_fake_setting_delete_
+
+/**
+ * Perform the standard program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately retuns without doing anything.
+ *
+ * @param arguments
+ * The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ *
+ * This alters setting.status:
+ * F_none on success.
+ *
+ * Errors (with error bit) from: f_console_parameter_process().
+ * Errors (with error bit) from: fll_program_parameter_process_context().
+ *
+ * @see f_console_parameter_process()
+ * @see fll_program_parameter_process_context()
+ */
+#ifndef _di_fake_setting_load_
+ extern void fake_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fake_setting_t * const setting);
+#endif // _di_fake_setting_load_
+
+/**
+ * Perform the standard program setting unload process.
+ *
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * All buffers are deallocated.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: utf8_setting_delete().
+ *
+ * @see utf8_setting_delete()
+ */
+#ifndef _di_fake_setting_unload_
+ extern f_status_t fake_setting_unload(fll_program_data_t * const main, fake_setting_t * const setting);
+#endif // _di_fake_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern "C" {
#endif
-#ifndef _di_fake_print_help_
- f_status_t fake_print_help(const f_file_t file, const f_color_context_t context) {
-
- flockfile(file.stream);
-
- //if (!(setting->flag & XXX_main_flag_line_first_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- fll_program_print_help_header(file, context, fake_program_name_long_s, fake_program_version_s);
-
- fll_program_print_help_option_standard(file, context);
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, fake_short_define_s, fake_long_define_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Append an additional define after defines from settings file.");
- fll_program_print_help_option(file, context, fake_short_fakefile_s, fake_long_fakefile_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Use this fakefile.");
- fll_program_print_help_option(file, context, fake_short_mode_s, fake_long_mode_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use this mode when processing the build settings.");
- fll_program_print_help_option(file, context, fake_short_process_s, fake_long_process_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Process name for storing build states.");
- fll_program_print_help_option(file, context, fake_short_settings_s, fake_long_settings_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Use this settings file.");
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, fake_short_path_build_s, fake_long_path_build_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a custom build directory.");
- fll_program_print_help_option(file, context, fake_short_path_data_s, fake_long_path_data_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a custom path to the data files.");
- fll_program_print_help_option(file, context, fake_short_path_sources_s, fake_long_path_sources_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Specify a custom path to the source files.");
- fll_program_print_help_option(file, context, fake_short_path_work_s, fake_long_path_work_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use includes/libraries/programs from this directory instead of system.");
-
- fl_print_format("%r%r %[Special Options:%] ", file.stream, f_string_eol_s, f_string_eol_s, context.set.important, context.set.important);
-
- fll_program_print_help_option_long(file, context, fake_long_documents_disabled_s, f_console_symbol_long_enable_s, " Forcibly do not build documents files.");
- fll_program_print_help_option_long(file, context, fake_long_documents_enabled_s, f_console_symbol_long_enable_s, " Forcibly do build documents files.");
- fll_program_print_help_option_long(file, context, fake_long_shared_disabled_s, f_console_symbol_long_enable_s, "Forcibly do not build shared files.");
- fll_program_print_help_option_long(file, context, fake_long_shared_enabled_s, f_console_symbol_long_enable_s, " Forcibly do build shared files.");
- fll_program_print_help_option_long(file, context, fake_long_static_disabled_s, f_console_symbol_long_enable_s, "Forcibly do not build static files.");
- fll_program_print_help_option_long(file, context, fake_long_static_enabled_s, f_console_symbol_long_enable_s, " Forcibly do build static files.");
-
- fl_print_format("%r%r %[Operations:%] ", file.stream, f_string_eol_s, f_string_eol_s, context.set.important, context.set.important);
-
- fll_program_print_help_option_other(file, context, fake_other_operation_build_s, " Build or compile the code based on build settings file.");
- fll_program_print_help_option_other(file, context, fake_other_operation_clean_s, " Delete all build files.");
- fll_program_print_help_option_other(file, context, fake_other_operation_make_s, " Build or compile the code based on fakefile (default).");
- fll_program_print_help_option_other(file, context, fake_other_operation_skeleton_s, "Build a skeleton directory structure.");
-
- fll_program_print_help_usage(file, context, fake_program_name_s, fake_program_help_parameters_s);
-
- fl_print_format("%r When performing the %[%r%] operation, the", file.stream, f_string_eol_s, context.set.notable, fake_other_operation_build_s, context.set.notable);
- fl_print_format(" %[%r%r%] parameter specifies a name (limited to alpha-numeric, underscore, and dash) to be used in addition to the global.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fake_long_mode_s, context.set.notable, f_string_eol_s);
-
- fl_print_format(" For example, when a %[%r%]", file.stream, context.set.notable, fake_make_parameter_variable_mode_s, context.set.notable);
- fl_print_format(" of 'fll_monolithic' is specified, build libraries from both 'build_libraries' and 'build_libraries-fll_monolithic' are used (but not 'build_libraries-fll_level').%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When specifying the %[%r%] or the %[%r%]", file.stream, context.set.notable, fake_make_parameter_variable_fakefile_s, context.set.notable, context.set.notable, fake_make_parameter_variable_settings_s, context.set.notable);
- fl_print_format(" parameters, the project root is seached first and then the build data director is searched when the given file does not contain a directory separator.%r", file.stream, f_string_eol_s);
-
- fl_print_format(" For example, with '%[%r%r my_fakefile%]' the fakefile at", file.stream, context.set.notable, f_console_symbol_long_enable_s, fake_long_fakefile_s, context.set.notable);
- fl_print_format(" '%[./my_fakefile%]' is used if found, but if it is not found then", file.stream, context.set.notable, context.set.notable);
- fl_print_format(" '%[./%r%rmy_fakefile%]' is used if found.%r", file.stream, context.set.notable, fake_default_path_data_s, fake_default_path_build_s, context.set.notable, f_string_eol_s);
- fl_print_format(" For example, with '%[%r%r ./my_fakefile%]' the fakefile at", file.stream, context.set.notable, f_console_symbol_long_enable_s, fake_long_fakefile_s, context.set.notable);
- fl_print_format(" '%[./my_fakefile%]' is used if found, but if it is not found then no other paths are attempted.%r%r", file.stream, context.set.notable, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When piping data to this program, the piped data is treated as if it were prepended to the %[%r%]", file.stream, context.set.notable, fake_make_parameter_variable_fakefile_s, context.set.notable);
- fl_print_format("or the %[%r%], depending on the operation.%r", file.stream, context.set.notable, fake_make_parameter_variable_settings_s, context.set.notable, f_string_eol_s);
-
- //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- f_file_stream_flush(file);
- funlockfile(file.stream);
-
- return F_none;
- }
-#endif // _di_fake_print_help_
-
#ifndef _di_fake_main_
- f_status_t fake_main(fll_program_data_t * const main, const f_console_arguments_t arguments) {
+ f_status_t fake_main(fll_program_data_t * const main, fake_setting_t * const setting) {
f_status_t status = F_none;
}
if (main->parameters.array[fake_parameter_help_e].result == f_console_result_found_e) {
- fake_print_help(main->output.to, main->context);
+ fake_print_help(setting, main->message);
return F_none;
}
if (main->parameters.array[fake_parameter_version_e].result == f_console_result_found_e) {
- fll_program_print_version(main->output.to, fake_program_version_s);
+ fll_program_print_version(main->message, fake_program_version_s);
return F_none;
}
if (F_status_set_fine(status) == F_interrupt || !(i % fake_signal_check_short_d)) {
if (fll_program_standard_signal_received(main)) {
- fake_print_signal_received(&data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
#endif
/**
- * Print help.
- *
- * @param file
- * The file to print to.
- * @param context
- * The color context settings.
- *
- * @return
- * F_none on success.
- */
-#ifndef _di_fake_print_help_
- extern f_status_t fake_print_help(const f_file_t file, const f_color_context_t context);
-#endif // _di_fake_print_help_
-
-/**
* Execute main program.
*
* If main.signal is non-zero, then this blocks and handles the following signals:
* Status codes (with error bit) are returned on any problem.
*/
#ifndef _di_fake_main_
- extern f_status_t fake_main(fll_program_data_t * const main, const f_console_arguments_t arguments);
+ extern f_status_t fake_main(fll_program_data_t * const main, fake_setting_t * const setting);
#endif // _di_fake_main_
/**
*/
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
fll_program_data_t data = fll_program_data_t_initialize;
+ fake_setting_t setting = fake_setting_t_initialize;
f_console_parameter_t parameters[] = fake_console_parameter_t_initialize;
data.parameters.array = parameters;
data.parameters.used = fake_total_parameters_d;
+ data.environment = envp;
if (f_pipe_input_exists()) {
data.pipe = fll_program_data_pipe_input_e;
f_file_umask_get(&data.umask);
- const f_status_t status = fake_main(&data, arguments);
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+
+ fake_setting_load(arguments, &data, &setting);
+ }
+
+ fake_main(&data, &setting);
+
+ fake_setting_unload(&data, &setting);
fll_program_data_delete(&data);
exit(data.child);
}
- if (F_status_is_error(status)) return 1;
-
- return 0;
+ return F_status_is_error(status) ? 1 : 0;
}
--- /dev/null
+#include "fake.h"
+#include "private-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fake_print_help_
+ f_status_t fake_print_help(fake_setting_t * const setting, const fl_print_t print) {
+
+ f_file_stream_lock(print.to);
+
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+
+ fll_program_print_help_header(print, fake_program_name_long_s, fake_program_version_s);
+
+ fll_program_print_help_option_standard(print);
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, fake_short_define_s, fake_long_define_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Append an additional define after defines from settings file.");
+ fll_program_print_help_option(print, fake_short_fakefile_s, fake_long_fakefile_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Use this fakefile.");
+ fll_program_print_help_option(print, fake_short_mode_s, fake_long_mode_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use this mode when processing the build settings.");
+ fll_program_print_help_option(print, fake_short_process_s, fake_long_process_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Process name for storing build states.");
+ fll_program_print_help_option(print, fake_short_settings_s, fake_long_settings_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Use this settings file.");
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, fake_short_path_build_s, fake_long_path_build_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a custom build directory.");
+ fll_program_print_help_option(print, fake_short_path_data_s, fake_long_path_data_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a custom path to the data files.");
+ fll_program_print_help_option(print, fake_short_path_sources_s, fake_long_path_sources_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Specify a custom path to the source files.");
+ fll_program_print_help_option(print, fake_short_path_work_s, fake_long_path_work_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use includes/libraries/programs from this directory instead of system.");
+
+ fl_print_format("%r%r %[Special Options:%] ", print.to.stream, f_string_eol_s, f_string_eol_s, print.set->important, print.set->important);
+
+ fll_program_print_help_option_long(print, fake_long_documents_disabled_s, f_console_symbol_long_enable_s, " Forcibly do not build documents files.");
+ fll_program_print_help_option_long(print, fake_long_documents_enabled_s, f_console_symbol_long_enable_s, " Forcibly do build documents files.");
+ fll_program_print_help_option_long(print, fake_long_shared_disabled_s, f_console_symbol_long_enable_s, "Forcibly do not build shared files.");
+ fll_program_print_help_option_long(print, fake_long_shared_enabled_s, f_console_symbol_long_enable_s, " Forcibly do build shared files.");
+ fll_program_print_help_option_long(print, fake_long_static_disabled_s, f_console_symbol_long_enable_s, "Forcibly do not build static files.");
+ fll_program_print_help_option_long(print, fake_long_static_enabled_s, f_console_symbol_long_enable_s, " Forcibly do build static files.");
+
+ fl_print_format("%r%r %[Operations:%] ", print.to.stream, f_string_eol_s, f_string_eol_s, print.set->important, print.set->important);
+
+ fll_program_print_help_option_other(print, fake_other_operation_build_s, " Build or compile the code based on build settings file.");
+ fll_program_print_help_option_other(print, fake_other_operation_clean_s, " Delete all build files.");
+ fll_program_print_help_option_other(print, fake_other_operation_make_s, " Build or compile the code based on fakefile (default).");
+ fll_program_print_help_option_other(print, fake_other_operation_skeleton_s, "Build a skeleton directory structure.");
+
+ fll_program_print_help_usage(print, fake_program_name_s, fake_program_help_parameters_s);
+
+ fl_print_format("%r When performing the %[%r%] operation, the", print.to.stream, f_string_eol_s, print.set->notable, fake_other_operation_build_s, print.set->notable);
+ fl_print_format(" %[%r%r%] parameter specifies a name (limited to alpha-numeric, underscore, and dash) to be used in addition to the global.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fake_long_mode_s, print.set->notable, f_string_eol_s);
+
+ fl_print_format(" For example, when a %[%r%]", print.to.stream, print.set->notable, fake_make_parameter_variable_mode_s, print.set->notable);
+ fl_print_format(" of 'fll_monolithic' is specified, build libraries from both 'build_libraries' and 'build_libraries-fll_monolithic' are used (but not 'build_libraries-fll_level').%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When specifying the %[%r%] or the %[%r%]", print.to.stream, print.set->notable, fake_make_parameter_variable_fakefile_s, print.set->notable, print.set->notable, fake_make_parameter_variable_settings_s, print.set->notable);
+ fl_print_format(" parameters, the project root is seached first and then the build data director is searched when the given file does not contain a directory separator.%r", print.to.stream, f_string_eol_s);
+
+ fl_print_format(" For example, with '%[%r%r my_fakefile%]' the fakefile at", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fake_long_fakefile_s, print.set->notable);
+ fl_print_format(" '%[./my_fakefile%]' is used if found, but if it is not found then", print.to.stream, print.set->notable, print.set->notable);
+ fl_print_format(" '%[./%r%rmy_fakefile%]' is used if found.%r", print.to.stream, print.set->notable, fake_default_path_data_s, fake_default_path_build_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" For example, with '%[%r%r ./my_fakefile%]' the fakefile at", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fake_long_fakefile_s, print.set->notable);
+ fl_print_format(" '%[./my_fakefile%]' is used if found, but if it is not found then no other paths are attempted.%r%r", print.to.stream, print.set->notable, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When piping data to this program, the piped data is treated as if it were prepended to the %[%r%]", print.to.stream, print.set->notable, fake_make_parameter_variable_fakefile_s, print.set->notable);
+ fl_print_format("or the %[%r%], depending on the operation.%r", print.to.stream, print.set->notable, fake_make_parameter_variable_settings_s, print.set->notable, f_string_eol_s);
+
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+
+ f_file_stream_flush(output);
+ f_file_stream_unlock(print.to);
+
+ return F_none;
+ }
+#endif // _di_fake_print_help_
+
+#ifndef _di_fake_print_line_first_
+ void fake_print_line_first(fake_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ }
+#endif // _di_fake_print_line_first_
+
+#ifndef _di_fake_print_line_last_
+ void fake_print_line_last(fake_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+ if (print.verbosity == f_console_verbosity_error_e && !F_status_is_error(setting->status)) return;
+ if (setting->flag & fake_main_flag_verify_e) return;
+ if ((setting->flag & fake_main_flag_file_to_e) && !F_status_is_error(setting->status)) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ }
+#endif // _di_fake_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: UTF-8
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _fake_print_h
+#define _fake_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print help.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * The output structure to print to.
+ *
+ * @return
+ * F_none on success.
+ */
+#ifndef _di_fake_print_help_
+ extern f_status_t fake_print_help(fake_setting_t * const setting, const fl_print_t print);
+#endif // _di_fake_print_help_
+
+/**
+ * Print first new line, unless verbosity says otherwise.
+ *
+ * This is generally either the first line in the program or the first line printed before an error message.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fake_print_line_first_
+ extern void fake_print_line_first(fake_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fake_print_line_first_
+
+/**
+ * Print last new line when the main is complete, unless verbosity says otherwise.
+ *
+ * This is generally the very last line printed in the program.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fake_print_line_last_
+ extern void fake_print_line_last(fake_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fake_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _fake_print_h
if (F_status_is_error(*status)) return;
if (fll_program_standard_signal_received(data->main)) {
- fake_print_signal_received(data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
*status = F_status_set_error(F_interrupt);
if (F_status_is_error(*status) && buffer.used) return;
if (fll_program_standard_signal_received(data->main)) {
- fake_print_signal_received(data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
*status = F_status_set_error(F_interrupt);
if (F_status_is_error(*status)) return;
if (fll_program_standard_signal_received(data->main)) {
- fake_print_signal_received(data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
*status = F_status_set_error(F_interrupt);
if (F_status_is_error(*status) || f_file_exists(file_stage, F_true) == F_true || *status == F_child) return;
if (fll_program_standard_signal_received(data->main)) {
- fake_print_signal_received(data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
*status = F_status_set_error(F_interrupt);
if (!(i % fake_signal_check_short_d)) {
if (fll_program_standard_signal_received(data->main)) {
- fake_print_signal_received(data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
*status = F_status_set_error(F_interrupt);
f_string_dynamics_resize(0, &arguments);
if (fll_program_standard_signal_received(data->main)) {
- fake_print_signal_received(data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
*status = F_status_set_error(F_interrupt);
}
f_status_t fake_build_operate(fake_data_t * const data, const f_string_statics_t * const build_arguments, const bool process_pipe) {
if (fll_program_standard_signal_received(data->main)) {
- fake_print_signal_received(data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (F_status_is_error(*status)) return;
if (fll_program_standard_signal_received(data->main)) {
- fake_print_signal_received(data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
*status = F_status_set_error(F_interrupt);
*status = fll_execute_program(program, arguments, ¶meter, 0, (void *) &return_code);
if (fll_program_standard_signal_received(data->main)) {
- fake_print_signal_received(data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
*status = F_status_set_error(F_interrupt);
f_status_t fake_file_buffer(fake_data_t * const data, const f_string_static_t path_file, const bool required, f_string_dynamic_t * const buffer) {
if (fll_program_standard_signal_received(data->main)) {
- fake_print_signal_received(data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
do {
if (fll_program_standard_signal_received(data->main)) {
- fake_print_signal_received(data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
f_status_t fake_validate_parameter_paths(fake_data_t * const data) {
if (fll_program_standard_signal_received(data->main)) {
- fake_print_signal_received(data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (F_status_is_error(*status)) return;
if (fll_program_standard_signal_received(data_make->main)) {
- fake_print_signal_received(data_make->data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
*status = F_status_set_error(F_interrupt);
if (!(i % fake_signal_check_short_d)) {
if (fll_program_standard_signal_received(data_make->main)) {
- fake_print_signal_received(data_make->data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
*status = F_status_set_error(F_interrupt);
f_status_t fake_make_operate(fake_data_t * const data) {
if (fll_program_standard_signal_received(data->main)) {
- fake_print_signal_received(data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (!(i % fake_signal_check_short_d)) {
if (fll_program_standard_signal_received(data_make->main)) {
- fake_print_signal_received(data_make->data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
*status = F_status_set_error(F_interrupt);
if (!program.used && !arguments.used) return F_data_not;
if (fll_program_standard_signal_received(data_make->main)) {
- fake_print_signal_received(data_make->data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
status = fll_execute_program(program, arguments, ¶meter, 0, (void *) &return_code);
if (fll_program_standard_signal_received(data_make->main)) {
- fake_print_signal_received(data_make->data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
}
#endif // _di_fake_print_message_section_operation_unknown_
-#ifndef _di_fake_print_signal_received_
- void fake_print_signal_received(fake_data_t * const data) {
-
- if (data->main->warning.verbosity != f_console_verbosity_verbose_e && data->main->warning.verbosity != f_console_verbosity_debug_e) return;
-
- // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
- fflush(data->main->warning.to.stream);
-
- flockfile(data->main->warning.to.stream);
-
- fl_print_format("%]%r%r%[Received signal code %]", data->main->warning.to.stream, data->main->context.set.reset, f_string_eol_s, f_string_eol_s, data->main->context.set.warning, data->main->context.set.warning);
- fl_print_format("%[%i%]", data->main->warning.to.stream, data->main->context.set.notable, data->main->signal_received, data->main->context.set.notable);
- fl_print_format("%[.%]%r", data->main->warning.to.stream, data->main->context.set.warning, data->main->context.set.warning, f_string_eol_s);
-
- funlockfile(data->main->warning.to.stream);
- }
-#endif // _di_fake_print_signal_received_
-
#ifndef _di_fake_print_warning_settings_content_empty_
void fake_print_warning_settings_content_empty(fake_data_t * const data, const f_string_static_t path_file, const f_string_dynamic_t buffer, const f_string_range_t range_object, const f_string_static_t settings_name) {
#endif // _di_fake_print_message_section_operation_unknown_
/**
- * Print a message about a process signal being recieved, such as an interrupt signal.
- *
- * @param data
- * The program data.
- *
- * @see flockfile()
- * @see funlockfile()
- *
- * @see fl_print_format()
- */
-#ifndef _di_fake_print_signal_received_
- extern void fake_print_signal_received(fake_data_t * const data) F_attribute_visibility_internal_d;
-#endif // _di_fake_print_signal_received_
-
-/**
* Print message when fake settings content is empty.
*
* @param data
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library fake.c common.c
+build_sources_library fake.c common.c print.c
build_sources_library private-build.c private-build-library.c private-build-load.c private-build-object.c private-build-objects.c private-build-program.c private-build-skeleton.c
build_sources_library private-clean.c private-common.c private-make.c private-print.c private-skeleton.c
build_sources_library private-make-load_fakefile.c private-make-load_parameters.c
build_sources_program main.c
-build_sources_headers fake.h common.h
+build_sources_headers fake.h common.h print.h
build_script yes
build_shared yes
const f_string_static_t firewall_tool_ipset_s = macro_f_string_static_t_initialize(FIREWALL_tool_ipset_s, 0, FIREWALL_tool_ipset_s_length);
#endif // _di_firewall_defines_
+#ifndef _di_firewall_setting_delete_
+ f_status_t firewall_setting_delete(firewall_setting_t * const setting) {
+
+ if (!setting) return F_status_set_error(F_parameter);
+
+ return F_none;
+ }
+#endif // _di_firewall_setting_delete_
+
+#ifndef _di_firewall_setting_load_
+ void firewall_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, firewall_setting_t * const setting) {
+
+ if (!main || !setting) return;
+
+ // Load parameters.
+ setting->status = f_console_parameter_process(arguments, &main->parameters);
+ if (F_status_is_error(setting->status)) return;
+
+ {
+ f_array_length_t choice = 0;
+ f_uint16s_t choices = f_uint16s_t_initialize;
+
+ // Identify and prioritize "color context" parameters.
+ {
+ uint16_t choices_array[3] = { firewall_parameter_no_color_e, firewall_parameter_light_e, firewall_parameter_dark_e };
+ choices.array = choices_array;
+ choices.used = 3;
+
+ const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
+
+ setting->status = fll_program_parameter_process_context(choices, modes, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ firewall_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_context", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[firewall_parameter_line_first_no_e].result == f_console_result_found_e) {
+ setting->line_first = f_string_empty_s;
+ }
+ else {
+ setting->line_first = f_string_eol_s;
+ }
+
+ if (main->parameters.array[firewall_parameter_line_last_no_e].result == f_console_result_found_e) {
+ setting->line_last = f_string_empty_s;
+ }
+ else {
+ setting->line_last = f_string_eol_s;
+ }
+
+ // Identify and prioritize "verbosity" parameters.
+ {
+ uint16_t choices_array[5] = { firewall_parameter_verbosity_quiet_e, firewall_parameter_verbosity_error_e, firewall_parameter_verbosity_verbose_e, firewall_parameter_verbosity_debug_e, firewall_parameter_verbosity_normal_e };
+ choices.array = choices_array;
+ choices.used = 5;
+
+ const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+
+ setting->status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ firewall_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_verbosity", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[firewall_parameter_help_e].result == f_console_result_found_e) {
+ setting->flag |= firewall_main_flag_help_e;
+
+ return;
+ }
+
+ if (main->parameters.array[firewall_parameter_version_e].result == f_console_result_found_e) {
+ setting->flag |= firewall_main_flag_version_e;
+
+ return;
+ }
+
+ // Identify and prioritize "from" mode parameters.
+ {
+ uint16_t choices_array[2] = { firewall_parameter_from_bytesequence_e, firewall_parameter_from_codepoint_e };
+ choices.array = choices_array;
+ choices.used = 2;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ firewall_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == firewall_parameter_from_bytesequence_e) {
+ if (setting->mode & firewall_mode_from_codepoint_e) {
+ setting->mode -= firewall_mode_from_codepoint_e;
+ }
+
+ setting->mode |= firewall_mode_from_bytesequence_e;
+ }
+ else if (choices.array[choice] == firewall_parameter_from_codepoint_e) {
+ if (setting->mode & firewall_mode_from_bytesequence_e) {
+ setting->mode -= firewall_mode_from_bytesequence_e;
+ }
+
+ setting->mode |= firewall_mode_from_codepoint_e;
+ }
+ }
+
+ // Identify and prioritize "to" mode parameters.
+ {
+ uint16_t choices_array[4] = { firewall_parameter_to_bytesequence_e, firewall_parameter_to_codepoint_e, firewall_parameter_to_combining_e, firewall_parameter_to_width_e };
+ choices.array = choices_array;
+ choices.used = 4;
+ choice = 1;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ firewall_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == firewall_parameter_to_bytesequence_e) {
+ if (setting->mode & firewall_mode_to_codepoint_e) {
+ setting->mode -= firewall_mode_to_codepoint_e;
+ }
+
+ if (setting->mode & firewall_mode_to_combining_e) {
+ setting->mode -= firewall_mode_to_combining_e;
+ }
+
+ if (setting->mode & firewall_mode_to_width_e) {
+ setting->mode -= firewall_mode_to_width_e;
+ }
+
+ setting->mode |= firewall_mode_to_bytesequence_e;
+ }
+ else if (choices.array[choice] == firewall_parameter_to_codepoint_e) {
+ if (setting->mode & firewall_mode_to_bytesequence_e) {
+ setting->mode -= firewall_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & firewall_mode_to_combining_e) {
+ setting->mode -= firewall_mode_to_combining_e;
+ }
+
+ if (setting->mode & firewall_mode_to_width_e) {
+ setting->mode -= firewall_mode_to_width_e;
+ }
+
+ setting->mode |= firewall_mode_to_codepoint_e;
+ }
+ else if (choices.array[choice] == firewall_parameter_to_combining_e) {
+ if (setting->mode & firewall_mode_to_bytesequence_e) {
+ setting->mode -= firewall_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & firewall_mode_to_codepoint_e) {
+ setting->mode -= firewall_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[firewall_parameter_to_width_e].result == f_console_result_found_e) {
+ setting->mode |= firewall_mode_to_width_e;
+ }
+
+ setting->mode |= firewall_mode_to_combining_e;
+ }
+ else if (choices.array[choice] == firewall_parameter_to_width_e) {
+ if (setting->mode & firewall_mode_to_bytesequence_e) {
+ setting->mode -= firewall_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & firewall_mode_to_codepoint_e) {
+ setting->mode -= firewall_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[firewall_parameter_to_combining_e].result == f_console_result_found_e) {
+ setting->mode |= firewall_mode_to_combining_e;
+ }
+
+ setting->mode |= firewall_mode_to_width_e;
+ }
+ }
+ }
+
+ f_string_static_t * const args = main->parameters.arguments.array;
+
+ if (main->parameters.array[firewall_parameter_to_file_e].result == f_console_result_additional_e) {
+ if (main->parameters.array[firewall_parameter_to_file_e].values.used > 1) {
+ firewall_print_error_parameter_file_to_too_many(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+
+ if (args[main->parameters.array[firewall_parameter_to_file_e].values.array[0]].used) {
+ setting->path_files_to.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(1, &setting->path_files_to);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_to.array[setting->path_files_to.used].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[main->parameters.array[firewall_parameter_to_file_e].values.array[0]], &setting->path_files_to.array[0]);
+ if (F_status_is_error(setting->status)) return;
+
+ ++setting->path_files_to.used;
+
+ setting->status = f_file_stream_open(args[main->parameters.array[firewall_parameter_to_file_e].values.array[0]], f_file_open_mode_append_s, &main->output.to);
+
+ if (F_status_is_error(setting->status)) {
+ fll_error_file_print(main->error, F_status_set_fine(setting->status), "f_file_stream_open", F_true, args[main->parameters.array[firewall_parameter_to_file_e].values.array[0]], f_file_operation_open_s, fll_error_file_type_file_e);
+
+ return;
+ }
+
+ setting->flag |= firewall_main_flag_file_to_e;
+ }
+ else {
+ firewall_print_error_parameter_file_name_empty(main, setting, main->parameters.array[firewall_parameter_to_file_e].values.array[0]);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+ else if (main->parameters.array[firewall_parameter_to_file_e].result == f_console_result_found_e) {
+ firewall_print_error_no_value(main, setting, firewall_long_to_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ main->output.to = main->message.to;
+
+ if (setting->flag & firewall_main_flag_file_to_e) {
+ setting->flag -= firewall_main_flag_file_to_e;
+ }
+ }
+
+ if (main->parameters.array[firewall_parameter_from_file_e].result == f_console_result_additional_e) {
+ setting->path_files_from.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(main->parameters.array[firewall_parameter_from_file_e].values.used, &setting->path_files_from);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_from.used = main->parameters.array[firewall_parameter_from_file_e].values.used;
+
+ f_array_length_t i = 0;
+ f_array_length_t index = 0;
+
+ for (; i < setting->path_files_from.used; ++i) {
+
+ index = main->parameters.array[firewall_parameter_from_file_e].values.array[i];
+ setting->path_files_from.array[i].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[index], &setting->path_files_from.array[i]);
+ if (F_status_is_error(setting->status)) return;
+
+ if (args[index].used) {
+ if (f_file_exists(args[index], F_true) != F_true) {
+ firewall_print_error_parameter_file_not_found(main, setting, F_true, args[index]);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_file_found_not);
+ }
+ }
+ }
+ else {
+ firewall_print_error_parameter_file_name_empty(main, setting, index);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_parameter);
+ }
+ }
+ } // for
+
+ if (F_status_is_error(setting->status)) return;
+
+ setting->flag |= firewall_main_flag_file_from_e;
+ }
+ else if (main->parameters.array[firewall_parameter_from_file_e].result == f_console_result_found_e) {
+ firewall_print_error_no_value(main, setting, firewall_long_from_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ if (setting->flag & firewall_main_flag_file_from_e) {
+ setting->flag -= firewall_main_flag_file_from_e;
+ }
+ }
+
+ if (F_status_is_error(setting->status)) return;
+
+ if (main->parameters.array[firewall_parameter_from_file_e].result == f_console_result_none_e && !((main->pipe & fll_program_data_pipe_input_e) || main->parameters.remaining.used)) {
+ firewall_print_error_no_from(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+ }
+
+ if (!(setting->mode & firewall_mode_to_bytesequence_e)) {
+ if (main->parameters.array[firewall_parameter_separate_e].result == f_console_result_found_e || main->parameters.array[firewall_parameter_headers_e].result == f_console_result_found_e) {
+ setting->prepend = firewall_string_prepend_padding_s;
+ setting->append = f_string_eol_s;
+ }
+ else {
+ setting->prepend = f_string_space_s;
+ }
+ }
+
+ if (main->parameters.array[firewall_parameter_headers_e].result == f_console_result_found_e) {
+ setting->flag |= firewall_main_flag_header_e;
+ }
+
+ if (main->parameters.array[firewall_parameter_separate_e].result == f_console_result_found_e) {
+ setting->flag |= firewall_main_flag_separate_e;
+ }
+
+ if (main->parameters.array[firewall_parameter_strip_invalid_e].result == f_console_result_found_e) {
+ setting->flag |= firewall_main_flag_strip_invalid_e;
+ }
+
+ setting->valid_not = main->message.set->error;
+ }
+#endif // _di_firewall_setting_load_
+
+#ifndef _di_firewall_setting_unload_
+ f_status_t firewall_setting_unload(fll_program_data_t * const main, firewall_setting_t * const setting) {
+
+ if (!main || !setting) return F_status_set_error(F_parameter);
+
+ firewall_setting_delete(setting);
+
+ return F_none;
+ }
+#endif // _di_firewall_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
#define firewall_total_parameters_d 17
#endif // _di_firewall_defines_
+/**
+ * Flags used to represent flags passed to the main function.
+ *
+ * firewall_main_flag_*_e:
+ * - none: No modes in use.
+ * - file_from: Using a specified source file.
+ * - file_to: Using a specified destination file.
+ * - help: Print help.
+ * - header: Enable printing of headers.
+ * - separate: Enable printing of separators.
+ * - strip_invalid: Using strip invalid character mode.
+ * - verify: Using verify mode.
+ * - version: Print version.
+ */
+#ifndef _di_firewall_main_flag_e_
+ enum {
+ firewall_main_flag_none_e = 0x0,
+ firewall_main_flag_file_from_e = 0x1,
+ firewall_main_flag_file_to_e = 0x2,
+ firewall_main_flag_header_e = 0x4,
+ firewall_main_flag_help_e = 0x8,
+ firewall_main_flag_separate_e = 0x10,
+ firewall_main_flag_strip_invalid_e = 0x20,
+ firewall_main_flag_verify_e = 0x40,
+ firewall_main_flag_version_e = 0x80,
+ };
+#endif // _di_firewall_main_flag_e_
+
+/**
+ * The firewall main program settings.
+ *
+ * This is passed to the program-specific main entry point to designate program settings.
+ * These program settings are often processed from the program arguments (often called the command line arguments).
+ *
+ * flag: Flags passed to the main function.
+ *
+ * status: The main status code, generally used by the load settings and main functions.
+ *
+ * line_first: A string expected to represent either "\n" or NULL to allow for easy handling of when to print first new line or not.
+ * line_last: A string expected to represent either "\n" or NULL to allow for easy handling of when to print last new line or not.
+ */
+#ifndef _di_firewall_setting_t_
+ typedef struct {
+ uint16_t flag;
+
+ f_status_t status;
+
+ f_string_static_t line_first;
+ f_string_static_t line_last;
+ } firewall_setting_t;
+
+ #define firewall_setting_t_initialize \
+ { \
+ firewall_main_flag_none_e, \
+ F_none, \
+ f_string_static_t_initialize, \
+ f_string_static_t_initialize, \
+ }
+#endif // _di_firewall_setting_t_
+
+/**
+ * Delete the program main setting data.
+ *
+ * @param setting
+ * The program main setting data.
+ * This does not alter setting.status.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_firewall_setting_delete_
+ extern f_status_t firewall_setting_delete(firewall_setting_t * const setting);
+#endif // _di_firewall_setting_delete_
+
+/**
+ * Perform the standard program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately retuns without doing anything.
+ *
+ * @param arguments
+ * The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ *
+ * This alters setting.status:
+ * F_none on success.
+ *
+ * Errors (with error bit) from: f_console_parameter_process().
+ * Errors (with error bit) from: fll_program_parameter_process_context().
+ *
+ * @see f_console_parameter_process()
+ * @see fll_program_parameter_process_context()
+ */
+#ifndef _di_firewall_setting_load_
+ extern void firewall_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, firewall_setting_t * const setting);
+#endif // _di_firewall_setting_load_
+
+/**
+ * Perform the standard program setting unload process.
+ *
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * All buffers are deallocated.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: utf8_setting_delete().
+ *
+ * @see utf8_setting_delete()
+ */
+#ifndef _di_firewall_setting_unload_
+ extern f_status_t firewall_setting_unload(fll_program_data_t * const main, firewall_setting_t * const setting);
+#endif // _di_firewall_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern "C" {
#endif
-#ifndef _di_firewall_print_help_
- f_status_t firewall_print_help(const f_file_t file, const f_color_context_t context) {
-
- flockfile(file.stream);
-
- //if (!(setting->flag & XXX_main_flag_line_first_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- fll_program_print_help_header(file, context, firewall_program_name_long_s, firewall_program_version_s);
-
- fll_program_print_help_option_standard(file, context);
-
- fl_print_format("%r%r %[Commands:%] ", file.stream, f_string_eol_s, f_string_eol_s, context.set.important, context.set.important);
- fl_print_format("%r %[%r%] Turn on the firewall.", file.stream, f_string_eol_s, context.set.standout, firewall_command_start_s, context.set.standout);
- fl_print_format("%r %[%r%] Turn off the firewall.", file.stream, f_string_eol_s, context.set.standout, firewall_command_stop_s, context.set.standout);
- fl_print_format("%r %[%r%] Turn off and then turn on the firewall.", file.stream, f_string_eol_s, context.set.standout, firewall_command_restart_s, context.set.standout);
- fl_print_format("%r %[%r%] Prevent all communication.", file.stream, f_string_eol_s, context.set.standout, firewall_command_lock_s, context.set.standout);
- fl_print_format("%r %[%r%] Show active firewall settings.", file.stream, f_string_eol_s, context.set.standout, firewall_command_show_s, context.set.standout);
-
- fll_program_print_help_usage(file, context, firewall_program_name_s, firewall_program_help_parameters_s);
-
- //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- f_file_stream_flush(file);
- funlockfile(file.stream);
-
- return F_none;
- }
-#endif // _di_firewall_print_help_
-
#ifndef _di_firewall_main_
- f_status_t firewall_main(fll_program_data_t * const main, const f_console_arguments_t arguments) {
+ f_status_t firewall_main(fll_program_data_t * const main, firewall_setting_t * const setting) {
f_status_t status = F_none;
status = F_none;
if (main->parameters.array[firewall_parameter_help_e].result == f_console_result_found_e) {
- firewall_print_help(main->output.to, main->context);
+ firewall_print_help(setting, main->message);
return F_none;
}
if (main->parameters.array[firewall_parameter_version_e].result == f_console_result_found_e) {
- fll_program_print_version(main->output.to, firewall_program_version_s);
+ fll_program_print_version(main->message, firewall_program_version_s);
return F_none;
}
#endif
/**
- * Print help.
- *
- * @param file
- * The file to print to.
- * @param context
- * The color context settings.
- *
- * @return
- * F_none on success.
- */
-#ifndef _di_firewall_print_help_
- extern f_status_t firewall_print_help(const f_file_t file, const f_color_context_t context);
-#endif // _di_firewall_print_help_
-
-/**
* Execute main program.
*
* If main.signal is non-zero, then this blocks and handles the following signals:
* Status codes (with error bit) are returned on any problem.
*/
#ifndef _di_firewall_main_
- extern f_status_t firewall_main(fll_program_data_t * const main, const f_console_arguments_t arguments);
+ extern f_status_t firewall_main(fll_program_data_t * const main, firewall_setting_t * const setting);
#endif // _di_firewall_main_
#ifdef __cplusplus
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
fll_program_data_t data = fll_program_data_t_initialize;
+ firewall_setting_t setting = firewall_setting_t_initialize;
f_console_parameter_t parameters[] = firewall_console_parameter_t_initialize;
data.parameters.array = parameters;
data.parameters.used = firewall_total_parameters_d;
+ data.environment = envp;
if (f_pipe_input_exists()) {
data.pipe = fll_program_data_pipe_input_e;
fll_program_standard_set_up(&data);
- const f_status_t status = firewall_main(&data, arguments);
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+
+ firewall_setting_load(arguments, &data, &setting);
+ }
+
+ firewall_main(&data, &setting);
+
+ firewall_setting_unload(&data, &setting);
fll_program_data_delete(&data);
exit(data.child);
}
- if (F_status_is_error(status)) return 1;
-
- return 0;
+ return F_status_is_error(status) ? 1 : 0;
}
--- /dev/null
+#include "firewall.h"
+#include "private-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_firewall_print_help_
+ f_status_t firewall_print_help(utf8_setting_t * const setting, const fl_print_t print) {
+
+ f_file_stream_lock(print.to);
+
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+
+ fll_program_print_help_header(print, firewall_program_name_long_s, firewall_program_version_s);
+
+ fll_program_print_help_option_standard(print);
+
+ fl_print_format("%r%r %[Commands:%] ", print.to.stream, f_string_eol_s, f_string_eol_s, print.set->important, print.set->important);
+ fl_print_format("%r %[%r%] Turn on the firewall.", print.to.stream, f_string_eol_s, print.set->standout, firewall_command_start_s, print.set->standout);
+ fl_print_format("%r %[%r%] Turn off the firewall.", print.to.stream, f_string_eol_s, print.set->standout, firewall_command_stop_s, print.set->standout);
+ fl_print_format("%r %[%r%] Turn off and then turn on the firewall.", print.to.stream, f_string_eol_s, print.set->standout, firewall_command_restart_s, print.set->standout);
+ fl_print_format("%r %[%r%] Prevent all communication.", print.to.stream, f_string_eol_s, print.set->standout, firewall_command_lock_s, print.set->standout);
+ fl_print_format("%r %[%r%] Show active firewall settings.", print.to.stream, f_string_eol_s, print.set->standout, firewall_command_show_s, print.set->standout);
+
+ fll_program_print_help_usage(print, firewall_program_name_s, firewall_program_help_parameters_s);
+
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+
+ f_file_stream_flush(print.to);
+ f_file_stream_unlock(print.to);
+
+ return F_none;
+ }
+#endif // _di_firewall_print_help_
+
+#ifndef _di_firewall_print_line_first_
+ void firewall_print_line_first(firewall_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ }
+#endif // _di_firewall_print_line_first_
+
+#ifndef _di_firewall_print_line_last_
+ void firewall_print_line_last(firewall_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+ if (print.verbosity == f_console_verbosity_error_e && !F_status_is_error(setting->status)) return;
+ if (setting->flag & firewall_main_flag_verify_e) return;
+ if ((setting->flag & firewall_main_flag_file_to_e) && !F_status_is_error(setting->status)) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ }
+#endif // _di_firewall_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: UTF-8
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _firewall_print_h
+#define _firewall_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print help.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * The output structure to print to.
+ *
+ * @return
+ * F_none on success.
+ */
+#ifndef _di_firewall_print_help_
+ extern f_status_t firewall_print_help(firewall_setting_t * const setting, const fl_print_t print);
+#endif // _di_firewall_print_help_
+
+/**
+ * Print first new line, unless verbosity says otherwise.
+ *
+ * This is generally either the first line in the program or the first line printed before an error message.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_firewall_print_line_first_
+ extern void firewall_print_line_first(firewall_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_firewall_print_line_first_
+
+/**
+ * Print last new line when the main is complete, unless verbosity says otherwise.
+ *
+ * This is generally the very last line printed in the program.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_firewall_print_line_last_
+ extern void firewall_print_line_last(firewall_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_firewall_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _firewall_print_h
fll_print_format("%r%[%QAn unhandled error (%ui) has occurred while calling %s() for the file '%Q'.%]%r", output.to.stream, f_string_eol_s, output.context, output.prefix, status, function, filename, output.context, f_string_eol_s);
}
-#ifndef _di_firewall_print_signal_received_
- void firewall_print_signal_received(firewall_data_t * const data, const f_status_t signal) {
-
- if (data->main->warning.verbosity != f_console_verbosity_verbose_e && data->main->warning.verbosity != f_console_verbosity_debug_e) return;
-
- // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
- fflush(data->main->warning.to.stream);
-
- flockfile(data->main->warning.to.stream);
-
- fl_print_format("%]%r%r%[Received signal code %]", data->main->warning.to.stream, data->main->context.set.reset, f_string_eol_s, f_string_eol_s, data->main->context.set.warning, data->main->context.set.warning);
- fl_print_format("%[%i%]", data->main->warning.to.stream, data->main->context.set.notable, signal, data->main->context.set.notable);
- fl_print_format("%[.%]%r", data->main->warning.to.stream, data->main->context.set.warning, data->main->context.set.warning, f_string_eol_s);
-
- funlockfile(data->main->warning.to.stream);
- }
-#endif // _di_firewall_print_signal_received_
-
#ifndef _di_firewall_signal_received_
f_status_t firewall_signal_received(firewall_data_t * const data) {
extern void firewall_print_error_on_unhandled_for_file(const fl_print_t output, const char *function, const f_status_t status, const f_string_static_t filename) F_attribute_visibility_internal_d;
/**
- * Print a message about a process signal being recieved, such as an interrupt signal.
- *
- * @param data
- * The program data.
- * @param signal
- * The signal received.
- */
-#ifndef _di_firewall_print_signal_received_
- extern void firewall_print_signal_received(firewall_data_t * const data, const f_status_t signal) F_attribute_visibility_internal_d;
-#endif // _di_firewall_print_signal_received_
-
-/**
* Check to see if a process signal is received.
*
* Only signals that are blocked via main.signal will be received.
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library firewall.c common.c private-common.c private-firewall.c
+build_sources_library firewall.c common.c print.c private-common.c private-firewall.c
build_sources_program main.c
-build_sources_headers firewall.h common.h
+build_sources_headers firewall.h common.h print.h
build_sources_setting default-blacklist default-whitelist example-device-firewall firewall-first firewall-last firewall-other
const f_string_static_t fss_basic_list_read_delimit_mode_name_lesser_s = macro_f_string_static_t_initialize(FSS_BASIC_LIST_READ_delimit_mode_name_lesser_s, 0, FSS_BASIC_LIST_READ_delimit_mode_name_lesser_s_length);
#endif // _di_fss_basic_list_read_delimit_mode_
+#ifndef _di_fss_basic_list_read_setting_delete_
+ f_status_t fss_basic_list_read_setting_delete(fss_basic_list_read_setting_t * const setting) {
+
+ if (!setting) return F_status_set_error(F_parameter);
+
+ return F_none;
+ }
+#endif // _di_fss_basic_list_read_setting_delete_
+
+#ifndef _di_fss_basic_list_read_setting_load_
+ void fss_basic_list_read_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_basic_list_read_setting_t * const setting) {
+
+ if (!main || !setting) return;
+
+ // Load parameters.
+ setting->status = f_console_parameter_process(arguments, &main->parameters);
+ if (F_status_is_error(setting->status)) return;
+
+ {
+ f_array_length_t choice = 0;
+ f_uint16s_t choices = f_uint16s_t_initialize;
+
+ // Identify and prioritize "color context" parameters.
+ {
+ uint16_t choices_array[3] = { fss_basic_list_read_parameter_no_color_e, fss_basic_list_read_parameter_light_e, fss_basic_list_read_parameter_dark_e };
+ choices.array = choices_array;
+ choices.used = 3;
+
+ const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
+
+ setting->status = fll_program_parameter_process_context(choices, modes, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_basic_list_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_context", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_basic_list_read_parameter_line_first_no_e].result == f_console_result_found_e) {
+ setting->line_first = f_string_empty_s;
+ }
+ else {
+ setting->line_first = f_string_eol_s;
+ }
+
+ if (main->parameters.array[fss_basic_list_read_parameter_line_last_no_e].result == f_console_result_found_e) {
+ setting->line_last = f_string_empty_s;
+ }
+ else {
+ setting->line_last = f_string_eol_s;
+ }
+
+ // Identify and prioritize "verbosity" parameters.
+ {
+ uint16_t choices_array[5] = { fss_basic_list_read_parameter_verbosity_quiet_e, fss_basic_list_read_parameter_verbosity_error_e, fss_basic_list_read_parameter_verbosity_verbose_e, fss_basic_list_read_parameter_verbosity_debug_e, fss_basic_list_read_parameter_verbosity_normal_e };
+ choices.array = choices_array;
+ choices.used = 5;
+
+ const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+
+ setting->status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_basic_list_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_verbosity", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_basic_list_read_parameter_help_e].result == f_console_result_found_e) {
+ setting->flag |= fss_basic_list_read_main_flag_help_e;
+
+ return;
+ }
+
+ if (main->parameters.array[fss_basic_list_read_parameter_version_e].result == f_console_result_found_e) {
+ setting->flag |= fss_basic_list_read_main_flag_version_e;
+
+ return;
+ }
+
+ // Identify and prioritize "from" mode parameters.
+ {
+ uint16_t choices_array[2] = { fss_basic_list_read_parameter_from_bytesequence_e, fss_basic_list_read_parameter_from_codepoint_e };
+ choices.array = choices_array;
+ choices.used = 2;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_basic_list_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_basic_list_read_parameter_from_bytesequence_e) {
+ if (setting->mode & fss_basic_list_read_mode_from_codepoint_e) {
+ setting->mode -= fss_basic_list_read_mode_from_codepoint_e;
+ }
+
+ setting->mode |= fss_basic_list_read_mode_from_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_basic_list_read_parameter_from_codepoint_e) {
+ if (setting->mode & fss_basic_list_read_mode_from_bytesequence_e) {
+ setting->mode -= fss_basic_list_read_mode_from_bytesequence_e;
+ }
+
+ setting->mode |= fss_basic_list_read_mode_from_codepoint_e;
+ }
+ }
+
+ // Identify and prioritize "to" mode parameters.
+ {
+ uint16_t choices_array[4] = { fss_basic_list_read_parameter_to_bytesequence_e, fss_basic_list_read_parameter_to_codepoint_e, fss_basic_list_read_parameter_to_combining_e, fss_basic_list_read_parameter_to_width_e };
+ choices.array = choices_array;
+ choices.used = 4;
+ choice = 1;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_basic_list_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_basic_list_read_parameter_to_bytesequence_e) {
+ if (setting->mode & fss_basic_list_read_mode_to_codepoint_e) {
+ setting->mode -= fss_basic_list_read_mode_to_codepoint_e;
+ }
+
+ if (setting->mode & fss_basic_list_read_mode_to_combining_e) {
+ setting->mode -= fss_basic_list_read_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_basic_list_read_mode_to_width_e) {
+ setting->mode -= fss_basic_list_read_mode_to_width_e;
+ }
+
+ setting->mode |= fss_basic_list_read_mode_to_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_basic_list_read_parameter_to_codepoint_e) {
+ if (setting->mode & fss_basic_list_read_mode_to_bytesequence_e) {
+ setting->mode -= fss_basic_list_read_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_basic_list_read_mode_to_combining_e) {
+ setting->mode -= fss_basic_list_read_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_basic_list_read_mode_to_width_e) {
+ setting->mode -= fss_basic_list_read_mode_to_width_e;
+ }
+
+ setting->mode |= fss_basic_list_read_mode_to_codepoint_e;
+ }
+ else if (choices.array[choice] == fss_basic_list_read_parameter_to_combining_e) {
+ if (setting->mode & fss_basic_list_read_mode_to_bytesequence_e) {
+ setting->mode -= fss_basic_list_read_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_basic_list_read_mode_to_codepoint_e) {
+ setting->mode -= fss_basic_list_read_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_basic_list_read_parameter_to_width_e].result == f_console_result_found_e) {
+ setting->mode |= fss_basic_list_read_mode_to_width_e;
+ }
+
+ setting->mode |= fss_basic_list_read_mode_to_combining_e;
+ }
+ else if (choices.array[choice] == fss_basic_list_read_parameter_to_width_e) {
+ if (setting->mode & fss_basic_list_read_mode_to_bytesequence_e) {
+ setting->mode -= fss_basic_list_read_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_basic_list_read_mode_to_codepoint_e) {
+ setting->mode -= fss_basic_list_read_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_basic_list_read_parameter_to_combining_e].result == f_console_result_found_e) {
+ setting->mode |= fss_basic_list_read_mode_to_combining_e;
+ }
+
+ setting->mode |= fss_basic_list_read_mode_to_width_e;
+ }
+ }
+ }
+
+ f_string_static_t * const args = main->parameters.arguments.array;
+
+ if (main->parameters.array[fss_basic_list_read_parameter_to_file_e].result == f_console_result_additional_e) {
+ if (main->parameters.array[fss_basic_list_read_parameter_to_file_e].values.used > 1) {
+ fss_basic_list_read_print_error_parameter_file_to_too_many(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+
+ if (args[main->parameters.array[fss_basic_list_read_parameter_to_file_e].values.array[0]].used) {
+ setting->path_files_to.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(1, &setting->path_files_to);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_to.array[setting->path_files_to.used].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[main->parameters.array[fss_basic_list_read_parameter_to_file_e].values.array[0]], &setting->path_files_to.array[0]);
+ if (F_status_is_error(setting->status)) return;
+
+ ++setting->path_files_to.used;
+
+ setting->status = f_file_stream_open(args[main->parameters.array[fss_basic_list_read_parameter_to_file_e].values.array[0]], f_file_open_mode_append_s, &main->output.to);
+
+ if (F_status_is_error(setting->status)) {
+ fll_error_file_print(main->error, F_status_set_fine(setting->status), "f_file_stream_open", F_true, args[main->parameters.array[fss_basic_list_read_parameter_to_file_e].values.array[0]], f_file_operation_open_s, fll_error_file_type_file_e);
+
+ return;
+ }
+
+ setting->flag |= fss_basic_list_read_main_flag_file_to_e;
+ }
+ else {
+ fss_basic_list_read_print_error_parameter_file_name_empty(main, setting, main->parameters.array[fss_basic_list_read_parameter_to_file_e].values.array[0]);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+ else if (main->parameters.array[fss_basic_list_read_parameter_to_file_e].result == f_console_result_found_e) {
+ fss_basic_list_read_print_error_no_value(main, setting, fss_basic_list_read_long_to_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ main->output.to = main->message.to;
+
+ if (setting->flag & fss_basic_list_read_main_flag_file_to_e) {
+ setting->flag -= fss_basic_list_read_main_flag_file_to_e;
+ }
+ }
+
+ if (main->parameters.array[fss_basic_list_read_parameter_from_file_e].result == f_console_result_additional_e) {
+ setting->path_files_from.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(main->parameters.array[fss_basic_list_read_parameter_from_file_e].values.used, &setting->path_files_from);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_from.used = main->parameters.array[fss_basic_list_read_parameter_from_file_e].values.used;
+
+ f_array_length_t i = 0;
+ f_array_length_t index = 0;
+
+ for (; i < setting->path_files_from.used; ++i) {
+
+ index = main->parameters.array[fss_basic_list_read_parameter_from_file_e].values.array[i];
+ setting->path_files_from.array[i].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[index], &setting->path_files_from.array[i]);
+ if (F_status_is_error(setting->status)) return;
+
+ if (args[index].used) {
+ if (f_file_exists(args[index], F_true) != F_true) {
+ fss_basic_list_read_print_error_parameter_file_not_found(main, setting, F_true, args[index]);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_file_found_not);
+ }
+ }
+ }
+ else {
+ fss_basic_list_read_print_error_parameter_file_name_empty(main, setting, index);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_parameter);
+ }
+ }
+ } // for
+
+ if (F_status_is_error(setting->status)) return;
+
+ setting->flag |= fss_basic_list_read_main_flag_file_from_e;
+ }
+ else if (main->parameters.array[fss_basic_list_read_parameter_from_file_e].result == f_console_result_found_e) {
+ fss_basic_list_read_print_error_no_value(main, setting, fss_basic_list_read_long_from_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ if (setting->flag & fss_basic_list_read_main_flag_file_from_e) {
+ setting->flag -= fss_basic_list_read_main_flag_file_from_e;
+ }
+ }
+
+ if (F_status_is_error(setting->status)) return;
+
+ if (main->parameters.array[fss_basic_list_read_parameter_from_file_e].result == f_console_result_none_e && !((main->pipe & fll_program_data_pipe_input_e) || main->parameters.remaining.used)) {
+ fss_basic_list_read_print_error_no_from(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+ }
+
+ if (!(setting->mode & fss_basic_list_read_mode_to_bytesequence_e)) {
+ if (main->parameters.array[fss_basic_list_read_parameter_separate_e].result == f_console_result_found_e || main->parameters.array[fss_basic_list_read_parameter_headers_e].result == f_console_result_found_e) {
+ setting->prepend = fss_basic_list_read_string_prepend_padding_s;
+ setting->append = f_string_eol_s;
+ }
+ else {
+ setting->prepend = f_string_space_s;
+ }
+ }
+
+ if (main->parameters.array[fss_basic_list_read_parameter_headers_e].result == f_console_result_found_e) {
+ setting->flag |= fss_basic_list_read_main_flag_header_e;
+ }
+
+ if (main->parameters.array[fss_basic_list_read_parameter_separate_e].result == f_console_result_found_e) {
+ setting->flag |= fss_basic_list_read_main_flag_separate_e;
+ }
+
+ if (main->parameters.array[fss_basic_list_read_parameter_strip_invalid_e].result == f_console_result_found_e) {
+ setting->flag |= fss_basic_list_read_main_flag_strip_invalid_e;
+ }
+
+ setting->valid_not = main->message.set->error;
+ }
+#endif // _di_fss_basic_list_read_setting_load_
+
+#ifndef _di_fss_basic_list_read_setting_unload_
+ f_status_t fss_basic_list_read_setting_unload(fll_program_data_t * const main, fss_basic_list_read_setting_t * const setting) {
+
+ if (!main || !setting) return F_status_set_error(F_parameter);
+
+ fss_basic_list_read_setting_delete(setting);
+
+ return F_none;
+ }
+#endif // _di_fss_basic_list_read_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
};
#endif // _di_fss_basic_list_read_delimit_modes_
+/**
+ * Flags used to represent flags passed to the main function.
+ *
+ * fss_basic_list_read_main_flag_*_e:
+ * - none: No modes in use.
+ * - file_from: Using a specified source file.
+ * - file_to: Using a specified destination file.
+ * - help: Print help.
+ * - header: Enable printing of headers.
+ * - separate: Enable printing of separators.
+ * - strip_invalid: Using strip invalid character mode.
+ * - verify: Using verify mode.
+ * - version: Print version.
+ */
+#ifndef _di_fss_basic_list_read_main_flag_e_
+ enum {
+ fss_basic_list_read_main_flag_none_e = 0x0,
+ fss_basic_list_read_main_flag_file_from_e = 0x1,
+ fss_basic_list_read_main_flag_file_to_e = 0x2,
+ fss_basic_list_read_main_flag_header_e = 0x4,
+ fss_basic_list_read_main_flag_help_e = 0x8,
+ fss_basic_list_read_main_flag_separate_e = 0x10,
+ fss_basic_list_read_main_flag_strip_invalid_e = 0x20,
+ fss_basic_list_read_main_flag_verify_e = 0x40,
+ fss_basic_list_read_main_flag_version_e = 0x80,
+ };
+#endif // _di_fss_basic_list_read_main_flag_e_
+
+/**
+ * The fss basic list read main program settings.
+ *
+ * This is passed to the program-specific main entry point to designate program settings.
+ * These program settings are often processed from the program arguments (often called the command line arguments).
+ *
+ * flag: Flags passed to the main function.
+ *
+ * status: The main status code, generally used by the load settings and main functions.
+ *
+ * line_first: A string expected to represent either "\n" or NULL to allow for easy handling of when to print first new line or not.
+ * line_last: A string expected to represent either "\n" or NULL to allow for easy handling of when to print last new line or not.
+ */
+#ifndef _di_fss_basic_list_read_setting_t_
+ typedef struct {
+ uint16_t flag;
+
+ f_status_t status;
+
+ f_string_static_t line_first;
+ f_string_static_t line_last;
+ } fss_basic_list_read_setting_t;
+
+ #define fss_basic_list_read_setting_t_initialize \
+ { \
+ fss_basic_list_read_main_flag_none_e, \
+ F_none, \
+ f_string_static_t_initialize, \
+ f_string_static_t_initialize, \
+ }
+#endif // _di_fss_basic_list_read_setting_t_
+
+/**
+ * Delete the program main setting data.
+ *
+ * @param setting
+ * The program main setting data.
+ * This does not alter setting.status.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fss_basic_list_read_setting_delete_
+ extern f_status_t fss_basic_list_read_setting_delete(fss_basic_list_read_setting_t * const setting);
+#endif // _di_fss_basic_list_read_setting_delete_
+
+/**
+ * Perform the standard program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately retuns without doing anything.
+ *
+ * @param arguments
+ * The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ *
+ * This alters setting.status:
+ * F_none on success.
+ *
+ * Errors (with error bit) from: f_console_parameter_process().
+ * Errors (with error bit) from: fll_program_parameter_process_context().
+ *
+ * @see f_console_parameter_process()
+ * @see fll_program_parameter_process_context()
+ */
+#ifndef _di_fss_basic_list_read_setting_load_
+ extern void fss_basic_list_read_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_basic_list_read_setting_t * const setting);
+#endif // _di_fss_basic_list_read_setting_load_
+
+/**
+ * Perform the standard program setting unload process.
+ *
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * All buffers are deallocated.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: utf8_setting_delete().
+ *
+ * @see utf8_setting_delete()
+ */
+#ifndef _di_fss_basic_list_read_setting_unload_
+ extern f_status_t fss_basic_list_read_setting_unload(fll_program_data_t * const main, fss_basic_list_read_setting_t * const setting);
+#endif // _di_fss_basic_list_read_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern "C" {
#endif
-#ifndef _di_fss_basic_list_read_print_help_
- f_status_t fss_basic_list_read_print_help(const f_file_t file, const f_color_context_t context) {
-
- flockfile(file.stream);
-
- //if (!(setting->flag & XXX_main_flag_line_first_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- fll_program_print_help_header(file, context, fss_basic_list_read_program_name_long_s, fss_basic_list_read_program_version_s);
-
- fll_program_print_help_option_standard(file, context);
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, fss_basic_list_read_short_at_s, fss_basic_list_read_long_at_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric index.");
- fll_program_print_help_option(file, context, fss_basic_list_read_short_content_s, fss_basic_list_read_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Content (default).");
- fll_program_print_help_option(file, context, fss_basic_list_read_short_columns_s, fss_basic_list_read_long_columns_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of columns.");
- fll_program_print_help_option(file, context, fss_basic_list_read_short_delimit_s, fss_basic_list_read_long_delimit_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Designate how to handle applying delimits.");
- fll_program_print_help_option(file, context, fss_basic_list_read_short_depth_s, fss_basic_list_read_long_depth_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric depth.");
- fll_program_print_help_option(file, context, fss_basic_list_read_short_empty_s, fss_basic_list_read_long_empty_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Include empty Content when processing.");
- fll_program_print_help_option(file, context, fss_basic_list_read_short_line_s, fss_basic_list_read_long_line_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print only the Content at the given line.");
- fll_program_print_help_option(file, context, fss_basic_list_read_short_name_s, fss_basic_list_read_long_name_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object with this name.");
- fll_program_print_help_option(file, context, fss_basic_list_read_short_object_s, fss_basic_list_read_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Object.");
- fll_program_print_help_option(file, context, fss_basic_list_read_short_pipe_s, fss_basic_list_read_long_pipe_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print using the special pipe format.");
- fll_program_print_help_option(file, context, fss_basic_list_read_short_original_s, fss_basic_list_read_long_original_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print with the original quotes and escapes.");
- fll_program_print_help_option(file, context, fss_basic_list_read_short_select_s, fss_basic_list_read_long_select_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select sub-Content at this index.");
- fll_program_print_help_option(file, context, fss_basic_list_read_short_total_s, fss_basic_list_read_long_total_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of lines.");
- fll_program_print_help_option(file, context, fss_basic_list_read_short_trim_s, fss_basic_list_read_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names on select or print.");
-
- fll_program_print_help_usage(file, context, fss_basic_list_read_program_name_s, fll_program_parameter_filenames_s);
-
- fl_print_format("%r %[Notes:%]%r", file.stream, f_string_eol_s, context.set.important, context.set.important, f_string_eol_s);
-
- fl_print_format(" This program will print the Content associated with the given Object and Content main based on the FSS-0002 Basic List standard.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" All numeric positions (indexes) start at 0 instead of 1.%r", file.stream, f_string_eol_s);
- fl_print_format(" For example, a file of 17 lines would range from 0 to 16.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When using the %[%r%r%] option, an order of operations is enforced on the parameters.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_depth_s, context.set.notable, f_string_eol_s);
-
- fl_print_format(" When this order of operations is in effect, parameters to the right of a depth parameter are influenced by that depth parameter:%r", file.stream, f_string_eol_s);
-
- fl_print_format(" %[%r%r%]: An Object index at the specified depth.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_at_s, context.set.notable, f_string_eol_s);
- fl_print_format(" %[%r%r%]: A new depth within the specified depth, indexed from the root.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_depth_s, context.set.notable, f_string_eol_s);
- fl_print_format(" %[%r%r%]: An Object name at the specified depth.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_name_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%] must be in numeric order, but values in between may be skipped.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_depth_s, context.set.notable, f_string_eol_s);
- fl_print_format(" ('-d 0 -a 1 -d 2 -a 2' would specify index 1 at depth 0, any index at depth 1, and index 2 at depth 2.)%r", file.stream, f_string_eol_s);
- fl_print_format(" ('-d 2 -a 1 -d 0 -a 2' would be invalid because depth 2 is before depth 1.)%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%] selects a Content column.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_select_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" Specify both %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_object_s, context.set.notable);
- fl_print_format(" and the %[%r%r%] parameters to get the total objects.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_total_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When both %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_at_s, context.set.notable);
- fl_print_format(" and %[%r%r%] parameters are specified (at the same depth),", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_name_s, context.set.notable);
- fl_print_format(" the %[%r%r%] parameter value will be treated as a position relative to the specified", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_at_s, context.set.notable);
- fl_print_format(" %[%r%r%] parameter value.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_name_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" This program may support parameters, such as %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_depth_s, context.set.notable);
- fl_print_format(" or %[%r%r%], even if not supported by the standard.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_select_s, context.set.notable, f_string_eol_s);
- fl_print_format(" This is done to help ensure consistency for scripting.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" For parameters like %[%r%r%],", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_depth_s, context.set.notable);
- fl_print_format(" if the standard doesn't support nested Content, then only a depth of 0 would be valid.%r", file.stream, f_string_eol_s);
-
- fl_print_format(" For parameters like %[%r%r%],", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_select_s, context.set.notable);
- fl_print_format(" if the standard doesn't support multiple Content groups, then only a select of 0 would be valid.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_trim_s, context.set.notable);
- fl_print_format(" will remove leading and trailing white spaces when selecting objects or when printing objects.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When specifying both the %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_object_s, context.set.notable);
- fl_print_format(" parameter and the %[%r%r%] parameter, the entire Object and Content are printed, including the formatting.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_content_s, context.set.notable, f_string_eol_s);
- fl_print_format(" Both the Object and Content printed are already escaped.%r", file.stream, f_string_eol_s);
- fl_print_format(" Both the Object and Content are separated by a New Line character '\\n' (U+000A).%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%] accepts the following:%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_delimit_s, context.set.notable, f_string_eol_s);
- fl_print_format(" - %[%r%]: Do not apply delimits.%r", file.stream, context.set.notable, fss_basic_list_read_delimit_mode_name_none_s, context.set.notable, f_string_eol_s);
- fl_print_format(" - %[%r%]: (default) Apply all delimits.%r", file.stream, context.set.notable, fss_basic_list_read_delimit_mode_name_all_s, context.set.notable, f_string_eol_s);
- fl_print_format(" - %[%r%]: Apply delimits for Objects.%r", file.stream, context.set.notable, fss_basic_list_read_delimit_mode_name_object_s, context.set.notable, f_string_eol_s);
- fl_print_format(" - A number, 0 or greater: apply delimits for Content at the specified depth.%r", file.stream, f_string_eol_s);
- fl_print_format(" - A number, 0 or greater, followed by a %[%r%]: (such as '1+') apply delimits for Content at the specified depth and any greater depth (numerically).%r", file.stream, context.set.notable, fss_basic_list_read_delimit_mode_name_greater_s, context.set.notable, f_string_eol_s, f_string_eol_s);
- fl_print_format(" - A number, 0 or lesser, followed by a %[%r%]: (such as '1-') apply delimits for Content at the specified depth and any lesser depth (numerically).%r%r", file.stream, context.set.notable, fss_basic_list_read_delimit_mode_name_lesser_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The %[%r%r%] parameter may be specified multiple times to customize the delimit behavior.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_delimit_s, context.set.notable, f_string_eol_s);
-
- fl_print_format(" The %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_delimit_s, context.set.notable);
- fl_print_format(" values %[%r%]", file.stream, context.set.notable, fss_basic_list_read_delimit_mode_name_none_s, context.set.notable);
- fl_print_format(" and %[%r%],", file.stream, context.set.notable, fss_basic_list_read_delimit_mode_name_all_s, context.set.notable);
- fl_print_format(" overrule all other delimit values.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameters %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_columns_s, context.set.notable);
- fl_print_format(" and %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_select_s, context.set.notable);
- fl_print_format(" refer to a Content column.%r", file.stream, f_string_eol_s);
- fl_print_format(" The word \"column\" is being loosely defined to refer to a specific Content.%r", file.stream, f_string_eol_s);
- fl_print_format(" This is not to be confused with a depth.%r", file.stream, f_string_eol_s);
-
- //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- f_file_stream_flush(file);
- funlockfile(file.stream);
-
- return F_none;
- }
-#endif // _di_fss_basic_list_read_print_help_
-
#ifndef _di_fss_basic_list_read_main_
- f_status_t fss_basic_list_read_main(fll_program_data_t * const main, const f_console_arguments_t arguments) {
+ f_status_t fss_basic_list_read_main(fll_program_data_t * const main, fss_basic_list_read_setting_t * const setting) {
f_status_t status = F_none;
status = F_none;
if (main->parameters.array[fss_basic_list_read_parameter_help_e].result == f_console_result_found_e) {
- fss_basic_list_read_print_help(main->output.to, main->context);
+ fss_basic_list_read_print_help(setting, main->message);
return status;
}
if (main->parameters.array[fss_basic_list_read_parameter_version_e].result == f_console_result_found_e) {
- fll_program_print_version(main->output.to, fss_basic_list_read_program_version_s);
+ fll_program_print_version(main->message, fss_basic_list_read_program_version_s);
return status;
}
if (!((++main->signal_check) % fss_basic_list_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_list_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
if (!((++main->signal_check) % fss_basic_list_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_list_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
// The signal check is always performed on each pass.
if (size_file > fss_basic_list_read_block_max && fll_program_standard_signal_received(main)) {
- fss_basic_list_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
#endif
/**
- * Print help.
- *
- * @param file
- * The file to print to.
- * @param context
- * The color context settings.
- *
- * @return
- * F_none on success.
- */
-#ifndef _di_fss_basic_list_read_print_help_
- extern f_status_t fss_basic_list_read_print_help(const f_file_t file, const f_color_context_t context);
-#endif // _di_fss_basic_list_read_print_help_
-
-/**
* Execute main program.
*
* If main.signal is non-zero, then this blocks and handles the following signals:
* Status codes (with error bit) are returned on any problem.
*/
#ifndef _di_fss_basic_list_read_main_
- extern f_status_t fss_basic_list_read_main(fll_program_data_t * const main, const f_console_arguments_t arguments);
+ extern f_status_t fss_basic_list_read_main(fll_program_data_t * const main, fss_basic_list_read_setting_t * const setting);
#endif // _di_fss_basic_list_read_main_
#ifdef __cplusplus
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
fll_program_data_t data = fll_program_data_t_initialize;
+ fss_basic_list_read_setting_t setting = fss_basic_list_read_setting_t_initialize;
f_console_parameter_t parameters[] = fss_basic_list_read_console_parameter_t_initialize;
data.parameters.array = parameters;
data.parameters.used = fss_basic_list_read_total_parameters_d;
+ data.environment = envp;
if (f_pipe_input_exists()) {
data.pipe = fll_program_data_pipe_input_e;
fll_program_standard_set_up(&data);
- const f_status_t status = fss_basic_list_read_main(&data, arguments);
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+
+ fss_basic_list_read_setting_load(arguments, &data, &setting);
+ }
+
+ fss_basic_list_read_main(&data, &setting);
+
+ fss_basic_list_read_setting_unload(&data, &setting);
fll_program_data_delete(&data);
fll_program_standard_set_down(&data);
- if (F_status_is_error(status)) return 1;
-
- return 0;
+ return F_status_is_error(status) ? 1 : 0;
}
--- /dev/null
+#include "fss_basic_list_read.h"
+#include "private-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fss_basic_list_read_print_help_
+ f_status_t fss_basic_list_read_print_help(utf8_setting_t * const setting, const fl_print_t print) {
+
+ f_file_stream_lock(print.to);
+
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+
+ fll_program_print_help_header(print, fss_basic_list_read_program_name_long_s, fss_basic_list_read_program_version_s);
+
+ fll_program_print_help_option_standard(print);
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, fss_basic_list_read_short_at_s, fss_basic_list_read_long_at_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric index.");
+ fll_program_print_help_option(print, fss_basic_list_read_short_content_s, fss_basic_list_read_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Content (default).");
+ fll_program_print_help_option(print, fss_basic_list_read_short_columns_s, fss_basic_list_read_long_columns_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of columns.");
+ fll_program_print_help_option(print, fss_basic_list_read_short_delimit_s, fss_basic_list_read_long_delimit_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Designate how to handle applying delimits.");
+ fll_program_print_help_option(print, fss_basic_list_read_short_depth_s, fss_basic_list_read_long_depth_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric depth.");
+ fll_program_print_help_option(print, fss_basic_list_read_short_empty_s, fss_basic_list_read_long_empty_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Include empty Content when processing.");
+ fll_program_print_help_option(print, fss_basic_list_read_short_line_s, fss_basic_list_read_long_line_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print only the Content at the given line.");
+ fll_program_print_help_option(print, fss_basic_list_read_short_name_s, fss_basic_list_read_long_name_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object with this name.");
+ fll_program_print_help_option(print, fss_basic_list_read_short_object_s, fss_basic_list_read_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Object.");
+ fll_program_print_help_option(print, fss_basic_list_read_short_pipe_s, fss_basic_list_read_long_pipe_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print using the special pipe format.");
+ fll_program_print_help_option(print, fss_basic_list_read_short_original_s, fss_basic_list_read_long_original_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print with the original quotes and escapes.");
+ fll_program_print_help_option(print, fss_basic_list_read_short_select_s, fss_basic_list_read_long_select_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select sub-Content at this index.");
+ fll_program_print_help_option(print, fss_basic_list_read_short_total_s, fss_basic_list_read_long_total_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of lines.");
+ fll_program_print_help_option(print, fss_basic_list_read_short_trim_s, fss_basic_list_read_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names on select or print.");
+
+ fll_program_print_help_usage(print, fss_basic_list_read_program_name_s, fll_program_parameter_filenames_s);
+
+ fl_print_format("%r %[Notes:%]%r", print.to.stream, f_string_eol_s, print.set->important, print.set->important, f_string_eol_s);
+
+ fl_print_format(" This program will print the Content associated with the given Object and Content main based on the FSS-0002 Basic List standard.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" All numeric positions (indexes) start at 0 instead of 1.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" For example, a file of 17 lines would range from 0 to 16.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When using the %[%r%r%] option, an order of operations is enforced on the parameters.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_depth_s, print.set->notable, f_string_eol_s);
+
+ fl_print_format(" When this order of operations is in effect, parameters to the right of a depth parameter are influenced by that depth parameter:%r", print.to.stream, f_string_eol_s);
+
+ fl_print_format(" %[%r%r%]: An Object index at the specified depth.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_at_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" %[%r%r%]: A new depth within the specified depth, indexed from the root.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_depth_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" %[%r%r%]: An Object name at the specified depth.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_name_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%] must be in numeric order, but values in between may be skipped.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_depth_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" ('-d 0 -a 1 -d 2 -a 2' would specify index 1 at depth 0, any index at depth 1, and index 2 at depth 2.)%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" ('-d 2 -a 1 -d 0 -a 2' would be invalid because depth 2 is before depth 1.)%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%] selects a Content column.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_select_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" Specify both %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_object_s, print.set->notable);
+ fl_print_format(" and the %[%r%r%] parameters to get the total objects.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_total_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When both %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_at_s, print.set->notable);
+ fl_print_format(" and %[%r%r%] parameters are specified (at the same depth),", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_name_s, print.set->notable);
+ fl_print_format(" the %[%r%r%] parameter value will be treated as a position relative to the specified", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_at_s, print.set->notable);
+ fl_print_format(" %[%r%r%] parameter value.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_name_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" This program may support parameters, such as %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_depth_s, print.set->notable);
+ fl_print_format(" or %[%r%r%], even if not supported by the standard.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_select_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" This is done to help ensure consistency for scripting.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" For parameters like %[%r%r%],", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_depth_s, print.set->notable);
+ fl_print_format(" if the standard doesn't support nested Content, then only a depth of 0 would be valid.%r", print.to.stream, f_string_eol_s);
+
+ fl_print_format(" For parameters like %[%r%r%],", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_select_s, print.set->notable);
+ fl_print_format(" if the standard doesn't support multiple Content groups, then only a select of 0 would be valid.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_trim_s, print.set->notable);
+ fl_print_format(" will remove leading and trailing white spaces when selecting objects or when printing objects.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When specifying both the %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_object_s, print.set->notable);
+ fl_print_format(" parameter and the %[%r%r%] parameter, the entire Object and Content are printed, including the formatting.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_content_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" Both the Object and Content printed are already escaped.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" Both the Object and Content are separated by a New Line character '\\n' (U+000A).%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%] accepts the following:%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_delimit_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" - %[%r%]: Do not apply delimits.%r", print.to.stream, print.set->notable, fss_basic_list_read_delimit_mode_name_none_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" - %[%r%]: (default) Apply all delimits.%r", print.to.stream, print.set->notable, fss_basic_list_read_delimit_mode_name_all_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" - %[%r%]: Apply delimits for Objects.%r", print.to.stream, print.set->notable, fss_basic_list_read_delimit_mode_name_object_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" - A number, 0 or greater: apply delimits for Content at the specified depth.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" - A number, 0 or greater, followed by a %[%r%]: (such as '1+') apply delimits for Content at the specified depth and any greater depth (numerically).%r", print.to.stream, print.set->notable, fss_basic_list_read_delimit_mode_name_greater_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+ fl_print_format(" - A number, 0 or lesser, followed by a %[%r%]: (such as '1-') apply delimits for Content at the specified depth and any lesser depth (numerically).%r%r", print.to.stream, print.set->notable, fss_basic_list_read_delimit_mode_name_lesser_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The %[%r%r%] parameter may be specified multiple times to customize the delimit behavior.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_delimit_s, print.set->notable, f_string_eol_s);
+
+ fl_print_format(" The %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_delimit_s, print.set->notable);
+ fl_print_format(" values %[%r%]", print.to.stream, print.set->notable, fss_basic_list_read_delimit_mode_name_none_s, print.set->notable);
+ fl_print_format(" and %[%r%],", print.to.stream, print.set->notable, fss_basic_list_read_delimit_mode_name_all_s, print.set->notable);
+ fl_print_format(" overrule all other delimit values.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameters %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_columns_s, print.set->notable);
+ fl_print_format(" and %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_read_long_select_s, print.set->notable);
+ fl_print_format(" refer to a Content column.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" The word \"column\" is being loosely defined to refer to a specific Content.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" This is not to be confused with a depth.%r", print.to.stream, f_string_eol_s);
+
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+
+ f_file_stream_flush(print.to);
+ f_file_stream_unlock(print.to);
+
+ return F_none;
+ }
+#endif // _di_fss_basic_list_read_print_help_
+
+#ifndef _di_fss_basic_list_read_print_line_first_
+ void fss_basic_list_read_print_line_first(fss_basic_list_read_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ }
+#endif // _di_fss_basic_list_read_print_line_first_
+
+#ifndef _di_fss_basic_list_read_print_line_last_
+ void fss_basic_list_read_print_line_last(fss_basic_list_read_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+ if (print.verbosity == f_console_verbosity_error_e && !F_status_is_error(setting->status)) return;
+ if (setting->flag & fss_basic_list_read_main_flag_verify_e) return;
+ if ((setting->flag & fss_basic_list_read_main_flag_file_to_e) && !F_status_is_error(setting->status)) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ }
+#endif // _di_fss_basic_list_read_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: UTF-8
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _fss_basic_list_read_print_h
+#define _fss_basic_list_read_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print help.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * The output structure to print to.
+ *
+ * @return
+ * F_none on success.
+ */
+#ifndef _di_fss_basic_list_read_print_help_
+ extern f_status_t fss_basic_list_read_print_help(fss_basic_list_read_setting_t * const setting, const fl_print_t print);
+#endif // _di_fss_basic_list_read_print_help_
+
+/**
+ * Print first new line, unless verbosity says otherwise.
+ *
+ * This is generally either the first line in the program or the first line printed before an error message.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_basic_list_read_print_line_first_
+ extern void fss_basic_list_read_print_line_first(fss_basic_list_read_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_basic_list_read_print_line_first_
+
+/**
+ * Print last new line when the main is complete, unless verbosity says otherwise.
+ *
+ * This is generally the very last line printed in the program.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_basic_list_read_print_line_last_
+ extern void fss_basic_list_read_print_line_last(fss_basic_list_read_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_basic_list_read_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _fss_basic_list_read_print_h
}
#endif // _di_fss_basic_list_read_depths_resize_
-#ifndef _di_fss_basic_list_read_print_signal_received_
- void fss_basic_list_read_print_signal_received(fll_program_data_t * const main) {
-
- if (main->warning.verbosity != f_console_verbosity_verbose_e && main->warning.verbosity != f_console_verbosity_debug_e) return;
-
- // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
- fflush(main->warning.to.stream);
-
- flockfile(main->warning.to.stream);
-
- fl_print_format("%]%r%r%[Received signal code %]", main->warning.to.stream, main->context.set.reset, f_string_eol_s, f_string_eol_s, main->context.set.warning, main->context.set.warning);
- fl_print_format("%[%i%]", main->warning.to.stream, main->context.set.notable, main->signal_received, main->context.set.notable);
- fl_print_format("%[.%]%r", main->warning.to.stream, main->context.set.warning, main->context.set.warning, f_string_eol_s);
-
- funlockfile(main->warning.to.stream);
- }
-#endif // _di_fss_basic_list_read_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
extern f_status_t fss_basic_list_read_depths_resize(const f_array_length_t length, fss_basic_list_read_depths_t *depths) F_attribute_visibility_internal_d;
#endif // _di_fss_basic_list_read_depths_resize_
-/**
- * Print a message about a process signal being recieved, such as an interrupt signal.
- *
- * @param main
- * The main program data.
- */
-#ifndef _di_fss_basic_list_read_print_signal_received_
- extern void fss_basic_list_read_print_signal_received(fll_program_data_t * const main) F_attribute_visibility_internal_d;
-#endif // _di_fss_basic_list_read_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
if (!((++main->signal_check) % fss_basic_list_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_list_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (!((++main->signal_check) % fss_basic_list_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_list_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (!((++main->signal_check) % fss_basic_list_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_list_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (!((++main->signal_check) % fss_basic_list_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_list_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (!((++main->signal_check) % fss_basic_list_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_list_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (!((++main->signal_check) % fss_basic_list_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_list_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (!((++main->signal_check) % fss_basic_list_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_list_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (!((++main->signal_check) % fss_basic_list_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_list_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library fss_basic_list_read.c common.c private-common.c private-print.c private-read.c
+build_sources_library fss_basic_list_read.c common.c print.c private-common.c private-print.c private-read.c
build_sources_program main.c
-build_sources_headers fss_basic_list_read.h common.h
+build_sources_headers fss_basic_list_read.h common.h print.h
build_script yes
build_shared yes
const f_string_static_t fss_basic_list_write_long_trim_s = macro_f_string_static_t_initialize(FSS_BASIC_LIST_WRITE_long_trim_s, 0, FSS_BASIC_LIST_WRITE_long_trim_s_length);
#endif // _di_fss_basic_list_write_parameters_
+#ifndef _di_fss_basic_list_write_setting_delete_
+ f_status_t fss_basic_list_write_setting_delete(fss_basic_list_write_setting_t * const setting) {
+
+ if (!setting) return F_status_set_error(F_parameter);
+
+ return F_none;
+ }
+#endif // _di_fss_basic_list_write_setting_delete_
+
+#ifndef _di_fss_basic_list_write_setting_load_
+ void fss_basic_list_write_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_basic_list_write_setting_t * const setting) {
+
+ if (!main || !setting) return;
+
+ // Load parameters.
+ setting->status = f_console_parameter_process(arguments, &main->parameters);
+ if (F_status_is_error(setting->status)) return;
+
+ {
+ f_array_length_t choice = 0;
+ f_uint16s_t choices = f_uint16s_t_initialize;
+
+ // Identify and prioritize "color context" parameters.
+ {
+ uint16_t choices_array[3] = { fss_basic_list_write_parameter_no_color_e, fss_basic_list_write_parameter_light_e, fss_basic_list_write_parameter_dark_e };
+ choices.array = choices_array;
+ choices.used = 3;
+
+ const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
+
+ setting->status = fll_program_parameter_process_context(choices, modes, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_basic_list_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_context", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_basic_list_write_parameter_line_first_no_e].result == f_console_result_found_e) {
+ setting->line_first = f_string_empty_s;
+ }
+ else {
+ setting->line_first = f_string_eol_s;
+ }
+
+ if (main->parameters.array[fss_basic_list_write_parameter_line_last_no_e].result == f_console_result_found_e) {
+ setting->line_last = f_string_empty_s;
+ }
+ else {
+ setting->line_last = f_string_eol_s;
+ }
+
+ // Identify and prioritize "verbosity" parameters.
+ {
+ uint16_t choices_array[5] = { fss_basic_list_write_parameter_verbosity_quiet_e, fss_basic_list_write_parameter_verbosity_error_e, fss_basic_list_write_parameter_verbosity_verbose_e, fss_basic_list_write_parameter_verbosity_debug_e, fss_basic_list_write_parameter_verbosity_normal_e };
+ choices.array = choices_array;
+ choices.used = 5;
+
+ const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+
+ setting->status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_basic_list_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_verbosity", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_basic_list_write_parameter_help_e].result == f_console_result_found_e) {
+ setting->flag |= fss_basic_list_write_main_flag_help_e;
+
+ return;
+ }
+
+ if (main->parameters.array[fss_basic_list_write_parameter_version_e].result == f_console_result_found_e) {
+ setting->flag |= fss_basic_list_write_main_flag_version_e;
+
+ return;
+ }
+
+ // Identify and prioritize "from" mode parameters.
+ {
+ uint16_t choices_array[2] = { fss_basic_list_write_parameter_from_bytesequence_e, fss_basic_list_write_parameter_from_codepoint_e };
+ choices.array = choices_array;
+ choices.used = 2;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_basic_list_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_basic_list_write_parameter_from_bytesequence_e) {
+ if (setting->mode & fss_basic_list_write_mode_from_codepoint_e) {
+ setting->mode -= fss_basic_list_write_mode_from_codepoint_e;
+ }
+
+ setting->mode |= fss_basic_list_write_mode_from_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_basic_list_write_parameter_from_codepoint_e) {
+ if (setting->mode & fss_basic_list_write_mode_from_bytesequence_e) {
+ setting->mode -= fss_basic_list_write_mode_from_bytesequence_e;
+ }
+
+ setting->mode |= fss_basic_list_write_mode_from_codepoint_e;
+ }
+ }
+
+ // Identify and prioritize "to" mode parameters.
+ {
+ uint16_t choices_array[4] = { fss_basic_list_write_parameter_to_bytesequence_e, fss_basic_list_write_parameter_to_codepoint_e, fss_basic_list_write_parameter_to_combining_e, fss_basic_list_write_parameter_to_width_e };
+ choices.array = choices_array;
+ choices.used = 4;
+ choice = 1;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_basic_list_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_basic_list_write_parameter_to_bytesequence_e) {
+ if (setting->mode & fss_basic_list_write_mode_to_codepoint_e) {
+ setting->mode -= fss_basic_list_write_mode_to_codepoint_e;
+ }
+
+ if (setting->mode & fss_basic_list_write_mode_to_combining_e) {
+ setting->mode -= fss_basic_list_write_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_basic_list_write_mode_to_width_e) {
+ setting->mode -= fss_basic_list_write_mode_to_width_e;
+ }
+
+ setting->mode |= fss_basic_list_write_mode_to_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_basic_list_write_parameter_to_codepoint_e) {
+ if (setting->mode & fss_basic_list_write_mode_to_bytesequence_e) {
+ setting->mode -= fss_basic_list_write_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_basic_list_write_mode_to_combining_e) {
+ setting->mode -= fss_basic_list_write_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_basic_list_write_mode_to_width_e) {
+ setting->mode -= fss_basic_list_write_mode_to_width_e;
+ }
+
+ setting->mode |= fss_basic_list_write_mode_to_codepoint_e;
+ }
+ else if (choices.array[choice] == fss_basic_list_write_parameter_to_combining_e) {
+ if (setting->mode & fss_basic_list_write_mode_to_bytesequence_e) {
+ setting->mode -= fss_basic_list_write_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_basic_list_write_mode_to_codepoint_e) {
+ setting->mode -= fss_basic_list_write_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_basic_list_write_parameter_to_width_e].result == f_console_result_found_e) {
+ setting->mode |= fss_basic_list_write_mode_to_width_e;
+ }
+
+ setting->mode |= fss_basic_list_write_mode_to_combining_e;
+ }
+ else if (choices.array[choice] == fss_basic_list_write_parameter_to_width_e) {
+ if (setting->mode & fss_basic_list_write_mode_to_bytesequence_e) {
+ setting->mode -= fss_basic_list_write_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_basic_list_write_mode_to_codepoint_e) {
+ setting->mode -= fss_basic_list_write_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_basic_list_write_parameter_to_combining_e].result == f_console_result_found_e) {
+ setting->mode |= fss_basic_list_write_mode_to_combining_e;
+ }
+
+ setting->mode |= fss_basic_list_write_mode_to_width_e;
+ }
+ }
+ }
+
+ f_string_static_t * const args = main->parameters.arguments.array;
+
+ if (main->parameters.array[fss_basic_list_write_parameter_to_file_e].result == f_console_result_additional_e) {
+ if (main->parameters.array[fss_basic_list_write_parameter_to_file_e].values.used > 1) {
+ fss_basic_list_write_print_error_parameter_file_to_too_many(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+
+ if (args[main->parameters.array[fss_basic_list_write_parameter_to_file_e].values.array[0]].used) {
+ setting->path_files_to.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(1, &setting->path_files_to);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_to.array[setting->path_files_to.used].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[main->parameters.array[fss_basic_list_write_parameter_to_file_e].values.array[0]], &setting->path_files_to.array[0]);
+ if (F_status_is_error(setting->status)) return;
+
+ ++setting->path_files_to.used;
+
+ setting->status = f_file_stream_open(args[main->parameters.array[fss_basic_list_write_parameter_to_file_e].values.array[0]], f_file_open_mode_append_s, &main->output.to);
+
+ if (F_status_is_error(setting->status)) {
+ fll_error_file_print(main->error, F_status_set_fine(setting->status), "f_file_stream_open", F_true, args[main->parameters.array[fss_basic_list_write_parameter_to_file_e].values.array[0]], f_file_operation_open_s, fll_error_file_type_file_e);
+
+ return;
+ }
+
+ setting->flag |= fss_basic_list_write_main_flag_file_to_e;
+ }
+ else {
+ fss_basic_list_write_print_error_parameter_file_name_empty(main, setting, main->parameters.array[fss_basic_list_write_parameter_to_file_e].values.array[0]);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+ else if (main->parameters.array[fss_basic_list_write_parameter_to_file_e].result == f_console_result_found_e) {
+ fss_basic_list_write_print_error_no_value(main, setting, fss_basic_list_write_long_to_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ main->output.to = main->message.to;
+
+ if (setting->flag & fss_basic_list_write_main_flag_file_to_e) {
+ setting->flag -= fss_basic_list_write_main_flag_file_to_e;
+ }
+ }
+
+ if (main->parameters.array[fss_basic_list_write_parameter_from_file_e].result == f_console_result_additional_e) {
+ setting->path_files_from.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(main->parameters.array[fss_basic_list_write_parameter_from_file_e].values.used, &setting->path_files_from);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_from.used = main->parameters.array[fss_basic_list_write_parameter_from_file_e].values.used;
+
+ f_array_length_t i = 0;
+ f_array_length_t index = 0;
+
+ for (; i < setting->path_files_from.used; ++i) {
+
+ index = main->parameters.array[fss_basic_list_write_parameter_from_file_e].values.array[i];
+ setting->path_files_from.array[i].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[index], &setting->path_files_from.array[i]);
+ if (F_status_is_error(setting->status)) return;
+
+ if (args[index].used) {
+ if (f_file_exists(args[index], F_true) != F_true) {
+ fss_basic_list_write_print_error_parameter_file_not_found(main, setting, F_true, args[index]);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_file_found_not);
+ }
+ }
+ }
+ else {
+ fss_basic_list_write_print_error_parameter_file_name_empty(main, setting, index);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_parameter);
+ }
+ }
+ } // for
+
+ if (F_status_is_error(setting->status)) return;
+
+ setting->flag |= fss_basic_list_write_main_flag_file_from_e;
+ }
+ else if (main->parameters.array[fss_basic_list_write_parameter_from_file_e].result == f_console_result_found_e) {
+ fss_basic_list_write_print_error_no_value(main, setting, fss_basic_list_write_long_from_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ if (setting->flag & fss_basic_list_write_main_flag_file_from_e) {
+ setting->flag -= fss_basic_list_write_main_flag_file_from_e;
+ }
+ }
+
+ if (F_status_is_error(setting->status)) return;
+
+ if (main->parameters.array[fss_basic_list_write_parameter_from_file_e].result == f_console_result_none_e && !((main->pipe & fll_program_data_pipe_input_e) || main->parameters.remaining.used)) {
+ fss_basic_list_write_print_error_no_from(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+ }
+
+ if (!(setting->mode & fss_basic_list_write_mode_to_bytesequence_e)) {
+ if (main->parameters.array[fss_basic_list_write_parameter_separate_e].result == f_console_result_found_e || main->parameters.array[fss_basic_list_write_parameter_headers_e].result == f_console_result_found_e) {
+ setting->prepend = fss_basic_list_write_string_prepend_padding_s;
+ setting->append = f_string_eol_s;
+ }
+ else {
+ setting->prepend = f_string_space_s;
+ }
+ }
+
+ if (main->parameters.array[fss_basic_list_write_parameter_headers_e].result == f_console_result_found_e) {
+ setting->flag |= fss_basic_list_write_main_flag_header_e;
+ }
+
+ if (main->parameters.array[fss_basic_list_write_parameter_separate_e].result == f_console_result_found_e) {
+ setting->flag |= fss_basic_list_write_main_flag_separate_e;
+ }
+
+ if (main->parameters.array[fss_basic_list_write_parameter_strip_invalid_e].result == f_console_result_found_e) {
+ setting->flag |= fss_basic_list_write_main_flag_strip_invalid_e;
+ }
+
+ setting->valid_not = main->message.set->error;
+ }
+#endif // _di_fss_basic_list_write_setting_load_
+
+#ifndef _di_fss_basic_list_write_setting_unload_
+ f_status_t fss_basic_list_write_setting_unload(fll_program_data_t * const main, fss_basic_list_write_setting_t * const setting) {
+
+ if (!main || !setting) return F_status_set_error(F_parameter);
+
+ fss_basic_list_write_setting_delete(setting);
+
+ return F_none;
+ }
+#endif // _di_fss_basic_list_write_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
#define fss_basic_list_write_total_parameters_d 21
#endif // _di_fss_basic_list_write_parameters_
+/**
+ * Flags used to represent flags passed to the main function.
+ *
+ * fss_basic_list_write_main_flag_*_e:
+ * - none: No modes in use.
+ * - file_from: Using a specified source file.
+ * - file_to: Using a specified destination file.
+ * - help: Print help.
+ * - header: Enable printing of headers.
+ * - separate: Enable printing of separators.
+ * - strip_invalid: Using strip invalid character mode.
+ * - verify: Using verify mode.
+ * - version: Print version.
+ */
+#ifndef _di_fss_basic_list_write_main_flag_e_
+ enum {
+ fss_basic_list_write_main_flag_none_e = 0x0,
+ fss_basic_list_write_main_flag_file_from_e = 0x1,
+ fss_basic_list_write_main_flag_file_to_e = 0x2,
+ fss_basic_list_write_main_flag_header_e = 0x4,
+ fss_basic_list_write_main_flag_help_e = 0x8,
+ fss_basic_list_write_main_flag_separate_e = 0x10,
+ fss_basic_list_write_main_flag_strip_invalid_e = 0x20,
+ fss_basic_list_write_main_flag_verify_e = 0x40,
+ fss_basic_list_write_main_flag_version_e = 0x80,
+ };
+#endif // _di_fss_basic_list_write_main_flag_e_
+
+/**
+ * The fss basic list write main program settings.
+ *
+ * This is passed to the program-specific main entry point to designate program settings.
+ * These program settings are often processed from the program arguments (often called the command line arguments).
+ *
+ * flag: Flags passed to the main function.
+ *
+ * status: The main status code, generally used by the load settings and main functions.
+ *
+ * line_first: A string expected to represent either "\n" or NULL to allow for easy handling of when to print first new line or not.
+ * line_last: A string expected to represent either "\n" or NULL to allow for easy handling of when to print last new line or not.
+ */
+#ifndef _di_fss_basic_list_write_setting_t_
+ typedef struct {
+ uint16_t flag;
+
+ f_status_t status;
+
+ f_string_static_t line_first;
+ f_string_static_t line_last;
+ } fss_basic_list_write_setting_t;
+
+ #define fss_basic_list_write_setting_t_initialize \
+ { \
+ fss_basic_list_write_main_flag_none_e, \
+ F_none, \
+ f_string_static_t_initialize, \
+ f_string_static_t_initialize, \
+ }
+#endif // _di_fss_basic_list_write_setting_t_
+
+/**
+ * Delete the program main setting data.
+ *
+ * @param setting
+ * The program main setting data.
+ * This does not alter setting.status.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fss_basic_list_write_setting_delete_
+ extern f_status_t fss_basic_list_write_setting_delete(fss_basic_list_write_setting_t * const setting);
+#endif // _di_fss_basic_list_write_setting_delete_
+
+/**
+ * Perform the standard program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately retuns without doing anything.
+ *
+ * @param arguments
+ * The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ *
+ * This alters setting.status:
+ * F_none on success.
+ *
+ * Errors (with error bit) from: f_console_parameter_process().
+ * Errors (with error bit) from: fll_program_parameter_process_context().
+ *
+ * @see f_console_parameter_process()
+ * @see fll_program_parameter_process_context()
+ */
+#ifndef _di_fss_basic_list_write_setting_load_
+ extern void fss_basic_list_write_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_basic_list_write_setting_t * const setting);
+#endif // _di_fss_basic_list_write_setting_load_
+
+/**
+ * Perform the standard program setting unload process.
+ *
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * All buffers are deallocated.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: utf8_setting_delete().
+ *
+ * @see utf8_setting_delete()
+ */
+#ifndef _di_fss_basic_list_write_setting_unload_
+ extern f_status_t fss_basic_list_write_setting_unload(fll_program_data_t * const main, fss_basic_list_write_setting_t * const setting);
+#endif // _di_fss_basic_list_write_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern "C" {
#endif
-#ifndef _di_fss_basic_list_write_print_help_
- f_status_t fss_basic_list_write_print_help(const f_file_t file, const f_color_context_t context) {
-
- flockfile(file.stream);
-
- //if (!(setting->flag & XXX_main_flag_line_first_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- fll_program_print_help_header(file, context, fss_basic_list_write_program_name_long_s, fss_basic_list_write_program_version_s);
-
- fll_program_print_help_option_standard(file, context);
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, fss_basic_list_write_short_file_s, fss_basic_list_write_long_file_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a file to send data to.");
- fll_program_print_help_option(file, context, fss_basic_list_write_short_content_s, fss_basic_list_write_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "The Content to write.");
- fll_program_print_help_option(file, context, fss_basic_list_write_short_double_s, fss_basic_list_write_long_double_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use double quotes (default).");
- fll_program_print_help_option(file, context, fss_basic_list_write_short_ignore_s, fss_basic_list_write_long_ignore_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Ignore a given range within a Content.");
- fll_program_print_help_option(file, context, fss_basic_list_write_short_object_s, fss_basic_list_write_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The Object to write.");
- fll_program_print_help_option(file, context, fss_basic_list_write_short_partial_s, fss_basic_list_write_long_partial_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Do not write end of Object/Content character.");
- fll_program_print_help_option(file, context, fss_basic_list_write_short_prepend_s, fss_basic_list_write_long_prepend_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Prepend the given white space characters to the start of each multi-line Content.");
- fll_program_print_help_option(file, context, fss_basic_list_write_short_single_s, fss_basic_list_write_long_single_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use single quotes.");
- fll_program_print_help_option(file, context, fss_basic_list_write_short_trim_s, fss_basic_list_write_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names.");
-
- fll_program_print_help_usage(file, context, fss_basic_list_write_program_name_s, f_string_empty_s);
-
- fl_print_format("%r The pipe uses the Backspace character '%[\\b%]' (%[U+0008%]) to designate the start of a Content.%r", file.stream, f_string_eol_s, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" The pipe uses the Form Feed character '%[\\f%]' (%[U+000C%]) to designate the end of the last Content.%r", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" The pipe uses the Vertical Line character '%[\\v%]' (%[U+000B%]) is used to ignore a Content range, which does nothing in this program.%r", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" For the pipe, an Object is terminated by either a Backspace character '%[\\b%]' (%[U+0008%])", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable);
- fl_print_format(" or a Form Feed character '%[\\f%]' (%[U+000C%]).%r", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" The end of the pipe represents the end of any Object or Content.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The FSS-0002 (Basic List) specification does not support quoted names, therefore the parameters '%[%r%r%]'", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_write_long_single_s, context.set.notable);
- fl_print_format(" and '%[%r%r%]' do nothing.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_write_long_double_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" This program does not use the parameter '%[%r%r%]', which therefore does nothing.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_list_write_long_ignore_s, context.set.notable, f_string_eol_s);
- fl_print_format(" This parameter requires two values.%r", file.stream, f_string_eol_s);
-
- //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- f_file_stream_flush(file);
- funlockfile(file.stream);
-
- return F_none;
- }
-#endif // _di_fss_basic_list_write_print_help_
-
#ifndef _di_fss_basic_list_write_main_
- f_status_t fss_basic_list_write_main(fll_program_data_t * const main, const f_console_arguments_t arguments) {
+ f_status_t fss_basic_list_write_main(fll_program_data_t * const main, fss_basic_list_write_setting_t * const setting) {
f_status_t status = F_none;
status = F_none;
if (main->parameters.array[fss_basic_list_write_parameter_help_e].result == f_console_result_found_e) {
- fss_basic_list_write_print_help(main->output.to, main->context);
+ fss_basic_list_write_print_help(setting, main->message);
return status;
}
if (main->parameters.array[fss_basic_list_write_parameter_version_e].result == f_console_result_found_e) {
- fll_program_print_version(main->output.to, fss_basic_list_write_program_version_s);
+ fll_program_print_version(main->message, fss_basic_list_write_program_version_s);
return status;
}
if (!((++main->signal_check) % fss_basic_list_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_list_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
if (!((++main->signal_check) % fss_basic_list_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_list_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
if (!((++main->signal_check) % fss_basic_list_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_list_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
#endif
/**
- * Print help.
- *
- * @param file
- * The file to print to.
- * @param context
- * The color context settings.
- *
- * @return
- * F_none on success.
- */
-#ifndef _di_fss_basic_list_write_print_help_
- extern f_status_t fss_basic_list_write_print_help(const f_file_t file, const f_color_context_t context);
-#endif // _di_fss_basic_list_write_print_help_
-
-/**
* Execute main program.
*
* If main.signal is non-zero, then this blocks and handles the following signals:
*
* @param main
* The main program data.
- * @param arguments
- * The parameters passed to the process.
+ * @param setting
+ * The main program settings.
*
- * @return
- * F_none on success.
+ * This alters setting.status:
+ * F_none on success.
+ * F_true on success when performing verification and verify passed.
+ * F_false on success when performing verification and verify failed.
+ * F_interrupt on (exit) signal received.
*
- * Status codes (with error bit) are returned on any problem.
+ * F_parameter (with error bit) if main is NULL or setting is NULL.
*/
#ifndef _di_fss_basic_list_write_main_
- extern f_status_t fss_basic_list_write_main(fll_program_data_t * const main, const f_console_arguments_t arguments);
+ extern f_status_t fss_basic_list_write_main(fll_program_data_t * const main, fss_basic_list_write_setting_t * const setting);
#endif // _di_fss_basic_list_write_main_
#ifdef __cplusplus
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
fll_program_data_t data = fll_program_data_t_initialize;
+ fss_basic_list_write_setting_t setting = fss_basic_list_write_setting_t_initialize;
f_console_parameter_t parameters[] = fss_basic_list_write_console_parameter_t_initialize;
data.parameters.array = parameters;
data.parameters.used = fss_basic_list_write_total_parameters_d;
+ data.environment = envp;
if (f_pipe_input_exists()) {
data.pipe = fll_program_data_pipe_input_e;
fll_program_standard_set_up(&data);
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+
+ fss_basic_list_write_setting_load(arguments, &data, &setting);
+ }
+
const f_status_t status = fss_basic_list_write_main(&data, arguments);
+ fss_basic_list_write_main(&data, &setting);
+
+ fss_basic_list_write_setting_unload(&data, &setting);
+
fll_program_data_delete(&data);
fll_program_standard_set_down(&data);
- if (F_status_is_error(status)) return 1;
-
- return 0;
+ return F_status_is_error(status) ? 1 : 0;
}
--- /dev/null
+#include "fss_basic_list_write.h"
+#include "private-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fss_basic_list_write_print_help_
+ f_status_t fss_basic_list_write_print_help(utf8_setting_t * const setting, const fl_print_t print) {
+
+ f_file_stream_lock(print.to);
+
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+
+ fll_program_print_help_header(print, fss_basic_list_write_program_name_long_s, fss_basic_list_write_program_version_s);
+
+ fll_program_print_help_option_standard(print);
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, fss_basic_list_write_short_file_s, fss_basic_list_write_long_file_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a file to send data to.");
+ fll_program_print_help_option(print, fss_basic_list_write_short_content_s, fss_basic_list_write_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "The Content to write.");
+ fll_program_print_help_option(print, fss_basic_list_write_short_double_s, fss_basic_list_write_long_double_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use double quotes (default).");
+ fll_program_print_help_option(print, fss_basic_list_write_short_ignore_s, fss_basic_list_write_long_ignore_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Ignore a given range within a Content.");
+ fll_program_print_help_option(print, fss_basic_list_write_short_object_s, fss_basic_list_write_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The Object to write.");
+ fll_program_print_help_option(print, fss_basic_list_write_short_partial_s, fss_basic_list_write_long_partial_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Do not write end of Object/Content character.");
+ fll_program_print_help_option(print, fss_basic_list_write_short_prepend_s, fss_basic_list_write_long_prepend_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Prepend the given white space characters to the start of each multi-line Content.");
+ fll_program_print_help_option(print, fss_basic_list_write_short_single_s, fss_basic_list_write_long_single_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use single quotes.");
+ fll_program_print_help_option(print, fss_basic_list_write_short_trim_s, fss_basic_list_write_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names.");
+
+ fll_program_print_help_usage(print, fss_basic_list_write_program_name_s, f_string_empty_s);
+
+ fl_print_format("%r The pipe uses the Backspace character '%[\\b%]' (%[U+0008%]) to designate the start of a Content.%r", print.to.stream, f_string_eol_s, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" The pipe uses the Form Feed character '%[\\f%]' (%[U+000C%]) to designate the end of the last Content.%r", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" The pipe uses the Vertical Line character '%[\\v%]' (%[U+000B%]) is used to ignore a Content range, which does nothing in this program.%r", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" For the pipe, an Object is terminated by either a Backspace character '%[\\b%]' (%[U+0008%])", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable);
+ fl_print_format(" or a Form Feed character '%[\\f%]' (%[U+000C%]).%r", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" The end of the pipe represents the end of any Object or Content.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The FSS-0002 (Basic List) specification does not support quoted names, therefore the parameters '%[%r%r%]'", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_write_long_single_s, print.set->notable);
+ fl_print_format(" and '%[%r%r%]' do nothing.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_write_long_double_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" This program does not use the parameter '%[%r%r%]', which therefore does nothing.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_list_write_long_ignore_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" This parameter requires two values.%r", print.to.stream, f_string_eol_s);
+
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+
+ f_file_stream_flush(print.to);
+ f_file_stream_unlock(print.to);
+
+ return F_none;
+ }
+#endif // _di_fss_basic_list_write_print_help_
+
+#ifndef _di_fss_basic_list_write_print_line_first_
+ void fss_basic_list_write_print_line_first(fss_basic_list_write_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ }
+#endif // _di_fss_basic_list_write_print_line_first_
+
+#ifndef _di_fss_basic_list_write_print_line_last_
+ void fss_basic_list_write_print_line_last(fss_basic_list_write_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+ if (print.verbosity == f_console_verbosity_error_e && !F_status_is_error(setting->status)) return;
+ if (setting->flag & fss_basic_list_write_main_flag_verify_e) return;
+ if ((setting->flag & fss_basic_list_write_main_flag_file_to_e) && !F_status_is_error(setting->status)) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ }
+#endif // _di_fss_basic_list_write_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: UTF-8
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _fss_basic_list_write_print_h
+#define _fss_basic_list_write_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print help.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * The output structure to print to.
+ *
+ * @return
+ * F_none on success.
+ */
+#ifndef _di_fss_basic_list_write_print_help_
+ extern f_status_t fss_basic_list_write_print_help(fss_basic_list_write_setting_t * const setting, const fl_print_t print);
+#endif // _di_fss_basic_list_write_print_help_
+
+/**
+ * Print first new line, unless verbosity says otherwise.
+ *
+ * This is generally either the first line in the program or the first line printed before an error message.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_basic_list_write_print_line_first_
+ extern void fss_basic_list_write_print_line_first(fss_basic_list_write_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_basic_list_write_print_line_first_
+
+/**
+ * Print last new line when the main is complete, unless verbosity says otherwise.
+ *
+ * This is generally the very last line printed in the program.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_basic_list_write_print_line_last_
+ extern void fss_basic_list_write_print_line_last(fss_basic_list_write_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_basic_list_write_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _fss_basic_list_write_print_h
extern "C" {
#endif
-#ifndef _di_fss_basic_list_write_print_signal_received_
- void fss_basic_list_write_print_signal_received(fll_program_data_t * const main) {
-
- if (main->warning.verbosity != f_console_verbosity_verbose_e && main->warning.verbosity != f_console_verbosity_debug_e) return;
-
- // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
- fflush(main->warning.to.stream);
-
- flockfile(main->warning.to.stream);
-
- fl_print_format("%]%r%r%[Received signal code %]", main->warning.to.stream, main->context.set.reset, f_string_eol_s, f_string_eol_s, main->context.set.warning, main->context.set.warning);
- fl_print_format("%[%i%]", main->warning.to.stream, main->context.set.notable, main->signal_received, main->context.set.notable);
- fl_print_format("%[.%]%r", main->warning.to.stream, main->context.set.warning, main->context.set.warning, f_string_eol_s);
-
- funlockfile(main->warning.to.stream);
- }
-#endif // _di_fss_basic_list_write_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
#define fss_basic_list_write_common_allocation_small_d 128
#endif // _di_fss_basic_list_write_common_
-/**
- * Print a message about a process signal being recieved, such as an interrupt signal.
- *
- * @param main
- * The main program data.
- */
-#ifndef _di_fss_basic_list_write_print_signal_received_
- extern void fss_basic_list_write_print_signal_received(fll_program_data_t * const main) F_attribute_visibility_internal_d;
-#endif // _di_fss_basic_list_write_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
if (!((++main->signal_check) % fss_basic_list_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_list_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library fss_basic_list_write.c common.c private-common.c private-write.c
+build_sources_library fss_basic_list_write.c common.c print.c private-common.c private-write.c
build_sources_program main.c
-build_sources_headers fss_basic_list_write.h common.h
+build_sources_headers fss_basic_list_write.h common.h print.h
build_script yes
build_shared yes
const f_string_static_t fss_basic_read_delimit_mode_name_lesser_s = macro_f_string_static_t_initialize(FSS_BASIC_READ_delimit_mode_name_lesser_s, 0, FSS_BASIC_READ_delimit_mode_name_lesser_s_length);
#endif // _di_fss_basic_read_delimit_mode_
+#ifndef _di_fss_basic_read_setting_delete_
+ f_status_t fss_basic_read_setting_delete(fss_basic_read_setting_t * const setting) {
+
+ if (!setting) return F_status_set_error(F_parameter);
+
+ return F_none;
+ }
+#endif // _di_fss_basic_read_setting_delete_
+
+#ifndef _di_fss_basic_read_setting_load_
+ void fss_basic_read_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_basic_read_setting_t * const setting) {
+
+ if (!main || !setting) return;
+
+ // Load parameters.
+ setting->status = f_console_parameter_process(arguments, &main->parameters);
+ if (F_status_is_error(setting->status)) return;
+
+ {
+ f_array_length_t choice = 0;
+ f_uint16s_t choices = f_uint16s_t_initialize;
+
+ // Identify and prioritize "color context" parameters.
+ {
+ uint16_t choices_array[3] = { fss_basic_read_parameter_no_color_e, fss_basic_read_parameter_light_e, fss_basic_read_parameter_dark_e };
+ choices.array = choices_array;
+ choices.used = 3;
+
+ const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
+
+ setting->status = fll_program_parameter_process_context(choices, modes, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_basic_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_context", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_basic_read_parameter_line_first_no_e].result == f_console_result_found_e) {
+ setting->line_first = f_string_empty_s;
+ }
+ else {
+ setting->line_first = f_string_eol_s;
+ }
+
+ if (main->parameters.array[fss_basic_read_parameter_line_last_no_e].result == f_console_result_found_e) {
+ setting->line_last = f_string_empty_s;
+ }
+ else {
+ setting->line_last = f_string_eol_s;
+ }
+
+ // Identify and prioritize "verbosity" parameters.
+ {
+ uint16_t choices_array[5] = { fss_basic_read_parameter_verbosity_quiet_e, fss_basic_read_parameter_verbosity_error_e, fss_basic_read_parameter_verbosity_verbose_e, fss_basic_read_parameter_verbosity_debug_e, fss_basic_read_parameter_verbosity_normal_e };
+ choices.array = choices_array;
+ choices.used = 5;
+
+ const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+
+ setting->status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_basic_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_verbosity", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_basic_read_parameter_help_e].result == f_console_result_found_e) {
+ setting->flag |= fss_basic_read_main_flag_help_e;
+
+ return;
+ }
+
+ if (main->parameters.array[fss_basic_read_parameter_version_e].result == f_console_result_found_e) {
+ setting->flag |= fss_basic_read_main_flag_version_e;
+
+ return;
+ }
+
+ // Identify and prioritize "from" mode parameters.
+ {
+ uint16_t choices_array[2] = { fss_basic_read_parameter_from_bytesequence_e, fss_basic_read_parameter_from_codepoint_e };
+ choices.array = choices_array;
+ choices.used = 2;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_basic_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_basic_read_parameter_from_bytesequence_e) {
+ if (setting->mode & fss_basic_read_mode_from_codepoint_e) {
+ setting->mode -= fss_basic_read_mode_from_codepoint_e;
+ }
+
+ setting->mode |= fss_basic_read_mode_from_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_basic_read_parameter_from_codepoint_e) {
+ if (setting->mode & fss_basic_read_mode_from_bytesequence_e) {
+ setting->mode -= fss_basic_read_mode_from_bytesequence_e;
+ }
+
+ setting->mode |= fss_basic_read_mode_from_codepoint_e;
+ }
+ }
+
+ // Identify and prioritize "to" mode parameters.
+ {
+ uint16_t choices_array[4] = { fss_basic_read_parameter_to_bytesequence_e, fss_basic_read_parameter_to_codepoint_e, fss_basic_read_parameter_to_combining_e, fss_basic_read_parameter_to_width_e };
+ choices.array = choices_array;
+ choices.used = 4;
+ choice = 1;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_basic_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_basic_read_parameter_to_bytesequence_e) {
+ if (setting->mode & fss_basic_read_mode_to_codepoint_e) {
+ setting->mode -= fss_basic_read_mode_to_codepoint_e;
+ }
+
+ if (setting->mode & fss_basic_read_mode_to_combining_e) {
+ setting->mode -= fss_basic_read_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_basic_read_mode_to_width_e) {
+ setting->mode -= fss_basic_read_mode_to_width_e;
+ }
+
+ setting->mode |= fss_basic_read_mode_to_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_basic_read_parameter_to_codepoint_e) {
+ if (setting->mode & fss_basic_read_mode_to_bytesequence_e) {
+ setting->mode -= fss_basic_read_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_basic_read_mode_to_combining_e) {
+ setting->mode -= fss_basic_read_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_basic_read_mode_to_width_e) {
+ setting->mode -= fss_basic_read_mode_to_width_e;
+ }
+
+ setting->mode |= fss_basic_read_mode_to_codepoint_e;
+ }
+ else if (choices.array[choice] == fss_basic_read_parameter_to_combining_e) {
+ if (setting->mode & fss_basic_read_mode_to_bytesequence_e) {
+ setting->mode -= fss_basic_read_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_basic_read_mode_to_codepoint_e) {
+ setting->mode -= fss_basic_read_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_basic_read_parameter_to_width_e].result == f_console_result_found_e) {
+ setting->mode |= fss_basic_read_mode_to_width_e;
+ }
+
+ setting->mode |= fss_basic_read_mode_to_combining_e;
+ }
+ else if (choices.array[choice] == fss_basic_read_parameter_to_width_e) {
+ if (setting->mode & fss_basic_read_mode_to_bytesequence_e) {
+ setting->mode -= fss_basic_read_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_basic_read_mode_to_codepoint_e) {
+ setting->mode -= fss_basic_read_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_basic_read_parameter_to_combining_e].result == f_console_result_found_e) {
+ setting->mode |= fss_basic_read_mode_to_combining_e;
+ }
+
+ setting->mode |= fss_basic_read_mode_to_width_e;
+ }
+ }
+ }
+
+ f_string_static_t * const args = main->parameters.arguments.array;
+
+ if (main->parameters.array[fss_basic_read_parameter_to_file_e].result == f_console_result_additional_e) {
+ if (main->parameters.array[fss_basic_read_parameter_to_file_e].values.used > 1) {
+ fss_basic_read_print_error_parameter_file_to_too_many(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+
+ if (args[main->parameters.array[fss_basic_read_parameter_to_file_e].values.array[0]].used) {
+ setting->path_files_to.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(1, &setting->path_files_to);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_to.array[setting->path_files_to.used].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[main->parameters.array[fss_basic_read_parameter_to_file_e].values.array[0]], &setting->path_files_to.array[0]);
+ if (F_status_is_error(setting->status)) return;
+
+ ++setting->path_files_to.used;
+
+ setting->status = f_file_stream_open(args[main->parameters.array[fss_basic_read_parameter_to_file_e].values.array[0]], f_file_open_mode_append_s, &main->output.to);
+
+ if (F_status_is_error(setting->status)) {
+ fll_error_file_print(main->error, F_status_set_fine(setting->status), "f_file_stream_open", F_true, args[main->parameters.array[fss_basic_read_parameter_to_file_e].values.array[0]], f_file_operation_open_s, fll_error_file_type_file_e);
+
+ return;
+ }
+
+ setting->flag |= fss_basic_read_main_flag_file_to_e;
+ }
+ else {
+ fss_basic_read_print_error_parameter_file_name_empty(main, setting, main->parameters.array[fss_basic_read_parameter_to_file_e].values.array[0]);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+ else if (main->parameters.array[fss_basic_read_parameter_to_file_e].result == f_console_result_found_e) {
+ fss_basic_read_print_error_no_value(main, setting, fss_basic_read_long_to_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ main->output.to = main->message.to;
+
+ if (setting->flag & fss_basic_read_main_flag_file_to_e) {
+ setting->flag -= fss_basic_read_main_flag_file_to_e;
+ }
+ }
+
+ if (main->parameters.array[fss_basic_read_parameter_from_file_e].result == f_console_result_additional_e) {
+ setting->path_files_from.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(main->parameters.array[fss_basic_read_parameter_from_file_e].values.used, &setting->path_files_from);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_from.used = main->parameters.array[fss_basic_read_parameter_from_file_e].values.used;
+
+ f_array_length_t i = 0;
+ f_array_length_t index = 0;
+
+ for (; i < setting->path_files_from.used; ++i) {
+
+ index = main->parameters.array[fss_basic_read_parameter_from_file_e].values.array[i];
+ setting->path_files_from.array[i].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[index], &setting->path_files_from.array[i]);
+ if (F_status_is_error(setting->status)) return;
+
+ if (args[index].used) {
+ if (f_file_exists(args[index], F_true) != F_true) {
+ fss_basic_read_print_error_parameter_file_not_found(main, setting, F_true, args[index]);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_file_found_not);
+ }
+ }
+ }
+ else {
+ fss_basic_read_print_error_parameter_file_name_empty(main, setting, index);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_parameter);
+ }
+ }
+ } // for
+
+ if (F_status_is_error(setting->status)) return;
+
+ setting->flag |= fss_basic_read_main_flag_file_from_e;
+ }
+ else if (main->parameters.array[fss_basic_read_parameter_from_file_e].result == f_console_result_found_e) {
+ fss_basic_read_print_error_no_value(main, setting, fss_basic_read_long_from_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ if (setting->flag & fss_basic_read_main_flag_file_from_e) {
+ setting->flag -= fss_basic_read_main_flag_file_from_e;
+ }
+ }
+
+ if (F_status_is_error(setting->status)) return;
+
+ if (main->parameters.array[fss_basic_read_parameter_from_file_e].result == f_console_result_none_e && !((main->pipe & fll_program_data_pipe_input_e) || main->parameters.remaining.used)) {
+ fss_basic_read_print_error_no_from(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+ }
+
+ if (!(setting->mode & fss_basic_read_mode_to_bytesequence_e)) {
+ if (main->parameters.array[fss_basic_read_parameter_separate_e].result == f_console_result_found_e || main->parameters.array[fss_basic_read_parameter_headers_e].result == f_console_result_found_e) {
+ setting->prepend = fss_basic_read_string_prepend_padding_s;
+ setting->append = f_string_eol_s;
+ }
+ else {
+ setting->prepend = f_string_space_s;
+ }
+ }
+
+ if (main->parameters.array[fss_basic_read_parameter_headers_e].result == f_console_result_found_e) {
+ setting->flag |= fss_basic_read_main_flag_header_e;
+ }
+
+ if (main->parameters.array[fss_basic_read_parameter_separate_e].result == f_console_result_found_e) {
+ setting->flag |= fss_basic_read_main_flag_separate_e;
+ }
+
+ if (main->parameters.array[fss_basic_read_parameter_strip_invalid_e].result == f_console_result_found_e) {
+ setting->flag |= fss_basic_read_main_flag_strip_invalid_e;
+ }
+
+ setting->valid_not = main->message.set->error;
+ }
+#endif // _di_fss_basic_read_setting_load_
+
+#ifndef _di_fss_basic_read_setting_unload_
+ f_status_t fss_basic_read_setting_unload(fll_program_data_t * const main, fss_basic_read_setting_t * const setting) {
+
+ if (!main || !setting) return F_status_set_error(F_parameter);
+
+ fss_basic_read_setting_delete(setting);
+
+ return F_none;
+ }
+#endif // _di_fss_basic_read_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
};
#endif // _di_fss_basic_read_delimit_modes_
+/**
+ * Flags used to represent flags passed to the main function.
+ *
+ * fss_basic_read_main_flag_*_e:
+ * - none: No modes in use.
+ * - file_from: Using a specified source file.
+ * - file_to: Using a specified destination file.
+ * - help: Print help.
+ * - header: Enable printing of headers.
+ * - separate: Enable printing of separators.
+ * - strip_invalid: Using strip invalid character mode.
+ * - verify: Using verify mode.
+ * - version: Print version.
+ */
+#ifndef _di_fss_basic_read_main_flag_e_
+ enum {
+ fss_basic_read_main_flag_none_e = 0x0,
+ fss_basic_read_main_flag_file_from_e = 0x1,
+ fss_basic_read_main_flag_file_to_e = 0x2,
+ fss_basic_read_main_flag_header_e = 0x4,
+ fss_basic_read_main_flag_help_e = 0x8,
+ fss_basic_read_main_flag_separate_e = 0x10,
+ fss_basic_read_main_flag_strip_invalid_e = 0x20,
+ fss_basic_read_main_flag_verify_e = 0x40,
+ fss_basic_read_main_flag_version_e = 0x80,
+ };
+#endif // _di_fss_basic_read_main_flag_e_
+
+/**
+ * The fss basic read main program settings.
+ *
+ * This is passed to the program-specific main entry point to designate program settings.
+ * These program settings are often processed from the program arguments (often called the command line arguments).
+ *
+ * flag: Flags passed to the main function.
+ *
+ * status: The main status code, generally used by the load settings and main functions.
+ *
+ * line_first: A string expected to represent either "\n" or NULL to allow for easy handling of when to print first new line or not.
+ * line_last: A string expected to represent either "\n" or NULL to allow for easy handling of when to print last new line or not.
+ */
+#ifndef _di_fss_basic_read_setting_t_
+ typedef struct {
+ uint16_t flag;
+
+ f_status_t status;
+
+ f_string_static_t line_first;
+ f_string_static_t line_last;
+ } fss_basic_read_setting_t;
+
+ #define fss_basic_read_setting_t_initialize \
+ { \
+ fss_basic_read_main_flag_none_e, \
+ F_none, \
+ f_string_static_t_initialize, \
+ f_string_static_t_initialize, \
+ }
+#endif // _di_fss_basic_read_setting_t_
+
+/**
+ * Delete the program main setting data.
+ *
+ * @param setting
+ * The program main setting data.
+ * This does not alter setting.status.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fss_basic_read_setting_delete_
+ extern f_status_t fss_basic_read_setting_delete(fss_basic_read_setting_t * const setting);
+#endif // _di_fss_basic_read_setting_delete_
+
+/**
+ * Perform the standard program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately retuns without doing anything.
+ *
+ * @param arguments
+ * The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ *
+ * This alters setting.status:
+ * F_none on success.
+ *
+ * Errors (with error bit) from: f_console_parameter_process().
+ * Errors (with error bit) from: fll_program_parameter_process_context().
+ *
+ * @see f_console_parameter_process()
+ * @see fll_program_parameter_process_context()
+ */
+#ifndef _di_fss_basic_read_setting_load_
+ extern void fss_basic_read_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_basic_read_setting_t * const setting);
+#endif // _di_fss_basic_read_setting_load_
+
+/**
+ * Perform the standard program setting unload process.
+ *
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * All buffers are deallocated.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: utf8_setting_delete().
+ *
+ * @see utf8_setting_delete()
+ */
+#ifndef _di_fss_basic_read_setting_unload_
+ extern f_status_t fss_basic_read_setting_unload(fll_program_data_t * const main, fss_basic_read_setting_t * const setting);
+#endif // _di_fss_basic_read_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern "C" {
#endif
-#ifndef _di_fss_basic_read_print_help_
- f_status_t fss_basic_read_print_help(const f_file_t file, const f_color_context_t context) {
-
- flockfile(file.stream);
-
- //if (!(setting->flag & XXX_main_flag_line_first_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- fll_program_print_help_header(file, context, fss_basic_read_program_name_long_s, fss_basic_read_program_version_s);
-
- fll_program_print_help_option_standard(file, context);
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, fss_basic_read_short_at_s, fss_basic_read_long_at_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric index.");
- fll_program_print_help_option(file, context, fss_basic_read_short_content_s, fss_basic_read_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Content (default).");
- fll_program_print_help_option(file, context, fss_basic_read_short_columns_s, fss_basic_read_long_columns_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of columns.");
- fll_program_print_help_option(file, context, fss_basic_read_short_delimit_s, fss_basic_read_long_delimit_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Designate how to handle applying delimits.");
- fll_program_print_help_option(file, context, fss_basic_read_short_depth_s, fss_basic_read_long_depth_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric depth.");
- fll_program_print_help_option(file, context, fss_basic_read_short_empty_s, fss_basic_read_long_empty_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Include empty Content when processing.");
- fll_program_print_help_option(file, context, fss_basic_read_short_line_s, fss_basic_read_long_line_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print only the Content at the given line.");
- fll_program_print_help_option(file, context, fss_basic_read_short_name_s, fss_basic_read_long_name_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object with this name.");
- fll_program_print_help_option(file, context, fss_basic_read_short_object_s, fss_basic_read_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Object.");
- fll_program_print_help_option(file, context, fss_basic_read_short_pipe_s, fss_basic_read_long_pipe_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print using the special pipe format.");
- fll_program_print_help_option(file, context, fss_basic_read_short_original_s, fss_basic_read_long_original_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print with the original quotes and escapes.");
- fll_program_print_help_option(file, context, fss_basic_read_short_select_s, fss_basic_read_long_select_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select sub-Content at this index.");
- fll_program_print_help_option(file, context, fss_basic_read_short_total_s, fss_basic_read_long_total_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of lines.");
- fll_program_print_help_option(file, context, fss_basic_read_short_trim_s, fss_basic_read_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names on select or print.");
-
- fll_program_print_help_usage(file, context, fss_basic_read_program_name_s, fll_program_parameter_filenames_s);
-
- fl_print_format("%r %[Notes:%]%r", file.stream, f_string_eol_s, context.set.important, context.set.important, f_string_eol_s);
-
- fl_print_format(" This program will print the Content associated with the given Object and Content main based on the FSS-0000 Basic standard.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" All numeric positions (indexes) start at 0 instead of 1.%r", file.stream, f_string_eol_s);
- fl_print_format(" For example, a file of 17 lines would range from 0 to 16.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When using the %[%r%r%] option, an order of operations is enforced on the parameters.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_depth_s, context.set.notable, f_string_eol_s);
-
- fl_print_format(" When this order of operations is in effect, parameters to the right of a depth parameter are influenced by that depth parameter:%r", file.stream, f_string_eol_s);
-
- fl_print_format(" %[%r%r%]: An Object index at the specified depth.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_at_s, context.set.notable, f_string_eol_s);
- fl_print_format(" %[%r%r%]: A new depth within the specified depth, indexed from the root.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_depth_s, context.set.notable, f_string_eol_s);
- fl_print_format(" %[%r%r%]: An Object name at the specified depth.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_name_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%] must be in numeric order, but values in between may be skipped.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_depth_s, context.set.notable, f_string_eol_s);
- fl_print_format(" ('-d 0 -a 1 -d 2 -a 2' would specify index 1 at depth 0, any index at depth 1, and index 2 at depth 2.)%r", file.stream, f_string_eol_s);
- fl_print_format(" ('-d 2 -a 1 -d 0 -a 2' would be invalid because depth 2 is before depth 1.)%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%] selects a Content column.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_select_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" Specify both %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_object_s, context.set.notable);
- fl_print_format(" and the %[%r%r%] parameters to get the total objects.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_total_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When both %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_at_s, context.set.notable);
- fl_print_format(" and %[%r%r%] parameters are specified (at the same depth),", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_name_s, context.set.notable);
- fl_print_format(" the %[%r%r%] parameter value will be treated as a position relative to the specified", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_at_s, context.set.notable);
- fl_print_format(" %[%r%r%] parameter value.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_name_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" This program may support parameters, such as %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_depth_s, context.set.notable);
- fl_print_format(" or %[%r%r%], even if not supported by the standard.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_select_s, context.set.notable, f_string_eol_s);
- fl_print_format(" This is done to help ensure consistency for scripting.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" For parameters like %[%r%r%],", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_depth_s, context.set.notable);
- fl_print_format(" if the standard doesn't support nested Content, then only a depth of 0 would be valid.%r", file.stream, f_string_eol_s);
-
- fl_print_format(" For parameters like %[%r%r%],", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_select_s, context.set.notable);
- fl_print_format(" if the standard doesn't support multiple Content groups, then only a select of 0 would be valid.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_trim_s, context.set.notable);
- fl_print_format(" will remove leading and trailing white spaces when selecting objects or when printing objects.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When specifying both the %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_object_s, context.set.notable);
- fl_print_format(" parameter and the %[%r%r%] parameter, the entire Object and Content are printed, including the formatting.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_content_s, context.set.notable, f_string_eol_s);
- fl_print_format(" Both the Object and Content printed are already escaped.%r", file.stream, f_string_eol_s);
- fl_print_format(" Both the Object and Content are separated by a space.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%] accepts the following:%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_delimit_s, context.set.notable, f_string_eol_s);
- fl_print_format(" - %[%r%]: Do not apply delimits.%r", file.stream, context.set.notable, fss_basic_read_delimit_mode_name_none_s, context.set.notable, f_string_eol_s);
- fl_print_format(" - %[%r%]: (default) Apply all delimits.%r", file.stream, context.set.notable, fss_basic_read_delimit_mode_name_all_s, context.set.notable, f_string_eol_s);
- fl_print_format(" - %[%r%]: Apply delimits for Objects.%r", file.stream, context.set.notable, fss_basic_read_delimit_mode_name_object_s, context.set.notable, f_string_eol_s);
- fl_print_format(" - A number, 0 or greater: apply delimits for Content at the specified depth.%r", file.stream, f_string_eol_s);
- fl_print_format(" - A number, 0 or greater, followed by a %[%r%]: (such as '1+') apply delimits for Content at the specified depth and any greater depth (numerically).%r", file.stream, context.set.notable, fss_basic_read_delimit_mode_name_greater_s, context.set.notable, f_string_eol_s, f_string_eol_s);
- fl_print_format(" - A number, 0 or lesser, followed by a %[%r%]: (such as '1-') apply delimits for Content at the specified depth and any lesser depth (numerically).%r%r", file.stream, context.set.notable, fss_basic_read_delimit_mode_name_lesser_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The %[%r%r%] parameter may be specified multiple times to customize the delimit behavior.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_delimit_s, context.set.notable, f_string_eol_s);
-
- fl_print_format(" The %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_delimit_s, context.set.notable);
- fl_print_format(" values %[%r%]", file.stream, context.set.notable, fss_basic_read_delimit_mode_name_none_s, context.set.notable);
- fl_print_format(" and %[%r%],", file.stream, context.set.notable, fss_basic_read_delimit_mode_name_all_s, context.set.notable);
- fl_print_format(" overrule all other delimit values.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameters %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_columns_s, context.set.notable);
- fl_print_format(" and %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_read_long_select_s, context.set.notable);
- fl_print_format(" refer to a Content column.%r", file.stream, f_string_eol_s);
- fl_print_format(" The word \"column\" is being loosely defined to refer to a specific Content.%r", file.stream, f_string_eol_s);
- fl_print_format(" This is not to be confused with a depth.%r", file.stream, f_string_eol_s);
-
- //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- f_file_stream_flush(file);
- funlockfile(file.stream);
-
- return F_none;
- }
-#endif // _di_fss_basic_read_print_help_
-
#ifndef _di_fss_basic_read_main_
- f_status_t fss_basic_read_main(fll_program_data_t * const main, const f_console_arguments_t arguments) {
+ f_status_t fss_basic_read_main(fll_program_data_t * const main, fss_basic_read_setting_t * const setting) {
f_status_t status = F_none;
status = F_none;
if (main->parameters.array[fss_basic_read_parameter_help_e].result == f_console_result_found_e) {
- fss_basic_read_print_help(main->output.to, main->context);
+ fss_basic_read_print_help(setting, main->message);
return status;
}
if (main->parameters.array[fss_basic_read_parameter_version_e].result == f_console_result_found_e) {
- fll_program_print_version(main->output.to, fss_basic_read_program_version_s);
+ fll_program_print_version(main->message, fss_basic_read_program_version_s);
return status;
}
if (!((++main->signal_check) % fss_basic_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
if (!((++main->signal_check) % fss_basic_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_signal);
// The signal check is always performed on each pass.
if (size_file > fss_basic_read_block_max && fll_program_standard_signal_received(main)) {
- fss_basic_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
#endif
/**
- * Print help.
- *
- * @param file
- * The file to print to.
- * @param context
- * The color context settings.
- *
- * @return
- * F_none on success.
- */
-#ifndef _di_fss_basic_read_print_help_
- extern f_status_t fss_basic_read_print_help(const f_file_t file, const f_color_context_t context);
-#endif // _di_fss_basic_read_print_help_
-
-/**
* Execute main program.
*
* If main.signal is non-zero, then this blocks and handles the following signals:
*
* @param main
* The main program data.
- * @param arguments
- * The parameters passed to the process.
+ * @param setting
+ * The main program settings.
*
- * @return
- * F_none on success.
+ * This alters setting.status:
+ * F_none on success.
+ * F_true on success when performing verification and verify passed.
+ * F_false on success when performing verification and verify failed.
+ * F_interrupt on (exit) signal received.
*
- * Status codes (with error bit) are returned on any problem.
+ * F_parameter (with error bit) if main is NULL or setting is NULL.
*/
#ifndef _di_fss_basic_read_main_
- extern f_status_t fss_basic_read_main(fll_program_data_t * const main, const f_console_arguments_t arguments);
+ extern f_status_t fss_basic_read_main(fll_program_data_t * const main, fss_basic_read_setting_t * const setting);
#endif // _di_fss_basic_read_main_
#ifdef __cplusplus
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
fll_program_data_t data = fll_program_data_t_initialize;
+ fss_basic_read_setting_t setting = fss_basic_read_setting_t_initialize;
f_console_parameter_t parameters[] = fss_basic_read_console_parameter_t_initialize;
data.parameters.array = parameters;
data.parameters.used = fss_basic_read_total_parameters_d;
+ data.environment = envp;
if (f_pipe_input_exists()) {
data.pipe = fll_program_data_pipe_input_e;
fll_program_standard_set_up(&data);
- const f_status_t status = fss_basic_read_main(&data, arguments);
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+
+ fss_basic_read_setting_load(arguments, &data, &setting);
+ }
+
+ fss_basic_read_main(&data, &setting);
+
+ fss_basic_read_setting_unload(&data, &setting);
fll_program_data_delete(&data);
fll_program_standard_set_down(&data);
- if (F_status_is_error(status)) return 1;
-
- return 0;
+ return F_status_is_error(status) ? 1 : 0;
}
--- /dev/null
+#include "fss_basic_read.h"
+#include "private-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fss_basic_read_print_help_
+ f_status_t fss_basic_read_print_help(fss_basic_read_setting_t * const setting, const fl_print_t print) {
+
+ f_file_stream_lock(print.to);
+
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+
+ fll_program_print_help_header(print, fss_basic_read_program_name_long_s, fss_basic_read_program_version_s);
+
+ fll_program_print_help_option_standard(print);
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, fss_basic_read_short_at_s, fss_basic_read_long_at_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric index.");
+ fll_program_print_help_option(print, fss_basic_read_short_content_s, fss_basic_read_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Content (default).");
+ fll_program_print_help_option(print, fss_basic_read_short_columns_s, fss_basic_read_long_columns_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of columns.");
+ fll_program_print_help_option(print, fss_basic_read_short_delimit_s, fss_basic_read_long_delimit_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Designate how to handle applying delimits.");
+ fll_program_print_help_option(print, fss_basic_read_short_depth_s, fss_basic_read_long_depth_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric depth.");
+ fll_program_print_help_option(print, fss_basic_read_short_empty_s, fss_basic_read_long_empty_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Include empty Content when processing.");
+ fll_program_print_help_option(print, fss_basic_read_short_line_s, fss_basic_read_long_line_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print only the Content at the given line.");
+ fll_program_print_help_option(print, fss_basic_read_short_name_s, fss_basic_read_long_name_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object with this name.");
+ fll_program_print_help_option(print, fss_basic_read_short_object_s, fss_basic_read_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Object.");
+ fll_program_print_help_option(print, fss_basic_read_short_pipe_s, fss_basic_read_long_pipe_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print using the special pipe format.");
+ fll_program_print_help_option(print, fss_basic_read_short_original_s, fss_basic_read_long_original_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print with the original quotes and escapes.");
+ fll_program_print_help_option(print, fss_basic_read_short_select_s, fss_basic_read_long_select_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select sub-Content at this index.");
+ fll_program_print_help_option(print, fss_basic_read_short_total_s, fss_basic_read_long_total_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of lines.");
+ fll_program_print_help_option(print, fss_basic_read_short_trim_s, fss_basic_read_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names on select or print.");
+
+ fll_program_print_help_usage(print, fss_basic_read_program_name_s, fll_program_parameter_filenames_s);
+
+ fl_print_format("%r %[Notes:%]%r", print.to.stream, f_string_eol_s, print.set->important, print.set->important, f_string_eol_s);
+
+ fl_print_format(" This program will print the Content associated with the given Object and Content main based on the FSS-0000 Basic standard.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" All numeric positions (indexes) start at 0 instead of 1.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" For example, a file of 17 lines would range from 0 to 16.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When using the %[%r%r%] option, an order of operations is enforced on the parameters.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_depth_s, print.set->notable, f_string_eol_s);
+
+ fl_print_format(" When this order of operations is in effect, parameters to the right of a depth parameter are influenced by that depth parameter:%r", print.to.stream, f_string_eol_s);
+
+ fl_print_format(" %[%r%r%]: An Object index at the specified depth.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_at_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" %[%r%r%]: A new depth within the specified depth, indexed from the root.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_depth_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" %[%r%r%]: An Object name at the specified depth.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_name_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%] must be in numeric order, but values in between may be skipped.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_depth_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" ('-d 0 -a 1 -d 2 -a 2' would specify index 1 at depth 0, any index at depth 1, and index 2 at depth 2.)%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" ('-d 2 -a 1 -d 0 -a 2' would be invalid because depth 2 is before depth 1.)%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%] selects a Content column.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_select_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" Specify both %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_object_s, print.set->notable);
+ fl_print_format(" and the %[%r%r%] parameters to get the total objects.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_total_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When both %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_at_s, print.set->notable);
+ fl_print_format(" and %[%r%r%] parameters are specified (at the same depth),", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_name_s, print.set->notable);
+ fl_print_format(" the %[%r%r%] parameter value will be treated as a position relative to the specified", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_at_s, print.set->notable);
+ fl_print_format(" %[%r%r%] parameter value.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_name_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" This program may support parameters, such as %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_depth_s, print.set->notable);
+ fl_print_format(" or %[%r%r%], even if not supported by the standard.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_select_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" This is done to help ensure consistency for scripting.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" For parameters like %[%r%r%],", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_depth_s, print.set->notable);
+ fl_print_format(" if the standard doesn't support nested Content, then only a depth of 0 would be valid.%r", print.to.stream, f_string_eol_s);
+
+ fl_print_format(" For parameters like %[%r%r%],", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_select_s, print.set->notable);
+ fl_print_format(" if the standard doesn't support multiple Content groups, then only a select of 0 would be valid.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_trim_s, print.set->notable);
+ fl_print_format(" will remove leading and trailing white spaces when selecting objects or when printing objects.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When specifying both the %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_object_s, print.set->notable);
+ fl_print_format(" parameter and the %[%r%r%] parameter, the entire Object and Content are printed, including the formatting.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_content_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" Both the Object and Content printed are already escaped.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" Both the Object and Content are separated by a space.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%] accepts the following:%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_delimit_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" - %[%r%]: Do not apply delimits.%r", print.to.stream, print.set->notable, fss_basic_read_delimit_mode_name_none_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" - %[%r%]: (default) Apply all delimits.%r", print.to.stream, print.set->notable, fss_basic_read_delimit_mode_name_all_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" - %[%r%]: Apply delimits for Objects.%r", print.to.stream, print.set->notable, fss_basic_read_delimit_mode_name_object_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" - A number, 0 or greater: apply delimits for Content at the specified depth.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" - A number, 0 or greater, followed by a %[%r%]: (such as '1+') apply delimits for Content at the specified depth and any greater depth (numerically).%r", print.to.stream, print.set->notable, fss_basic_read_delimit_mode_name_greater_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+ fl_print_format(" - A number, 0 or lesser, followed by a %[%r%]: (such as '1-') apply delimits for Content at the specified depth and any lesser depth (numerically).%r%r", print.to.stream, print.set->notable, fss_basic_read_delimit_mode_name_lesser_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The %[%r%r%] parameter may be specified multiple times to customize the delimit behavior.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_delimit_s, print.set->notable, f_string_eol_s);
+
+ fl_print_format(" The %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_delimit_s, print.set->notable);
+ fl_print_format(" values %[%r%]", print.to.stream, print.set->notable, fss_basic_read_delimit_mode_name_none_s, print.set->notable);
+ fl_print_format(" and %[%r%],", print.to.stream, print.set->notable, fss_basic_read_delimit_mode_name_all_s, print.set->notable);
+ fl_print_format(" overrule all other delimit values.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameters %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_columns_s, print.set->notable);
+ fl_print_format(" and %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_read_long_select_s, print.set->notable);
+ fl_print_format(" refer to a Content column.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" The word \"column\" is being loosely defined to refer to a specific Content.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" This is not to be confused with a depth.%r", print.to.stream, f_string_eol_s);
+
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+
+ f_file_stream_flush(print.to);
+ f_file_stream_unlock(print.to);
+
+ return F_none;
+ }
+#endif // _di_fss_basic_read_print_help_
+
+#ifndef _di_fss_basic_read_print_line_first_
+ void fss_basic_read_print_line_first(fss_basic_read_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ }
+#endif // _di_fss_basic_read_print_line_first_
+
+#ifndef _di_fss_basic_read_print_line_last_
+ void fss_basic_read_print_line_last(fss_basic_read_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+ if (print.verbosity == f_console_verbosity_error_e && !F_status_is_error(setting->status)) return;
+ if (setting->flag & fss_basic_read_main_flag_verify_e) return;
+ if ((setting->flag & fss_basic_read_main_flag_file_to_e) && !F_status_is_error(setting->status)) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ }
+#endif // _di_fss_basic_read_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: UTF-8
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _fss_basic_read_print_h
+#define _fss_basic_read_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print help.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * The output structure to print to.
+ *
+ * @return
+ * F_none on success.
+ */
+#ifndef _di_fss_basic_read_print_help_
+ extern f_status_t fss_basic_read_print_help(fss_basic_read_setting_t * const setting, const fl_print_t print);
+#endif // _di_fss_basic_read_print_help_
+
+/**
+ * Print first new line, unless verbosity says otherwise.
+ *
+ * This is generally either the first line in the program or the first line printed before an error message.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_basic_read_print_line_first_
+ extern void fss_basic_read_print_line_first(fss_basic_read_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_basic_read_print_line_first_
+
+/**
+ * Print last new line when the main is complete, unless verbosity says otherwise.
+ *
+ * This is generally the very last line printed in the program.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_basic_read_print_line_last_
+ extern void fss_basic_read_print_line_last(fss_basic_read_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_basic_read_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _fss_basic_read_print_h
}
#endif // _di_fss_basic_read_depths_resize_
-#ifndef _di_fss_basic_read_print_signal_received_
- void fss_basic_read_print_signal_received(fll_program_data_t * const main) {
-
- if (main->warning.verbosity != f_console_verbosity_verbose_e && main->warning.verbosity != f_console_verbosity_debug_e) return;
-
- // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
- fflush(main->warning.to.stream);
-
- flockfile(main->warning.to.stream);
-
- fl_print_format("%]%r%r%[Received signal code %]", main->warning.to.stream, main->context.set.reset, f_string_eol_s, f_string_eol_s, main->context.set.warning, main->context.set.warning);
- fl_print_format("%[%i%]", main->warning.to.stream, main->context.set.notable, main->signal_received, main->context.set.notable);
- fl_print_format("%[.%]%r", main->warning.to.stream, main->context.set.warning, main->context.set.warning, f_string_eol_s);
-
- funlockfile(main->warning.to.stream);
- }
-#endif // _di_fss_basic_read_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
extern f_status_t fss_basic_read_depths_resize(const f_array_length_t length, fss_basic_read_depths_t *depths) F_attribute_visibility_internal_d;
#endif // _di_fss_basic_read_depths_resize_
-/**
- * Print a message about a process signal being recieved, such as an interrupt signal.
- *
- * @param main
- * The main program data.
- */
-#ifndef _di_fss_basic_read_print_signal_received_
- extern void fss_basic_read_print_signal_received(fll_program_data_t * const main) F_attribute_visibility_internal_d;
-#endif // _di_fss_basic_read_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
if (!((++main->signal_check) % fss_basic_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (!((++main->signal_check) % fss_basic_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (F_status_is_error(status)) {
if (F_status_set_fine(status) == F_interrupt) {
- fss_basic_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return status;
}
if (!((++main->signal_check) % fss_basic_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (!((++main->signal_check) % fss_basic_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (!((++main->signal_check) % fss_basic_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (!((++main->signal_check) % fss_basic_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library fss_basic_read.c common.c private-common.c private-print.c private-read.c
+build_sources_library fss_basic_read.c common.c print.c private-common.c private-print.c private-read.c
build_sources_program main.c
-build_sources_headers fss_basic_read.h common.h
+build_sources_headers fss_basic_read.h common.h print.h
build_script yes
build_shared yes
const f_string_static_t fss_basic_write_long_trim_s = macro_f_string_static_t_initialize(FSS_BASIC_WRITE_long_trim_s, 0, FSS_BASIC_WRITE_long_trim_s_length);
#endif // _di_fss_basic_write_program_parameters_
+#ifndef _di_fss_basic_write_setting_delete_
+ f_status_t fss_basic_write_setting_delete(fss_basic_write_setting_t * const setting) {
+
+ if (!setting) return F_status_set_error(F_parameter);
+
+ return F_none;
+ }
+#endif // _di_fss_basic_write_setting_delete_
+
+#ifndef _di_fss_basic_write_setting_load_
+ void fss_basic_write_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_basic_write_setting_t * const setting) {
+
+ if (!main || !setting) return;
+
+ // Load parameters.
+ setting->status = f_console_parameter_process(arguments, &main->parameters);
+ if (F_status_is_error(setting->status)) return;
+
+ {
+ f_array_length_t choice = 0;
+ f_uint16s_t choices = f_uint16s_t_initialize;
+
+ // Identify and prioritize "color context" parameters.
+ {
+ uint16_t choices_array[3] = { fss_basic_write_parameter_no_color_e, fss_basic_write_parameter_light_e, fss_basic_write_parameter_dark_e };
+ choices.array = choices_array;
+ choices.used = 3;
+
+ const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
+
+ setting->status = fll_program_parameter_process_context(choices, modes, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_basic_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_context", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_basic_write_parameter_line_first_no_e].result == f_console_result_found_e) {
+ setting->line_first = f_string_empty_s;
+ }
+ else {
+ setting->line_first = f_string_eol_s;
+ }
+
+ if (main->parameters.array[fss_basic_write_parameter_line_last_no_e].result == f_console_result_found_e) {
+ setting->line_last = f_string_empty_s;
+ }
+ else {
+ setting->line_last = f_string_eol_s;
+ }
+
+ // Identify and prioritize "verbosity" parameters.
+ {
+ uint16_t choices_array[5] = { fss_basic_write_parameter_verbosity_quiet_e, fss_basic_write_parameter_verbosity_error_e, fss_basic_write_parameter_verbosity_verbose_e, fss_basic_write_parameter_verbosity_debug_e, fss_basic_write_parameter_verbosity_normal_e };
+ choices.array = choices_array;
+ choices.used = 5;
+
+ const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+
+ setting->status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_basic_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_verbosity", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_basic_write_parameter_help_e].result == f_console_result_found_e) {
+ setting->flag |= fss_basic_write_main_flag_help_e;
+
+ return;
+ }
+
+ if (main->parameters.array[fss_basic_write_parameter_version_e].result == f_console_result_found_e) {
+ setting->flag |= fss_basic_write_main_flag_version_e;
+
+ return;
+ }
+
+ // Identify and prioritize "from" mode parameters.
+ {
+ uint16_t choices_array[2] = { fss_basic_write_parameter_from_bytesequence_e, fss_basic_write_parameter_from_codepoint_e };
+ choices.array = choices_array;
+ choices.used = 2;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_basic_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_basic_write_parameter_from_bytesequence_e) {
+ if (setting->mode & fss_basic_write_mode_from_codepoint_e) {
+ setting->mode -= fss_basic_write_mode_from_codepoint_e;
+ }
+
+ setting->mode |= fss_basic_write_mode_from_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_basic_write_parameter_from_codepoint_e) {
+ if (setting->mode & fss_basic_write_mode_from_bytesequence_e) {
+ setting->mode -= fss_basic_write_mode_from_bytesequence_e;
+ }
+
+ setting->mode |= fss_basic_write_mode_from_codepoint_e;
+ }
+ }
+
+ // Identify and prioritize "to" mode parameters.
+ {
+ uint16_t choices_array[4] = { fss_basic_write_parameter_to_bytesequence_e, fss_basic_write_parameter_to_codepoint_e, fss_basic_write_parameter_to_combining_e, fss_basic_write_parameter_to_width_e };
+ choices.array = choices_array;
+ choices.used = 4;
+ choice = 1;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_basic_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_basic_write_parameter_to_bytesequence_e) {
+ if (setting->mode & fss_basic_write_mode_to_codepoint_e) {
+ setting->mode -= fss_basic_write_mode_to_codepoint_e;
+ }
+
+ if (setting->mode & fss_basic_write_mode_to_combining_e) {
+ setting->mode -= fss_basic_write_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_basic_write_mode_to_width_e) {
+ setting->mode -= fss_basic_write_mode_to_width_e;
+ }
+
+ setting->mode |= fss_basic_write_mode_to_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_basic_write_parameter_to_codepoint_e) {
+ if (setting->mode & fss_basic_write_mode_to_bytesequence_e) {
+ setting->mode -= fss_basic_write_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_basic_write_mode_to_combining_e) {
+ setting->mode -= fss_basic_write_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_basic_write_mode_to_width_e) {
+ setting->mode -= fss_basic_write_mode_to_width_e;
+ }
+
+ setting->mode |= fss_basic_write_mode_to_codepoint_e;
+ }
+ else if (choices.array[choice] == fss_basic_write_parameter_to_combining_e) {
+ if (setting->mode & fss_basic_write_mode_to_bytesequence_e) {
+ setting->mode -= fss_basic_write_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_basic_write_mode_to_codepoint_e) {
+ setting->mode -= fss_basic_write_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_basic_write_parameter_to_width_e].result == f_console_result_found_e) {
+ setting->mode |= fss_basic_write_mode_to_width_e;
+ }
+
+ setting->mode |= fss_basic_write_mode_to_combining_e;
+ }
+ else if (choices.array[choice] == fss_basic_write_parameter_to_width_e) {
+ if (setting->mode & fss_basic_write_mode_to_bytesequence_e) {
+ setting->mode -= fss_basic_write_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_basic_write_mode_to_codepoint_e) {
+ setting->mode -= fss_basic_write_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_basic_write_parameter_to_combining_e].result == f_console_result_found_e) {
+ setting->mode |= fss_basic_write_mode_to_combining_e;
+ }
+
+ setting->mode |= fss_basic_write_mode_to_width_e;
+ }
+ }
+ }
+
+ f_string_static_t * const args = main->parameters.arguments.array;
+
+ if (main->parameters.array[fss_basic_write_parameter_to_file_e].result == f_console_result_additional_e) {
+ if (main->parameters.array[fss_basic_write_parameter_to_file_e].values.used > 1) {
+ fss_basic_write_print_error_parameter_file_to_too_many(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+
+ if (args[main->parameters.array[fss_basic_write_parameter_to_file_e].values.array[0]].used) {
+ setting->path_files_to.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(1, &setting->path_files_to);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_to.array[setting->path_files_to.used].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[main->parameters.array[fss_basic_write_parameter_to_file_e].values.array[0]], &setting->path_files_to.array[0]);
+ if (F_status_is_error(setting->status)) return;
+
+ ++setting->path_files_to.used;
+
+ setting->status = f_file_stream_open(args[main->parameters.array[fss_basic_write_parameter_to_file_e].values.array[0]], f_file_open_mode_append_s, &main->output.to);
+
+ if (F_status_is_error(setting->status)) {
+ fll_error_file_print(main->error, F_status_set_fine(setting->status), "f_file_stream_open", F_true, args[main->parameters.array[fss_basic_write_parameter_to_file_e].values.array[0]], f_file_operation_open_s, fll_error_file_type_file_e);
+
+ return;
+ }
+
+ setting->flag |= fss_basic_write_main_flag_file_to_e;
+ }
+ else {
+ fss_basic_write_print_error_parameter_file_name_empty(main, setting, main->parameters.array[fss_basic_write_parameter_to_file_e].values.array[0]);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+ else if (main->parameters.array[fss_basic_write_parameter_to_file_e].result == f_console_result_found_e) {
+ fss_basic_write_print_error_no_value(main, setting, fss_basic_write_long_to_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ main->output.to = main->message.to;
+
+ if (setting->flag & fss_basic_write_main_flag_file_to_e) {
+ setting->flag -= fss_basic_write_main_flag_file_to_e;
+ }
+ }
+
+ if (main->parameters.array[fss_basic_write_parameter_from_file_e].result == f_console_result_additional_e) {
+ setting->path_files_from.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(main->parameters.array[fss_basic_write_parameter_from_file_e].values.used, &setting->path_files_from);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_from.used = main->parameters.array[fss_basic_write_parameter_from_file_e].values.used;
+
+ f_array_length_t i = 0;
+ f_array_length_t index = 0;
+
+ for (; i < setting->path_files_from.used; ++i) {
+
+ index = main->parameters.array[fss_basic_write_parameter_from_file_e].values.array[i];
+ setting->path_files_from.array[i].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[index], &setting->path_files_from.array[i]);
+ if (F_status_is_error(setting->status)) return;
+
+ if (args[index].used) {
+ if (f_file_exists(args[index], F_true) != F_true) {
+ fss_basic_write_print_error_parameter_file_not_found(main, setting, F_true, args[index]);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_file_found_not);
+ }
+ }
+ }
+ else {
+ fss_basic_write_print_error_parameter_file_name_empty(main, setting, index);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_parameter);
+ }
+ }
+ } // for
+
+ if (F_status_is_error(setting->status)) return;
+
+ setting->flag |= fss_basic_write_main_flag_file_from_e;
+ }
+ else if (main->parameters.array[fss_basic_write_parameter_from_file_e].result == f_console_result_found_e) {
+ fss_basic_write_print_error_no_value(main, setting, fss_basic_write_long_from_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ if (setting->flag & fss_basic_write_main_flag_file_from_e) {
+ setting->flag -= fss_basic_write_main_flag_file_from_e;
+ }
+ }
+
+ if (F_status_is_error(setting->status)) return;
+
+ if (main->parameters.array[fss_basic_write_parameter_from_file_e].result == f_console_result_none_e && !((main->pipe & fll_program_data_pipe_input_e) || main->parameters.remaining.used)) {
+ fss_basic_write_print_error_no_from(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+ }
+
+ if (!(setting->mode & fss_basic_write_mode_to_bytesequence_e)) {
+ if (main->parameters.array[fss_basic_write_parameter_separate_e].result == f_console_result_found_e || main->parameters.array[fss_basic_write_parameter_headers_e].result == f_console_result_found_e) {
+ setting->prepend = fss_basic_write_string_prepend_padding_s;
+ setting->append = f_string_eol_s;
+ }
+ else {
+ setting->prepend = f_string_space_s;
+ }
+ }
+
+ if (main->parameters.array[fss_basic_write_parameter_headers_e].result == f_console_result_found_e) {
+ setting->flag |= fss_basic_write_main_flag_header_e;
+ }
+
+ if (main->parameters.array[fss_basic_write_parameter_separate_e].result == f_console_result_found_e) {
+ setting->flag |= fss_basic_write_main_flag_separate_e;
+ }
+
+ if (main->parameters.array[fss_basic_write_parameter_strip_invalid_e].result == f_console_result_found_e) {
+ setting->flag |= fss_basic_write_main_flag_strip_invalid_e;
+ }
+
+ setting->valid_not = main->message.set->error;
+ }
+#endif // _di_fss_basic_write_setting_load_
+
+#ifndef _di_fss_basic_write_setting_unload_
+ f_status_t fss_basic_write_setting_unload(fll_program_data_t * const main, fss_basic_write_setting_t * const setting) {
+
+ if (!main || !setting) return F_status_set_error(F_parameter);
+
+ fss_basic_write_setting_delete(setting);
+
+ return F_none;
+ }
+#endif // _di_fss_basic_write_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
#define fss_basic_write_total_parameters_d 20
#endif // _di_fss_basic_write_parameters_
+/**
+ * Flags used to represent flags passed to the main function.
+ *
+ * fss_basic_write_main_flag_*_e:
+ * - none: No modes in use.
+ * - file_from: Using a specified source file.
+ * - file_to: Using a specified destination file.
+ * - help: Print help.
+ * - header: Enable printing of headers.
+ * - separate: Enable printing of separators.
+ * - strip_invalid: Using strip invalid character mode.
+ * - verify: Using verify mode.
+ * - version: Print version.
+ */
+#ifndef _di_fss_basic_write_main_flag_e_
+ enum {
+ fss_basic_write_main_flag_none_e = 0x0,
+ fss_basic_write_main_flag_file_from_e = 0x1,
+ fss_basic_write_main_flag_file_to_e = 0x2,
+ fss_basic_write_main_flag_header_e = 0x4,
+ fss_basic_write_main_flag_help_e = 0x8,
+ fss_basic_write_main_flag_separate_e = 0x10,
+ fss_basic_write_main_flag_strip_invalid_e = 0x20,
+ fss_basic_write_main_flag_verify_e = 0x40,
+ fss_basic_write_main_flag_version_e = 0x80,
+ };
+#endif // _di_fss_basic_write_main_flag_e_
+
+/**
+ * The fss basic write main program settings.
+ *
+ * This is passed to the program-specific main entry point to designate program settings.
+ * These program settings are often processed from the program arguments (often called the command line arguments).
+ *
+ * flag: Flags passed to the main function.
+ *
+ * status: The main status code, generally used by the load settings and main functions.
+ *
+ * line_first: A string expected to represent either "\n" or NULL to allow for easy handling of when to print first new line or not.
+ * line_last: A string expected to represent either "\n" or NULL to allow for easy handling of when to print last new line or not.
+ */
+#ifndef _di_fss_basic_write_setting_t_
+ typedef struct {
+ uint16_t flag;
+
+ f_status_t status;
+
+ f_string_static_t line_first;
+ f_string_static_t line_last;
+ } fss_basic_write_setting_t;
+
+ #define fss_basic_write_setting_t_initialize \
+ { \
+ fss_basic_write_main_flag_none_e, \
+ F_none, \
+ f_string_static_t_initialize, \
+ f_string_static_t_initialize, \
+ }
+#endif // _di_fss_basic_write_setting_t_
+
+/**
+ * Delete the program main setting data.
+ *
+ * @param setting
+ * The program main setting data.
+ * This does not alter setting.status.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fss_basic_write_setting_delete_
+ extern f_status_t fss_basic_write_setting_delete(fss_basic_write_setting_t * const setting);
+#endif // _di_fss_basic_write_setting_delete_
+
+/**
+ * Perform the standard program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately retuns without doing anything.
+ *
+ * @param arguments
+ * The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ *
+ * This alters setting.status:
+ * F_none on success.
+ *
+ * Errors (with error bit) from: f_console_parameter_process().
+ * Errors (with error bit) from: fll_program_parameter_process_context().
+ *
+ * @see f_console_parameter_process()
+ * @see fll_program_parameter_process_context()
+ */
+#ifndef _di_fss_basic_write_setting_load_
+ extern void fss_basic_write_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_basic_write_setting_t * const setting);
+#endif // _di_fss_basic_write_setting_load_
+
+/**
+ * Perform the standard program setting unload process.
+ *
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * All buffers are deallocated.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: utf8_setting_delete().
+ *
+ * @see utf8_setting_delete()
+ */
+#ifndef _di_fss_basic_write_setting_unload_
+ extern f_status_t fss_basic_write_setting_unload(fll_program_data_t * const main, fss_basic_write_setting_t * const setting);
+#endif // _di_fss_basic_write_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern "C" {
#endif
-#ifndef _di_fss_basic_write_print_help_
- f_status_t fss_basic_write_print_help(const f_file_t file, const f_color_context_t context) {
-
- flockfile(file.stream);
-
- //if (!(setting->flag & XXX_main_flag_line_first_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- fll_program_print_help_header(file, context, fss_basic_write_program_name_long_s, fss_basic_write_program_version_s);
-
- fll_program_print_help_option_standard(file, context);
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, fss_basic_write_short_file_s, fss_basic_write_long_file_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a file to send data to.");
- fll_program_print_help_option(file, context, fss_basic_write_short_content_s, fss_basic_write_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "The Content to write.");
- fll_program_print_help_option(file, context, fss_basic_write_short_double_s, fss_basic_write_long_double_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use double quotes (default).");
- fll_program_print_help_option(file, context, fss_basic_write_short_ignore_s, fss_basic_write_long_ignore_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Ignore a given range within a Content.");
- fll_program_print_help_option(file, context, fss_basic_write_short_object_s, fss_basic_write_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The Object to write.");
- fll_program_print_help_option(file, context, fss_basic_write_short_partial_s, fss_basic_write_long_partial_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Do not write end of Object/Content character.");
- fll_program_print_help_option(file, context, fss_basic_write_short_prepend_s, fss_basic_write_long_prepend_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Prepend the given white space characters to the start of each multi-line Content.");
- fll_program_print_help_option(file, context, fss_basic_write_short_single_s, fss_basic_write_long_single_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use single quotes.");
- fll_program_print_help_option(file, context, fss_basic_write_short_trim_s, fss_basic_write_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names.");
-
- fll_program_print_help_usage(file, context, fss_basic_write_program_name_s, f_string_empty_s);
-
- fl_print_format("%r The pipe uses the Backspace character '%[\\b%]' (%[U+0008%]) to designate the start of a Content.%r", file.stream, f_string_eol_s, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" The pipe uses the Form Feed character '%[\\f%]' (%[U+000C%]) to designate the end of the last Content.%r", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" The pipe uses the Vertical Line character '%[\\v%]' (%[U+000B%]) is used to ignore a Content range, which does nothing in this program.%r", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" For the pipe, an Object is terminated by either a Backspace character '%[\\b%]' (%[U+0008%])", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable);
- fl_print_format(" or a Form Feed character '%[\\f%]' (%[U+000C%]).%r", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" The end of the pipe represents the end of any Object or Content.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The FSS-0000 (Basic) specification does not support multi-line Content, therefore the parameter '%[%r%r%]'", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_write_long_prepend_s, context.set.notable);
- fl_print_format(" does nothing.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" This program does not use the parameter '%[%r%r%]', which therefore does nothing.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_basic_write_long_ignore_s, context.set.notable, f_string_eol_s);
- fl_print_format(" This parameter requires two values.%r", file.stream, f_string_eol_s);
-
- //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- f_file_stream_flush(file);
- funlockfile(file.stream);
-
- return F_none;
- }
-#endif // _di_fss_basic_write_print_help_
-
#ifndef _di_fss_basic_write_main_
- f_status_t fss_basic_write_main(fll_program_data_t * const main, const f_console_arguments_t arguments) {
+ f_status_t fss_basic_write_main(fll_program_data_t * const main, fss_basic_write_setting_t * const setting) {
f_status_t status = F_none;
status = F_none;
if (main->parameters.array[fss_basic_write_parameter_help_e].result == f_console_result_found_e) {
- fss_basic_write_print_help(main->output.to, main->context);
+ fss_basic_write_print_help(setting, main->message);
return status;
}
if (main->parameters.array[fss_basic_write_parameter_version_e].result == f_console_result_found_e) {
- fll_program_print_version(main->output.to, fss_basic_write_program_version_s);
+ fll_program_print_version(main->message, fss_basic_write_program_version_s);
return status;
}
if (!((++main->signal_check) % fss_basic_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
if (!((++main->signal_check) % fss_basic_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
if (!((++main->signal_check) % fss_basic_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
#endif
/**
- * Print help.
- *
- * @param file
- * The file to print to.
- * @param context
- * The color context settings.
- *
- * @return
- * F_none on success.
- */
-#ifndef _di_fss_basic_write_print_help_
- extern f_status_t fss_basic_write_print_help(const f_file_t file, const f_color_context_t context);
-#endif // _di_fss_basic_write_print_help_
-
-/**
* Execute main program.
*
* If main.signal is non-zero, then this blocks and handles the following signals:
* Status codes (with error bit) are returned on any problem.
*/
#ifndef _di_fss_basic_write_main_
- extern f_status_t fss_basic_write_main(fll_program_data_t * const main, const f_console_arguments_t arguments);
+ extern f_status_t fss_basic_write_main(fll_program_data_t * const main, fss_basic_write_setting_t * const setting);
#endif // _di_fss_basic_write_main_
#ifdef __cplusplus
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
fll_program_data_t data = fll_program_data_t_initialize;
+ fss_basic_write_setting_t setting = fss_basic_write_setting_t_initialize;
f_console_parameter_t parameters[] = fss_basic_write_console_parameter_t_initialize;
data.parameters.array = parameters;
data.parameters.used = fss_basic_write_total_parameters_d;
+ data.environment = envp;
if (f_pipe_input_exists()) {
data.pipe = fll_program_data_pipe_input_e;
fll_program_standard_set_up(&data);
- const f_status_t status = fss_basic_write_main(&data, arguments);
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+
+ fss_basic_write_setting_load(arguments, &data, &setting);
+ }
+
+ fss_basic_write_main(&data, &setting);
+
+ fss_basic_write_setting_unload(&data, &setting);
fll_program_data_delete(&data);
fll_program_standard_set_down(&data);
- if (F_status_is_error(status)) return 1;
-
- return 0;
+ return F_status_is_error(status) ? 1 : 0;
}
--- /dev/null
+#include "fss_basic_write.h"
+#include "private-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fss_basic_write_print_help_
+ f_status_t fss_basic_write_print_help(fss_basic_write_setting_t * const setting, const fl_print_t print) {
+
+ f_file_stream_lock(print.to);
+
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+
+ fll_program_print_help_header(print, fss_basic_write_program_name_long_s, fss_basic_write_program_version_s);
+
+ fll_program_print_help_option_standard(print);
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, fss_basic_write_short_file_s, fss_basic_write_long_file_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a file to send data to.");
+ fll_program_print_help_option(print, fss_basic_write_short_content_s, fss_basic_write_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "The Content to write.");
+ fll_program_print_help_option(print, fss_basic_write_short_double_s, fss_basic_write_long_double_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use double quotes (default).");
+ fll_program_print_help_option(print, fss_basic_write_short_ignore_s, fss_basic_write_long_ignore_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Ignore a given range within a Content.");
+ fll_program_print_help_option(print, fss_basic_write_short_object_s, fss_basic_write_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The Object to write.");
+ fll_program_print_help_option(print, fss_basic_write_short_partial_s, fss_basic_write_long_partial_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Do not write end of Object/Content character.");
+ fll_program_print_help_option(print, fss_basic_write_short_prepend_s, fss_basic_write_long_prepend_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Prepend the given white space characters to the start of each multi-line Content.");
+ fll_program_print_help_option(print, fss_basic_write_short_single_s, fss_basic_write_long_single_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use single quotes.");
+ fll_program_print_help_option(print, fss_basic_write_short_trim_s, fss_basic_write_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names.");
+
+ fll_program_print_help_usage(print, fss_basic_write_program_name_s, f_string_empty_s);
+
+ fl_print_format("%r The pipe uses the Backspace character '%[\\b%]' (%[U+0008%]) to designate the start of a Content.%r", print.to.stream, f_string_eol_s, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" The pipe uses the Form Feed character '%[\\f%]' (%[U+000C%]) to designate the end of the last Content.%r", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" The pipe uses the Vertical Line character '%[\\v%]' (%[U+000B%]) is used to ignore a Content range, which does nothing in this program.%r", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" For the pipe, an Object is terminated by either a Backspace character '%[\\b%]' (%[U+0008%])", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable);
+ fl_print_format(" or a Form Feed character '%[\\f%]' (%[U+000C%]).%r", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" The end of the pipe represents the end of any Object or Content.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The FSS-0000 (Basic) specification does not support multi-line Content, therefore the parameter '%[%r%r%]'", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_write_long_prepend_s, print.set->notable);
+ fl_print_format(" does nothing.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" This program does not use the parameter '%[%r%r%]', which therefore does nothing.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_basic_write_long_ignore_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" This parameter requires two values.%r", print.to.stream, f_string_eol_s);
+
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+
+ f_file_stream_flush(print.to);
+ f_file_stream_unlock(print.to);
+
+ return F_none;
+ }
+#endif // _di_fss_basic_write_print_help_
+
+#ifndef _di_fss_basic_write_print_line_first_
+ void fss_basic_write_print_line_first(fss_basic_write_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ }
+#endif // _di_fss_basic_write_print_line_first_
+
+#ifndef _di_fss_basic_write_print_line_last_
+ void fss_basic_write_print_line_last(fss_basic_write_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+ if (print.verbosity == f_console_verbosity_error_e && !F_status_is_error(setting->status)) return;
+ if (setting->flag & fss_basic_write_main_flag_verify_e) return;
+ if ((setting->flag & fss_basic_write_main_flag_file_to_e) && !F_status_is_error(setting->status)) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ }
+#endif // _di_fss_basic_write_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: UTF-8
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _fss_basic_write_print_h
+#define _fss_basic_write_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print help.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * The output structure to print to.
+ *
+ * @return
+ * F_none on success.
+ */
+#ifndef _di_fss_basic_write_print_help_
+ extern f_status_t fss_basic_write_print_help(fss_basic_write_setting_t * const setting, const fl_print_t print);
+#endif // _di_fss_basic_write_print_help_
+
+/**
+ * Print first new line, unless verbosity says otherwise.
+ *
+ * This is generally either the first line in the program or the first line printed before an error message.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_basic_write_print_line_first_
+ extern void fss_basic_write_print_line_first(fss_basic_write_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_basic_write_print_line_first_
+
+/**
+ * Print last new line when the main is complete, unless verbosity says otherwise.
+ *
+ * This is generally the very last line printed in the program.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_basic_write_print_line_last_
+ extern void fss_basic_write_print_line_last(fss_basic_write_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_basic_write_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _fss_basic_write_print_h
extern "C" {
#endif
-#ifndef _di_fss_basic_write_print_signal_received_
- void fss_basic_write_print_signal_received(fll_program_data_t * const main) {
-
- if (main->warning.verbosity != f_console_verbosity_verbose_e && main->warning.verbosity != f_console_verbosity_debug_e) return;
-
- // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
- fflush(main->warning.to.stream);
-
- flockfile(main->warning.to.stream);
-
- fl_print_format("%]%r%r%[Received signal code %]", main->warning.to.stream, main->context.set.reset, f_string_eol_s, f_string_eol_s, main->context.set.warning, main->context.set.warning);
- fl_print_format("%[%i%]", main->warning.to.stream, main->context.set.notable, main->signal_received, main->context.set.notable);
- fl_print_format("%[.%]%r", main->warning.to.stream, main->context.set.warning, main->context.set.warning, f_string_eol_s);
-
- funlockfile(main->warning.to.stream);
- }
-#endif // _di_fss_basic_write_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
#define fss_basic_write_common_allocation_small_d 128
#endif // _di_fss_basic_write_common_
-/**
- * Print a message about a process signal being recieved, such as an interrupt signal.
- *
- * @param main
- * The main program data.
- */
-#ifndef _di_fss_basic_write_print_signal_received_
- extern void fss_basic_write_print_signal_received(fll_program_data_t * const main) F_attribute_visibility_internal_d;
-#endif // _di_fss_basic_write_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
if (!((++main->signal_check) % fss_basic_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_basic_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library fss_basic_write.c common.c private-common.c private-write.c
+build_sources_library fss_basic_write.c common.c print.c private-common.c private-write.c
build_sources_program main.c
-build_sources_headers fss_basic_write.h common.h
+build_sources_headers fss_basic_write.h common.h print.h
build_script yes
build_shared yes
const f_string_static_t fss_embedded_list_read_delimit_mode_name_lesser_s = macro_f_string_static_t_initialize(FSS_EMBEDDED_LIST_READ_delimit_mode_name_lesser_s, 0, FSS_EMBEDDED_LIST_READ_delimit_mode_name_lesser_s_length);
#endif // _di_fss_embedded_list_read_delimit_mode_
+#ifndef _di_fss_embedded_list_read_setting_delete_
+ f_status_t fss_embedded_list_read_setting_delete(fss_embedded_list_read_setting_t * const setting) {
+
+ if (!setting) return F_status_set_error(F_parameter);
+
+ return F_none;
+ }
+#endif // _di_fss_embedded_list_read_setting_delete_
+
+#ifndef _di_fss_embedded_list_read_setting_load_
+ void fss_embedded_list_read_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_embedded_list_read_setting_t * const setting) {
+
+ if (!main || !setting) return;
+
+ // Load parameters.
+ setting->status = f_console_parameter_process(arguments, &main->parameters);
+ if (F_status_is_error(setting->status)) return;
+
+ {
+ f_array_length_t choice = 0;
+ f_uint16s_t choices = f_uint16s_t_initialize;
+
+ // Identify and prioritize "color context" parameters.
+ {
+ uint16_t choices_array[3] = { fss_embedded_list_read_parameter_no_color_e, fss_embedded_list_read_parameter_light_e, fss_embedded_list_read_parameter_dark_e };
+ choices.array = choices_array;
+ choices.used = 3;
+
+ const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
+
+ setting->status = fll_program_parameter_process_context(choices, modes, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_embedded_list_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_context", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_embedded_list_read_parameter_line_first_no_e].result == f_console_result_found_e) {
+ setting->line_first = f_string_empty_s;
+ }
+ else {
+ setting->line_first = f_string_eol_s;
+ }
+
+ if (main->parameters.array[fss_embedded_list_read_parameter_line_last_no_e].result == f_console_result_found_e) {
+ setting->line_last = f_string_empty_s;
+ }
+ else {
+ setting->line_last = f_string_eol_s;
+ }
+
+ // Identify and prioritize "verbosity" parameters.
+ {
+ uint16_t choices_array[5] = { fss_embedded_list_read_parameter_verbosity_quiet_e, fss_embedded_list_read_parameter_verbosity_error_e, fss_embedded_list_read_parameter_verbosity_verbose_e, fss_embedded_list_read_parameter_verbosity_debug_e, fss_embedded_list_read_parameter_verbosity_normal_e };
+ choices.array = choices_array;
+ choices.used = 5;
+
+ const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+
+ setting->status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_embedded_list_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_verbosity", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_embedded_list_read_parameter_help_e].result == f_console_result_found_e) {
+ setting->flag |= fss_embedded_list_read_main_flag_help_e;
+
+ return;
+ }
+
+ if (main->parameters.array[fss_embedded_list_read_parameter_version_e].result == f_console_result_found_e) {
+ setting->flag |= fss_embedded_list_read_main_flag_version_e;
+
+ return;
+ }
+
+ // Identify and prioritize "from" mode parameters.
+ {
+ uint16_t choices_array[2] = { fss_embedded_list_read_parameter_from_bytesequence_e, fss_embedded_list_read_parameter_from_codepoint_e };
+ choices.array = choices_array;
+ choices.used = 2;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_embedded_list_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_embedded_list_read_parameter_from_bytesequence_e) {
+ if (setting->mode & fss_embedded_list_read_mode_from_codepoint_e) {
+ setting->mode -= fss_embedded_list_read_mode_from_codepoint_e;
+ }
+
+ setting->mode |= fss_embedded_list_read_mode_from_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_embedded_list_read_parameter_from_codepoint_e) {
+ if (setting->mode & fss_embedded_list_read_mode_from_bytesequence_e) {
+ setting->mode -= fss_embedded_list_read_mode_from_bytesequence_e;
+ }
+
+ setting->mode |= fss_embedded_list_read_mode_from_codepoint_e;
+ }
+ }
+
+ // Identify and prioritize "to" mode parameters.
+ {
+ uint16_t choices_array[4] = { fss_embedded_list_read_parameter_to_bytesequence_e, fss_embedded_list_read_parameter_to_codepoint_e, fss_embedded_list_read_parameter_to_combining_e, fss_embedded_list_read_parameter_to_width_e };
+ choices.array = choices_array;
+ choices.used = 4;
+ choice = 1;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_embedded_list_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_embedded_list_read_parameter_to_bytesequence_e) {
+ if (setting->mode & fss_embedded_list_read_mode_to_codepoint_e) {
+ setting->mode -= fss_embedded_list_read_mode_to_codepoint_e;
+ }
+
+ if (setting->mode & fss_embedded_list_read_mode_to_combining_e) {
+ setting->mode -= fss_embedded_list_read_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_embedded_list_read_mode_to_width_e) {
+ setting->mode -= fss_embedded_list_read_mode_to_width_e;
+ }
+
+ setting->mode |= fss_embedded_list_read_mode_to_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_embedded_list_read_parameter_to_codepoint_e) {
+ if (setting->mode & fss_embedded_list_read_mode_to_bytesequence_e) {
+ setting->mode -= fss_embedded_list_read_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_embedded_list_read_mode_to_combining_e) {
+ setting->mode -= fss_embedded_list_read_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_embedded_list_read_mode_to_width_e) {
+ setting->mode -= fss_embedded_list_read_mode_to_width_e;
+ }
+
+ setting->mode |= fss_embedded_list_read_mode_to_codepoint_e;
+ }
+ else if (choices.array[choice] == fss_embedded_list_read_parameter_to_combining_e) {
+ if (setting->mode & fss_embedded_list_read_mode_to_bytesequence_e) {
+ setting->mode -= fss_embedded_list_read_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_embedded_list_read_mode_to_codepoint_e) {
+ setting->mode -= fss_embedded_list_read_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_embedded_list_read_parameter_to_width_e].result == f_console_result_found_e) {
+ setting->mode |= fss_embedded_list_read_mode_to_width_e;
+ }
+
+ setting->mode |= fss_embedded_list_read_mode_to_combining_e;
+ }
+ else if (choices.array[choice] == fss_embedded_list_read_parameter_to_width_e) {
+ if (setting->mode & fss_embedded_list_read_mode_to_bytesequence_e) {
+ setting->mode -= fss_embedded_list_read_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_embedded_list_read_mode_to_codepoint_e) {
+ setting->mode -= fss_embedded_list_read_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_embedded_list_read_parameter_to_combining_e].result == f_console_result_found_e) {
+ setting->mode |= fss_embedded_list_read_mode_to_combining_e;
+ }
+
+ setting->mode |= fss_embedded_list_read_mode_to_width_e;
+ }
+ }
+ }
+
+ f_string_static_t * const args = main->parameters.arguments.array;
+
+ if (main->parameters.array[fss_embedded_list_read_parameter_to_file_e].result == f_console_result_additional_e) {
+ if (main->parameters.array[fss_embedded_list_read_parameter_to_file_e].values.used > 1) {
+ fss_embedded_list_read_print_error_parameter_file_to_too_many(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+
+ if (args[main->parameters.array[fss_embedded_list_read_parameter_to_file_e].values.array[0]].used) {
+ setting->path_files_to.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(1, &setting->path_files_to);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_to.array[setting->path_files_to.used].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[main->parameters.array[fss_embedded_list_read_parameter_to_file_e].values.array[0]], &setting->path_files_to.array[0]);
+ if (F_status_is_error(setting->status)) return;
+
+ ++setting->path_files_to.used;
+
+ setting->status = f_file_stream_open(args[main->parameters.array[fss_embedded_list_read_parameter_to_file_e].values.array[0]], f_file_open_mode_append_s, &main->output.to);
+
+ if (F_status_is_error(setting->status)) {
+ fll_error_file_print(main->error, F_status_set_fine(setting->status), "f_file_stream_open", F_true, args[main->parameters.array[fss_embedded_list_read_parameter_to_file_e].values.array[0]], f_file_operation_open_s, fll_error_file_type_file_e);
+
+ return;
+ }
+
+ setting->flag |= fss_embedded_list_read_main_flag_file_to_e;
+ }
+ else {
+ fss_embedded_list_read_print_error_parameter_file_name_empty(main, setting, main->parameters.array[fss_embedded_list_read_parameter_to_file_e].values.array[0]);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+ else if (main->parameters.array[fss_embedded_list_read_parameter_to_file_e].result == f_console_result_found_e) {
+ fss_embedded_list_read_print_error_no_value(main, setting, fss_embedded_list_read_long_to_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ main->output.to = main->message.to;
+
+ if (setting->flag & fss_embedded_list_read_main_flag_file_to_e) {
+ setting->flag -= fss_embedded_list_read_main_flag_file_to_e;
+ }
+ }
+
+ if (main->parameters.array[fss_embedded_list_read_parameter_from_file_e].result == f_console_result_additional_e) {
+ setting->path_files_from.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(main->parameters.array[fss_embedded_list_read_parameter_from_file_e].values.used, &setting->path_files_from);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_from.used = main->parameters.array[fss_embedded_list_read_parameter_from_file_e].values.used;
+
+ f_array_length_t i = 0;
+ f_array_length_t index = 0;
+
+ for (; i < setting->path_files_from.used; ++i) {
+
+ index = main->parameters.array[fss_embedded_list_read_parameter_from_file_e].values.array[i];
+ setting->path_files_from.array[i].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[index], &setting->path_files_from.array[i]);
+ if (F_status_is_error(setting->status)) return;
+
+ if (args[index].used) {
+ if (f_file_exists(args[index], F_true) != F_true) {
+ fss_embedded_list_read_print_error_parameter_file_not_found(main, setting, F_true, args[index]);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_file_found_not);
+ }
+ }
+ }
+ else {
+ fss_embedded_list_read_print_error_parameter_file_name_empty(main, setting, index);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_parameter);
+ }
+ }
+ } // for
+
+ if (F_status_is_error(setting->status)) return;
+
+ setting->flag |= fss_embedded_list_read_main_flag_file_from_e;
+ }
+ else if (main->parameters.array[fss_embedded_list_read_parameter_from_file_e].result == f_console_result_found_e) {
+ fss_embedded_list_read_print_error_no_value(main, setting, fss_embedded_list_read_long_from_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ if (setting->flag & fss_embedded_list_read_main_flag_file_from_e) {
+ setting->flag -= fss_embedded_list_read_main_flag_file_from_e;
+ }
+ }
+
+ if (F_status_is_error(setting->status)) return;
+
+ if (main->parameters.array[fss_embedded_list_read_parameter_from_file_e].result == f_console_result_none_e && !((main->pipe & fll_program_data_pipe_input_e) || main->parameters.remaining.used)) {
+ fss_embedded_list_read_print_error_no_from(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+ }
+
+ if (!(setting->mode & fss_embedded_list_read_mode_to_bytesequence_e)) {
+ if (main->parameters.array[fss_embedded_list_read_parameter_separate_e].result == f_console_result_found_e || main->parameters.array[fss_embedded_list_read_parameter_headers_e].result == f_console_result_found_e) {
+ setting->prepend = fss_embedded_list_read_string_prepend_padding_s;
+ setting->append = f_string_eol_s;
+ }
+ else {
+ setting->prepend = f_string_space_s;
+ }
+ }
+
+ if (main->parameters.array[fss_embedded_list_read_parameter_headers_e].result == f_console_result_found_e) {
+ setting->flag |= fss_embedded_list_read_main_flag_header_e;
+ }
+
+ if (main->parameters.array[fss_embedded_list_read_parameter_separate_e].result == f_console_result_found_e) {
+ setting->flag |= fss_embedded_list_read_main_flag_separate_e;
+ }
+
+ if (main->parameters.array[fss_embedded_list_read_parameter_strip_invalid_e].result == f_console_result_found_e) {
+ setting->flag |= fss_embedded_list_read_main_flag_strip_invalid_e;
+ }
+
+ setting->valid_not = main->message.set->error;
+ }
+#endif // _di_fss_embedded_list_read_setting_load_
+
+#ifndef _di_fss_embedded_list_read_setting_unload_
+ f_status_t fss_embedded_list_read_setting_unload(fll_program_data_t * const main, fss_embedded_list_read_setting_t * const setting) {
+
+ if (!main || !setting) return F_status_set_error(F_parameter);
+
+ fss_embedded_list_read_setting_delete(setting);
+
+ return F_none;
+ }
+#endif // _di_fss_embedded_list_read_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
};
#endif // _di_fss_embedded_list_read_delimit_modes_
+/**
+ * Flags used to represent flags passed to the main function.
+ *
+ * fss_embedded_list_read_main_flag_*_e:
+ * - none: No modes in use.
+ * - file_from: Using a specified source file.
+ * - file_to: Using a specified destination file.
+ * - help: Print help.
+ * - header: Enable printing of headers.
+ * - separate: Enable printing of separators.
+ * - strip_invalid: Using strip invalid character mode.
+ * - verify: Using verify mode.
+ * - version: Print version.
+ */
+#ifndef _di_fss_embedded_list_read_main_flag_e_
+ enum {
+ fss_embedded_list_read_main_flag_none_e = 0x0,
+ fss_embedded_list_read_main_flag_file_from_e = 0x1,
+ fss_embedded_list_read_main_flag_file_to_e = 0x2,
+ fss_embedded_list_read_main_flag_header_e = 0x4,
+ fss_embedded_list_read_main_flag_help_e = 0x8,
+ fss_embedded_list_read_main_flag_separate_e = 0x10,
+ fss_embedded_list_read_main_flag_strip_invalid_e = 0x20,
+ fss_embedded_list_read_main_flag_verify_e = 0x40,
+ fss_embedded_list_read_main_flag_version_e = 0x80,
+ };
+#endif // _di_fss_embedded_list_read_main_flag_e_
+
+/**
+ * The fss embedded list read main program settings.
+ *
+ * This is passed to the program-specific main entry point to designate program settings.
+ * These program settings are often processed from the program arguments (often called the command line arguments).
+ *
+ * flag: Flags passed to the main function.
+ *
+ * status: The main status code, generally used by the load settings and main functions.
+ *
+ * line_first: A string expected to represent either "\n" or NULL to allow for easy handling of when to print first new line or not.
+ * line_last: A string expected to represent either "\n" or NULL to allow for easy handling of when to print last new line or not.
+ */
+#ifndef _di_fss_embedded_list_read_setting_t_
+ typedef struct {
+ uint16_t flag;
+
+ f_status_t status;
+
+ f_string_static_t line_first;
+ f_string_static_t line_last;
+ } fss_embedded_list_read_setting_t;
+
+ #define fss_embedded_list_read_setting_t_initialize \
+ { \
+ fss_embedded_list_read_main_flag_none_e, \
+ F_none, \
+ f_string_static_t_initialize, \
+ f_string_static_t_initialize, \
+ }
+#endif // _di_fss_embedded_list_read_setting_t_
+
+/**
+ * Delete the program main setting data.
+ *
+ * @param setting
+ * The program main setting data.
+ * This does not alter setting.status.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fss_embedded_list_read_setting_delete_
+ extern f_status_t fss_embedded_list_read_setting_delete(fss_embedded_list_read_setting_t * const setting);
+#endif // _di_fss_embedded_list_read_setting_delete_
+
+/**
+ * Perform the standard program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately retuns without doing anything.
+ *
+ * @param arguments
+ * The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ *
+ * This alters setting.status:
+ * F_none on success.
+ *
+ * Errors (with error bit) from: f_console_parameter_process().
+ * Errors (with error bit) from: fll_program_parameter_process_context().
+ *
+ * @see f_console_parameter_process()
+ * @see fll_program_parameter_process_context()
+ */
+#ifndef _di_fss_embedded_list_read_setting_load_
+ extern void fss_embedded_list_read_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_embedded_list_read_setting_t * const setting);
+#endif // _di_fss_embedded_list_read_setting_load_
+
+/**
+ * Perform the standard program setting unload process.
+ *
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * All buffers are deallocated.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: utf8_setting_delete().
+ *
+ * @see utf8_setting_delete()
+ */
+#ifndef _di_fss_embedded_list_read_setting_unload_
+ extern f_status_t fss_embedded_list_read_setting_unload(fll_program_data_t * const main, fss_embedded_list_read_setting_t * const setting);
+#endif // _di_fss_embedded_list_read_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern "C" {
#endif
-#ifndef _di_fss_embedded_list_read_print_help_
- f_status_t fss_embedded_list_read_print_help(const f_file_t file, const f_color_context_t context) {
-
- flockfile(file.stream);
-
- //if (!(setting->flag & XXX_main_flag_line_first_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- fll_program_print_help_header(file, context, fss_embedded_list_read_program_name_long_s, fss_embedded_list_read_program_version_s);
-
- fll_program_print_help_option_standard(file, context);
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, fss_embedded_list_read_short_at_s, fss_embedded_list_read_long_at_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric index.");
- fll_program_print_help_option(file, context, fss_embedded_list_read_short_content_s, fss_embedded_list_read_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Content (default).");
- fll_program_print_help_option(file, context, fss_embedded_list_read_short_columns_s, fss_embedded_list_read_long_columns_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of columns.");
- fll_program_print_help_option(file, context, fss_embedded_list_read_short_delimit_s, fss_embedded_list_read_long_delimit_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Designate how to handle applying delimits.");
- fll_program_print_help_option(file, context, fss_embedded_list_read_short_depth_s, fss_embedded_list_read_long_depth_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric depth.");
- fll_program_print_help_option(file, context, fss_embedded_list_read_short_empty_s, fss_embedded_list_read_long_empty_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Include empty Content when processing.");
- fll_program_print_help_option(file, context, fss_embedded_list_read_short_line_s, fss_embedded_list_read_long_line_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print only the Content at the given line.");
- fll_program_print_help_option(file, context, fss_embedded_list_read_short_name_s, fss_embedded_list_read_long_name_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object with this name.");
- fll_program_print_help_option(file, context, fss_embedded_list_read_short_object_s, fss_embedded_list_read_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Object.");
- fll_program_print_help_option(file, context, fss_embedded_list_read_short_pipe_s, fss_embedded_list_read_long_pipe_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print using the special pipe format.");
- fll_program_print_help_option(file, context, fss_embedded_list_read_short_original_s, fss_embedded_list_read_long_original_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print with the original quotes and escapes.");
- fll_program_print_help_option(file, context, fss_embedded_list_read_short_select_s, fss_embedded_list_read_long_select_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select sub-Content at this index.");
- fll_program_print_help_option(file, context, fss_embedded_list_read_short_total_s, fss_embedded_list_read_long_total_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of lines.");
- fll_program_print_help_option(file, context, fss_embedded_list_read_short_trim_s, fss_embedded_list_read_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names on select or print.");
-
- fll_program_print_help_usage(file, context, fss_embedded_list_read_program_name_s, fll_program_parameter_filenames_s);
-
- fl_print_format("%r %[Notes:%]%r", file.stream, f_string_eol_s, context.set.important, context.set.important, f_string_eol_s);
-
- fl_print_format(" This program will print the Content associated with the given Object and Content main based on the FSS-0008 Embedded List standard.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" All numeric positions (indexes) start at 0 instead of 1.%r", file.stream, f_string_eol_s);
- fl_print_format(" For example, a file of 17 lines would range from 0 to 16.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When using the %[%r%r%] option, an order of operations is enforced on the parameters.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_depth_s, context.set.notable, f_string_eol_s);
-
- fl_print_format(" When this order of operations is in effect, parameters to the right of a depth parameter are influenced by that depth parameter:%r", file.stream, f_string_eol_s);
-
- fl_print_format(" %[%r%r%]: An Object index at the specified depth.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_at_s, context.set.notable, f_string_eol_s);
- fl_print_format(" %[%r%r%]: A new depth within the specified depth, indexed from the root.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_depth_s, context.set.notable, f_string_eol_s);
- fl_print_format(" %[%r%r%]: An Object name at the specified depth.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_name_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%] must be in numeric order, but values in between may be skipped.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_depth_s, context.set.notable, f_string_eol_s);
- fl_print_format(" ('-d 0 -a 1 -d 2 -a 2' would specify index 1 at depth 0, any index at depth 1, and index 2 at depth 2.)%r", file.stream, f_string_eol_s);
- fl_print_format(" ('-d 2 -a 1 -d 0 -a 2' would be invalid because depth 2 is before depth 1.)%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%] selects a Content column.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_select_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" Specify both %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_object_s, context.set.notable);
- fl_print_format(" and the %[%r%r%] parameters to get the total objects.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_total_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When both %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_at_s, context.set.notable);
- fl_print_format(" and %[%r%r%] parameters are specified (at the same depth),", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_name_s, context.set.notable);
- fl_print_format(" the %[%r%r%] parameter value will be treated as a position relative to the specified", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_at_s, context.set.notable);
- fl_print_format(" %[%r%r%] parameter value.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_name_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" This program may support parameters, such as %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_depth_s, context.set.notable);
- fl_print_format(" or %[%r%r%], even if not supported by the standard.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_select_s, context.set.notable, f_string_eol_s);
- fl_print_format(" This is done to help ensure consistency for scripting.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" For parameters like %[%r%r%],", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_depth_s, context.set.notable);
- fl_print_format(" if the standard doesn't support nested Content, then only a depth of 0 would be valid.%r", file.stream, f_string_eol_s);
-
- fl_print_format(" For parameters like %[%r%r%],", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_select_s, context.set.notable);
- fl_print_format(" if the standard doesn't support multiple Content groups, then only a select of 0 would be valid.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_trim_s, context.set.notable);
- fl_print_format(" will remove leading and trailing white spaces when selecting objects or when printing objects.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When specifying both the %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_object_s, context.set.notable);
- fl_print_format(" parameter and the %[%r%r%] parameter, the entire Object and Content are printed, including the formatting.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_content_s, context.set.notable, f_string_eol_s);
- fl_print_format(" Both the Object and Content printed are already escaped.%r", file.stream, f_string_eol_s);
- fl_print_format(" Both the Object and Content are separated by a New Line character '\\n' (U+000A).%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%] accepts the following:%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_delimit_s, context.set.notable, f_string_eol_s);
- fl_print_format(" - %[%r%]: Do not apply delimits.%r", file.stream, context.set.notable, fss_embedded_list_read_delimit_mode_name_none_s, context.set.notable, f_string_eol_s);
- fl_print_format(" - %[%r%]: (default) Apply all delimits.%r", file.stream, context.set.notable, fss_embedded_list_read_delimit_mode_name_all_s, context.set.notable, f_string_eol_s);
- fl_print_format(" - A number, 0 or greater: apply delimits for Content at the specified depth.%r", file.stream, f_string_eol_s);
- fl_print_format(" - A number, 0 or greater, followed by a %[%r%]: (such as '1+') apply delimits for Content at the specified depth and any greater depth (numerically).%r", file.stream, context.set.notable, fss_embedded_list_read_delimit_mode_name_greater_s, context.set.notable, f_string_eol_s, f_string_eol_s);
- fl_print_format(" - A number, 0 or lesser, followed by a %[%r%]: (such as '1-') apply delimits for Content at the specified depth and any lesser depth (numerically).%r%r", file.stream, context.set.notable, fss_embedded_list_read_delimit_mode_name_lesser_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The %[%r%r%] parameter may be specified multiple times to customize the delimit behavior.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_delimit_s, context.set.notable, f_string_eol_s);
-
- fl_print_format(" The %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_delimit_s, context.set.notable);
- fl_print_format(" values %[%r%]", file.stream, context.set.notable, fss_embedded_list_read_delimit_mode_name_none_s, context.set.notable);
- fl_print_format(" and %[%r%],", file.stream, context.set.notable, fss_embedded_list_read_delimit_mode_name_all_s, context.set.notable);
- fl_print_format(" overrule all other delimit values.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameters %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_columns_s, context.set.notable);
- fl_print_format(" and %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_select_s, context.set.notable);
- fl_print_format(" refer to a Content column.%r", file.stream, f_string_eol_s);
- fl_print_format(" The word \"column\" is being loosely defined to refer to a specific Content.%r", file.stream, f_string_eol_s);
- fl_print_format(" This is not to be confused with a depth.%r", file.stream, f_string_eol_s);
-
- //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- f_file_stream_flush(file);
- funlockfile(file.stream);
-
- return F_none;
- }
-#endif // _di_fss_embedded_list_read_print_help_
-
#ifndef _di_fss_embedded_list_read_main_
- f_status_t fss_embedded_list_read_main(fll_program_data_t * const main, const f_console_arguments_t arguments) {
+ f_status_t fss_embedded_list_read_main(fll_program_data_t * const main, fss_embedded_list_read_setting_t * const setting) {
f_status_t status = F_none;
status = F_none;
if (main->parameters.array[fss_embedded_list_read_parameter_help_e].result == f_console_result_found_e) {
- fss_embedded_list_read_print_help(main->output.to, main->context);
+ fss_embedded_list_read_print_help(setting, main->message);
fss_embedded_list_read_data_delete(&data);
}
if (main->parameters.array[fss_embedded_list_read_parameter_version_e].result == f_console_result_found_e) {
- fll_program_print_version(main->output.to, fss_embedded_list_read_program_version_s);
+ fll_program_print_version(main->message, fss_embedded_list_read_program_version_s);
fss_embedded_list_read_data_delete(&data);
if (!((++main->signal_check) % fss_embedded_list_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_embedded_list_read_print_signal_received(&data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
// The signal check is always performed on each pass.
if (size_file > fss_embedded_list_read_block_max && fll_program_standard_signal_received(main)) {
- fss_embedded_list_read_print_signal_received(&data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
#endif
/**
- * Print help.
- *
- * @param file
- * The file to print to.
- * @param context
- * The color context settings.
- *
- * @return
- * F_none on success.
- */
-#ifndef _di_fss_embedded_list_read_print_help_
- extern f_status_t fss_embedded_list_read_print_help(const f_file_t file, const f_color_context_t context);
-#endif // _di_fss_embedded_list_read_print_help_
-
-/**
* Execute main program.
*
* If main.signal is non-zero, then this blocks and handles the following signals:
*
* @param main
* The main program data.
- * @param arguments
- * The parameters passed to the process.
+ * @param setting
+ * The main program settings.
*
- * @return
- * F_none on success.
+ * This alters setting.status:
+ * F_none on success.
+ * F_true on success when performing verification and verify passed.
+ * F_false on success when performing verification and verify failed.
+ * F_interrupt on (exit) signal received.
*
- * Status codes (with error bit) are returned on any problem.
+ * F_parameter (with error bit) if main is NULL or setting is NULL.
*/
#ifndef _di_fss_embedded_list_read_main_
- extern f_status_t fss_embedded_list_read_main(fll_program_data_t * const main, const f_console_arguments_t arguments);
+ extern f_status_t fss_embedded_list_read_main(fll_program_data_t * const main, fss_embedded_list_read_setting_t * const setting);
#endif // _di_fss_embedded_list_read_main_
#ifdef __cplusplus
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
fll_program_data_t data = fll_program_data_t_initialize;
+ fss_extended_list_read_setting_t setting = fss_extended_list_read_setting_t_initialize;
f_console_parameter_t parameters[] = fss_embedded_list_read_console_parameter_t_initialize;
data.parameters.array = parameters;
data.parameters.used = fss_embedded_list_read_total_parameters_d;
+ data.environment = envp;
if (f_pipe_input_exists()) {
data.pipe = fll_program_data_pipe_input_e;
fll_program_standard_set_up(&data);
- const f_status_t status = fss_embedded_list_read_main(&data, arguments);
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+
+ fss_embedded_list_read_setting_load(arguments, &data, &setting);
+ }
+
+ fss_embedded_list_read_main(&data, &setting);
+
+ fss_embedded_list_read_setting_unload(&data, &setting);
fll_program_data_delete(&data);
fll_program_standard_set_down(&data);
- if (F_status_is_error(status)) return 1;
-
- return 0;
+ return F_status_is_error(status) ? 1 : 0;
}
--- /dev/null
+#include "fss_embedded_list_read.h"
+#include "private-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fss_embedded_list_read_print_help_
+ f_status_t fss_embedded_list_read_print_help(fss_embedded_list_read_setting_t * const setting, const fl_print_t print) {
+
+ f_file_stream_lock(print.to);
+
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+
+ fll_program_print_help_header(print, fss_embedded_list_read_program_name_long_s, fss_embedded_list_read_program_version_s);
+
+ fll_program_print_help_option_standard(print);
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, fss_embedded_list_read_short_at_s, fss_embedded_list_read_long_at_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric index.");
+ fll_program_print_help_option(print, fss_embedded_list_read_short_content_s, fss_embedded_list_read_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Content (default).");
+ fll_program_print_help_option(print, fss_embedded_list_read_short_columns_s, fss_embedded_list_read_long_columns_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of columns.");
+ fll_program_print_help_option(print, fss_embedded_list_read_short_delimit_s, fss_embedded_list_read_long_delimit_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Designate how to handle applying delimits.");
+ fll_program_print_help_option(print, fss_embedded_list_read_short_depth_s, fss_embedded_list_read_long_depth_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric depth.");
+ fll_program_print_help_option(print, fss_embedded_list_read_short_empty_s, fss_embedded_list_read_long_empty_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Include empty Content when processing.");
+ fll_program_print_help_option(print, fss_embedded_list_read_short_line_s, fss_embedded_list_read_long_line_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print only the Content at the given line.");
+ fll_program_print_help_option(print, fss_embedded_list_read_short_name_s, fss_embedded_list_read_long_name_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object with this name.");
+ fll_program_print_help_option(print, fss_embedded_list_read_short_object_s, fss_embedded_list_read_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Object.");
+ fll_program_print_help_option(print, fss_embedded_list_read_short_pipe_s, fss_embedded_list_read_long_pipe_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print using the special pipe format.");
+ fll_program_print_help_option(print, fss_embedded_list_read_short_original_s, fss_embedded_list_read_long_original_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print with the original quotes and escapes.");
+ fll_program_print_help_option(print, fss_embedded_list_read_short_select_s, fss_embedded_list_read_long_select_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select sub-Content at this index.");
+ fll_program_print_help_option(print, fss_embedded_list_read_short_total_s, fss_embedded_list_read_long_total_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of lines.");
+ fll_program_print_help_option(print, fss_embedded_list_read_short_trim_s, fss_embedded_list_read_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names on select or print.");
+
+ fll_program_print_help_usage(print, fss_embedded_list_read_program_name_s, fll_program_parameter_filenames_s);
+
+ fl_print_format("%r %[Notes:%]%r", print.to.stream, f_string_eol_s, print.set->important, print.set->important, f_string_eol_s);
+
+ fl_print_format(" This program will print the Content associated with the given Object and Content main based on the FSS-0008 Embedded List standard.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" All numeric positions (indexes) start at 0 instead of 1.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" For example, a file of 17 lines would range from 0 to 16.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When using the %[%r%r%] option, an order of operations is enforced on the parameters.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_depth_s, print.set->notable, f_string_eol_s);
+
+ fl_print_format(" When this order of operations is in effect, parameters to the right of a depth parameter are influenced by that depth parameter:%r", print.to.stream, f_string_eol_s);
+
+ fl_print_format(" %[%r%r%]: An Object index at the specified depth.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_at_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" %[%r%r%]: A new depth within the specified depth, indexed from the root.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_depth_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" %[%r%r%]: An Object name at the specified depth.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_name_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%] must be in numeric order, but values in between may be skipped.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_depth_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" ('-d 0 -a 1 -d 2 -a 2' would specify index 1 at depth 0, any index at depth 1, and index 2 at depth 2.)%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" ('-d 2 -a 1 -d 0 -a 2' would be invalid because depth 2 is before depth 1.)%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%] selects a Content column.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_select_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" Specify both %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_object_s, print.set->notable);
+ fl_print_format(" and the %[%r%r%] parameters to get the total objects.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_total_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When both %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_at_s, print.set->notable);
+ fl_print_format(" and %[%r%r%] parameters are specified (at the same depth),", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_name_s, print.set->notable);
+ fl_print_format(" the %[%r%r%] parameter value will be treated as a position relative to the specified", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_at_s, print.set->notable);
+ fl_print_format(" %[%r%r%] parameter value.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_name_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" This program may support parameters, such as %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_depth_s, print.set->notable);
+ fl_print_format(" or %[%r%r%], even if not supported by the standard.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_select_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" This is done to help ensure consistency for scripting.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" For parameters like %[%r%r%],", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_depth_s, print.set->notable);
+ fl_print_format(" if the standard doesn't support nested Content, then only a depth of 0 would be valid.%r", print.to.stream, f_string_eol_s);
+
+ fl_print_format(" For parameters like %[%r%r%],", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_select_s, print.set->notable);
+ fl_print_format(" if the standard doesn't support multiple Content groups, then only a select of 0 would be valid.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_trim_s, print.set->notable);
+ fl_print_format(" will remove leading and trailing white spaces when selecting objects or when printing objects.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When specifying both the %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_object_s, print.set->notable);
+ fl_print_format(" parameter and the %[%r%r%] parameter, the entire Object and Content are printed, including the formatting.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_content_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" Both the Object and Content printed are already escaped.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" Both the Object and Content are separated by a New Line character '\\n' (U+000A).%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%] accepts the following:%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_delimit_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" - %[%r%]: Do not apply delimits.%r", print.to.stream, print.set->notable, fss_embedded_list_read_delimit_mode_name_none_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" - %[%r%]: (default) Apply all delimits.%r", print.to.stream, print.set->notable, fss_embedded_list_read_delimit_mode_name_all_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" - A number, 0 or greater: apply delimits for Content at the specified depth.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" - A number, 0 or greater, followed by a %[%r%]: (such as '1+') apply delimits for Content at the specified depth and any greater depth (numerically).%r", print.to.stream, print.set->notable, fss_embedded_list_read_delimit_mode_name_greater_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+ fl_print_format(" - A number, 0 or lesser, followed by a %[%r%]: (such as '1-') apply delimits for Content at the specified depth and any lesser depth (numerically).%r%r", print.to.stream, print.set->notable, fss_embedded_list_read_delimit_mode_name_lesser_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The %[%r%r%] parameter may be specified multiple times to customize the delimit behavior.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_delimit_s, print.set->notable, f_string_eol_s);
+
+ fl_print_format(" The %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_delimit_s, print.set->notable);
+ fl_print_format(" values %[%r%]", print.to.stream, print.set->notable, fss_embedded_list_read_delimit_mode_name_none_s, print.set->notable);
+ fl_print_format(" and %[%r%],", print.to.stream, print.set->notable, fss_embedded_list_read_delimit_mode_name_all_s, print.set->notable);
+ fl_print_format(" overrule all other delimit values.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameters %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_columns_s, print.set->notable);
+ fl_print_format(" and %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_read_long_select_s, print.set->notable);
+ fl_print_format(" refer to a Content column.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" The word \"column\" is being loosely defined to refer to a specific Content.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" This is not to be confused with a depth.%r", print.to.stream, f_string_eol_s);
+
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+
+ f_file_stream_flush(print.to);
+ f_file_stream_unlock(print.to);
+
+ return F_none;
+ }
+#endif // _di_fss_embedded_list_read_print_help_
+
+#ifndef _di_fss_embedded_list_read_print_line_first_
+ void fss_embedded_list_read_print_line_first(fss_embedded_list_read_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ }
+#endif // _di_fss_embedded_list_read_print_line_first_
+
+#ifndef _di_fss_embedded_list_read_print_line_last_
+ void fss_embedded_list_read_print_line_last(fss_embedded_list_read_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+ if (print.verbosity == f_console_verbosity_error_e && !F_status_is_error(setting->status)) return;
+ if (setting->flag & fss_embedded_list_read_main_flag_verify_e) return;
+ if ((setting->flag & fss_embedded_list_read_main_flag_file_to_e) && !F_status_is_error(setting->status)) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ }
+#endif // _di_fss_embedded_list_read_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: UTF-8
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _fss_embedded_list_read_print_h
+#define _fss_embedded_list_read_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print help.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * The output structure to print to.
+ *
+ * @return
+ * F_none on success.
+ */
+#ifndef _di_fss_embedded_list_read_print_help_
+ extern f_status_t fss_embedded_list_read_print_help(fss_embedded_list_read_setting_t * const setting, const fl_print_t print);
+#endif // _di_fss_embedded_list_read_print_help_
+
+/**
+ * Print first new line, unless verbosity says otherwise.
+ *
+ * This is generally either the first line in the program or the first line printed before an error message.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_embedded_list_read_print_line_first_
+ extern void fss_embedded_list_read_print_line_first(fss_embedded_list_read_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_embedded_list_read_print_line_first_
+
+/**
+ * Print last new line when the main is complete, unless verbosity says otherwise.
+ *
+ * This is generally the very last line printed in the program.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_embedded_list_read_print_line_last_
+ extern void fss_embedded_list_read_print_line_last(fss_embedded_list_read_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_embedded_list_read_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _fss_embedded_list_read_print_h
}
#endif // _di_fss_embedded_list_read_depths_resize_
-#ifndef _di_fss_embedded_list_read_print_signal_received_
- void fss_embedded_list_read_print_signal_received(fss_embedded_list_read_data_t * const data) {
-
- if (data->main->warning.verbosity != f_console_verbosity_verbose_e && data->main->warning.verbosity != f_console_verbosity_debug_e) return;
-
- // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
- fflush(data->main->warning.to.stream);
-
- flockfile(data->main->warning.to.stream);
-
- fl_print_format("%]%r%r%[Received signal code %]", data->main->warning.to.stream, data->main->context.set.reset, f_string_eol_s, f_string_eol_s, data->main->context.set.warning, data->main->context.set.warning);
- fl_print_format("%[%i%]", data->main->warning.to.stream, data->main->context.set.notable, data->main->signal_received, data->main->context.set.notable);
- fl_print_format("%[.%]%r", data->main->warning.to.stream, data->main->context.set.warning, data->main->context.set.warning, f_string_eol_s);
-
- funlockfile(data->main->warning.to.stream);
- }
-#endif // _di_fss_embedded_list_read_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
extern f_status_t fss_embedded_list_read_depths_resize(const f_array_length_t length, fss_embedded_list_read_depths_t *depths) F_attribute_visibility_internal_d;
#endif // _di_fss_embedded_list_read_depths_resize_
-/**
- * Print a message about a process signal being recieved, such as an interrupt signal.
- *
- * @param data
- * The program data.
- */
-#ifndef _di_fss_embedded_list_read_print_signal_received_
- extern void fss_embedded_list_read_print_signal_received(fss_embedded_list_read_data_t * const data) F_attribute_visibility_internal_d;
-#endif // _di_fss_embedded_list_read_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
if (!((++data->main->signal_check) % fss_embedded_list_read_signal_check_d)) {
if (fll_program_standard_signal_received(data->main)) {
- fss_embedded_list_read_print_signal_received(data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (!((++data->main->signal_check) % fss_embedded_list_read_signal_check_d)) {
if (fll_program_standard_signal_received(data->main)) {
- fss_embedded_list_read_print_signal_received(data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library fss_embedded_list_read.c common.c private-common.c private-print.c private-read.c
+build_sources_library fss_embedded_list_read.c common.c print.c private-common.c private-print.c private-read.c
build_sources_program main.c
-build_sources_headers fss_embedded_list_read.h common.h
+build_sources_headers fss_embedded_list_read.h common.h print.h
build_script yes
build_shared yes
const f_string_static_t fss_embedded_list_write_long_trim_s = macro_f_string_static_t_initialize(FSS_EMBEDDED_LIST_WRITE_long_trim_s, 0, FSS_EMBEDDED_LIST_WRITE_long_trim_s_length);
#endif // _di_fss_embedded_list_write_parameters_
+#ifndef _di_fss_embedded_list_write_setting_delete_
+ f_status_t fss_embedded_list_write_setting_delete(fss_embedded_list_write_setting_t * const setting) {
+
+ if (!setting) return F_status_set_error(F_parameter);
+
+ return F_none;
+ }
+#endif // _di_fss_embedded_list_write_setting_delete_
+
+#ifndef _di_fss_embedded_list_write_setting_load_
+ void fss_embedded_list_write_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_embedded_list_write_setting_t * const setting) {
+
+ if (!main || !setting) return;
+
+ // Load parameters.
+ setting->status = f_console_parameter_process(arguments, &main->parameters);
+ if (F_status_is_error(setting->status)) return;
+
+ {
+ f_array_length_t choice = 0;
+ f_uint16s_t choices = f_uint16s_t_initialize;
+
+ // Identify and prioritize "color context" parameters.
+ {
+ uint16_t choices_array[3] = { fss_embedded_list_write_parameter_no_color_e, fss_embedded_list_write_parameter_light_e, fss_embedded_list_write_parameter_dark_e };
+ choices.array = choices_array;
+ choices.used = 3;
+
+ const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
+
+ setting->status = fll_program_parameter_process_context(choices, modes, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_embedded_list_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_context", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_embedded_list_write_parameter_line_first_no_e].result == f_console_result_found_e) {
+ setting->line_first = f_string_empty_s;
+ }
+ else {
+ setting->line_first = f_string_eol_s;
+ }
+
+ if (main->parameters.array[fss_embedded_list_write_parameter_line_last_no_e].result == f_console_result_found_e) {
+ setting->line_last = f_string_empty_s;
+ }
+ else {
+ setting->line_last = f_string_eol_s;
+ }
+
+ // Identify and prioritize "verbosity" parameters.
+ {
+ uint16_t choices_array[5] = { fss_embedded_list_write_parameter_verbosity_quiet_e, fss_embedded_list_write_parameter_verbosity_error_e, fss_embedded_list_write_parameter_verbosity_verbose_e, fss_embedded_list_write_parameter_verbosity_debug_e, fss_embedded_list_write_parameter_verbosity_normal_e };
+ choices.array = choices_array;
+ choices.used = 5;
+
+ const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+
+ setting->status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_embedded_list_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_verbosity", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_embedded_list_write_parameter_help_e].result == f_console_result_found_e) {
+ setting->flag |= fss_embedded_list_write_main_flag_help_e;
+
+ return;
+ }
+
+ if (main->parameters.array[fss_embedded_list_write_parameter_version_e].result == f_console_result_found_e) {
+ setting->flag |= fss_embedded_list_write_main_flag_version_e;
+
+ return;
+ }
+
+ // Identify and prioritize "from" mode parameters.
+ {
+ uint16_t choices_array[2] = { fss_embedded_list_write_parameter_from_bytesequence_e, fss_embedded_list_write_parameter_from_codepoint_e };
+ choices.array = choices_array;
+ choices.used = 2;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_embedded_list_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_embedded_list_write_parameter_from_bytesequence_e) {
+ if (setting->mode & fss_embedded_list_write_mode_from_codepoint_e) {
+ setting->mode -= fss_embedded_list_write_mode_from_codepoint_e;
+ }
+
+ setting->mode |= fss_embedded_list_write_mode_from_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_embedded_list_write_parameter_from_codepoint_e) {
+ if (setting->mode & fss_embedded_list_write_mode_from_bytesequence_e) {
+ setting->mode -= fss_embedded_list_write_mode_from_bytesequence_e;
+ }
+
+ setting->mode |= fss_embedded_list_write_mode_from_codepoint_e;
+ }
+ }
+
+ // Identify and prioritize "to" mode parameters.
+ {
+ uint16_t choices_array[4] = { fss_embedded_list_write_parameter_to_bytesequence_e, fss_embedded_list_write_parameter_to_codepoint_e, fss_embedded_list_write_parameter_to_combining_e, fss_embedded_list_write_parameter_to_width_e };
+ choices.array = choices_array;
+ choices.used = 4;
+ choice = 1;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_embedded_list_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_embedded_list_write_parameter_to_bytesequence_e) {
+ if (setting->mode & fss_embedded_list_write_mode_to_codepoint_e) {
+ setting->mode -= fss_embedded_list_write_mode_to_codepoint_e;
+ }
+
+ if (setting->mode & fss_embedded_list_write_mode_to_combining_e) {
+ setting->mode -= fss_embedded_list_write_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_embedded_list_write_mode_to_width_e) {
+ setting->mode -= fss_embedded_list_write_mode_to_width_e;
+ }
+
+ setting->mode |= fss_embedded_list_write_mode_to_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_embedded_list_write_parameter_to_codepoint_e) {
+ if (setting->mode & fss_embedded_list_write_mode_to_bytesequence_e) {
+ setting->mode -= fss_embedded_list_write_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_embedded_list_write_mode_to_combining_e) {
+ setting->mode -= fss_embedded_list_write_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_embedded_list_write_mode_to_width_e) {
+ setting->mode -= fss_embedded_list_write_mode_to_width_e;
+ }
+
+ setting->mode |= fss_embedded_list_write_mode_to_codepoint_e;
+ }
+ else if (choices.array[choice] == fss_embedded_list_write_parameter_to_combining_e) {
+ if (setting->mode & fss_embedded_list_write_mode_to_bytesequence_e) {
+ setting->mode -= fss_embedded_list_write_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_embedded_list_write_mode_to_codepoint_e) {
+ setting->mode -= fss_embedded_list_write_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_embedded_list_write_parameter_to_width_e].result == f_console_result_found_e) {
+ setting->mode |= fss_embedded_list_write_mode_to_width_e;
+ }
+
+ setting->mode |= fss_embedded_list_write_mode_to_combining_e;
+ }
+ else if (choices.array[choice] == fss_embedded_list_write_parameter_to_width_e) {
+ if (setting->mode & fss_embedded_list_write_mode_to_bytesequence_e) {
+ setting->mode -= fss_embedded_list_write_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_embedded_list_write_mode_to_codepoint_e) {
+ setting->mode -= fss_embedded_list_write_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_embedded_list_write_parameter_to_combining_e].result == f_console_result_found_e) {
+ setting->mode |= fss_embedded_list_write_mode_to_combining_e;
+ }
+
+ setting->mode |= fss_embedded_list_write_mode_to_width_e;
+ }
+ }
+ }
+
+ f_string_static_t * const args = main->parameters.arguments.array;
+
+ if (main->parameters.array[fss_embedded_list_write_parameter_to_file_e].result == f_console_result_additional_e) {
+ if (main->parameters.array[fss_embedded_list_write_parameter_to_file_e].values.used > 1) {
+ fss_embedded_list_write_print_error_parameter_file_to_too_many(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+
+ if (args[main->parameters.array[fss_embedded_list_write_parameter_to_file_e].values.array[0]].used) {
+ setting->path_files_to.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(1, &setting->path_files_to);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_to.array[setting->path_files_to.used].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[main->parameters.array[fss_embedded_list_write_parameter_to_file_e].values.array[0]], &setting->path_files_to.array[0]);
+ if (F_status_is_error(setting->status)) return;
+
+ ++setting->path_files_to.used;
+
+ setting->status = f_file_stream_open(args[main->parameters.array[fss_embedded_list_write_parameter_to_file_e].values.array[0]], f_file_open_mode_append_s, &main->output.to);
+
+ if (F_status_is_error(setting->status)) {
+ fll_error_file_print(main->error, F_status_set_fine(setting->status), "f_file_stream_open", F_true, args[main->parameters.array[fss_embedded_list_write_parameter_to_file_e].values.array[0]], f_file_operation_open_s, fll_error_file_type_file_e);
+
+ return;
+ }
+
+ setting->flag |= fss_embedded_list_write_main_flag_file_to_e;
+ }
+ else {
+ fss_embedded_list_write_print_error_parameter_file_name_empty(main, setting, main->parameters.array[fss_embedded_list_write_parameter_to_file_e].values.array[0]);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+ else if (main->parameters.array[fss_embedded_list_write_parameter_to_file_e].result == f_console_result_found_e) {
+ fss_embedded_list_write_print_error_no_value(main, setting, fss_embedded_list_write_long_to_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ main->output.to = main->message.to;
+
+ if (setting->flag & fss_embedded_list_write_main_flag_file_to_e) {
+ setting->flag -= fss_embedded_list_write_main_flag_file_to_e;
+ }
+ }
+
+ if (main->parameters.array[fss_embedded_list_write_parameter_from_file_e].result == f_console_result_additional_e) {
+ setting->path_files_from.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(main->parameters.array[fss_embedded_list_write_parameter_from_file_e].values.used, &setting->path_files_from);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_from.used = main->parameters.array[fss_embedded_list_write_parameter_from_file_e].values.used;
+
+ f_array_length_t i = 0;
+ f_array_length_t index = 0;
+
+ for (; i < setting->path_files_from.used; ++i) {
+
+ index = main->parameters.array[fss_embedded_list_write_parameter_from_file_e].values.array[i];
+ setting->path_files_from.array[i].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[index], &setting->path_files_from.array[i]);
+ if (F_status_is_error(setting->status)) return;
+
+ if (args[index].used) {
+ if (f_file_exists(args[index], F_true) != F_true) {
+ fss_embedded_list_write_print_error_parameter_file_not_found(main, setting, F_true, args[index]);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_file_found_not);
+ }
+ }
+ }
+ else {
+ fss_embedded_list_write_print_error_parameter_file_name_empty(main, setting, index);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_parameter);
+ }
+ }
+ } // for
+
+ if (F_status_is_error(setting->status)) return;
+
+ setting->flag |= fss_embedded_list_write_main_flag_file_from_e;
+ }
+ else if (main->parameters.array[fss_embedded_list_write_parameter_from_file_e].result == f_console_result_found_e) {
+ fss_embedded_list_write_print_error_no_value(main, setting, fss_embedded_list_write_long_from_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ if (setting->flag & fss_embedded_list_write_main_flag_file_from_e) {
+ setting->flag -= fss_embedded_list_write_main_flag_file_from_e;
+ }
+ }
+
+ if (F_status_is_error(setting->status)) return;
+
+ if (main->parameters.array[fss_embedded_list_write_parameter_from_file_e].result == f_console_result_none_e && !((main->pipe & fll_program_data_pipe_input_e) || main->parameters.remaining.used)) {
+ fss_embedded_list_write_print_error_no_from(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+ }
+
+ if (!(setting->mode & fss_embedded_list_write_mode_to_bytesequence_e)) {
+ if (main->parameters.array[fss_embedded_list_write_parameter_separate_e].result == f_console_result_found_e || main->parameters.array[fss_embedded_list_write_parameter_headers_e].result == f_console_result_found_e) {
+ setting->prepend = fss_embedded_list_write_string_prepend_padding_s;
+ setting->append = f_string_eol_s;
+ }
+ else {
+ setting->prepend = f_string_space_s;
+ }
+ }
+
+ if (main->parameters.array[fss_embedded_list_write_parameter_headers_e].result == f_console_result_found_e) {
+ setting->flag |= fss_embedded_list_write_main_flag_header_e;
+ }
+
+ if (main->parameters.array[fss_embedded_list_write_parameter_separate_e].result == f_console_result_found_e) {
+ setting->flag |= fss_embedded_list_write_main_flag_separate_e;
+ }
+
+ if (main->parameters.array[fss_embedded_list_write_parameter_strip_invalid_e].result == f_console_result_found_e) {
+ setting->flag |= fss_embedded_list_write_main_flag_strip_invalid_e;
+ }
+
+ setting->valid_not = main->message.set->error;
+ }
+#endif // _di_fss_embedded_list_write_setting_load_
+
+#ifndef _di_fss_embedded_list_write_setting_unload_
+ f_status_t fss_embedded_list_write_setting_unload(fll_program_data_t * const main, fss_embedded_list_write_setting_t * const setting) {
+
+ if (!main || !setting) return F_status_set_error(F_parameter);
+
+ fss_embedded_list_write_setting_delete(setting);
+
+ return F_none;
+ }
+#endif // _di_fss_embedded_list_write_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
#define fss_embedded_list_write_total_parameters_d 21
#endif // _di_fss_embedded_list_write_parameters_
+/**
+ * Flags used to represent flags passed to the main function.
+ *
+ * fss_embedded_list_write_main_flag_*_e:
+ * - none: No modes in use.
+ * - file_from: Using a specified source file.
+ * - file_to: Using a specified destination file.
+ * - help: Print help.
+ * - header: Enable printing of headers.
+ * - separate: Enable printing of separators.
+ * - strip_invalid: Using strip invalid character mode.
+ * - verify: Using verify mode.
+ * - version: Print version.
+ */
+#ifndef _di_fss_embedded_list_write_main_flag_e_
+ enum {
+ fss_embedded_list_write_main_flag_none_e = 0x0,
+ fss_embedded_list_write_main_flag_file_from_e = 0x1,
+ fss_embedded_list_write_main_flag_file_to_e = 0x2,
+ fss_embedded_list_write_main_flag_header_e = 0x4,
+ fss_embedded_list_write_main_flag_help_e = 0x8,
+ fss_embedded_list_write_main_flag_separate_e = 0x10,
+ fss_embedded_list_write_main_flag_strip_invalid_e = 0x20,
+ fss_embedded_list_write_main_flag_verify_e = 0x40,
+ fss_embedded_list_write_main_flag_version_e = 0x80,
+ };
+#endif // _di_fss_embedded_list_write_main_flag_e_
+
+/**
+ * The fss embedded list write main program settings.
+ *
+ * This is passed to the program-specific main entry point to designate program settings.
+ * These program settings are often processed from the program arguments (often called the command line arguments).
+ *
+ * flag: Flags passed to the main function.
+ *
+ * status: The main status code, generally used by the load settings and main functions.
+ *
+ * line_first: A string expected to represent either "\n" or NULL to allow for easy handling of when to print first new line or not.
+ * line_last: A string expected to represent either "\n" or NULL to allow for easy handling of when to print last new line or not.
+ */
+#ifndef _di_fss_embedded_list_write_setting_t_
+ typedef struct {
+ uint16_t flag;
+
+ f_status_t status;
+
+ f_string_static_t line_first;
+ f_string_static_t line_last;
+ } fss_embedded_list_write_setting_t;
+
+ #define fss_embedded_list_write_setting_t_initialize \
+ { \
+ fss_embedded_list_write_main_flag_none_e, \
+ F_none, \
+ f_string_static_t_initialize, \
+ f_string_static_t_initialize, \
+ }
+#endif // _di_fss_embedded_list_write_setting_t_
+
+/**
+ * Delete the program main setting data.
+ *
+ * @param setting
+ * The program main setting data.
+ * This does not alter setting.status.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fss_embedded_list_write_setting_delete_
+ extern f_status_t fss_embedded_list_write_setting_delete(fss_embedded_list_write_setting_t * const setting);
+#endif // _di_fss_embedded_list_write_setting_delete_
+
+/**
+ * Perform the standard program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately retuns without doing anything.
+ *
+ * @param arguments
+ * The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ *
+ * This alters setting.status:
+ * F_none on success.
+ *
+ * Errors (with error bit) from: f_console_parameter_process().
+ * Errors (with error bit) from: fll_program_parameter_process_context().
+ *
+ * @see f_console_parameter_process()
+ * @see fll_program_parameter_process_context()
+ */
+#ifndef _di_fss_embedded_list_write_setting_load_
+ extern void fss_embedded_list_write_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_embedded_list_write_setting_t * const setting);
+#endif // _di_fss_embedded_list_write_setting_load_
+
+/**
+ * Perform the standard program setting unload process.
+ *
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * All buffers are deallocated.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: utf8_setting_delete().
+ *
+ * @see utf8_setting_delete()
+ */
+#ifndef _di_fss_embedded_list_write_setting_unload_
+ extern f_status_t fss_embedded_list_write_setting_unload(fll_program_data_t * const main, fss_embedded_list_write_setting_t * const setting);
+#endif // _di_fss_embedded_list_write_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern "C" {
#endif
-#ifndef _di_fss_embedded_list_write_print_help_
- f_status_t fss_embedded_list_write_print_help(const f_file_t file, const f_color_context_t context) {
-
- flockfile(file.stream);
-
- //if (!(setting->flag & XXX_main_flag_line_first_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- fll_program_print_help_header(file, context, fss_embedded_list_write_program_name_long_s, fss_embedded_list_write_program_version_s);
-
- fll_program_print_help_option_standard(file, context);
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, fss_embedded_list_write_short_file_s, fss_embedded_list_write_long_file_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a file to send data to.");
- fll_program_print_help_option(file, context, fss_embedded_list_write_short_content_s, fss_embedded_list_write_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "The Content to write.");
- fll_program_print_help_option(file, context, fss_embedded_list_write_short_double_s, fss_embedded_list_write_long_double_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use double quotes (default).");
- fll_program_print_help_option(file, context, fss_embedded_list_write_short_ignore_s, fss_embedded_list_write_long_ignore_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Ignore a given range within a Content.");
- fll_program_print_help_option(file, context, fss_embedded_list_write_short_object_s, fss_embedded_list_write_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The Object to write.");
- fll_program_print_help_option(file, context, fss_embedded_list_write_short_partial_s, fss_embedded_list_write_long_partial_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Do not write end of Object/Content character.");
- fll_program_print_help_option(file, context, fss_embedded_list_write_short_prepend_s, fss_embedded_list_write_long_prepend_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Prepend the given white space characters to the start of each multi-line Content.");
- fll_program_print_help_option(file, context, fss_embedded_list_write_short_single_s, fss_embedded_list_write_long_single_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use single quotes.");
- fll_program_print_help_option(file, context, fss_embedded_list_write_short_trim_s, fss_embedded_list_write_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names.");
-
- fll_program_print_help_usage(file, context, fss_embedded_list_write_program_name_s, f_string_empty_s);
-
- fl_print_format("%r The pipe uses the Backspace character '%[\\b%]' (%[U+0008%]) to designate the start of a Content.%r", file.stream, f_string_eol_s, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" The pipe uses the Form Feed character '%[\\f%]' (%[U+000C%]) to designate the end of the last Content.%r", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" The pipe uses the Vertical Line character '%[\\v%]' (%[U+000B%]) is used to ignore a Content range (use this both before and after the range).%r", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" For the pipe, an Object is terminated by either a Backspace character '%[\\b%]' (%[U+0008%])", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable);
- fl_print_format(" or a Form Feed character '%[\\f%]' (%[U+000C%]).%r", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" The end of the pipe represents the end of any Object or Content.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The FSS-0008 (Embedded List) specification does not support quoted names, therefore the parameters '%[%r%r%]'", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_write_long_single_s, context.set.notable);
- fl_print_format(" and '%[%r%r%]' do nothing.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_write_long_double_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter '%[%r%r%]' designates to not escape any valid nested Object or Content within some Content.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_write_long_ignore_s, context.set.notable, f_string_eol_s);
- fl_print_format(" This parameter requires two values.%r", file.stream, f_string_eol_s);
- fl_print_format(" This parameter is not used for ignoring anything from the input pipe.%r", file.stream, f_string_eol_s);
- fl_print_format(" This parameter must be specified after a '%[%r%r%]'", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_write_long_content_s, context.set.notable);
- fl_print_format(" parameter and this applies only to the Content represented by that specific '%[%r%r%]' parameter.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_embedded_list_write_long_content_s, context.set.notable, f_string_eol_s);
-
- //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- f_file_stream_flush(file);
- funlockfile(file.stream);
-
- return F_none;
- }
-#endif // _di_fss_embedded_list_write_print_help_
-
#ifndef _di_fss_embedded_list_write_main_
- f_status_t fss_embedded_list_write_main(fll_program_data_t * const main, const f_console_arguments_t arguments) {
+ f_status_t fss_embedded_list_write_main(fll_program_data_t * const main, fss_embedded_list_write_setting_t * const setting) {
f_status_t status = F_none;
status = F_none;
if (main->parameters.array[fss_embedded_list_write_parameter_help_e].result == f_console_result_found_e) {
- fss_embedded_list_write_print_help(main->output.to, main->context);
+ fss_embedded_list_write_print_help(setting, main->message);
return status;
}
if (main->parameters.array[fss_embedded_list_write_parameter_version_e].result == f_console_result_found_e) {
- fll_program_print_version(main->output.to, fss_embedded_list_write_program_version_s);
+ fll_program_print_version(main->message, fss_embedded_list_write_program_version_s);
return status;
}
if (!((++main->signal_check) % fss_embedded_list_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_embedded_list_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
if (!((++main->signal_check) % fss_embedded_list_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_embedded_list_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
if (!((++main->signal_check) % fss_embedded_list_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_embedded_list_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
#endif
/**
- * Print help.
- *
- * @param file
- * The file to print to.
- * @param context
- * The color context settings.
- *
- * @return
- * F_none on success.
- */
-#ifndef _di_fss_embedded_list_write_print_help_
- extern f_status_t fss_embedded_list_write_print_help(const f_file_t file, const f_color_context_t context);
-#endif // _di_fss_embedded_list_write_print_help_
-
-/**
* Execute main program.
*
* Be sure to call fss_embedded_list_write_main_delete() after executing this.
* Status codes (with error bit) are returned on any problem.
*/
#ifndef _di_fss_embedded_list_write_main_
- extern f_status_t fss_embedded_list_write_main(fll_program_data_t * const main, const f_console_arguments_t arguments);
+ extern f_status_t fss_embedded_list_write_main(fll_program_data_t * const main, fss_embedded_list_write_setting_t * const setting);
#endif // _di_fss_embedded_list_write_main_
#ifdef __cplusplus
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
fll_program_data_t data = fll_program_data_t_initialize;
+ fss_extended_list_write_setting_t setting = fss_extended_list_write_setting_t_initialize;
f_console_parameter_t parameters[] = fss_embedded_list_write_console_parameter_t_initialize;
data.parameters.array = parameters;
data.parameters.used = fss_embedded_list_write_total_parameters_d;
+ data.environment = envp;
if (f_pipe_input_exists()) {
data.pipe = fll_program_data_pipe_input_e;
fll_program_standard_set_up(&data);
- const f_status_t status = fss_embedded_list_write_main(&data, arguments);
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+
+ fss_embedded_list_write_setting_load(arguments, &data, &setting);
+ }
+
+ fss_embedded_list_write_main(&data, &setting);
+
+ fss_embedded_list_write_setting_unload(&data, &setting);
fll_program_data_delete(&data);
fll_program_standard_set_down(&data);
- if (F_status_is_error(status)) return 1;
-
- return 0;
+ return F_status_is_error(status) ? 1 : 0;
}
--- /dev/null
+#include "fss_embedded_list_write.h"
+#include "private-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fss_embedded_list_write_print_help_
+ f_status_t fss_embedded_list_write_print_help(fss_embedded_list_write_setting_t * const setting, const fl_print_t print) {
+
+ f_file_stream_lock(print.to);
+
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+
+ fll_program_print_help_header(print, fss_embedded_list_write_program_name_long_s, fss_embedded_list_write_program_version_s);
+
+ fll_program_print_help_option_standard(print);
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, fss_embedded_list_write_short_file_s, fss_embedded_list_write_long_file_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a file to send data to.");
+ fll_program_print_help_option(print, fss_embedded_list_write_short_content_s, fss_embedded_list_write_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "The Content to write.");
+ fll_program_print_help_option(print, fss_embedded_list_write_short_double_s, fss_embedded_list_write_long_double_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use double quotes (default).");
+ fll_program_print_help_option(print, fss_embedded_list_write_short_ignore_s, fss_embedded_list_write_long_ignore_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Ignore a given range within a Content.");
+ fll_program_print_help_option(print, fss_embedded_list_write_short_object_s, fss_embedded_list_write_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The Object to write.");
+ fll_program_print_help_option(print, fss_embedded_list_write_short_partial_s, fss_embedded_list_write_long_partial_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Do not write end of Object/Content character.");
+ fll_program_print_help_option(print, fss_embedded_list_write_short_prepend_s, fss_embedded_list_write_long_prepend_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Prepend the given white space characters to the start of each multi-line Content.");
+ fll_program_print_help_option(print, fss_embedded_list_write_short_single_s, fss_embedded_list_write_long_single_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use single quotes.");
+ fll_program_print_help_option(print, fss_embedded_list_write_short_trim_s, fss_embedded_list_write_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names.");
+
+ fll_program_print_help_usage(print, fss_embedded_list_write_program_name_s, f_string_empty_s);
+
+ fl_print_format("%r The pipe uses the Backspace character '%[\\b%]' (%[U+0008%]) to designate the start of a Content.%r", print.to.stream, f_string_eol_s, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" The pipe uses the Form Feed character '%[\\f%]' (%[U+000C%]) to designate the end of the last Content.%r", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" The pipe uses the Vertical Line character '%[\\v%]' (%[U+000B%]) is used to ignore a Content range (use this both before and after the range).%r", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" For the pipe, an Object is terminated by either a Backspace character '%[\\b%]' (%[U+0008%])", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable);
+ fl_print_format(" or a Form Feed character '%[\\f%]' (%[U+000C%]).%r", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" The end of the pipe represents the end of any Object or Content.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The FSS-0008 (Embedded List) specification does not support quoted names, therefore the parameters '%[%r%r%]'", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_write_long_single_s, print.set->notable);
+ fl_print_format(" and '%[%r%r%]' do nothing.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_write_long_double_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter '%[%r%r%]' designates to not escape any valid nested Object or Content within some Content.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_write_long_ignore_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" This parameter requires two values.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" This parameter is not used for ignoring anything from the input pipe.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" This parameter must be specified after a '%[%r%r%]'", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_write_long_content_s, print.set->notable);
+ fl_print_format(" parameter and this applies only to the Content represented by that specific '%[%r%r%]' parameter.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_embedded_list_write_long_content_s, print.set->notable, f_string_eol_s);
+
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+
+ f_file_stream_flush(print.to);
+ f_file_stream_unlock(print.to);
+
+ return F_none;
+ }
+#endif // _di_fss_embedded_list_write_print_help_
+
+#ifndef _di_fss_embedded_list_write_print_line_first_
+ void fss_embedded_list_write_print_line_first(fss_embedded_list_write_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ }
+#endif // _di_fss_embedded_list_write_print_line_first_
+
+#ifndef _di_fss_embedded_list_write_print_line_last_
+ void fss_embedded_list_write_print_line_last(fss_embedded_list_write_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+ if (print.verbosity == f_console_verbosity_error_e && !F_status_is_error(setting->status)) return;
+ if (setting->flag & fss_embedded_list_write_main_flag_verify_e) return;
+ if ((setting->flag & fss_embedded_list_write_main_flag_file_to_e) && !F_status_is_error(setting->status)) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ }
+#endif // _di_fss_embedded_list_write_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: UTF-8
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _fss_embedded_list_write_print_h
+#define _fss_embedded_list_write_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print help.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * The output structure to print to.
+ *
+ * @return
+ * F_none on success.
+ */
+#ifndef _di_fss_embedded_list_write_print_help_
+ extern f_status_t fss_embedded_list_write_print_help(fss_embedded_list_write_setting_t * const setting, const fl_print_t print);
+#endif // _di_fss_embedded_list_write_print_help_
+
+/**
+ * Print first new line, unless verbosity says otherwise.
+ *
+ * This is generally either the first line in the program or the first line printed before an error message.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_embedded_list_write_print_line_first_
+ extern void fss_embedded_list_write_print_line_first(fss_embedded_list_write_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_embedded_list_write_print_line_first_
+
+/**
+ * Print last new line when the main is complete, unless verbosity says otherwise.
+ *
+ * This is generally the very last line printed in the program.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_embedded_list_write_print_line_last_
+ extern void fss_embedded_list_write_print_line_last(fss_embedded_list_write_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_embedded_list_write_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _fss_embedded_list_write_print_h
extern "C" {
#endif
-#ifndef _di_fss_embedded_list_write_print_signal_received_
- void fss_embedded_list_write_print_signal_received(fll_program_data_t * const main) {
-
- if (main->warning.verbosity != f_console_verbosity_verbose_e && main->warning.verbosity != f_console_verbosity_debug_e) return;
-
- // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
- fflush(main->warning.to.stream);
-
- flockfile(main->warning.to.stream);
-
- fl_print_format("%]%r%r%[Received signal code %]", main->warning.to.stream, main->context.set.reset, f_string_eol_s, f_string_eol_s, main->context.set.warning, main->context.set.warning);
- fl_print_format("%[%i%]", main->warning.to.stream, main->context.set.notable, main->signal_received, main->context.set.notable);
- fl_print_format("%[.%]%r", main->warning.to.stream, main->context.set.warning, main->context.set.warning, f_string_eol_s);
-
- funlockfile(main->warning.to.stream);
- }
-#endif // _di_fss_embedded_list_write_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
#define fss_embedded_list_write_common_allocation_small_d 128
#endif // _di_fss_embedded_list_write_common_
-/**
- * Print a message about a process signal being recieved, such as an interrupt signal.
- *
- * @param main
- * The main program data.
- */
-#ifndef _di_fss_embedded_list_write_print_signal_received_
- extern void fss_embedded_list_write_print_signal_received(fll_program_data_t * const main) F_attribute_visibility_internal_d;
-#endif // _di_fss_embedded_list_write_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
if (!((++main->signal_check) % fss_embedded_list_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_embedded_list_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
f_string_dynamic_resize(0, &block);
f_string_dynamic_resize(0, &object);
if (!((++main->signal_check) % fss_embedded_list_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_embedded_list_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library fss_embedded_list_write.c common.c private-common.c private-write.c
+build_sources_library fss_embedded_list_write.c common.c print.c private-common.c private-write.c
build_sources_program main.c
-build_sources_headers fss_embedded_list_write.h common.h
+build_sources_headers fss_embedded_list_write.h common.h print.h
build_script yes
build_shared yes
}
#endif // _di_fss_extended_list_read_main_delete_
+#ifndef _di_fss_extended_list_read_setting_delete_
+ f_status_t fss_extended_list_read_setting_delete(fss_extended_list_read_setting_t * const setting) {
+
+ if (!setting) return F_status_set_error(F_parameter);
+
+ return F_none;
+ }
+#endif // _di_fss_extended_list_read_setting_delete_
+
+#ifndef _di_fss_extended_list_read_setting_load_
+ void fss_extended_list_read_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_extended_list_read_setting_t * const setting) {
+
+ if (!main || !setting) return;
+
+ // Load parameters.
+ setting->status = f_console_parameter_process(arguments, &main->parameters);
+ if (F_status_is_error(setting->status)) return;
+
+ {
+ f_array_length_t choice = 0;
+ f_uint16s_t choices = f_uint16s_t_initialize;
+
+ // Identify and prioritize "color context" parameters.
+ {
+ uint16_t choices_array[3] = { fss_extended_list_read_parameter_no_color_e, fss_extended_list_read_parameter_light_e, fss_extended_list_read_parameter_dark_e };
+ choices.array = choices_array;
+ choices.used = 3;
+
+ const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
+
+ setting->status = fll_program_parameter_process_context(choices, modes, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_extended_list_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_context", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_extended_list_read_parameter_line_first_no_e].result == f_console_result_found_e) {
+ setting->line_first = f_string_empty_s;
+ }
+ else {
+ setting->line_first = f_string_eol_s;
+ }
+
+ if (main->parameters.array[fss_extended_list_read_parameter_line_last_no_e].result == f_console_result_found_e) {
+ setting->line_last = f_string_empty_s;
+ }
+ else {
+ setting->line_last = f_string_eol_s;
+ }
+
+ // Identify and prioritize "verbosity" parameters.
+ {
+ uint16_t choices_array[5] = { fss_extended_list_read_parameter_verbosity_quiet_e, fss_extended_list_read_parameter_verbosity_error_e, fss_extended_list_read_parameter_verbosity_verbose_e, fss_extended_list_read_parameter_verbosity_debug_e, fss_extended_list_read_parameter_verbosity_normal_e };
+ choices.array = choices_array;
+ choices.used = 5;
+
+ const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+
+ setting->status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_extended_list_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_verbosity", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_extended_list_read_parameter_help_e].result == f_console_result_found_e) {
+ setting->flag |= fss_extended_list_read_main_flag_help_e;
+
+ return;
+ }
+
+ if (main->parameters.array[fss_extended_list_read_parameter_version_e].result == f_console_result_found_e) {
+ setting->flag |= fss_extended_list_read_main_flag_version_e;
+
+ return;
+ }
+
+ // Identify and prioritize "from" mode parameters.
+ {
+ uint16_t choices_array[2] = { fss_extended_list_read_parameter_from_bytesequence_e, fss_extended_list_read_parameter_from_codepoint_e };
+ choices.array = choices_array;
+ choices.used = 2;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_extended_list_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_extended_list_read_parameter_from_bytesequence_e) {
+ if (setting->mode & fss_extended_list_read_mode_from_codepoint_e) {
+ setting->mode -= fss_extended_list_read_mode_from_codepoint_e;
+ }
+
+ setting->mode |= fss_extended_list_read_mode_from_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_extended_list_read_parameter_from_codepoint_e) {
+ if (setting->mode & fss_extended_list_read_mode_from_bytesequence_e) {
+ setting->mode -= fss_extended_list_read_mode_from_bytesequence_e;
+ }
+
+ setting->mode |= fss_extended_list_read_mode_from_codepoint_e;
+ }
+ }
+
+ // Identify and prioritize "to" mode parameters.
+ {
+ uint16_t choices_array[4] = { fss_extended_list_read_parameter_to_bytesequence_e, fss_extended_list_read_parameter_to_codepoint_e, fss_extended_list_read_parameter_to_combining_e, fss_extended_list_read_parameter_to_width_e };
+ choices.array = choices_array;
+ choices.used = 4;
+ choice = 1;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_extended_list_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_extended_list_read_parameter_to_bytesequence_e) {
+ if (setting->mode & fss_extended_list_read_mode_to_codepoint_e) {
+ setting->mode -= fss_extended_list_read_mode_to_codepoint_e;
+ }
+
+ if (setting->mode & fss_extended_list_read_mode_to_combining_e) {
+ setting->mode -= fss_extended_list_read_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_extended_list_read_mode_to_width_e) {
+ setting->mode -= fss_extended_list_read_mode_to_width_e;
+ }
+
+ setting->mode |= fss_extended_list_read_mode_to_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_extended_list_read_parameter_to_codepoint_e) {
+ if (setting->mode & fss_extended_list_read_mode_to_bytesequence_e) {
+ setting->mode -= fss_extended_list_read_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_extended_list_read_mode_to_combining_e) {
+ setting->mode -= fss_extended_list_read_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_extended_list_read_mode_to_width_e) {
+ setting->mode -= fss_extended_list_read_mode_to_width_e;
+ }
+
+ setting->mode |= fss_extended_list_read_mode_to_codepoint_e;
+ }
+ else if (choices.array[choice] == fss_extended_list_read_parameter_to_combining_e) {
+ if (setting->mode & fss_extended_list_read_mode_to_bytesequence_e) {
+ setting->mode -= fss_extended_list_read_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_extended_list_read_mode_to_codepoint_e) {
+ setting->mode -= fss_extended_list_read_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_extended_list_read_parameter_to_width_e].result == f_console_result_found_e) {
+ setting->mode |= fss_extended_list_read_mode_to_width_e;
+ }
+
+ setting->mode |= fss_extended_list_read_mode_to_combining_e;
+ }
+ else if (choices.array[choice] == fss_extended_list_read_parameter_to_width_e) {
+ if (setting->mode & fss_extended_list_read_mode_to_bytesequence_e) {
+ setting->mode -= fss_extended_list_read_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_extended_list_read_mode_to_codepoint_e) {
+ setting->mode -= fss_extended_list_read_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_extended_list_read_parameter_to_combining_e].result == f_console_result_found_e) {
+ setting->mode |= fss_extended_list_read_mode_to_combining_e;
+ }
+
+ setting->mode |= fss_extended_list_read_mode_to_width_e;
+ }
+ }
+ }
+
+ f_string_static_t * const args = main->parameters.arguments.array;
+
+ if (main->parameters.array[fss_extended_list_read_parameter_to_file_e].result == f_console_result_additional_e) {
+ if (main->parameters.array[fss_extended_list_read_parameter_to_file_e].values.used > 1) {
+ fss_extended_list_read_print_error_parameter_file_to_too_many(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+
+ if (args[main->parameters.array[fss_extended_list_read_parameter_to_file_e].values.array[0]].used) {
+ setting->path_files_to.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(1, &setting->path_files_to);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_to.array[setting->path_files_to.used].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[main->parameters.array[fss_extended_list_read_parameter_to_file_e].values.array[0]], &setting->path_files_to.array[0]);
+ if (F_status_is_error(setting->status)) return;
+
+ ++setting->path_files_to.used;
+
+ setting->status = f_file_stream_open(args[main->parameters.array[fss_extended_list_read_parameter_to_file_e].values.array[0]], f_file_open_mode_append_s, &main->output.to);
+
+ if (F_status_is_error(setting->status)) {
+ fll_error_file_print(main->error, F_status_set_fine(setting->status), "f_file_stream_open", F_true, args[main->parameters.array[fss_extended_list_read_parameter_to_file_e].values.array[0]], f_file_operation_open_s, fll_error_file_type_file_e);
+
+ return;
+ }
+
+ setting->flag |= fss_extended_list_read_main_flag_file_to_e;
+ }
+ else {
+ fss_extended_list_read_print_error_parameter_file_name_empty(main, setting, main->parameters.array[fss_extended_list_read_parameter_to_file_e].values.array[0]);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+ else if (main->parameters.array[fss_extended_list_read_parameter_to_file_e].result == f_console_result_found_e) {
+ fss_extended_list_read_print_error_no_value(main, setting, fss_extended_list_read_long_to_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ main->output.to = main->message.to;
+
+ if (setting->flag & fss_extended_list_read_main_flag_file_to_e) {
+ setting->flag -= fss_extended_list_read_main_flag_file_to_e;
+ }
+ }
+
+ if (main->parameters.array[fss_extended_list_read_parameter_from_file_e].result == f_console_result_additional_e) {
+ setting->path_files_from.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(main->parameters.array[fss_extended_list_read_parameter_from_file_e].values.used, &setting->path_files_from);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_from.used = main->parameters.array[fss_extended_list_read_parameter_from_file_e].values.used;
+
+ f_array_length_t i = 0;
+ f_array_length_t index = 0;
+
+ for (; i < setting->path_files_from.used; ++i) {
+
+ index = main->parameters.array[fss_extended_list_read_parameter_from_file_e].values.array[i];
+ setting->path_files_from.array[i].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[index], &setting->path_files_from.array[i]);
+ if (F_status_is_error(setting->status)) return;
+
+ if (args[index].used) {
+ if (f_file_exists(args[index], F_true) != F_true) {
+ fss_extended_list_read_print_error_parameter_file_not_found(main, setting, F_true, args[index]);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_file_found_not);
+ }
+ }
+ }
+ else {
+ fss_extended_list_read_print_error_parameter_file_name_empty(main, setting, index);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_parameter);
+ }
+ }
+ } // for
+
+ if (F_status_is_error(setting->status)) return;
+
+ setting->flag |= fss_extended_list_read_main_flag_file_from_e;
+ }
+ else if (main->parameters.array[fss_extended_list_read_parameter_from_file_e].result == f_console_result_found_e) {
+ fss_extended_list_read_print_error_no_value(main, setting, fss_extended_list_read_long_from_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ if (setting->flag & fss_extended_list_read_main_flag_file_from_e) {
+ setting->flag -= fss_extended_list_read_main_flag_file_from_e;
+ }
+ }
+
+ if (F_status_is_error(setting->status)) return;
+
+ if (main->parameters.array[fss_extended_list_read_parameter_from_file_e].result == f_console_result_none_e && !((main->pipe & fll_program_data_pipe_input_e) || main->parameters.remaining.used)) {
+ fss_extended_list_read_print_error_no_from(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+ }
+
+ if (!(setting->mode & fss_extended_list_read_mode_to_bytesequence_e)) {
+ if (main->parameters.array[fss_extended_list_read_parameter_separate_e].result == f_console_result_found_e || main->parameters.array[fss_extended_list_read_parameter_headers_e].result == f_console_result_found_e) {
+ setting->prepend = fss_extended_list_read_string_prepend_padding_s;
+ setting->append = f_string_eol_s;
+ }
+ else {
+ setting->prepend = f_string_space_s;
+ }
+ }
+
+ if (main->parameters.array[fss_extended_list_read_parameter_headers_e].result == f_console_result_found_e) {
+ setting->flag |= fss_extended_list_read_main_flag_header_e;
+ }
+
+ if (main->parameters.array[fss_extended_list_read_parameter_separate_e].result == f_console_result_found_e) {
+ setting->flag |= fss_extended_list_read_main_flag_separate_e;
+ }
+
+ if (main->parameters.array[fss_extended_list_read_parameter_strip_invalid_e].result == f_console_result_found_e) {
+ setting->flag |= fss_extended_list_read_main_flag_strip_invalid_e;
+ }
+
+ setting->valid_not = main->message.set->error;
+ }
+#endif // _di_fss_extended_list_read_setting_load_
+
+#ifndef _di_fss_extended_list_read_setting_unload_
+ f_status_t fss_extended_list_read_setting_unload(fll_program_data_t * const main, fss_extended_list_read_setting_t * const setting) {
+
+ if (!main || !setting) return F_status_set_error(F_parameter);
+
+ fss_extended_list_read_setting_delete(setting);
+
+ return F_none;
+ }
+#endif // _di_fss_extended_list_read_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
#endif // _di_fss_extended_list_read_delimit_modes_
/**
+ * Flags used to represent flags passed to the main function.
+ *
+ * fss_extended_list_read_main_flag_*_e:
+ * - none: No modes in use.
+ * - file_from: Using a specified source file.
+ * - file_to: Using a specified destination file.
+ * - help: Print help.
+ * - header: Enable printing of headers.
+ * - separate: Enable printing of separators.
+ * - strip_invalid: Using strip invalid character mode.
+ * - verify: Using verify mode.
+ * - version: Print version.
+ */
+#ifndef _di_fss_extended_list_read_main_flag_e_
+ enum {
+ fss_extended_list_read_main_flag_none_e = 0x0,
+ fss_extended_list_read_main_flag_file_from_e = 0x1,
+ fss_extended_list_read_main_flag_file_to_e = 0x2,
+ fss_extended_list_read_main_flag_header_e = 0x4,
+ fss_extended_list_read_main_flag_help_e = 0x8,
+ fss_extended_list_read_main_flag_separate_e = 0x10,
+ fss_extended_list_read_main_flag_strip_invalid_e = 0x20,
+ fss_extended_list_read_main_flag_verify_e = 0x40,
+ fss_extended_list_read_main_flag_version_e = 0x80,
+ };
+#endif // _di_fss_extended_list_read_main_flag_e_
+
+/**
+ * The fss extended list read main program settings.
+ *
+ * This is passed to the program-specific main entry point to designate program settings.
+ * These program settings are often processed from the program arguments (often called the command line arguments).
+ *
+ * flag: Flags passed to the main function.
+ *
+ * status: The main status code, generally used by the load settings and main functions.
+ *
+ * line_first: A string expected to represent either "\n" or NULL to allow for easy handling of when to print first new line or not.
+ * line_last: A string expected to represent either "\n" or NULL to allow for easy handling of when to print last new line or not.
+ */
+#ifndef _di_fss_extended_list_read_setting_t_
+ typedef struct {
+ uint16_t flag;
+
+ f_status_t status;
+
+ f_string_static_t line_first;
+ f_string_static_t line_last;
+ } fss_extended_list_read_setting_t;
+
+ #define fss_extended_list_read_setting_t_initialize \
+ { \
+ fss_extended_list_read_main_flag_none_e, \
+ F_none, \
+ f_string_static_t_initialize, \
+ f_string_static_t_initialize, \
+ }
+#endif // _di_fss_extended_list_read_setting_t_
+
+/**
* Deallocate main.
*
* @param main
extern f_status_t fss_extended_list_read_main_delete(fll_program_data_t *main);
#endif // _di_fss_extended_list_read_main_delete_
+/**
+ * Delete the program main setting data.
+ *
+ * @param setting
+ * The program main setting data.
+ * This does not alter setting.status.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fss_extended_list_read_setting_delete_
+ extern f_status_t fss_extended_list_read_setting_delete(fss_extended_list_read_setting_t * const setting);
+#endif // _di_fss_extended_list_read_setting_delete_
+
+/**
+ * Perform the standard program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately retuns without doing anything.
+ *
+ * @param arguments
+ * The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ *
+ * This alters setting.status:
+ * F_none on success.
+ *
+ * Errors (with error bit) from: f_console_parameter_process().
+ * Errors (with error bit) from: fll_program_parameter_process_context().
+ *
+ * @see f_console_parameter_process()
+ * @see fll_program_parameter_process_context()
+ */
+#ifndef _di_fss_extended_list_read_setting_load_
+ extern void fss_extended_list_read_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_extended_list_read_setting_t * const setting);
+#endif // _di_fss_extended_list_read_setting_load_
+
+/**
+ * Perform the standard program setting unload process.
+ *
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * All buffers are deallocated.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: utf8_setting_delete().
+ *
+ * @see utf8_setting_delete()
+ */
+#ifndef _di_fss_extended_list_read_setting_unload_
+ extern f_status_t fss_extended_list_read_setting_unload(fll_program_data_t * const main, fss_extended_list_read_setting_t * const setting);
+#endif // _di_fss_extended_list_read_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern "C" {
#endif
-#ifndef _di_fss_extended_list_read_print_help_
- f_status_t fss_extended_list_read_print_help(const f_file_t file, const f_color_context_t context) {
-
- flockfile(file.stream);
-
- //if (!(setting->flag & XXX_main_flag_line_first_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- fll_program_print_help_header(file, context, fss_extended_list_read_program_name_long_s, fss_extended_list_read_program_version_s);
-
- fll_program_print_help_option_standard(file, context);
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, fss_extended_list_read_short_at_s, fss_extended_list_read_long_at_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric index.");
- fll_program_print_help_option(file, context, fss_extended_list_read_short_content_s, fss_extended_list_read_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Content (default).");
- fll_program_print_help_option(file, context, fss_extended_list_read_short_columns_s, fss_extended_list_read_long_columns_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of columns.");
- fll_program_print_help_option(file, context, fss_extended_list_read_short_delimit_s, fss_extended_list_read_long_delimit_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Designate how to handle applying delimits.");
- fll_program_print_help_option(file, context, fss_extended_list_read_short_depth_s, fss_extended_list_read_long_depth_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric depth.");
- fll_program_print_help_option(file, context, fss_extended_list_read_short_empty_s, fss_extended_list_read_long_empty_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Include empty Content when processing.");
- fll_program_print_help_option(file, context, fss_extended_list_read_short_line_s, fss_extended_list_read_long_line_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print only the Content at the given line.");
- fll_program_print_help_option(file, context, fss_extended_list_read_short_name_s, fss_extended_list_read_long_name_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object with this name.");
- fll_program_print_help_option(file, context, fss_extended_list_read_short_object_s, fss_extended_list_read_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Object.");
- fll_program_print_help_option(file, context, fss_extended_list_read_short_pipe_s, fss_extended_list_read_long_pipe_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print using the special pipe format.");
- fll_program_print_help_option(file, context, fss_extended_list_read_short_original_s, fss_extended_list_read_long_original_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print with the original quotes and escapes.");
- fll_program_print_help_option(file, context, fss_extended_list_read_short_select_s, fss_extended_list_read_long_select_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select sub-Content at this index.");
- fll_program_print_help_option(file, context, fss_extended_list_read_short_total_s, fss_extended_list_read_long_total_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of lines.");
- fll_program_print_help_option(file, context, fss_extended_list_read_short_trim_s, fss_extended_list_read_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names on select or print.");
-
- fll_program_print_help_usage(file, context, fss_extended_list_read_program_name_s, fll_program_parameter_filenames_s);
-
- fl_print_format("%r %[Notes:%]%r", file.stream, f_string_eol_s, context.set.important, context.set.important, f_string_eol_s);
-
- fl_print_format(" This program will print the Content associated with the given Object and Content main based on the FSS-0003 Extended List standard.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" All numeric positions (indexes) start at 0 instead of 1.%r", file.stream, f_string_eol_s);
- fl_print_format(" For example, a file of 17 lines would range from 0 to 16.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When using the %[%r%r%] option, an order of operations is enforced on the parameters.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_depth_s, context.set.notable, f_string_eol_s);
-
- fl_print_format(" When this order of operations is in effect, parameters to the right of a depth parameter are influenced by that depth parameter:%r", file.stream, f_string_eol_s);
-
- fl_print_format(" %[%r%r%]: An Object index at the specified depth.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_at_s, context.set.notable, f_string_eol_s);
- fl_print_format(" %[%r%r%]: A new depth within the specified depth, indexed from the root.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_depth_s, context.set.notable, f_string_eol_s);
- fl_print_format(" %[%r%r%]: An Object name at the specified depth.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_name_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%] must be in numeric order, but values in between may be skipped.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_depth_s, context.set.notable, f_string_eol_s);
- fl_print_format(" ('-d 0 -a 1 -d 2 -a 2' would specify index 1 at depth 0, any index at depth 1, and index 2 at depth 2.)%r", file.stream, f_string_eol_s);
- fl_print_format(" ('-d 2 -a 1 -d 0 -a 2' would be invalid because depth 2 is before depth 1.)%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%] selects a Content column.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_select_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" Specify both %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_object_s, context.set.notable);
- fl_print_format(" and the %[%r%r%] parameters to get the total objects.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_total_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When both %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_at_s, context.set.notable);
- fl_print_format(" and %[%r%r%] parameters are specified (at the same depth),", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_name_s, context.set.notable);
- fl_print_format(" the %[%r%r%] parameter value will be treated as a position relative to the specified", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_at_s, context.set.notable);
- fl_print_format(" %[%r%r%] parameter value.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_name_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" This program may support parameters, such as %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_depth_s, context.set.notable);
- fl_print_format(" or %[%r%r%], even if not supported by the standard.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_select_s, context.set.notable, f_string_eol_s);
- fl_print_format(" This is done to help ensure consistency for scripting.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" For parameters like %[%r%r%],", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_depth_s, context.set.notable);
- fl_print_format(" if the standard doesn't support nested Content, then only a depth of 0 would be valid.%r", file.stream, f_string_eol_s);
-
- fl_print_format(" For parameters like %[%r%r%],", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_select_s, context.set.notable);
- fl_print_format(" if the standard doesn't support multiple Content groups, then only a select of 0 would be valid.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_trim_s, context.set.notable);
- fl_print_format(" will remove leading and trailing white spaces when selecting objects or when printing objects.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When specifying both the %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_object_s, context.set.notable);
- fl_print_format(" parameter and the %[%r%r%] parameter, the entire Object and Content are printed, including the formatting.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_content_s, context.set.notable, f_string_eol_s);
- fl_print_format(" Both the Object and Content printed are already escaped.%r", file.stream, f_string_eol_s);
- fl_print_format(" Both the Object and Content are separated by a New Line character '\\n' (U+000A).%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%] accepts the following:%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_delimit_s, context.set.notable, f_string_eol_s);
- fl_print_format(" - %[%r%]: Do not apply delimits.%r", file.stream, context.set.notable, fss_extended_list_read_delimit_mode_name_none_s, context.set.notable, f_string_eol_s);
- fl_print_format(" - %[%r%]: (default) Apply all delimits.%r", file.stream, context.set.notable, fss_extended_list_read_delimit_mode_name_all_s, context.set.notable, f_string_eol_s);
- fl_print_format(" - %[%r%]: Apply delimits for Objects.%r", file.stream, context.set.notable, fss_extended_list_read_delimit_mode_name_object_s, context.set.notable, f_string_eol_s);
- fl_print_format(" - A number, 0 or greater: apply delimits for Content at the specified depth.%r", file.stream, f_string_eol_s);
- fl_print_format(" - A number, 0 or greater, followed by a %[%r%]: (such as '1+') apply delimits for Content at the specified depth and any greater depth (numerically).%r", file.stream, context.set.notable, fss_extended_list_read_delimit_mode_name_greater_s, context.set.notable, f_string_eol_s, f_string_eol_s);
- fl_print_format(" - A number, 0 or lesser, followed by a %[%r%]: (such as '1-') apply delimits for Content at the specified depth and any lesser depth (numerically).%r%r", file.stream, context.set.notable, fss_extended_list_read_delimit_mode_name_lesser_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The %[%r%r%] parameter may be specified multiple times to customize the delimit behavior.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_delimit_s, context.set.notable, f_string_eol_s);
-
- fl_print_format(" The %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_delimit_s, context.set.notable);
- fl_print_format(" values %[%r%]", file.stream, context.set.notable, fss_extended_list_read_delimit_mode_name_none_s, context.set.notable);
- fl_print_format(" and %[%r%],", file.stream, context.set.notable, fss_extended_list_read_delimit_mode_name_all_s, context.set.notable);
- fl_print_format(" overrule all other delimit values.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameters %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_columns_s, context.set.notable);
- fl_print_format(" and %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_select_s, context.set.notable);
- fl_print_format(" refer to a Content column.%r", file.stream, f_string_eol_s);
- fl_print_format(" The word \"column\" is being loosely defined to refer to a specific Content.%r", file.stream, f_string_eol_s);
- fl_print_format(" This is not to be confused with a depth.%r", file.stream, f_string_eol_s);
-
- //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- f_file_stream_flush(file);
- funlockfile(file.stream);
-
- return F_none;
- }
-#endif // _di_fss_extended_list_read_print_help_
-
#ifndef _di_fss_extended_list_read_main_
- f_status_t fss_extended_list_read_main(fll_program_data_t * const main, const f_console_arguments_t arguments) {
+ f_status_t fss_extended_list_read_main(fll_program_data_t * const main, fss_extended_list_read_setting_t * const setting) {
f_status_t status = F_none;
status = F_none;
if (main->parameters.array[fss_extended_list_read_parameter_help_e].result == f_console_result_found_e) {
- fss_extended_list_read_print_help(main->output.to, main->context);
+ fss_extended_list_read_print_help(setting, main->message);
return status;
}
if (main->parameters.array[fss_extended_list_read_parameter_version_e].result == f_console_result_found_e) {
- fll_program_print_version(main->output.to, fss_extended_list_read_program_version_s);
+ fll_program_print_version(main->message, fss_extended_list_read_program_version_s);
return status;
}
if (!((++main->signal_check) % fss_extended_list_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_extended_list_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
if (!((++main->signal_check) % fss_extended_list_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_extended_list_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
// The signal check is always performed on each pass.
if (size_file > fss_extended_list_read_block_max && fll_program_standard_signal_received(main)) {
- fss_extended_list_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
#endif
/**
- * Print help.
- *
- * @param file
- * The file to print to.
- * @param context
- * The color context settings.
- *
- * @return
- * F_none on success.
- */
-#ifndef _di_fss_extended_list_read_print_help_
- extern f_status_t fss_extended_list_read_print_help(const f_file_t file, const f_color_context_t context);
-#endif // _di_fss_extended_list_read_print_help_
-
-/**
* Execute main program.
*
* If main.signal is non-zero, then this blocks and handles the following signals:
*
* @param main
* The main program data.
- * @param arguments
- * The parameters passed to the process.
+ * @param setting
+ * The main program settings.
*
- * @return
- * F_none on success.
+ * This alters setting.status:
+ * F_none on success.
+ * F_true on success when performing verification and verify passed.
+ * F_false on success when performing verification and verify failed.
+ * F_interrupt on (exit) signal received.
*
- * Status codes (with error bit) are returned on any problem.
+ * F_parameter (with error bit) if main is NULL or setting is NULL.
*/
#ifndef _di_fss_extended_list_read_main_
- extern f_status_t fss_extended_list_read_main(fll_program_data_t * const main, const f_console_arguments_t arguments);
+ extern f_status_t fss_extended_list_read_main(fll_program_data_t * const main, fss_extended_list_read_setting_t * const setting);
#endif // _di_fss_extended_list_read_main_
#ifdef __cplusplus
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
fll_program_data_t data = fll_program_data_t_initialize;
+ fss_extended_list_read_setting_t setting = fss_extended_list_read_setting_t_initialize;
f_console_parameter_t parameters[] = fss_extended_list_read_console_parameter_t_initialize;
data.parameters.array = parameters;
data.parameters.used = fss_extended_list_read_total_parameters_d;
+ data.environment = envp;
if (f_pipe_input_exists()) {
data.pipe = fll_program_data_pipe_input_e;
fll_program_standard_set_up(&data);
- const f_status_t status = fss_extended_list_read_main(&data, arguments);
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+
+ fss_extended_list_read_setting_load(arguments, &data, &setting);
+ }
+
+ fss_extended_list_read_main(&data, &setting);
+
+ fss_extended_list_read_setting_unload(&data, &setting);
fll_program_data_delete(&data);
fll_program_standard_set_down(&data);
- if (F_status_is_error(status)) return 1;
-
- return 0;
+ return F_status_is_error(status) ? 1 : 0;
}
--- /dev/null
+#include "fss_embedded_list_read.h"
+#include "private-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fss_extended_list_read_print_help_
+ f_status_t fss_extended_list_read_print_help(fss_extended_list_read_setting_t * const setting, const fl_print_t print) {
+
+ f_file_stream_lock(print.to);
+
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+
+ fll_program_print_help_header(print, fss_extended_list_read_program_name_long_s, fss_extended_list_read_program_version_s);
+
+ fll_program_print_help_option_standard(print);
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, fss_extended_list_read_short_at_s, fss_extended_list_read_long_at_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric index.");
+ fll_program_print_help_option(print, fss_extended_list_read_short_content_s, fss_extended_list_read_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Content (default).");
+ fll_program_print_help_option(print, fss_extended_list_read_short_columns_s, fss_extended_list_read_long_columns_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of columns.");
+ fll_program_print_help_option(print, fss_extended_list_read_short_delimit_s, fss_extended_list_read_long_delimit_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Designate how to handle applying delimits.");
+ fll_program_print_help_option(print, fss_extended_list_read_short_depth_s, fss_extended_list_read_long_depth_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric depth.");
+ fll_program_print_help_option(print, fss_extended_list_read_short_empty_s, fss_extended_list_read_long_empty_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Include empty Content when processing.");
+ fll_program_print_help_option(print, fss_extended_list_read_short_line_s, fss_extended_list_read_long_line_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print only the Content at the given line.");
+ fll_program_print_help_option(print, fss_extended_list_read_short_name_s, fss_extended_list_read_long_name_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object with this name.");
+ fll_program_print_help_option(print, fss_extended_list_read_short_object_s, fss_extended_list_read_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Object.");
+ fll_program_print_help_option(print, fss_extended_list_read_short_pipe_s, fss_extended_list_read_long_pipe_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print using the special pipe format.");
+ fll_program_print_help_option(print, fss_extended_list_read_short_original_s, fss_extended_list_read_long_original_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print with the original quotes and escapes.");
+ fll_program_print_help_option(print, fss_extended_list_read_short_select_s, fss_extended_list_read_long_select_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select sub-Content at this index.");
+ fll_program_print_help_option(print, fss_extended_list_read_short_total_s, fss_extended_list_read_long_total_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of lines.");
+ fll_program_print_help_option(print, fss_extended_list_read_short_trim_s, fss_extended_list_read_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names on select or print.");
+
+ fll_program_print_help_usage(print, fss_extended_list_read_program_name_s, fll_program_parameter_filenames_s);
+
+ fl_print_format("%r %[Notes:%]%r", print.to.stream, f_string_eol_s, print.set->important, print.set->important, f_string_eol_s);
+
+ fl_print_format(" This program will print the Content associated with the given Object and Content main based on the FSS-0003 Extended List standard.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" All numeric positions (indexes) start at 0 instead of 1.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" For example, a file of 17 lines would range from 0 to 16.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When using the %[%r%r%] option, an order of operations is enforced on the parameters.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_depth_s, print.set->notable, f_string_eol_s);
+
+ fl_print_format(" When this order of operations is in effect, parameters to the right of a depth parameter are influenced by that depth parameter:%r", print.to.stream, f_string_eol_s);
+
+ fl_print_format(" %[%r%r%]: An Object index at the specified depth.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_at_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" %[%r%r%]: A new depth within the specified depth, indexed from the root.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_depth_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" %[%r%r%]: An Object name at the specified depth.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_name_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%] must be in numeric order, but values in between may be skipped.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_depth_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" ('-d 0 -a 1 -d 2 -a 2' would specify index 1 at depth 0, any index at depth 1, and index 2 at depth 2.)%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" ('-d 2 -a 1 -d 0 -a 2' would be invalid because depth 2 is before depth 1.)%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%] selects a Content column.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_select_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" Specify both %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_object_s, print.set->notable);
+ fl_print_format(" and the %[%r%r%] parameters to get the total objects.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_total_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When both %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_at_s, print.set->notable);
+ fl_print_format(" and %[%r%r%] parameters are specified (at the same depth),", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_name_s, print.set->notable);
+ fl_print_format(" the %[%r%r%] parameter value will be treated as a position relative to the specified", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_at_s, print.set->notable);
+ fl_print_format(" %[%r%r%] parameter value.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_name_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" This program may support parameters, such as %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_depth_s, print.set->notable);
+ fl_print_format(" or %[%r%r%], even if not supported by the standard.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_select_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" This is done to help ensure consistency for scripting.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" For parameters like %[%r%r%],", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_depth_s, print.set->notable);
+ fl_print_format(" if the standard doesn't support nested Content, then only a depth of 0 would be valid.%r", print.to.stream, f_string_eol_s);
+
+ fl_print_format(" For parameters like %[%r%r%],", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_select_s, print.set->notable);
+ fl_print_format(" if the standard doesn't support multiple Content groups, then only a select of 0 would be valid.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_trim_s, print.set->notable);
+ fl_print_format(" will remove leading and trailing white spaces when selecting objects or when printing objects.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When specifying both the %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_object_s, print.set->notable);
+ fl_print_format(" parameter and the %[%r%r%] parameter, the entire Object and Content are printed, including the formatting.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_content_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" Both the Object and Content printed are already escaped.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" Both the Object and Content are separated by a New Line character '\\n' (U+000A).%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%] accepts the following:%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_delimit_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" - %[%r%]: Do not apply delimits.%r", print.to.stream, print.set->notable, fss_extended_list_read_delimit_mode_name_none_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" - %[%r%]: (default) Apply all delimits.%r", print.to.stream, print.set->notable, fss_extended_list_read_delimit_mode_name_all_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" - %[%r%]: Apply delimits for Objects.%r", print.to.stream, print.set->notable, fss_extended_list_read_delimit_mode_name_object_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" - A number, 0 or greater: apply delimits for Content at the specified depth.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" - A number, 0 or greater, followed by a %[%r%]: (such as '1+') apply delimits for Content at the specified depth and any greater depth (numerically).%r", print.to.stream, print.set->notable, fss_extended_list_read_delimit_mode_name_greater_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+ fl_print_format(" - A number, 0 or lesser, followed by a %[%r%]: (such as '1-') apply delimits for Content at the specified depth and any lesser depth (numerically).%r%r", print.to.stream, print.set->notable, fss_extended_list_read_delimit_mode_name_lesser_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The %[%r%r%] parameter may be specified multiple times to customize the delimit behavior.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_delimit_s, print.set->notable, f_string_eol_s);
+
+ fl_print_format(" The %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_delimit_s, print.set->notable);
+ fl_print_format(" values %[%r%]", print.to.stream, print.set->notable, fss_extended_list_read_delimit_mode_name_none_s, print.set->notable);
+ fl_print_format(" and %[%r%],", print.to.stream, print.set->notable, fss_extended_list_read_delimit_mode_name_all_s, print.set->notable);
+ fl_print_format(" overrule all other delimit values.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameters %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_columns_s, print.set->notable);
+ fl_print_format(" and %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_read_long_select_s, print.set->notable);
+ fl_print_format(" refer to a Content column.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" The word \"column\" is being loosely defined to refer to a specific Content.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" This is not to be confused with a depth.%r", print.to.stream, f_string_eol_s);
+
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+
+ f_file_stream_flush(print.to);
+ f_file_stream_unlock(print.to);
+
+ return F_none;
+ }
+#endif // _di_fss_extended_list_read_print_help_
+
+#ifndef _di_fss_embedded_list_read_print_line_first_
+ void fss_embedded_list_read_print_line_first(fss_embedded_list_read_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ }
+#endif // _di_fss_embedded_list_read_print_line_first_
+
+#ifndef _di_fss_embedded_list_read_print_line_last_
+ void fss_embedded_list_read_print_line_last(fss_embedded_list_read_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+ if (print.verbosity == f_console_verbosity_error_e && !F_status_is_error(setting->status)) return;
+ if (setting->flag & fss_embedded_list_read_main_flag_verify_e) return;
+ if ((setting->flag & fss_embedded_list_read_main_flag_file_to_e) && !F_status_is_error(setting->status)) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ }
+#endif // _di_fss_embedded_list_read_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: UTF-8
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _fss_embedded_list_read_print_h
+#define _fss_embedded_list_read_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print help.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * The output structure to print to.
+ *
+ * @return
+ * F_none on success.
+ */
+#ifndef _di_fss_extended_list_read_print_help_
+ extern f_status_t fss_extended_list_read_print_help(fss_extended_list_read_setting_t * const setting, const fl_print_t print);
+#endif // _di_fss_extended_list_read_print_help_
+
+/**
+ * Print first new line, unless verbosity says otherwise.
+ *
+ * This is generally either the first line in the program or the first line printed before an error message.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_embedded_list_read_print_line_first_
+ extern void fss_embedded_list_read_print_line_first(fss_embedded_list_read_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_embedded_list_read_print_line_first_
+
+/**
+ * Print last new line when the main is complete, unless verbosity says otherwise.
+ *
+ * This is generally the very last line printed in the program.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_embedded_list_read_print_line_last_
+ extern void fss_embedded_list_read_print_line_last(fss_embedded_list_read_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_embedded_list_read_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _fss_embedded_list_read_print_h
}
#endif // _di_fss_extended_list_read_depths_resize_
-#ifndef _di_fss_extended_list_read_print_signal_received_
- void fss_extended_list_read_print_signal_received(fll_program_data_t * const main) {
-
- if (main->warning.verbosity != f_console_verbosity_verbose_e && main->warning.verbosity != f_console_verbosity_debug_e) return;
-
- // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
- fflush(main->warning.to.stream);
-
- flockfile(main->warning.to.stream);
-
- fl_print_format("%]%r%r%[Received signal code %]", main->warning.to.stream, main->context.set.reset, f_string_eol_s, f_string_eol_s, main->context.set.warning, main->context.set.warning);
- fl_print_format("%[%i%]", main->warning.to.stream, main->context.set.notable, main->signal_received, main->context.set.notable);
- fl_print_format("%[.%]%r", main->warning.to.stream, main->context.set.warning, main->context.set.warning, f_string_eol_s);
-
- funlockfile(main->warning.to.stream);
- }
-#endif // _di_fss_extended_list_read_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
extern f_status_t fss_extended_list_read_depths_resize(const f_array_length_t length, fss_extended_list_read_depths_t *depths) F_attribute_visibility_internal_d;
#endif // _di_fss_extended_list_read_depths_resize_
-/**
- * Print a message about a process signal being recieved, such as an interrupt signal.
- *
- * @param main
- * The main program data.
- */
-#ifndef _di_fss_extended_list_read_print_signal_received_
- extern void fss_extended_list_read_print_signal_received(fll_program_data_t * const main) F_attribute_visibility_internal_d;
-#endif // _di_fss_extended_list_read_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
if (!((++main->signal_check) % fss_extended_list_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_extended_list_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (!((++main->signal_check) % fss_extended_list_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_extended_list_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library fss_extended_list_read.c common.c private-common.c private-print.c private-read.c
+build_sources_library fss_extended_list_read.c common.c print.c private-common.c private-print.c private-read.c
build_sources_program main.c
-build_sources_headers fss_extended_list_read.h common.h
+build_sources_headers fss_extended_list_read.h common.h print.h
build_script yes
build_shared yes
}
#endif // _di_fss_extended_list_write_main_delete_
+#ifndef _di_fss_extended_list_write_setting_delete_
+ f_status_t fss_extended_list_write_setting_delete(fss_extended_list_write_setting_t * const setting) {
+
+ if (!setting) return F_status_set_error(F_parameter);
+
+ return F_none;
+ }
+#endif // _di_fss_extended_list_write_setting_delete_
+
+#ifndef _di_fss_extended_list_write_setting_load_
+ void fss_extended_list_write_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_extended_list_write_setting_t * const setting) {
+
+ if (!main || !setting) return;
+
+ // Load parameters.
+ setting->status = f_console_parameter_process(arguments, &main->parameters);
+ if (F_status_is_error(setting->status)) return;
+
+ {
+ f_array_length_t choice = 0;
+ f_uint16s_t choices = f_uint16s_t_initialize;
+
+ // Identify and prioritize "color context" parameters.
+ {
+ uint16_t choices_array[3] = { fss_extended_list_write_parameter_no_color_e, fss_extended_list_write_parameter_light_e, fss_extended_list_write_parameter_dark_e };
+ choices.array = choices_array;
+ choices.used = 3;
+
+ const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
+
+ setting->status = fll_program_parameter_process_context(choices, modes, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_extended_list_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_context", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_extended_list_write_parameter_line_first_no_e].result == f_console_result_found_e) {
+ setting->line_first = f_string_empty_s;
+ }
+ else {
+ setting->line_first = f_string_eol_s;
+ }
+
+ if (main->parameters.array[fss_extended_list_write_parameter_line_last_no_e].result == f_console_result_found_e) {
+ setting->line_last = f_string_empty_s;
+ }
+ else {
+ setting->line_last = f_string_eol_s;
+ }
+
+ // Identify and prioritize "verbosity" parameters.
+ {
+ uint16_t choices_array[5] = { fss_extended_list_write_parameter_verbosity_quiet_e, fss_extended_list_write_parameter_verbosity_error_e, fss_extended_list_write_parameter_verbosity_verbose_e, fss_extended_list_write_parameter_verbosity_debug_e, fss_extended_list_write_parameter_verbosity_normal_e };
+ choices.array = choices_array;
+ choices.used = 5;
+
+ const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+
+ setting->status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_extended_list_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_verbosity", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_extended_list_write_parameter_help_e].result == f_console_result_found_e) {
+ setting->flag |= fss_extended_list_write_main_flag_help_e;
+
+ return;
+ }
+
+ if (main->parameters.array[fss_extended_list_write_parameter_version_e].result == f_console_result_found_e) {
+ setting->flag |= fss_extended_list_write_main_flag_version_e;
+
+ return;
+ }
+
+ // Identify and prioritize "from" mode parameters.
+ {
+ uint16_t choices_array[2] = { fss_extended_list_write_parameter_from_bytesequence_e, fss_extended_list_write_parameter_from_codepoint_e };
+ choices.array = choices_array;
+ choices.used = 2;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_extended_list_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_extended_list_write_parameter_from_bytesequence_e) {
+ if (setting->mode & fss_extended_list_write_mode_from_codepoint_e) {
+ setting->mode -= fss_extended_list_write_mode_from_codepoint_e;
+ }
+
+ setting->mode |= fss_extended_list_write_mode_from_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_extended_list_write_parameter_from_codepoint_e) {
+ if (setting->mode & fss_extended_list_write_mode_from_bytesequence_e) {
+ setting->mode -= fss_extended_list_write_mode_from_bytesequence_e;
+ }
+
+ setting->mode |= fss_extended_list_write_mode_from_codepoint_e;
+ }
+ }
+
+ // Identify and prioritize "to" mode parameters.
+ {
+ uint16_t choices_array[4] = { fss_extended_list_write_parameter_to_bytesequence_e, fss_extended_list_write_parameter_to_codepoint_e, fss_extended_list_write_parameter_to_combining_e, fss_extended_list_write_parameter_to_width_e };
+ choices.array = choices_array;
+ choices.used = 4;
+ choice = 1;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_extended_list_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_extended_list_write_parameter_to_bytesequence_e) {
+ if (setting->mode & fss_extended_list_write_mode_to_codepoint_e) {
+ setting->mode -= fss_extended_list_write_mode_to_codepoint_e;
+ }
+
+ if (setting->mode & fss_extended_list_write_mode_to_combining_e) {
+ setting->mode -= fss_extended_list_write_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_extended_list_write_mode_to_width_e) {
+ setting->mode -= fss_extended_list_write_mode_to_width_e;
+ }
+
+ setting->mode |= fss_extended_list_write_mode_to_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_extended_list_write_parameter_to_codepoint_e) {
+ if (setting->mode & fss_extended_list_write_mode_to_bytesequence_e) {
+ setting->mode -= fss_extended_list_write_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_extended_list_write_mode_to_combining_e) {
+ setting->mode -= fss_extended_list_write_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_extended_list_write_mode_to_width_e) {
+ setting->mode -= fss_extended_list_write_mode_to_width_e;
+ }
+
+ setting->mode |= fss_extended_list_write_mode_to_codepoint_e;
+ }
+ else if (choices.array[choice] == fss_extended_list_write_parameter_to_combining_e) {
+ if (setting->mode & fss_extended_list_write_mode_to_bytesequence_e) {
+ setting->mode -= fss_extended_list_write_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_extended_list_write_mode_to_codepoint_e) {
+ setting->mode -= fss_extended_list_write_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_extended_list_write_parameter_to_width_e].result == f_console_result_found_e) {
+ setting->mode |= fss_extended_list_write_mode_to_width_e;
+ }
+
+ setting->mode |= fss_extended_list_write_mode_to_combining_e;
+ }
+ else if (choices.array[choice] == fss_extended_list_write_parameter_to_width_e) {
+ if (setting->mode & fss_extended_list_write_mode_to_bytesequence_e) {
+ setting->mode -= fss_extended_list_write_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_extended_list_write_mode_to_codepoint_e) {
+ setting->mode -= fss_extended_list_write_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_extended_list_write_parameter_to_combining_e].result == f_console_result_found_e) {
+ setting->mode |= fss_extended_list_write_mode_to_combining_e;
+ }
+
+ setting->mode |= fss_extended_list_write_mode_to_width_e;
+ }
+ }
+ }
+
+ f_string_static_t * const args = main->parameters.arguments.array;
+
+ if (main->parameters.array[fss_extended_list_write_parameter_to_file_e].result == f_console_result_additional_e) {
+ if (main->parameters.array[fss_extended_list_write_parameter_to_file_e].values.used > 1) {
+ fss_extended_list_write_print_error_parameter_file_to_too_many(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+
+ if (args[main->parameters.array[fss_extended_list_write_parameter_to_file_e].values.array[0]].used) {
+ setting->path_files_to.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(1, &setting->path_files_to);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_to.array[setting->path_files_to.used].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[main->parameters.array[fss_extended_list_write_parameter_to_file_e].values.array[0]], &setting->path_files_to.array[0]);
+ if (F_status_is_error(setting->status)) return;
+
+ ++setting->path_files_to.used;
+
+ setting->status = f_file_stream_open(args[main->parameters.array[fss_extended_list_write_parameter_to_file_e].values.array[0]], f_file_open_mode_append_s, &main->output.to);
+
+ if (F_status_is_error(setting->status)) {
+ fll_error_file_print(main->error, F_status_set_fine(setting->status), "f_file_stream_open", F_true, args[main->parameters.array[fss_extended_list_write_parameter_to_file_e].values.array[0]], f_file_operation_open_s, fll_error_file_type_file_e);
+
+ return;
+ }
+
+ setting->flag |= fss_extended_list_write_main_flag_file_to_e;
+ }
+ else {
+ fss_extended_list_write_print_error_parameter_file_name_empty(main, setting, main->parameters.array[fss_extended_list_write_parameter_to_file_e].values.array[0]);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+ else if (main->parameters.array[fss_extended_list_write_parameter_to_file_e].result == f_console_result_found_e) {
+ fss_extended_list_write_print_error_no_value(main, setting, fss_extended_list_write_long_to_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ main->output.to = main->message.to;
+
+ if (setting->flag & fss_extended_list_write_main_flag_file_to_e) {
+ setting->flag -= fss_extended_list_write_main_flag_file_to_e;
+ }
+ }
+
+ if (main->parameters.array[fss_extended_list_write_parameter_from_file_e].result == f_console_result_additional_e) {
+ setting->path_files_from.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(main->parameters.array[fss_extended_list_write_parameter_from_file_e].values.used, &setting->path_files_from);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_from.used = main->parameters.array[fss_extended_list_write_parameter_from_file_e].values.used;
+
+ f_array_length_t i = 0;
+ f_array_length_t index = 0;
+
+ for (; i < setting->path_files_from.used; ++i) {
+
+ index = main->parameters.array[fss_extended_list_write_parameter_from_file_e].values.array[i];
+ setting->path_files_from.array[i].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[index], &setting->path_files_from.array[i]);
+ if (F_status_is_error(setting->status)) return;
+
+ if (args[index].used) {
+ if (f_file_exists(args[index], F_true) != F_true) {
+ fss_extended_list_write_print_error_parameter_file_not_found(main, setting, F_true, args[index]);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_file_found_not);
+ }
+ }
+ }
+ else {
+ fss_extended_list_write_print_error_parameter_file_name_empty(main, setting, index);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_parameter);
+ }
+ }
+ } // for
+
+ if (F_status_is_error(setting->status)) return;
+
+ setting->flag |= fss_extended_list_write_main_flag_file_from_e;
+ }
+ else if (main->parameters.array[fss_extended_list_write_parameter_from_file_e].result == f_console_result_found_e) {
+ fss_extended_list_write_print_error_no_value(main, setting, fss_extended_list_write_long_from_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ if (setting->flag & fss_extended_list_write_main_flag_file_from_e) {
+ setting->flag -= fss_extended_list_write_main_flag_file_from_e;
+ }
+ }
+
+ if (F_status_is_error(setting->status)) return;
+
+ if (main->parameters.array[fss_extended_list_write_parameter_from_file_e].result == f_console_result_none_e && !((main->pipe & fll_program_data_pipe_input_e) || main->parameters.remaining.used)) {
+ fss_extended_list_write_print_error_no_from(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+ }
+
+ if (!(setting->mode & fss_extended_list_write_mode_to_bytesequence_e)) {
+ if (main->parameters.array[fss_extended_list_write_parameter_separate_e].result == f_console_result_found_e || main->parameters.array[fss_extended_list_write_parameter_headers_e].result == f_console_result_found_e) {
+ setting->prepend = fss_extended_list_write_string_prepend_padding_s;
+ setting->append = f_string_eol_s;
+ }
+ else {
+ setting->prepend = f_string_space_s;
+ }
+ }
+
+ if (main->parameters.array[fss_extended_list_write_parameter_headers_e].result == f_console_result_found_e) {
+ setting->flag |= fss_extended_list_write_main_flag_header_e;
+ }
+
+ if (main->parameters.array[fss_extended_list_write_parameter_separate_e].result == f_console_result_found_e) {
+ setting->flag |= fss_extended_list_write_main_flag_separate_e;
+ }
+
+ if (main->parameters.array[fss_extended_list_write_parameter_strip_invalid_e].result == f_console_result_found_e) {
+ setting->flag |= fss_extended_list_write_main_flag_strip_invalid_e;
+ }
+
+ setting->valid_not = main->message.set->error;
+ }
+#endif // _di_fss_extended_list_write_setting_load_
+
+#ifndef _di_fss_extended_list_write_setting_unload_
+ f_status_t fss_extended_list_write_setting_unload(fll_program_data_t * const main, fss_extended_list_write_setting_t * const setting) {
+
+ if (!main || !setting) return F_status_set_error(F_parameter);
+
+ fss_extended_list_write_setting_delete(setting);
+
+ return F_none;
+ }
+#endif // _di_fss_extended_list_write_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern f_status_t fss_extended_list_write_main_delete(fll_program_data_t *main);
#endif // _di_fss_extended_list_write_main_delete_
+/**
+ * Flags used to represent flags passed to the main function.
+ *
+ * fss_extended_list_write_main_flag_*_e:
+ * - none: No modes in use.
+ * - file_from: Using a specified source file.
+ * - file_to: Using a specified destination file.
+ * - help: Print help.
+ * - header: Enable printing of headers.
+ * - separate: Enable printing of separators.
+ * - strip_invalid: Using strip invalid character mode.
+ * - verify: Using verify mode.
+ * - version: Print version.
+ */
+#ifndef _di_fss_extended_list_write_main_flag_e_
+ enum {
+ fss_extended_list_write_main_flag_none_e = 0x0,
+ fss_extended_list_write_main_flag_file_from_e = 0x1,
+ fss_extended_list_write_main_flag_file_to_e = 0x2,
+ fss_extended_list_write_main_flag_header_e = 0x4,
+ fss_extended_list_write_main_flag_help_e = 0x8,
+ fss_extended_list_write_main_flag_separate_e = 0x10,
+ fss_extended_list_write_main_flag_strip_invalid_e = 0x20,
+ fss_extended_list_write_main_flag_verify_e = 0x40,
+ fss_extended_list_write_main_flag_version_e = 0x80,
+ };
+#endif // _di_fss_extended_list_write_main_flag_e_
+
+/**
+ * The fss extended list write main program settings.
+ *
+ * This is passed to the program-specific main entry point to designate program settings.
+ * These program settings are often processed from the program arguments (often called the command line arguments).
+ *
+ * flag: Flags passed to the main function.
+ *
+ * status: The main status code, generally used by the load settings and main functions.
+ *
+ * line_first: A string expected to represent either "\n" or NULL to allow for easy handling of when to print first new line or not.
+ * line_last: A string expected to represent either "\n" or NULL to allow for easy handling of when to print last new line or not.
+ */
+#ifndef _di_fss_extended_list_write_setting_t_
+ typedef struct {
+ uint16_t flag;
+
+ f_status_t status;
+
+ f_string_static_t line_first;
+ f_string_static_t line_last;
+ } fss_extended_list_write_setting_t;
+
+ #define fss_extended_list_write_setting_t_initialize \
+ { \
+ fss_extended_list_write_main_flag_none_e, \
+ F_none, \
+ f_string_static_t_initialize, \
+ f_string_static_t_initialize, \
+ }
+#endif // _di_fss_extended_list_write_setting_t_
+
+/**
+ * Delete the program main setting data.
+ *
+ * @param setting
+ * The program main setting data.
+ * This does not alter setting.status.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fss_extended_list_write_setting_delete_
+ extern f_status_t fss_extended_list_write_setting_delete(fss_extended_list_write_setting_t * const setting);
+#endif // _di_fss_extended_list_write_setting_delete_
+
+/**
+ * Perform the standard program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately retuns without doing anything.
+ *
+ * @param arguments
+ * The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ *
+ * This alters setting.status:
+ * F_none on success.
+ *
+ * Errors (with error bit) from: f_console_parameter_process().
+ * Errors (with error bit) from: fll_program_parameter_process_context().
+ *
+ * @see f_console_parameter_process()
+ * @see fll_program_parameter_process_context()
+ */
+#ifndef _di_fss_extended_list_write_setting_load_
+ extern void fss_extended_list_write_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_extended_list_write_setting_t * const setting);
+#endif // _di_fss_extended_list_write_setting_load_
+
+/**
+ * Perform the standard program setting unload process.
+ *
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * All buffers are deallocated.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: utf8_setting_delete().
+ *
+ * @see utf8_setting_delete()
+ */
+#ifndef _di_fss_extended_list_write_setting_unload_
+ extern f_status_t fss_extended_list_write_setting_unload(fll_program_data_t * const main, fss_extended_list_write_setting_t * const setting);
+#endif // _di_fss_extended_list_write_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern "C" {
#endif
-#ifndef _di_fss_extended_list_write_print_help_
- f_status_t fss_extended_list_write_print_help(const f_file_t file, const f_color_context_t context) {
-
- flockfile(file.stream);
-
- //if (!(setting->flag & XXX_main_flag_line_first_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- fll_program_print_help_header(file, context, fss_extended_list_write_program_name_long_s, fss_extended_list_write_program_version_s);
-
- fll_program_print_help_option_standard(file, context);
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, fss_extended_list_write_short_file_s, fss_extended_list_write_long_file_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a file to send data to.");
- fll_program_print_help_option(file, context, fss_extended_list_write_short_content_s, fss_extended_list_write_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "The Content to write.");
- fll_program_print_help_option(file, context, fss_extended_list_write_short_double_s, fss_extended_list_write_long_double_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use double quotes (default).");
- fll_program_print_help_option(file, context, fss_extended_list_write_short_ignore_s, fss_extended_list_write_long_ignore_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Ignore a given range within a Content.");
- fll_program_print_help_option(file, context, fss_extended_list_write_short_object_s, fss_extended_list_write_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The Object to write.");
- fll_program_print_help_option(file, context, fss_extended_list_write_short_partial_s, fss_extended_list_write_long_partial_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Do not write end of Object/Content character.");
- fll_program_print_help_option(file, context, fss_extended_list_write_short_prepend_s, fss_extended_list_write_long_prepend_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Prepend the given white space characters to the start of each multi-line Content.");
- fll_program_print_help_option(file, context, fss_extended_list_write_short_single_s, fss_extended_list_write_long_single_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use single quotes.");
- fll_program_print_help_option(file, context, fss_extended_list_write_short_trim_s, fss_extended_list_write_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names.");
-
- fll_program_print_help_usage(file, context, fss_extended_list_write_program_name_s, f_string_empty_s);
-
- fl_print_format("%r The pipe uses the Backspace character '%[\\b%]' (%[U+0008%]) to designate the start of a Content.%r", file.stream, f_string_eol_s, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" The pipe uses the Form Feed character '%[\\f%]' (%[U+000C%]) to designate the end of the last Content.%r", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" The pipe uses the Vertical Line character '%[\\v%]' (%[U+000B%]) is used to ignore a Content range (use this both before and after the range).%r", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" For the pipe, an Object is terminated by either a Backspace character '%[\\b%]' (%[U+0008%])", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable);
- fl_print_format(" or a Form Feed character '%[\\f%]' (%[U+000C%]).%r", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" The end of the pipe represents the end of any Object or Content.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The FSS-0003 (Extended List) specification does not support quoted names, therefore the parameters '%[%r%r%]'", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_write_long_single_s, context.set.notable);
- fl_print_format(" and '%[%r%r%]' do nothing.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_write_long_double_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter '%[%r%r%]' designates to not escape any valid nested Object or Content within some Content.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_write_long_ignore_s, context.set.notable, f_string_eol_s);
- fl_print_format(" This parameter requires two values.%r", file.stream, f_string_eol_s);
- fl_print_format(" This parameter is not used for ignoring anything from the input pipe.%r", file.stream, f_string_eol_s);
- fl_print_format(" This parameter must be specified after a '%[%r%r%]'", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_write_long_content_s, context.set.notable);
- fl_print_format(" parameter and this applies only to the Content represented by that specific '%[%r%r%]' parameter.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_list_write_long_content_s, context.set.notable, f_string_eol_s);
-
- //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- f_file_stream_flush(file);
- funlockfile(file.stream);
-
- return F_none;
- }
-#endif // _di_fss_extended_list_write_print_help_
-
#ifndef _di_fss_extended_list_write_main_
- f_status_t fss_extended_list_write_main(fll_program_data_t * const main, const f_console_arguments_t arguments) {
+ f_status_t fss_extended_list_write_main(fll_program_data_t * const main, fss_extended_list_write_setting_t * const setting) {
f_status_t status = F_none;
status = F_none;
if (main->parameters.array[fss_extended_list_write_parameter_help_e].result == f_console_result_found_e) {
- fss_extended_list_write_print_help(main->output.to, main->context);
+ fss_extended_list_write_print_help(setting, main->message);
return status;
}
if (main->parameters.array[fss_extended_list_write_parameter_version_e].result == f_console_result_found_e) {
- fll_program_print_version(main->output.to, fss_extended_list_write_program_version_s);
+ fll_program_print_version(main->message, fss_extended_list_write_program_version_s);
return status;
}
if (!((++main->signal_check) % fss_extended_list_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_extended_list_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
if (!((++main->signal_check) % fss_extended_list_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_extended_list_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
if (!((++main->signal_check) % fss_extended_list_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_extended_list_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
#endif
/**
- * Print help.
- *
- * @param file
- * The file to print to.
- * @param context
- * The color context settings.
- *
- * @return
- * F_none on success.
- */
-#ifndef _di_fss_extended_list_write_print_help_
- extern f_status_t fss_extended_list_write_print_help(const f_file_t file, const f_color_context_t context);
-#endif // _di_fss_extended_list_write_print_help_
-
-/**
* Execute main program.
*
* If main.signal is non-zero, then this blocks and handles the following signals:
*
* @param main
* The main program data.
- * @param arguments
- * The parameters passed to the process.
+ * @param setting
+ * The main program settings.
*
- * @return
- * F_none on success.
+ * This alters setting.status:
+ * F_none on success.
+ * F_true on success when performing verification and verify passed.
+ * F_false on success when performing verification and verify failed.
+ * F_interrupt on (exit) signal received.
*
- * Status codes (with error bit) are returned on any problem.
+ * F_parameter (with error bit) if main is NULL or setting is NULL.
*/
#ifndef _di_fss_extended_list_write_main_
- extern f_status_t fss_extended_list_write_main(fll_program_data_t * const main, const f_console_arguments_t arguments);
+ extern f_status_t fss_extended_list_write_main(fll_program_data_t * const main, fss_extended_list_write_setting_t * const setting);
#endif // _di_fss_extended_list_write_main_
#ifdef __cplusplus
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
fll_program_data_t data = fll_program_data_t_initialize;
+ fss_extended_list_write_setting_t setting = fss_extended_list_write_setting_t_initialize;
f_console_parameter_t parameters[] = fss_extended_list_write_console_parameter_t_initialize;
data.parameters.array = parameters;
data.parameters.used = fss_extended_list_write_total_parameters_d;
+ data.environment = envp;
if (f_pipe_input_exists()) {
data.pipe = fll_program_data_pipe_input_e;
fll_program_standard_set_up(&data);
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+
+ fss_extended_list_write_setting_load(arguments, &data, &setting);
+ }
+
const f_status_t status = fss_extended_list_write_main(&data, arguments);
+ fss_extended_list_write_main(&data, &setting);
+
+ fss_extended_list_write_setting_unload(&data, &setting);
+
fll_program_data_delete(&data);
fll_program_standard_set_down(&data);
- if (F_status_is_error(status)) return 1;
-
- return 0;
+ return F_status_is_error(status) ? 1 : 0;
}
--- /dev/null
+#include "fss_embedded_list_write.h"
+#include "private-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fss_extended_list_write_print_help_
+ f_status_t fss_extended_list_write_print_help(fss_extended_list_write_setting_t * const setting, const fl_print_t print) {
+
+ f_file_stream_lock(print.to);
+
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+
+ fll_program_print_help_header(print, fss_extended_list_write_program_name_long_s, fss_extended_list_write_program_version_s);
+
+ fll_program_print_help_option_standard(print);
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, fss_extended_list_write_short_file_s, fss_extended_list_write_long_file_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a file to send data to.");
+ fll_program_print_help_option(print, fss_extended_list_write_short_content_s, fss_extended_list_write_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "The Content to write.");
+ fll_program_print_help_option(print, fss_extended_list_write_short_double_s, fss_extended_list_write_long_double_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use double quotes (default).");
+ fll_program_print_help_option(print, fss_extended_list_write_short_ignore_s, fss_extended_list_write_long_ignore_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Ignore a given range within a Content.");
+ fll_program_print_help_option(print, fss_extended_list_write_short_object_s, fss_extended_list_write_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The Object to write.");
+ fll_program_print_help_option(print, fss_extended_list_write_short_partial_s, fss_extended_list_write_long_partial_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Do not write end of Object/Content character.");
+ fll_program_print_help_option(print, fss_extended_list_write_short_prepend_s, fss_extended_list_write_long_prepend_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Prepend the given white space characters to the start of each multi-line Content.");
+ fll_program_print_help_option(print, fss_extended_list_write_short_single_s, fss_extended_list_write_long_single_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use single quotes.");
+ fll_program_print_help_option(print, fss_extended_list_write_short_trim_s, fss_extended_list_write_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names.");
+
+ fll_program_print_help_usage(print, fss_extended_list_write_program_name_s, f_string_empty_s);
+
+ fl_print_format("%r The pipe uses the Backspace character '%[\\b%]' (%[U+0008%]) to designate the start of a Content.%r", print.to.stream, f_string_eol_s, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" The pipe uses the Form Feed character '%[\\f%]' (%[U+000C%]) to designate the end of the last Content.%r", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" The pipe uses the Vertical Line character '%[\\v%]' (%[U+000B%]) is used to ignore a Content range (use this both before and after the range).%r", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" For the pipe, an Object is terminated by either a Backspace character '%[\\b%]' (%[U+0008%])", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable);
+ fl_print_format(" or a Form Feed character '%[\\f%]' (%[U+000C%]).%r", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" The end of the pipe represents the end of any Object or Content.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The FSS-0003 (Extended List) specification does not support quoted names, therefore the parameters '%[%r%r%]'", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_write_long_single_s, print.set->notable);
+ fl_print_format(" and '%[%r%r%]' do nothing.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_write_long_double_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter '%[%r%r%]' designates to not escape any valid nested Object or Content within some Content.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_write_long_ignore_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" This parameter requires two values.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" This parameter is not used for ignoring anything from the input pipe.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" This parameter must be specified after a '%[%r%r%]'", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_write_long_content_s, print.set->notable);
+ fl_print_format(" parameter and this applies only to the Content represented by that specific '%[%r%r%]' parameter.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_list_write_long_content_s, print.set->notable, f_string_eol_s);
+
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+
+ f_file_stream_flush(print.to);
+ f_file_stream_unlock(print.to);
+
+ return F_none;
+ }
+#endif // _di_fss_extended_list_write_print_help_
+
+#ifndef _di_fss_embedded_list_write_print_line_first_
+ void fss_embedded_list_write_print_line_first(fss_embedded_list_write_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ }
+#endif // _di_fss_embedded_list_write_print_line_first_
+
+#ifndef _di_fss_embedded_list_write_print_line_last_
+ void fss_embedded_list_write_print_line_last(fss_embedded_list_write_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+ if (print.verbosity == f_console_verbosity_error_e && !F_status_is_error(setting->status)) return;
+ if (setting->flag & fss_embedded_list_write_main_flag_verify_e) return;
+ if ((setting->flag & fss_embedded_list_write_main_flag_file_to_e) && !F_status_is_error(setting->status)) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ }
+#endif // _di_fss_embedded_list_write_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: UTF-8
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _fss_embedded_list_write_print_h
+#define _fss_embedded_list_write_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print help.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * The output structure to print to.
+ *
+ * @return
+ * F_none on success.
+ */
+#ifndef _di_fss_extended_list_write_print_help_
+ extern f_status_t fss_extended_list_write_print_help(fss_extended_list_write_setting_t * const setting, const fl_print_t print);
+#endif // _di_fss_extended_list_write_print_help_
+
+/**
+ * Print first new line, unless verbosity says otherwise.
+ *
+ * This is generally either the first line in the program or the first line printed before an error message.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_embedded_list_write_print_line_first_
+ extern void fss_embedded_list_write_print_line_first(fss_embedded_list_write_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_embedded_list_write_print_line_first_
+
+/**
+ * Print last new line when the main is complete, unless verbosity says otherwise.
+ *
+ * This is generally the very last line printed in the program.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_embedded_list_write_print_line_last_
+ extern void fss_embedded_list_write_print_line_last(fss_embedded_list_write_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_embedded_list_write_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _fss_embedded_list_write_print_h
extern "C" {
#endif
-#ifndef _di_fss_extended_list_write_print_signal_received_
- void fss_extended_list_write_print_signal_received(fll_program_data_t * const main) {
-
- if (main->warning.verbosity != f_console_verbosity_verbose_e && main->warning.verbosity != f_console_verbosity_debug_e) return;
-
- // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
- fflush(main->warning.to.stream);
-
- flockfile(main->warning.to.stream);
-
- fl_print_format("%]%r%r%[Received signal code %]", main->warning.to.stream, main->context.set.reset, f_string_eol_s, f_string_eol_s, main->context.set.warning, main->context.set.warning);
- fl_print_format("%[%i%]", main->warning.to.stream, main->context.set.notable, signal, main->context.set.notable);
- fl_print_format("%[.%]%r", main->warning.to.stream, main->context.set.warning, main->context.set.warning, f_string_eol_s);
-
- funlockfile(main->warning.to.stream);
- }
-#endif // _di_fss_extended_list_write_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
#define fss_extended_list_write_common_allocation_small_d 128
#endif // _di_fss_extended_list_write_common_
-/**
- * Print a message about a process signal being recieved, such as an interrupt signal.
- *
- * @param main
- * The main program data.
- */
-#ifndef _di_fss_extended_list_write_print_signal_received_
- extern void fss_extended_list_write_print_signal_received(fll_program_data_t * const main) F_attribute_visibility_internal_d;
-#endif // _di_fss_extended_list_write_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
if (!((++main->signal_check) % fss_extended_list_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_extended_list_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (!((++main->signal_check) % fss_extended_list_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_extended_list_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library fss_extended_list_write.c common.c private-common.c private-write.c
+build_sources_library fss_extended_list_write.c common.c print.c private-common.c private-write.c
build_sources_program main.c
-build_sources_headers fss_extended_list_write.h common.h
+build_sources_headers fss_extended_list_write.h common.h print.h
build_script yes
build_shared yes
const f_string_static_t fss_extended_read_delimit_mode_name_lesser_s = macro_f_string_static_t_initialize(FSS_EXTENDED_READ_delimit_mode_name_lesser_s, 0, FSS_EXTENDED_READ_delimit_mode_name_lesser_s_length);
#endif // _di_fss_extended_read_delimit_mode_
+#ifndef _di_fss_extended_read_setting_delete_
+ f_status_t fss_extended_read_setting_delete(fss_extended_read_setting_t * const setting) {
+
+ if (!setting) return F_status_set_error(F_parameter);
+
+ return F_none;
+ }
+#endif // _di_fss_extended_read_setting_delete_
+
+#ifndef _di_fss_extended_read_setting_load_
+ void fss_extended_read_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_extended_read_setting_t * const setting) {
+
+ if (!main || !setting) return;
+
+ // Load parameters.
+ setting->status = f_console_parameter_process(arguments, &main->parameters);
+ if (F_status_is_error(setting->status)) return;
+
+ {
+ f_array_length_t choice = 0;
+ f_uint16s_t choices = f_uint16s_t_initialize;
+
+ // Identify and prioritize "color context" parameters.
+ {
+ uint16_t choices_array[3] = { fss_extended_read_parameter_no_color_e, fss_extended_read_parameter_light_e, fss_extended_read_parameter_dark_e };
+ choices.array = choices_array;
+ choices.used = 3;
+
+ const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
+
+ setting->status = fll_program_parameter_process_context(choices, modes, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_extended_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_context", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_extended_read_parameter_line_first_no_e].result == f_console_result_found_e) {
+ setting->line_first = f_string_empty_s;
+ }
+ else {
+ setting->line_first = f_string_eol_s;
+ }
+
+ if (main->parameters.array[fss_extended_read_parameter_line_last_no_e].result == f_console_result_found_e) {
+ setting->line_last = f_string_empty_s;
+ }
+ else {
+ setting->line_last = f_string_eol_s;
+ }
+
+ // Identify and prioritize "verbosity" parameters.
+ {
+ uint16_t choices_array[5] = { fss_extended_read_parameter_verbosity_quiet_e, fss_extended_read_parameter_verbosity_error_e, fss_extended_read_parameter_verbosity_verbose_e, fss_extended_read_parameter_verbosity_debug_e, fss_extended_read_parameter_verbosity_normal_e };
+ choices.array = choices_array;
+ choices.used = 5;
+
+ const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+
+ setting->status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_extended_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_verbosity", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_extended_read_parameter_help_e].result == f_console_result_found_e) {
+ setting->flag |= fss_extended_read_main_flag_help_e;
+
+ return;
+ }
+
+ if (main->parameters.array[fss_extended_read_parameter_version_e].result == f_console_result_found_e) {
+ setting->flag |= fss_extended_read_main_flag_version_e;
+
+ return;
+ }
+
+ // Identify and prioritize "from" mode parameters.
+ {
+ uint16_t choices_array[2] = { fss_extended_read_parameter_from_bytesequence_e, fss_extended_read_parameter_from_codepoint_e };
+ choices.array = choices_array;
+ choices.used = 2;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_extended_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_extended_read_parameter_from_bytesequence_e) {
+ if (setting->mode & fss_extended_read_mode_from_codepoint_e) {
+ setting->mode -= fss_extended_read_mode_from_codepoint_e;
+ }
+
+ setting->mode |= fss_extended_read_mode_from_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_extended_read_parameter_from_codepoint_e) {
+ if (setting->mode & fss_extended_read_mode_from_bytesequence_e) {
+ setting->mode -= fss_extended_read_mode_from_bytesequence_e;
+ }
+
+ setting->mode |= fss_extended_read_mode_from_codepoint_e;
+ }
+ }
+
+ // Identify and prioritize "to" mode parameters.
+ {
+ uint16_t choices_array[4] = { fss_extended_read_parameter_to_bytesequence_e, fss_extended_read_parameter_to_codepoint_e, fss_extended_read_parameter_to_combining_e, fss_extended_read_parameter_to_width_e };
+ choices.array = choices_array;
+ choices.used = 4;
+ choice = 1;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_extended_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_extended_read_parameter_to_bytesequence_e) {
+ if (setting->mode & fss_extended_read_mode_to_codepoint_e) {
+ setting->mode -= fss_extended_read_mode_to_codepoint_e;
+ }
+
+ if (setting->mode & fss_extended_read_mode_to_combining_e) {
+ setting->mode -= fss_extended_read_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_extended_read_mode_to_width_e) {
+ setting->mode -= fss_extended_read_mode_to_width_e;
+ }
+
+ setting->mode |= fss_extended_read_mode_to_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_extended_read_parameter_to_codepoint_e) {
+ if (setting->mode & fss_extended_read_mode_to_bytesequence_e) {
+ setting->mode -= fss_extended_read_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_extended_read_mode_to_combining_e) {
+ setting->mode -= fss_extended_read_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_extended_read_mode_to_width_e) {
+ setting->mode -= fss_extended_read_mode_to_width_e;
+ }
+
+ setting->mode |= fss_extended_read_mode_to_codepoint_e;
+ }
+ else if (choices.array[choice] == fss_extended_read_parameter_to_combining_e) {
+ if (setting->mode & fss_extended_read_mode_to_bytesequence_e) {
+ setting->mode -= fss_extended_read_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_extended_read_mode_to_codepoint_e) {
+ setting->mode -= fss_extended_read_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_extended_read_parameter_to_width_e].result == f_console_result_found_e) {
+ setting->mode |= fss_extended_read_mode_to_width_e;
+ }
+
+ setting->mode |= fss_extended_read_mode_to_combining_e;
+ }
+ else if (choices.array[choice] == fss_extended_read_parameter_to_width_e) {
+ if (setting->mode & fss_extended_read_mode_to_bytesequence_e) {
+ setting->mode -= fss_extended_read_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_extended_read_mode_to_codepoint_e) {
+ setting->mode -= fss_extended_read_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_extended_read_parameter_to_combining_e].result == f_console_result_found_e) {
+ setting->mode |= fss_extended_read_mode_to_combining_e;
+ }
+
+ setting->mode |= fss_extended_read_mode_to_width_e;
+ }
+ }
+ }
+
+ f_string_static_t * const args = main->parameters.arguments.array;
+
+ if (main->parameters.array[fss_extended_read_parameter_to_file_e].result == f_console_result_additional_e) {
+ if (main->parameters.array[fss_extended_read_parameter_to_file_e].values.used > 1) {
+ fss_extended_read_print_error_parameter_file_to_too_many(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+
+ if (args[main->parameters.array[fss_extended_read_parameter_to_file_e].values.array[0]].used) {
+ setting->path_files_to.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(1, &setting->path_files_to);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_to.array[setting->path_files_to.used].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[main->parameters.array[fss_extended_read_parameter_to_file_e].values.array[0]], &setting->path_files_to.array[0]);
+ if (F_status_is_error(setting->status)) return;
+
+ ++setting->path_files_to.used;
+
+ setting->status = f_file_stream_open(args[main->parameters.array[fss_extended_read_parameter_to_file_e].values.array[0]], f_file_open_mode_append_s, &main->output.to);
+
+ if (F_status_is_error(setting->status)) {
+ fll_error_file_print(main->error, F_status_set_fine(setting->status), "f_file_stream_open", F_true, args[main->parameters.array[fss_extended_read_parameter_to_file_e].values.array[0]], f_file_operation_open_s, fll_error_file_type_file_e);
+
+ return;
+ }
+
+ setting->flag |= fss_extended_read_main_flag_file_to_e;
+ }
+ else {
+ fss_extended_read_print_error_parameter_file_name_empty(main, setting, main->parameters.array[fss_extended_read_parameter_to_file_e].values.array[0]);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+ else if (main->parameters.array[fss_extended_read_parameter_to_file_e].result == f_console_result_found_e) {
+ fss_extended_read_print_error_no_value(main, setting, fss_extended_read_long_to_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ main->output.to = main->message.to;
+
+ if (setting->flag & fss_extended_read_main_flag_file_to_e) {
+ setting->flag -= fss_extended_read_main_flag_file_to_e;
+ }
+ }
+
+ if (main->parameters.array[fss_extended_read_parameter_from_file_e].result == f_console_result_additional_e) {
+ setting->path_files_from.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(main->parameters.array[fss_extended_read_parameter_from_file_e].values.used, &setting->path_files_from);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_from.used = main->parameters.array[fss_extended_read_parameter_from_file_e].values.used;
+
+ f_array_length_t i = 0;
+ f_array_length_t index = 0;
+
+ for (; i < setting->path_files_from.used; ++i) {
+
+ index = main->parameters.array[fss_extended_read_parameter_from_file_e].values.array[i];
+ setting->path_files_from.array[i].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[index], &setting->path_files_from.array[i]);
+ if (F_status_is_error(setting->status)) return;
+
+ if (args[index].used) {
+ if (f_file_exists(args[index], F_true) != F_true) {
+ fss_extended_read_print_error_parameter_file_not_found(main, setting, F_true, args[index]);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_file_found_not);
+ }
+ }
+ }
+ else {
+ fss_extended_read_print_error_parameter_file_name_empty(main, setting, index);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_parameter);
+ }
+ }
+ } // for
+
+ if (F_status_is_error(setting->status)) return;
+
+ setting->flag |= fss_extended_read_main_flag_file_from_e;
+ }
+ else if (main->parameters.array[fss_extended_read_parameter_from_file_e].result == f_console_result_found_e) {
+ fss_extended_read_print_error_no_value(main, setting, fss_extended_read_long_from_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ if (setting->flag & fss_extended_read_main_flag_file_from_e) {
+ setting->flag -= fss_extended_read_main_flag_file_from_e;
+ }
+ }
+
+ if (F_status_is_error(setting->status)) return;
+
+ if (main->parameters.array[fss_extended_read_parameter_from_file_e].result == f_console_result_none_e && !((main->pipe & fll_program_data_pipe_input_e) || main->parameters.remaining.used)) {
+ fss_extended_read_print_error_no_from(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+ }
+
+ if (!(setting->mode & fss_extended_read_mode_to_bytesequence_e)) {
+ if (main->parameters.array[fss_extended_read_parameter_separate_e].result == f_console_result_found_e || main->parameters.array[fss_extended_read_parameter_headers_e].result == f_console_result_found_e) {
+ setting->prepend = fss_extended_read_string_prepend_padding_s;
+ setting->append = f_string_eol_s;
+ }
+ else {
+ setting->prepend = f_string_space_s;
+ }
+ }
+
+ if (main->parameters.array[fss_extended_read_parameter_headers_e].result == f_console_result_found_e) {
+ setting->flag |= fss_extended_read_main_flag_header_e;
+ }
+
+ if (main->parameters.array[fss_extended_read_parameter_separate_e].result == f_console_result_found_e) {
+ setting->flag |= fss_extended_read_main_flag_separate_e;
+ }
+
+ if (main->parameters.array[fss_extended_read_parameter_strip_invalid_e].result == f_console_result_found_e) {
+ setting->flag |= fss_extended_read_main_flag_strip_invalid_e;
+ }
+
+ setting->valid_not = main->message.set->error;
+ }
+#endif // _di_fss_extended_read_setting_load_
+
+#ifndef _di_fss_extended_read_setting_unload_
+ f_status_t fss_extended_read_setting_unload(fll_program_data_t * const main, fss_extended_read_setting_t * const setting) {
+
+ if (!main || !setting) return F_status_set_error(F_parameter);
+
+ fss_extended_read_setting_delete(setting);
+
+ return F_none;
+ }
+#endif // _di_fss_extended_read_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
};
#endif // _di_fss_extended_read_delimit_modes_
+/**
+ * Flags used to represent flags passed to the main function.
+ *
+ * fss_extended_read_main_flag_*_e:
+ * - none: No modes in use.
+ * - file_from: Using a specified source file.
+ * - file_to: Using a specified destination file.
+ * - help: Print help.
+ * - header: Enable printing of headers.
+ * - separate: Enable printing of separators.
+ * - strip_invalid: Using strip invalid character mode.
+ * - verify: Using verify mode.
+ * - version: Print version.
+ */
+#ifndef _di_fss_extended_read_main_flag_e_
+ enum {
+ fss_extended_read_main_flag_none_e = 0x0,
+ fss_extended_read_main_flag_file_from_e = 0x1,
+ fss_extended_read_main_flag_file_to_e = 0x2,
+ fss_extended_read_main_flag_header_e = 0x4,
+ fss_extended_read_main_flag_help_e = 0x8,
+ fss_extended_read_main_flag_separate_e = 0x10,
+ fss_extended_read_main_flag_strip_invalid_e = 0x20,
+ fss_extended_read_main_flag_verify_e = 0x40,
+ fss_extended_read_main_flag_version_e = 0x80,
+ };
+#endif // _di_fss_extended_read_main_flag_e_
+
+/**
+ * The fss extended read main program settings.
+ *
+ * This is passed to the program-specific main entry point to designate program settings.
+ * These program settings are often processed from the program arguments (often called the command line arguments).
+ *
+ * flag: Flags passed to the main function.
+ *
+ * status: The main status code, generally used by the load settings and main functions.
+ *
+ * line_first: A string expected to represent either "\n" or NULL to allow for easy handling of when to print first new line or not.
+ * line_last: A string expected to represent either "\n" or NULL to allow for easy handling of when to print last new line or not.
+ */
+#ifndef _di_fss_extended_read_setting_t_
+ typedef struct {
+ uint16_t flag;
+
+ f_status_t status;
+
+ f_string_static_t line_first;
+ f_string_static_t line_last;
+ } fss_extended_read_setting_t;
+
+ #define fss_extended_read_setting_t_initialize \
+ { \
+ fss_extended_read_main_flag_none_e, \
+ F_none, \
+ f_string_static_t_initialize, \
+ f_string_static_t_initialize, \
+ }
+#endif // _di_fss_extended_read_setting_t_
+
+/**
+ * Delete the program main setting data.
+ *
+ * @param setting
+ * The program main setting data.
+ * This does not alter setting.status.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fss_extended_read_setting_delete_
+ extern f_status_t fss_extended_read_setting_delete(fss_extended_read_setting_t * const setting);
+#endif // _di_fss_extended_read_setting_delete_
+
+/**
+ * Perform the standard program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately retuns without doing anything.
+ *
+ * @param arguments
+ * The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ *
+ * This alters setting.status:
+ * F_none on success.
+ *
+ * Errors (with error bit) from: f_console_parameter_process().
+ * Errors (with error bit) from: fll_program_parameter_process_context().
+ *
+ * @see f_console_parameter_process()
+ * @see fll_program_parameter_process_context()
+ */
+#ifndef _di_fss_extended_read_setting_load_
+ extern void fss_extended_read_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_extended_read_setting_t * const setting);
+#endif // _di_fss_extended_read_setting_load_
+
+/**
+ * Perform the standard program setting unload process.
+ *
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * All buffers are deallocated.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: utf8_setting_delete().
+ *
+ * @see utf8_setting_delete()
+ */
+#ifndef _di_fss_extended_read_setting_unload_
+ extern f_status_t fss_extended_read_setting_unload(fll_program_data_t * const main, fss_extended_read_setting_t * const setting);
+#endif // _di_fss_extended_read_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern "C" {
#endif
-#ifndef _di_fss_extended_read_print_help_
- f_status_t fss_extended_read_print_help(const f_file_t file, const f_color_context_t context) {
-
- flockfile(file.stream);
-
- //if (!(setting->flag & XXX_main_flag_line_first_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- fll_program_print_help_header(file, context, fss_extended_read_program_name_long_s, fss_extended_read_program_version_s);
-
- fll_program_print_help_option_standard(file, context);
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, fss_extended_read_short_at_s, fss_extended_read_long_at_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric index.");
- fll_program_print_help_option(file, context, fss_extended_read_short_content_s, fss_extended_read_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Content (default).");
- fll_program_print_help_option(file, context, fss_extended_read_short_columns_s, fss_extended_read_long_columns_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of columns.");
- fll_program_print_help_option(file, context, fss_extended_read_short_delimit_s, fss_extended_read_long_delimit_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Designate how to handle applying delimits.");
- fll_program_print_help_option(file, context, fss_extended_read_short_depth_s, fss_extended_read_long_depth_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric depth.");
- fll_program_print_help_option(file, context, fss_extended_read_short_empty_s, fss_extended_read_long_empty_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Include empty Content when processing.");
- fll_program_print_help_option(file, context, fss_extended_read_short_line_s, fss_extended_read_long_line_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print only the Content at the given line.");
- fll_program_print_help_option(file, context, fss_extended_read_short_name_s, fss_extended_read_long_name_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object with this name.");
- fll_program_print_help_option(file, context, fss_extended_read_short_object_s, fss_extended_read_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Object.");
- fll_program_print_help_option(file, context, fss_extended_read_short_pipe_s, fss_extended_read_long_pipe_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print using the special pipe format.");
- fll_program_print_help_option(file, context, fss_extended_read_short_original_s, fss_extended_read_long_original_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print with the original quotes and escapes.");
- fll_program_print_help_option(file, context, fss_extended_read_short_select_s, fss_extended_read_long_select_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select sub-Content at this index.");
- fll_program_print_help_option(file, context, fss_extended_read_short_total_s, fss_extended_read_long_total_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of lines.");
- fll_program_print_help_option(file, context, fss_extended_read_short_trim_s, fss_extended_read_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names on select or print.");
-
- fll_program_print_help_usage(file, context, fss_extended_read_program_name_s, fll_program_parameter_filenames_s);
-
- fl_print_format("%r %[Notes:%]%r", file.stream, f_string_eol_s, context.set.important, context.set.important, f_string_eol_s);
-
- fl_print_format(" This program will print the Content associated with the given Object and Content main based on the FSS-0001 Extended standard.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" All numeric positions (indexes) start at 0 instead of 1.%r", file.stream, f_string_eol_s);
- fl_print_format(" For example, a file of 17 lines would range from 0 to 16.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When using the %[%r%r%] option, an order of operations is enforced on the parameters.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_depth_s, context.set.notable, f_string_eol_s);
-
- fl_print_format(" When this order of operations is in effect, parameters to the right of a depth parameter are influenced by that depth parameter:%r", file.stream, f_string_eol_s);
-
- fl_print_format(" %[%r%r%]: An Object index at the specified depth.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_at_s, context.set.notable, f_string_eol_s);
- fl_print_format(" %[%r%r%]: A new depth within the specified depth, indexed from the root.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_depth_s, context.set.notable, f_string_eol_s);
- fl_print_format(" %[%r%r%]: An Object name at the specified depth.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_name_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%] must be in numeric order, but values in between may be skipped.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_depth_s, context.set.notable, f_string_eol_s);
- fl_print_format(" ('-d 0 -a 1 -d 2 -a 2' would specify index 1 at depth 0, any index at depth 1, and index 2 at depth 2.)%r", file.stream, f_string_eol_s);
- fl_print_format(" ('-d 2 -a 1 -d 0 -a 2' would be invalid because depth 2 is before depth 1.)%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%] selects a Content column.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_select_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" Specify both %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_object_s, context.set.notable);
- fl_print_format(" and the %[%r%r%] parameters to get the total objects.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_total_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When both %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_at_s, context.set.notable);
- fl_print_format(" and %[%r%r%] parameters are specified (at the same depth),", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_name_s, context.set.notable);
- fl_print_format(" the %[%r%r%] parameter value will be treated as a position relative to the specified", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_at_s, context.set.notable);
- fl_print_format(" %[%r%r%] parameter value.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_name_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" This program may support parameters, such as %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_depth_s, context.set.notable);
- fl_print_format(" or %[%r%r%], even if not supported by the standard.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_select_s, context.set.notable, f_string_eol_s);
- fl_print_format(" This is done to help ensure consistency for scripting.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" For parameters like %[%r%r%],", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_depth_s, context.set.notable);
- fl_print_format(" if the standard doesn't support nested Content, then only a depth of 0 would be valid.%r", file.stream, f_string_eol_s);
-
- fl_print_format(" For parameters like %[%r%r%],", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_select_s, context.set.notable);
- fl_print_format(" if the standard doesn't support multiple Content groups, then only a select of 0 would be valid.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_trim_s, context.set.notable);
- fl_print_format(" will remove leading and trailing white spaces when selecting objects or when printing objects.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When specifying both the %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_object_s, context.set.notable);
- fl_print_format(" parameter and the %[%r%r%] parameter, the entire Object and Content are printed, including the formatting.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_content_s, context.set.notable, f_string_eol_s);
- fl_print_format(" Both the Object and Content printed are already escaped.%r", file.stream, f_string_eol_s);
- fl_print_format(" Both the Object and Content are separated by a space.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%] accepts the following:%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_delimit_s, context.set.notable, f_string_eol_s);
- fl_print_format(" - %[%r%]: Do not apply delimits.%r", file.stream, context.set.notable, fss_extended_read_delimit_mode_name_none_s, context.set.notable, f_string_eol_s);
- fl_print_format(" - %[%r%]: (default) Apply all delimits.%r", file.stream, context.set.notable, fss_extended_read_delimit_mode_name_all_s, context.set.notable, f_string_eol_s);
- fl_print_format(" - %[%r%]: Apply delimits for Objects.%r", file.stream, context.set.notable, fss_extended_read_delimit_mode_name_object_s, context.set.notable, f_string_eol_s);
- fl_print_format(" - A number, 0 or greater: apply delimits for Content at the specified depth.%r", file.stream, f_string_eol_s);
- fl_print_format(" - A number, 0 or greater, followed by a %[%r%]: (such as '1+') apply delimits for Content at the specified depth and any greater depth (numerically).%r", file.stream, context.set.notable, fss_extended_read_delimit_mode_name_greater_s, context.set.notable, f_string_eol_s, f_string_eol_s);
- fl_print_format(" - A number, 0 or lesser, followed by a %[%r%]: (such as '1-') apply delimits for Content at the specified depth and any lesser depth (numerically).%r%r", file.stream, context.set.notable, fss_extended_read_delimit_mode_name_lesser_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The %[%r%r%] parameter may be specified multiple times to customize the delimit behavior.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_delimit_s, context.set.notable, f_string_eol_s);
-
- fl_print_format(" The %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_delimit_s, context.set.notable);
- fl_print_format(" values %[%r%]", file.stream, context.set.notable, fss_extended_read_delimit_mode_name_none_s, context.set.notable);
- fl_print_format(" and %[%r%],", file.stream, context.set.notable, fss_extended_read_delimit_mode_name_all_s, context.set.notable);
- fl_print_format(" overrule all other delimit values.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameters %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_columns_s, context.set.notable);
- fl_print_format(" and %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_read_long_select_s, context.set.notable);
- fl_print_format(" refer to a Content column.%r", file.stream, f_string_eol_s);
- fl_print_format(" The word \"column\" is being loosely defined to refer to a specific Content.%r", file.stream, f_string_eol_s);
- fl_print_format(" This is not to be confused with a depth.%r", file.stream, f_string_eol_s);
-
- //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- f_file_stream_flush(file);
- funlockfile(file.stream);
-
- return F_none;
- }
-#endif // _di_fss_extended_read_print_help_
-
#ifndef _di_fss_extended_read_main_
- f_status_t fss_extended_read_main(fll_program_data_t * const main, const f_console_arguments_t arguments) {
+ f_status_t fss_extended_read_main(fll_program_data_t * const main, fss_extended_read_setting_t * const setting) {
f_status_t status = F_none;
status = F_none;
if (main->parameters.array[fss_extended_read_parameter_help_e].result == f_console_result_found_e) {
- fss_extended_read_print_help(main->output.to, main->context);
+ fss_extended_read_print_help(setting, main->message);
return status;
}
if (main->parameters.array[fss_extended_read_parameter_version_e].result == f_console_result_found_e) {
- fll_program_print_version(main->output.to, fss_extended_read_program_version_s);
+ fll_program_print_version(main->message, fss_extended_read_program_version_s);
return status;
}
if (!((++main->signal_check) % fss_extended_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_extended_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_signal);
if (!((++main->signal_check) % fss_extended_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_extended_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_signal);
// The signal check is always performed on each pass.
if (size_file > fss_extended_read_block_max && fll_program_standard_signal_received(main)) {
- fss_extended_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
#endif
/**
- * Print help.
- *
- * @param file
- * The file to print to.
- * @param context
- * The color context settings.
- *
- * @return
- * F_none on success.
- */
-#ifndef _di_fss_extended_read_print_help_
- extern f_status_t fss_extended_read_print_help(const f_file_t file, const f_color_context_t context);
-#endif // _di_fss_extended_read_print_help_
-
-/**
* Execute main program.
*
* If main.signal is non-zero, then this blocks and handles the following signals:
* Status codes (with error bit) are returned on any problem.
*/
#ifndef _di_fss_extended_read_main_
- extern f_status_t fss_extended_read_main(fll_program_data_t * const main, const f_console_arguments_t arguments);
+ extern f_status_t fss_extended_read_main(fll_program_data_t * const main, fss_extended_read_setting_t * const setting);
#endif // _di_fss_extended_read_main_
#ifdef __cplusplus
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
fll_program_data_t data = fll_program_data_t_initialize;
+ fss_extended_read_setting_t setting = fss_extended_read_setting_t_initialize;
f_console_parameter_t parameters[] = fss_extended_read_console_parameter_t_initialize;
data.parameters.array = parameters;
data.parameters.used = fss_extended_read_total_parameters_d;
+ data.environment = envp;
if (f_pipe_input_exists()) {
data.pipe = fll_program_data_pipe_input_e;
fll_program_standard_set_up(&data);
- const f_status_t status = fss_extended_read_main(&data, arguments);
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+
+ fss_extended_read_setting_load(arguments, &data, &setting);
+ }
+
+ fss_extended_read_main(&data, &setting);
+
+ fss_extended_read_setting_unload(&data, &setting);
fll_program_data_delete(&data);
fll_program_standard_set_down(&data);
- if (F_status_is_error(status)) return 1;
-
- return 0;
+ return F_status_is_error(status) ? 1 : 0;
}
--- /dev/null
+#include "fss_extended_read.h"
+#include "private-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fss_extended_read_print_help_
+ f_status_t fss_extended_read_print_help(fss_extended_read_setting_t * const setting, const fl_print_t print) {
+
+ f_file_stream_lock(print.to);
+
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+
+ fll_program_print_help_header(print, fss_extended_read_program_name_long_s, fss_extended_read_program_version_s);
+
+ fll_program_print_help_option_standard(print);
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, fss_extended_read_short_at_s, fss_extended_read_long_at_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric index.");
+ fll_program_print_help_option(print, fss_extended_read_short_content_s, fss_extended_read_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Content (default).");
+ fll_program_print_help_option(print, fss_extended_read_short_columns_s, fss_extended_read_long_columns_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of columns.");
+ fll_program_print_help_option(print, fss_extended_read_short_delimit_s, fss_extended_read_long_delimit_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Designate how to handle applying delimits.");
+ fll_program_print_help_option(print, fss_extended_read_short_depth_s, fss_extended_read_long_depth_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric depth.");
+ fll_program_print_help_option(print, fss_extended_read_short_empty_s, fss_extended_read_long_empty_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Include empty Content when processing.");
+ fll_program_print_help_option(print, fss_extended_read_short_line_s, fss_extended_read_long_line_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print only the Content at the given line.");
+ fll_program_print_help_option(print, fss_extended_read_short_name_s, fss_extended_read_long_name_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object with this name.");
+ fll_program_print_help_option(print, fss_extended_read_short_object_s, fss_extended_read_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Object.");
+ fll_program_print_help_option(print, fss_extended_read_short_pipe_s, fss_extended_read_long_pipe_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print using the special pipe format.");
+ fll_program_print_help_option(print, fss_extended_read_short_original_s, fss_extended_read_long_original_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print with the original quotes and escapes.");
+ fll_program_print_help_option(print, fss_extended_read_short_select_s, fss_extended_read_long_select_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select sub-Content at this index.");
+ fll_program_print_help_option(print, fss_extended_read_short_total_s, fss_extended_read_long_total_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of lines.");
+ fll_program_print_help_option(print, fss_extended_read_short_trim_s, fss_extended_read_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names on select or print.");
+
+ fll_program_print_help_usage(print, fss_extended_read_program_name_s, fll_program_parameter_filenames_s);
+
+ fl_print_format("%r %[Notes:%]%r", print.to.stream, f_string_eol_s, print.set->important, print.set->important, f_string_eol_s);
+
+ fl_print_format(" This program will print the Content associated with the given Object and Content main based on the FSS-0001 Extended standard.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" All numeric positions (indexes) start at 0 instead of 1.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" For example, a file of 17 lines would range from 0 to 16.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When using the %[%r%r%] option, an order of operations is enforced on the parameters.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_depth_s, print.set->notable, f_string_eol_s);
+
+ fl_print_format(" When this order of operations is in effect, parameters to the right of a depth parameter are influenced by that depth parameter:%r", print.to.stream, f_string_eol_s);
+
+ fl_print_format(" %[%r%r%]: An Object index at the specified depth.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_at_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" %[%r%r%]: A new depth within the specified depth, indexed from the root.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_depth_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" %[%r%r%]: An Object name at the specified depth.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_name_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%] must be in numeric order, but values in between may be skipped.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_depth_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" ('-d 0 -a 1 -d 2 -a 2' would specify index 1 at depth 0, any index at depth 1, and index 2 at depth 2.)%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" ('-d 2 -a 1 -d 0 -a 2' would be invalid because depth 2 is before depth 1.)%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%] selects a Content column.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_select_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" Specify both %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_object_s, print.set->notable);
+ fl_print_format(" and the %[%r%r%] parameters to get the total objects.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_total_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When both %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_at_s, print.set->notable);
+ fl_print_format(" and %[%r%r%] parameters are specified (at the same depth),", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_name_s, print.set->notable);
+ fl_print_format(" the %[%r%r%] parameter value will be treated as a position relative to the specified", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_at_s, print.set->notable);
+ fl_print_format(" %[%r%r%] parameter value.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_name_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" This program may support parameters, such as %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_depth_s, print.set->notable);
+ fl_print_format(" or %[%r%r%], even if not supported by the standard.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_select_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" This is done to help ensure consistency for scripting.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" For parameters like %[%r%r%],", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_depth_s, print.set->notable);
+ fl_print_format(" if the standard doesn't support nested Content, then only a depth of 0 would be valid.%r", print.to.stream, f_string_eol_s);
+
+ fl_print_format(" For parameters like %[%r%r%],", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_select_s, print.set->notable);
+ fl_print_format(" if the standard doesn't support multiple Content groups, then only a select of 0 would be valid.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_trim_s, print.set->notable);
+ fl_print_format(" will remove leading and trailing white spaces when selecting objects or when printing objects.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When specifying both the %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_object_s, print.set->notable);
+ fl_print_format(" parameter and the %[%r%r%] parameter, the entire Object and Content are printed, including the formatting.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_content_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" Both the Object and Content printed are already escaped.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" Both the Object and Content are separated by a space.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%] accepts the following:%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_delimit_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" - %[%r%]: Do not apply delimits.%r", print.to.stream, print.set->notable, fss_extended_read_delimit_mode_name_none_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" - %[%r%]: (default) Apply all delimits.%r", print.to.stream, print.set->notable, fss_extended_read_delimit_mode_name_all_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" - %[%r%]: Apply delimits for Objects.%r", print.to.stream, print.set->notable, fss_extended_read_delimit_mode_name_object_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" - A number, 0 or greater: apply delimits for Content at the specified depth.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" - A number, 0 or greater, followed by a %[%r%]: (such as '1+') apply delimits for Content at the specified depth and any greater depth (numerically).%r", print.to.stream, print.set->notable, fss_extended_read_delimit_mode_name_greater_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+ fl_print_format(" - A number, 0 or lesser, followed by a %[%r%]: (such as '1-') apply delimits for Content at the specified depth and any lesser depth (numerically).%r%r", print.to.stream, print.set->notable, fss_extended_read_delimit_mode_name_lesser_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The %[%r%r%] parameter may be specified multiple times to customize the delimit behavior.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_delimit_s, print.set->notable, f_string_eol_s);
+
+ fl_print_format(" The %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_delimit_s, print.set->notable);
+ fl_print_format(" values %[%r%]", print.to.stream, print.set->notable, fss_extended_read_delimit_mode_name_none_s, print.set->notable);
+ fl_print_format(" and %[%r%],", print.to.stream, print.set->notable, fss_extended_read_delimit_mode_name_all_s, print.set->notable);
+ fl_print_format(" overrule all other delimit values.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameters %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_columns_s, print.set->notable);
+ fl_print_format(" and %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_read_long_select_s, print.set->notable);
+ fl_print_format(" refer to a Content column.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" The word \"column\" is being loosely defined to refer to a specific Content.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" This is not to be confused with a depth.%r", print.to.stream, f_string_eol_s);
+
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+
+ f_file_stream_flush(print.to);
+ f_file_stream_unlock(print.to);
+
+ return F_none;
+ }
+#endif // _di_fss_extended_read_print_help_
+
+#ifndef _di_fss_extended_read_print_line_first_
+ void fss_extended_read_print_line_first(fss_extended_read_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ }
+#endif // _di_fss_extended_read_print_line_first_
+
+#ifndef _di_fss_extended_read_print_line_last_
+ void fss_extended_read_print_line_last(fss_extended_read_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+ if (print.verbosity == f_console_verbosity_error_e && !F_status_is_error(setting->status)) return;
+ if (setting->flag & fss_extended_read_main_flag_verify_e) return;
+ if ((setting->flag & fss_extended_read_main_flag_file_to_e) && !F_status_is_error(setting->status)) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ }
+#endif // _di_fss_extended_read_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: UTF-8
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _fss_extended_read_print_h
+#define _fss_extended_read_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print help.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * The output structure to print to.
+ *
+ * @return
+ * F_none on success.
+ */
+#ifndef _di_fss_extended_read_print_help_
+ extern f_status_t fss_extended_read_print_help(fss_extended_read_setting_t * const setting, const fl_print_t print);
+#endif // _di_fss_extended_read_print_help_
+
+/**
+ * Print first new line, unless verbosity says otherwise.
+ *
+ * This is generally either the first line in the program or the first line printed before an error message.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_extended_read_print_line_first_
+ extern void fss_extended_read_print_line_first(fss_extended_read_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_extended_read_print_line_first_
+
+/**
+ * Print last new line when the main is complete, unless verbosity says otherwise.
+ *
+ * This is generally the very last line printed in the program.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_extended_read_print_line_last_
+ extern void fss_extended_read_print_line_last(fss_extended_read_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_extended_read_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _fss_extended_read_print_h
}
#endif // _di_fss_extended_read_depths_resize_
-#ifndef _di_fss_extended_read_print_signal_received_
- void fss_extended_read_print_signal_received(fll_program_data_t * const main) {
-
- if (main->warning.verbosity != f_console_verbosity_verbose_e && main->warning.verbosity != f_console_verbosity_debug_e) return;
-
- // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
- fflush(main->warning.to.stream);
-
- flockfile(main->warning.to.stream);
-
- fl_print_format("%]%r%r%[Received signal code %]", main->warning.to.stream, main->context.set.reset, f_string_eol_s, f_string_eol_s, main->context.set.warning, main->context.set.warning);
- fl_print_format("%[%i%]", main->warning.to.stream, main->context.set.notable, main->signal_received, main->context.set.notable);
- fl_print_format("%[.%]%r", main->warning.to.stream, main->context.set.warning, main->context.set.warning, f_string_eol_s);
-
- funlockfile(main->warning.to.stream);
- }
-#endif // _di_fss_extended_read_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
extern f_status_t fss_extended_read_depths_resize(const f_array_length_t length, fss_extended_read_depths_t *depths) F_attribute_visibility_internal_d;
#endif // _di_fss_extended_read_depths_resize_
-/**
- * Print a message about a process signal being recieved, such as an interrupt signal.
- *
- * @param main
- * The main program data.
- */
-#ifndef _di_fss_extended_read_print_signal_received_
- extern void fss_extended_read_print_signal_received(fll_program_data_t * const main) F_attribute_visibility_internal_d;
-#endif // _di_fss_extended_read_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
if (!((++main->signal_check) % fss_extended_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_extended_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (!((++main->signal_check) % fss_extended_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_extended_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library fss_extended_read.c common.c private-common.c private-print.c private-read.c
+build_sources_library fss_extended_read.c common.c print.c private-common.c private-print.c private-read.c
build_sources_program main.c
-build_sources_headers fss_extended_read.h common.h
+build_sources_headers fss_extended_read.h common.h print.h
build_script yes
build_shared yes
const f_string_static_t fss_extended_write_long_trim_s = macro_f_string_static_t_initialize(FSS_EXTENDED_WRITE_long_trim_s, 0, FSS_EXTENDED_WRITE_long_trim_s_length);
#endif // _di_fss_extended_write_parameters_
+#ifndef _di_fss_extended_write_setting_delete_
+ f_status_t fss_extended_write_setting_delete(fss_extended_write_setting_t * const setting) {
+
+ if (!setting) return F_status_set_error(F_parameter);
+
+ return F_none;
+ }
+#endif // _di_fss_extended_write_setting_delete_
+
+#ifndef _di_fss_extended_write_setting_load_
+ void fss_extended_write_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_extended_write_setting_t * const setting) {
+
+ if (!main || !setting) return;
+
+ // Load parameters.
+ setting->status = f_console_parameter_process(arguments, &main->parameters);
+ if (F_status_is_error(setting->status)) return;
+
+ {
+ f_array_length_t choice = 0;
+ f_uint16s_t choices = f_uint16s_t_initialize;
+
+ // Identify and prioritize "color context" parameters.
+ {
+ uint16_t choices_array[3] = { fss_extended_write_parameter_no_color_e, fss_extended_write_parameter_light_e, fss_extended_write_parameter_dark_e };
+ choices.array = choices_array;
+ choices.used = 3;
+
+ const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
+
+ setting->status = fll_program_parameter_process_context(choices, modes, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_extended_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_context", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_extended_write_parameter_line_first_no_e].result == f_console_result_found_e) {
+ setting->line_first = f_string_empty_s;
+ }
+ else {
+ setting->line_first = f_string_eol_s;
+ }
+
+ if (main->parameters.array[fss_extended_write_parameter_line_last_no_e].result == f_console_result_found_e) {
+ setting->line_last = f_string_empty_s;
+ }
+ else {
+ setting->line_last = f_string_eol_s;
+ }
+
+ // Identify and prioritize "verbosity" parameters.
+ {
+ uint16_t choices_array[5] = { fss_extended_write_parameter_verbosity_quiet_e, fss_extended_write_parameter_verbosity_error_e, fss_extended_write_parameter_verbosity_verbose_e, fss_extended_write_parameter_verbosity_debug_e, fss_extended_write_parameter_verbosity_normal_e };
+ choices.array = choices_array;
+ choices.used = 5;
+
+ const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+
+ setting->status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_extended_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_verbosity", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_extended_write_parameter_help_e].result == f_console_result_found_e) {
+ setting->flag |= fss_extended_write_main_flag_help_e;
+
+ return;
+ }
+
+ if (main->parameters.array[fss_extended_write_parameter_version_e].result == f_console_result_found_e) {
+ setting->flag |= fss_extended_write_main_flag_version_e;
+
+ return;
+ }
+
+ // Identify and prioritize "from" mode parameters.
+ {
+ uint16_t choices_array[2] = { fss_extended_write_parameter_from_bytesequence_e, fss_extended_write_parameter_from_codepoint_e };
+ choices.array = choices_array;
+ choices.used = 2;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_extended_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_extended_write_parameter_from_bytesequence_e) {
+ if (setting->mode & fss_extended_write_mode_from_codepoint_e) {
+ setting->mode -= fss_extended_write_mode_from_codepoint_e;
+ }
+
+ setting->mode |= fss_extended_write_mode_from_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_extended_write_parameter_from_codepoint_e) {
+ if (setting->mode & fss_extended_write_mode_from_bytesequence_e) {
+ setting->mode -= fss_extended_write_mode_from_bytesequence_e;
+ }
+
+ setting->mode |= fss_extended_write_mode_from_codepoint_e;
+ }
+ }
+
+ // Identify and prioritize "to" mode parameters.
+ {
+ uint16_t choices_array[4] = { fss_extended_write_parameter_to_bytesequence_e, fss_extended_write_parameter_to_codepoint_e, fss_extended_write_parameter_to_combining_e, fss_extended_write_parameter_to_width_e };
+ choices.array = choices_array;
+ choices.used = 4;
+ choice = 1;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_extended_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_extended_write_parameter_to_bytesequence_e) {
+ if (setting->mode & fss_extended_write_mode_to_codepoint_e) {
+ setting->mode -= fss_extended_write_mode_to_codepoint_e;
+ }
+
+ if (setting->mode & fss_extended_write_mode_to_combining_e) {
+ setting->mode -= fss_extended_write_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_extended_write_mode_to_width_e) {
+ setting->mode -= fss_extended_write_mode_to_width_e;
+ }
+
+ setting->mode |= fss_extended_write_mode_to_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_extended_write_parameter_to_codepoint_e) {
+ if (setting->mode & fss_extended_write_mode_to_bytesequence_e) {
+ setting->mode -= fss_extended_write_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_extended_write_mode_to_combining_e) {
+ setting->mode -= fss_extended_write_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_extended_write_mode_to_width_e) {
+ setting->mode -= fss_extended_write_mode_to_width_e;
+ }
+
+ setting->mode |= fss_extended_write_mode_to_codepoint_e;
+ }
+ else if (choices.array[choice] == fss_extended_write_parameter_to_combining_e) {
+ if (setting->mode & fss_extended_write_mode_to_bytesequence_e) {
+ setting->mode -= fss_extended_write_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_extended_write_mode_to_codepoint_e) {
+ setting->mode -= fss_extended_write_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_extended_write_parameter_to_width_e].result == f_console_result_found_e) {
+ setting->mode |= fss_extended_write_mode_to_width_e;
+ }
+
+ setting->mode |= fss_extended_write_mode_to_combining_e;
+ }
+ else if (choices.array[choice] == fss_extended_write_parameter_to_width_e) {
+ if (setting->mode & fss_extended_write_mode_to_bytesequence_e) {
+ setting->mode -= fss_extended_write_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_extended_write_mode_to_codepoint_e) {
+ setting->mode -= fss_extended_write_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_extended_write_parameter_to_combining_e].result == f_console_result_found_e) {
+ setting->mode |= fss_extended_write_mode_to_combining_e;
+ }
+
+ setting->mode |= fss_extended_write_mode_to_width_e;
+ }
+ }
+ }
+
+ f_string_static_t * const args = main->parameters.arguments.array;
+
+ if (main->parameters.array[fss_extended_write_parameter_to_file_e].result == f_console_result_additional_e) {
+ if (main->parameters.array[fss_extended_write_parameter_to_file_e].values.used > 1) {
+ fss_extended_write_print_error_parameter_file_to_too_many(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+
+ if (args[main->parameters.array[fss_extended_write_parameter_to_file_e].values.array[0]].used) {
+ setting->path_files_to.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(1, &setting->path_files_to);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_to.array[setting->path_files_to.used].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[main->parameters.array[fss_extended_write_parameter_to_file_e].values.array[0]], &setting->path_files_to.array[0]);
+ if (F_status_is_error(setting->status)) return;
+
+ ++setting->path_files_to.used;
+
+ setting->status = f_file_stream_open(args[main->parameters.array[fss_extended_write_parameter_to_file_e].values.array[0]], f_file_open_mode_append_s, &main->output.to);
+
+ if (F_status_is_error(setting->status)) {
+ fll_error_file_print(main->error, F_status_set_fine(setting->status), "f_file_stream_open", F_true, args[main->parameters.array[fss_extended_write_parameter_to_file_e].values.array[0]], f_file_operation_open_s, fll_error_file_type_file_e);
+
+ return;
+ }
+
+ setting->flag |= fss_extended_write_main_flag_file_to_e;
+ }
+ else {
+ fss_extended_write_print_error_parameter_file_name_empty(main, setting, main->parameters.array[fss_extended_write_parameter_to_file_e].values.array[0]);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+ else if (main->parameters.array[fss_extended_write_parameter_to_file_e].result == f_console_result_found_e) {
+ fss_extended_write_print_error_no_value(main, setting, fss_extended_write_long_to_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ main->output.to = main->message.to;
+
+ if (setting->flag & fss_extended_write_main_flag_file_to_e) {
+ setting->flag -= fss_extended_write_main_flag_file_to_e;
+ }
+ }
+
+ if (main->parameters.array[fss_extended_write_parameter_from_file_e].result == f_console_result_additional_e) {
+ setting->path_files_from.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(main->parameters.array[fss_extended_write_parameter_from_file_e].values.used, &setting->path_files_from);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_from.used = main->parameters.array[fss_extended_write_parameter_from_file_e].values.used;
+
+ f_array_length_t i = 0;
+ f_array_length_t index = 0;
+
+ for (; i < setting->path_files_from.used; ++i) {
+
+ index = main->parameters.array[fss_extended_write_parameter_from_file_e].values.array[i];
+ setting->path_files_from.array[i].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[index], &setting->path_files_from.array[i]);
+ if (F_status_is_error(setting->status)) return;
+
+ if (args[index].used) {
+ if (f_file_exists(args[index], F_true) != F_true) {
+ fss_extended_write_print_error_parameter_file_not_found(main, setting, F_true, args[index]);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_file_found_not);
+ }
+ }
+ }
+ else {
+ fss_extended_write_print_error_parameter_file_name_empty(main, setting, index);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_parameter);
+ }
+ }
+ } // for
+
+ if (F_status_is_error(setting->status)) return;
+
+ setting->flag |= fss_extended_write_main_flag_file_from_e;
+ }
+ else if (main->parameters.array[fss_extended_write_parameter_from_file_e].result == f_console_result_found_e) {
+ fss_extended_write_print_error_no_value(main, setting, fss_extended_write_long_from_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ if (setting->flag & fss_extended_write_main_flag_file_from_e) {
+ setting->flag -= fss_extended_write_main_flag_file_from_e;
+ }
+ }
+
+ if (F_status_is_error(setting->status)) return;
+
+ if (main->parameters.array[fss_extended_write_parameter_from_file_e].result == f_console_result_none_e && !((main->pipe & fll_program_data_pipe_input_e) || main->parameters.remaining.used)) {
+ fss_extended_write_print_error_no_from(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+ }
+
+ if (!(setting->mode & fss_extended_write_mode_to_bytesequence_e)) {
+ if (main->parameters.array[fss_extended_write_parameter_separate_e].result == f_console_result_found_e || main->parameters.array[fss_extended_write_parameter_headers_e].result == f_console_result_found_e) {
+ setting->prepend = fss_extended_write_string_prepend_padding_s;
+ setting->append = f_string_eol_s;
+ }
+ else {
+ setting->prepend = f_string_space_s;
+ }
+ }
+
+ if (main->parameters.array[fss_extended_write_parameter_headers_e].result == f_console_result_found_e) {
+ setting->flag |= fss_extended_write_main_flag_header_e;
+ }
+
+ if (main->parameters.array[fss_extended_write_parameter_separate_e].result == f_console_result_found_e) {
+ setting->flag |= fss_extended_write_main_flag_separate_e;
+ }
+
+ if (main->parameters.array[fss_extended_write_parameter_strip_invalid_e].result == f_console_result_found_e) {
+ setting->flag |= fss_extended_write_main_flag_strip_invalid_e;
+ }
+
+ setting->valid_not = main->message.set->error;
+ }
+#endif // _di_fss_extended_write_setting_load_
+
+#ifndef _di_fss_extended_write_setting_unload_
+ f_status_t fss_extended_write_setting_unload(fll_program_data_t * const main, fss_extended_write_setting_t * const setting) {
+
+ if (!main || !setting) return F_status_set_error(F_parameter);
+
+ fss_extended_write_setting_delete(setting);
+
+ return F_none;
+ }
+#endif // _di_fss_extended_write_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
#define fss_extended_write_total_parameters_d 20
#endif // _di_fss_extended_write_parameters_
+/**
+ * Flags used to represent flags passed to the main function.
+ *
+ * fss_extended_write_main_flag_*_e:
+ * - none: No modes in use.
+ * - file_from: Using a specified source file.
+ * - file_to: Using a specified destination file.
+ * - help: Print help.
+ * - header: Enable printing of headers.
+ * - separate: Enable printing of separators.
+ * - strip_invalid: Using strip invalid character mode.
+ * - verify: Using verify mode.
+ * - version: Print version.
+ */
+#ifndef _di_fss_extended_write_main_flag_e_
+ enum {
+ fss_extended_write_main_flag_none_e = 0x0,
+ fss_extended_write_main_flag_file_from_e = 0x1,
+ fss_extended_write_main_flag_file_to_e = 0x2,
+ fss_extended_write_main_flag_header_e = 0x4,
+ fss_extended_write_main_flag_help_e = 0x8,
+ fss_extended_write_main_flag_separate_e = 0x10,
+ fss_extended_write_main_flag_strip_invalid_e = 0x20,
+ fss_extended_write_main_flag_verify_e = 0x40,
+ fss_extended_write_main_flag_version_e = 0x80,
+ };
+#endif // _di_fss_extended_write_main_flag_e_
+
+/**
+ * The fss extended write main program settings.
+ *
+ * This is passed to the program-specific main entry point to designate program settings.
+ * These program settings are often processed from the program arguments (often called the command line arguments).
+ *
+ * flag: Flags passed to the main function.
+ *
+ * status: The main status code, generally used by the load settings and main functions.
+ *
+ * line_first: A string expected to represent either "\n" or NULL to allow for easy handling of when to print first new line or not.
+ * line_last: A string expected to represent either "\n" or NULL to allow for easy handling of when to print last new line or not.
+ */
+#ifndef _di_fss_extended_write_setting_t_
+ typedef struct {
+ uint16_t flag;
+
+ f_status_t status;
+
+ f_string_static_t line_first;
+ f_string_static_t line_last;
+ } fss_extended_write_setting_t;
+
+ #define fss_extended_write_setting_t_initialize \
+ { \
+ fss_extended_write_main_flag_none_e, \
+ F_none, \
+ f_string_static_t_initialize, \
+ f_string_static_t_initialize, \
+ }
+#endif // _di_fss_extended_write_setting_t_
+
+/**
+ * Delete the program main setting data.
+ *
+ * @param setting
+ * The program main setting data.
+ * This does not alter setting.status.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fss_extended_write_setting_delete_
+ extern f_status_t fss_extended_write_setting_delete(fss_extended_write_setting_t * const setting);
+#endif // _di_fss_extended_write_setting_delete_
+
+/**
+ * Perform the standard program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately retuns without doing anything.
+ *
+ * @param arguments
+ * The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ *
+ * This alters setting.status:
+ * F_none on success.
+ *
+ * Errors (with error bit) from: f_console_parameter_process().
+ * Errors (with error bit) from: fll_program_parameter_process_context().
+ *
+ * @see f_console_parameter_process()
+ * @see fll_program_parameter_process_context()
+ */
+#ifndef _di_fss_extended_write_setting_load_
+ extern void fss_extended_write_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_extended_write_setting_t * const setting);
+#endif // _di_fss_extended_write_setting_load_
+
+/**
+ * Perform the standard program setting unload process.
+ *
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * All buffers are deallocated.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: utf8_setting_delete().
+ *
+ * @see utf8_setting_delete()
+ */
+#ifndef _di_fss_extended_write_setting_unload_
+ extern f_status_t fss_extended_write_setting_unload(fll_program_data_t * const main, fss_extended_write_setting_t * const setting);
+#endif // _di_fss_extended_write_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern "C" {
#endif
-#ifndef _di_fss_extended_write_print_help_
- f_status_t fss_extended_write_print_help(const f_file_t file, const f_color_context_t context) {
-
- flockfile(file.stream);
-
- //if (!(setting->flag & XXX_main_flag_line_first_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- fll_program_print_help_header(file, context, fss_extended_write_program_name_long_s, fss_extended_write_program_version_s);
-
- fll_program_print_help_option_standard(file, context);
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, fss_extended_write_short_file_s, fss_extended_write_long_file_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a file to send data to.");
- fll_program_print_help_option(file, context, fss_extended_write_short_content_s, fss_extended_write_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "The Content to write.");
- fll_program_print_help_option(file, context, fss_extended_write_short_double_s, fss_extended_write_long_double_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use double quotes (default).");
- fll_program_print_help_option(file, context, fss_extended_write_short_ignore_s, fss_extended_write_long_ignore_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Ignore a given range within a Content.");
- fll_program_print_help_option(file, context, fss_extended_write_short_object_s, fss_extended_write_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The Object to write.");
- fll_program_print_help_option(file, context, fss_extended_write_short_partial_s, fss_extended_write_long_partial_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Do not write end of Object/Content character.");
- fll_program_print_help_option(file, context, fss_extended_write_short_prepend_s, fss_extended_write_long_prepend_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Prepend the given white space characters to the start of each multi-line Content.");
- fll_program_print_help_option(file, context, fss_extended_write_short_single_s, fss_extended_write_long_single_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use single quotes.");
- fll_program_print_help_option(file, context, fss_extended_write_short_trim_s, fss_extended_write_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names.");
-
- fll_program_print_help_usage(file, context, fss_extended_write_program_name_s, f_string_empty_s);
-
- fl_print_format("%r The pipe uses the Backspace character '%[\\b%]' (%[U+0008%]) to designate the start of a Content.%r", file.stream, f_string_eol_s, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" The pipe uses the Form Feed character '%[\\f%]' (%[U+000C%]) to designate the end of the last Content.%r", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" The pipe uses the Vertical Line character '%[\\v%]' (%[U+000B%]) is used to ignore a Content range, which does nothing in this program.%r", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" For the pipe, an Object is terminated by either a Backspace character '%[\\b%]' (%[U+0008%])", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable);
- fl_print_format(" or a Form Feed character '%[\\f%]' (%[U+000C%]).%r", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" The end of the pipe represents the end of any Object or Content.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The FSS-0001 (Extended) specification does not support multi-line Content, therefore the parameter '%[%r%r%]'", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_write_long_prepend_s, context.set.notable);
- fl_print_format(" does nothing.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" This program does not use the parameter '%[%r%r%]', which therefore does nothing.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_extended_write_long_ignore_s, context.set.notable, f_string_eol_s);
- fl_print_format(" This parameter requires two values.%r", file.stream, f_string_eol_s);
-
- //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- f_file_stream_flush(file);
- funlockfile(file.stream);
-
- return F_none;
- }
-#endif // _di_fss_extended_write_print_help_
-
#ifndef _di_fss_extended_write_main_
- f_status_t fss_extended_write_main(fll_program_data_t * const main, const f_console_arguments_t arguments) {
+ f_status_t fss_extended_write_main(fll_program_data_t * const main, fss_extended_write_setting_t * const setting) {
f_status_t status = F_none;
status = F_none;
if (main->parameters.array[fss_extended_write_parameter_help_e].result == f_console_result_found_e) {
- fss_extended_write_print_help(main->output.to, main->context);
+ fss_extended_write_print_help(setting, main->message);
return status;
}
if (main->parameters.array[fss_extended_write_parameter_version_e].result == f_console_result_found_e) {
- fll_program_print_version(main->output.to, fss_extended_write_program_version_s);
+ fll_program_print_version(main->message, fss_extended_write_program_version_s);
return status;
}
if (!((++main->signal_check) % fss_extended_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_extended_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
if (!((++main->signal_check) % fss_extended_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_extended_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
#endif
/**
- * Print help.
- *
- * @param file
- * The file to print to.
- * @param context
- * The color context settings.
- *
- * @return
- * F_none on success.
- */
-#ifndef _di_fss_extended_write_print_help_
- extern f_status_t fss_extended_write_print_help(const f_file_t file, const f_color_context_t context);
-#endif // _di_fss_extended_write_print_help_
-
-/**
* Execute main program.
*
* If main.signal is non-zero, then this blocks and handles the following signals:
*
* @param main
* The main program data.
- * @param arguments
- * The parameters passed to the process.
+ * @param setting
+ * The main program settings.
*
- * @return
- * F_none on success.
+ * This alters setting.status:
+ * F_none on success.
+ * F_true on success when performing verification and verify passed.
+ * F_false on success when performing verification and verify failed.
+ * F_interrupt on (exit) signal received.
*
- * Status codes (with error bit) are returned on any problem.
+ * F_parameter (with error bit) if main is NULL or setting is NULL.
*/
#ifndef _di_fss_extended_write_main_
- extern f_status_t fss_extended_write_main(fll_program_data_t * const main, const f_console_arguments_t arguments);
+ extern f_status_t fss_extended_write_main(fll_program_data_t * const main, fss_extended_write_setting_t * const setting);
#endif // _di_fss_extended_write_main_
#ifdef __cplusplus
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
fll_program_data_t data = fll_program_data_t_initialize;
+ fss_extended_write_setting_t setting = fss_extended_write_setting_t_initialize;
f_console_parameter_t parameters[] = fss_extended_write_console_parameter_t_initialize;
data.parameters.array = parameters;
data.parameters.used = fss_extended_write_total_parameters_d;
+ data.environment = envp;
if (f_pipe_input_exists()) {
data.pipe = fll_program_data_pipe_input_e;
fll_program_standard_set_up(&data);
- const f_status_t status = fss_extended_write_main(&data, arguments);
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+
+ fss_extended_write_setting_load(arguments, &data, &setting);
+ }
+
+ fss_extended_write_main(&data, &setting);
+
+ fss_extended_write_setting_unload(&data, &setting);
fll_program_data_delete(&data);
fll_program_standard_set_down(&data);
- if (F_status_is_error(status)) return 1;
-
- return 0;
+ return F_status_is_error(status) ? 1 : 0;
}
--- /dev/null
+#include "fss_extended_write.h"
+#include "private-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fss_extended_write_print_help_
+ f_status_t fss_extended_write_print_help(fss_extended_write_setting_t * const setting, const fl_print_t print) {
+
+ f_file_stream_lock(print.to);
+
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+
+ fll_program_print_help_header(print, fss_extended_write_program_name_long_s, fss_extended_write_program_version_s);
+
+ fll_program_print_help_option_standard(print);
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, fss_extended_write_short_file_s, fss_extended_write_long_file_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a file to send data to.");
+ fll_program_print_help_option(print, fss_extended_write_short_content_s, fss_extended_write_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "The Content to write.");
+ fll_program_print_help_option(print, fss_extended_write_short_double_s, fss_extended_write_long_double_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use double quotes (default).");
+ fll_program_print_help_option(print, fss_extended_write_short_ignore_s, fss_extended_write_long_ignore_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Ignore a given range within a Content.");
+ fll_program_print_help_option(print, fss_extended_write_short_object_s, fss_extended_write_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The Object to write.");
+ fll_program_print_help_option(print, fss_extended_write_short_partial_s, fss_extended_write_long_partial_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Do not write end of Object/Content character.");
+ fll_program_print_help_option(print, fss_extended_write_short_prepend_s, fss_extended_write_long_prepend_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Prepend the given white space characters to the start of each multi-line Content.");
+ fll_program_print_help_option(print, fss_extended_write_short_single_s, fss_extended_write_long_single_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use single quotes.");
+ fll_program_print_help_option(print, fss_extended_write_short_trim_s, fss_extended_write_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names.");
+
+ fll_program_print_help_usage(print, fss_extended_write_program_name_s, f_string_empty_s);
+
+ fl_print_format("%r The pipe uses the Backspace character '%[\\b%]' (%[U+0008%]) to designate the start of a Content.%r", print.to.stream, f_string_eol_s, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" The pipe uses the Form Feed character '%[\\f%]' (%[U+000C%]) to designate the end of the last Content.%r", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" The pipe uses the Vertical Line character '%[\\v%]' (%[U+000B%]) is used to ignore a Content range, which does nothing in this program.%r", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" For the pipe, an Object is terminated by either a Backspace character '%[\\b%]' (%[U+0008%])", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable);
+ fl_print_format(" or a Form Feed character '%[\\f%]' (%[U+000C%]).%r", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" The end of the pipe represents the end of any Object or Content.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The FSS-0001 (Extended) specification does not support multi-line Content, therefore the parameter '%[%r%r%]'", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_write_long_prepend_s, print.set->notable);
+ fl_print_format(" does nothing.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" This program does not use the parameter '%[%r%r%]', which therefore does nothing.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_extended_write_long_ignore_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" This parameter requires two values.%r", print.to.stream, f_string_eol_s);
+
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+
+ f_file_stream_flush(print.to);
+ f_file_stream_unlock(print.to);
+
+ return F_none;
+ }
+#endif // _di_fss_extended_write_print_help_
+
+#ifndef _di_fss_extended_write_print_line_first_
+ void fss_extended_write_print_line_first(fss_extended_write_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ }
+#endif // _di_fss_extended_write_print_line_first_
+
+#ifndef _di_fss_extended_write_print_line_last_
+ void fss_extended_write_print_line_last(fss_extended_write_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+ if (print.verbosity == f_console_verbosity_error_e && !F_status_is_error(setting->status)) return;
+ if (setting->flag & fss_extended_write_main_flag_verify_e) return;
+ if ((setting->flag & fss_extended_write_main_flag_file_to_e) && !F_status_is_error(setting->status)) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ }
+#endif // _di_fss_extended_write_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: UTF-8
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _fss_extended_write_print_h
+#define _fss_extended_write_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print help.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * The output structure to print to.
+ *
+ * @return
+ * F_none on success.
+ */
+#ifndef _di_fss_extended_write_print_help_
+ extern f_status_t fss_extended_write_print_help(fss_extended_write_setting_t * const setting, const fl_print_t print);
+#endif // _di_fss_extended_write_print_help_
+
+/**
+ * Print first new line, unless verbosity says otherwise.
+ *
+ * This is generally either the first line in the program or the first line printed before an error message.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_extended_write_print_line_first_
+ extern void fss_extended_write_print_line_first(fss_extended_write_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_extended_write_print_line_first_
+
+/**
+ * Print last new line when the main is complete, unless verbosity says otherwise.
+ *
+ * This is generally the very last line printed in the program.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_extended_write_print_line_last_
+ extern void fss_extended_write_print_line_last(fss_extended_write_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_extended_write_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _fss_extended_write_print_h
extern "C" {
#endif
-#ifndef _di_fss_extended_write_print_signal_received_
- void fss_extended_write_print_signal_received(fll_program_data_t * const main) {
-
- if (main->warning.verbosity != f_console_verbosity_verbose_e && main->warning.verbosity != f_console_verbosity_debug_e) return;
-
- // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
- fflush(main->warning.to.stream);
-
- flockfile(main->warning.to.stream);
-
- fl_print_format("%]%r%r%[Received signal code %]", main->warning.to.stream, main->context.set.reset, f_string_eol_s, f_string_eol_s, main->context.set.warning, main->context.set.warning);
- fl_print_format("%[%i%]", main->warning.to.stream, main->context.set.notable, main->signal_received, main->context.set.notable);
- fl_print_format("%[.%]%r", main->warning.to.stream, main->context.set.warning, main->context.set.warning, f_string_eol_s);
-
- funlockfile(main->warning.to.stream);
- }
-#endif // _di_fss_extended_write_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
#define fss_extended_write_common_allocation_small_d 128
#endif // _di_fss_extended_write_common_
-/**
- * Print a message about a process signal being recieved, such as an interrupt signal.
- *
- * @param main
- * The main program data.
- */
-#ifndef _di_fss_extended_write_print_signal_received_
- extern void fss_extended_write_print_signal_received(fll_program_data_t * const main) F_attribute_visibility_internal_d;
-#endif // _di_fss_extended_write_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
if (!((++main->signal_check) % fss_extended_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_extended_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library fss_extended_write.c common.c private-common.c private-write.c
+build_sources_library fss_extended_write.c common.c print.c private-common.c private-write.c
build_sources_program main.c
-build_sources_headers fss_extended_write.h common.h
+build_sources_headers fss_extended_write.h common.h print.h
build_script yes
build_shared yes
const f_string_static_t fss_identify_long_total_s = macro_f_string_static_t_initialize(FSS_IDENTIFY_long_total_s, 0, FSS_IDENTIFY_long_total_s_length);
#endif // _di_fss_identify_parameters_
+#ifndef _di_fss_identify_setting_delete_
+ f_status_t fss_identify_setting_delete(fss_identify_setting_t * const setting) {
+
+ if (!setting) return F_status_set_error(F_parameter);
+
+ return F_none;
+ }
+#endif // _di_fss_identify_setting_delete_
+
+#ifndef _di_fss_identify_setting_load_
+ void fss_identify_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_identify_setting_t * const setting) {
+
+ if (!main || !setting) return;
+
+ // Load parameters.
+ setting->status = f_console_parameter_process(arguments, &main->parameters);
+ if (F_status_is_error(setting->status)) return;
+
+ {
+ f_array_length_t choice = 0;
+ f_uint16s_t choices = f_uint16s_t_initialize;
+
+ // Identify and prioritize "color context" parameters.
+ {
+ uint16_t choices_array[3] = { fss_identify_parameter_no_color_e, fss_identify_parameter_light_e, fss_identify_parameter_dark_e };
+ choices.array = choices_array;
+ choices.used = 3;
+
+ const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
+
+ setting->status = fll_program_parameter_process_context(choices, modes, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_identify_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_context", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_identify_parameter_line_first_no_e].result == f_console_result_found_e) {
+ setting->line_first = f_string_empty_s;
+ }
+ else {
+ setting->line_first = f_string_eol_s;
+ }
+
+ if (main->parameters.array[fss_identify_parameter_line_last_no_e].result == f_console_result_found_e) {
+ setting->line_last = f_string_empty_s;
+ }
+ else {
+ setting->line_last = f_string_eol_s;
+ }
+
+ // Identify and prioritize "verbosity" parameters.
+ {
+ uint16_t choices_array[5] = { fss_identify_parameter_verbosity_quiet_e, fss_identify_parameter_verbosity_error_e, fss_identify_parameter_verbosity_verbose_e, fss_identify_parameter_verbosity_debug_e, fss_identify_parameter_verbosity_normal_e };
+ choices.array = choices_array;
+ choices.used = 5;
+
+ const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+
+ setting->status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_identify_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_verbosity", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_identify_parameter_help_e].result == f_console_result_found_e) {
+ setting->flag |= fss_identify_main_flag_help_e;
+
+ return;
+ }
+
+ if (main->parameters.array[fss_identify_parameter_version_e].result == f_console_result_found_e) {
+ setting->flag |= fss_identify_main_flag_version_e;
+
+ return;
+ }
+
+ // Identify and prioritize "from" mode parameters.
+ {
+ uint16_t choices_array[2] = { fss_identify_parameter_from_bytesequence_e, fss_identify_parameter_from_codepoint_e };
+ choices.array = choices_array;
+ choices.used = 2;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_identify_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_identify_parameter_from_bytesequence_e) {
+ if (setting->mode & fss_identify_mode_from_codepoint_e) {
+ setting->mode -= fss_identify_mode_from_codepoint_e;
+ }
+
+ setting->mode |= fss_identify_mode_from_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_identify_parameter_from_codepoint_e) {
+ if (setting->mode & fss_identify_mode_from_bytesequence_e) {
+ setting->mode -= fss_identify_mode_from_bytesequence_e;
+ }
+
+ setting->mode |= fss_identify_mode_from_codepoint_e;
+ }
+ }
+
+ // Identify and prioritize "to" mode parameters.
+ {
+ uint16_t choices_array[4] = { fss_identify_parameter_to_bytesequence_e, fss_identify_parameter_to_codepoint_e, fss_identify_parameter_to_combining_e, fss_identify_parameter_to_width_e };
+ choices.array = choices_array;
+ choices.used = 4;
+ choice = 1;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_identify_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_identify_parameter_to_bytesequence_e) {
+ if (setting->mode & fss_identify_mode_to_codepoint_e) {
+ setting->mode -= fss_identify_mode_to_codepoint_e;
+ }
+
+ if (setting->mode & fss_identify_mode_to_combining_e) {
+ setting->mode -= fss_identify_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_identify_mode_to_width_e) {
+ setting->mode -= fss_identify_mode_to_width_e;
+ }
+
+ setting->mode |= fss_identify_mode_to_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_identify_parameter_to_codepoint_e) {
+ if (setting->mode & fss_identify_mode_to_bytesequence_e) {
+ setting->mode -= fss_identify_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_identify_mode_to_combining_e) {
+ setting->mode -= fss_identify_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_identify_mode_to_width_e) {
+ setting->mode -= fss_identify_mode_to_width_e;
+ }
+
+ setting->mode |= fss_identify_mode_to_codepoint_e;
+ }
+ else if (choices.array[choice] == fss_identify_parameter_to_combining_e) {
+ if (setting->mode & fss_identify_mode_to_bytesequence_e) {
+ setting->mode -= fss_identify_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_identify_mode_to_codepoint_e) {
+ setting->mode -= fss_identify_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_identify_parameter_to_width_e].result == f_console_result_found_e) {
+ setting->mode |= fss_identify_mode_to_width_e;
+ }
+
+ setting->mode |= fss_identify_mode_to_combining_e;
+ }
+ else if (choices.array[choice] == fss_identify_parameter_to_width_e) {
+ if (setting->mode & fss_identify_mode_to_bytesequence_e) {
+ setting->mode -= fss_identify_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_identify_mode_to_codepoint_e) {
+ setting->mode -= fss_identify_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_identify_parameter_to_combining_e].result == f_console_result_found_e) {
+ setting->mode |= fss_identify_mode_to_combining_e;
+ }
+
+ setting->mode |= fss_identify_mode_to_width_e;
+ }
+ }
+ }
+
+ f_string_static_t * const args = main->parameters.arguments.array;
+
+ if (main->parameters.array[fss_identify_parameter_to_file_e].result == f_console_result_additional_e) {
+ if (main->parameters.array[fss_identify_parameter_to_file_e].values.used > 1) {
+ fss_identify_print_error_parameter_file_to_too_many(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+
+ if (args[main->parameters.array[fss_identify_parameter_to_file_e].values.array[0]].used) {
+ setting->path_files_to.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(1, &setting->path_files_to);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_to.array[setting->path_files_to.used].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[main->parameters.array[fss_identify_parameter_to_file_e].values.array[0]], &setting->path_files_to.array[0]);
+ if (F_status_is_error(setting->status)) return;
+
+ ++setting->path_files_to.used;
+
+ setting->status = f_file_stream_open(args[main->parameters.array[fss_identify_parameter_to_file_e].values.array[0]], f_file_open_mode_append_s, &main->output.to);
+
+ if (F_status_is_error(setting->status)) {
+ fll_error_file_print(main->error, F_status_set_fine(setting->status), "f_file_stream_open", F_true, args[main->parameters.array[fss_identify_parameter_to_file_e].values.array[0]], f_file_operation_open_s, fll_error_file_type_file_e);
+
+ return;
+ }
+
+ setting->flag |= fss_identify_main_flag_file_to_e;
+ }
+ else {
+ fss_identify_print_error_parameter_file_name_empty(main, setting, main->parameters.array[fss_identify_parameter_to_file_e].values.array[0]);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+ else if (main->parameters.array[fss_identify_parameter_to_file_e].result == f_console_result_found_e) {
+ fss_identify_print_error_no_value(main, setting, fss_identify_long_to_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ main->output.to = main->message.to;
+
+ if (setting->flag & fss_identify_main_flag_file_to_e) {
+ setting->flag -= fss_identify_main_flag_file_to_e;
+ }
+ }
+
+ if (main->parameters.array[fss_identify_parameter_from_file_e].result == f_console_result_additional_e) {
+ setting->path_files_from.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(main->parameters.array[fss_identify_parameter_from_file_e].values.used, &setting->path_files_from);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_from.used = main->parameters.array[fss_identify_parameter_from_file_e].values.used;
+
+ f_array_length_t i = 0;
+ f_array_length_t index = 0;
+
+ for (; i < setting->path_files_from.used; ++i) {
+
+ index = main->parameters.array[fss_identify_parameter_from_file_e].values.array[i];
+ setting->path_files_from.array[i].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[index], &setting->path_files_from.array[i]);
+ if (F_status_is_error(setting->status)) return;
+
+ if (args[index].used) {
+ if (f_file_exists(args[index], F_true) != F_true) {
+ fss_identify_print_error_parameter_file_not_found(main, setting, F_true, args[index]);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_file_found_not);
+ }
+ }
+ }
+ else {
+ fss_identify_print_error_parameter_file_name_empty(main, setting, index);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_parameter);
+ }
+ }
+ } // for
+
+ if (F_status_is_error(setting->status)) return;
+
+ setting->flag |= fss_identify_main_flag_file_from_e;
+ }
+ else if (main->parameters.array[fss_identify_parameter_from_file_e].result == f_console_result_found_e) {
+ fss_identify_print_error_no_value(main, setting, fss_identify_long_from_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ if (setting->flag & fss_identify_main_flag_file_from_e) {
+ setting->flag -= fss_identify_main_flag_file_from_e;
+ }
+ }
+
+ if (F_status_is_error(setting->status)) return;
+
+ if (main->parameters.array[fss_identify_parameter_from_file_e].result == f_console_result_none_e && !((main->pipe & fll_program_data_pipe_input_e) || main->parameters.remaining.used)) {
+ fss_identify_print_error_no_from(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+ }
+
+ if (!(setting->mode & fss_identify_mode_to_bytesequence_e)) {
+ if (main->parameters.array[fss_identify_parameter_separate_e].result == f_console_result_found_e || main->parameters.array[fss_identify_parameter_headers_e].result == f_console_result_found_e) {
+ setting->prepend = fss_identify_string_prepend_padding_s;
+ setting->append = f_string_eol_s;
+ }
+ else {
+ setting->prepend = f_string_space_s;
+ }
+ }
+
+ if (main->parameters.array[fss_identify_parameter_headers_e].result == f_console_result_found_e) {
+ setting->flag |= fss_identify_main_flag_header_e;
+ }
+
+ if (main->parameters.array[fss_identify_parameter_separate_e].result == f_console_result_found_e) {
+ setting->flag |= fss_identify_main_flag_separate_e;
+ }
+
+ if (main->parameters.array[fss_identify_parameter_strip_invalid_e].result == f_console_result_found_e) {
+ setting->flag |= fss_identify_main_flag_strip_invalid_e;
+ }
+
+ setting->valid_not = main->message.set->error;
+ }
+#endif // _di_fss_identify_setting_load_
+
+#ifndef _di_fss_identify_setting_unload_
+ f_status_t fss_identify_setting_unload(fll_program_data_t * const main, fss_identify_setting_t * const setting) {
+
+ if (!main || !setting) return F_status_set_error(F_parameter);
+
+ fss_identify_setting_delete(setting);
+
+ return F_none;
+ }
+#endif // _di_fss_identify_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
#define fss_identify_total_parameters_d 17
#endif // _di_fss_identify_parameters_
+/**
+ * Flags used to represent flags passed to the main function.
+ *
+ * fss_identify_main_flag_*_e:
+ * - none: No modes in use.
+ * - file_from: Using a specified source file.
+ * - file_to: Using a specified destination file.
+ * - help: Print help.
+ * - header: Enable printing of headers.
+ * - separate: Enable printing of separators.
+ * - strip_invalid: Using strip invalid character mode.
+ * - verify: Using verify mode.
+ * - version: Print version.
+ */
+#ifndef _di_fss_identify_main_flag_e_
+ enum {
+ fss_identify_main_flag_none_e = 0x0,
+ fss_identify_main_flag_file_from_e = 0x1,
+ fss_identify_main_flag_file_to_e = 0x2,
+ fss_identify_main_flag_header_e = 0x4,
+ fss_identify_main_flag_help_e = 0x8,
+ fss_identify_main_flag_separate_e = 0x10,
+ fss_identify_main_flag_strip_invalid_e = 0x20,
+ fss_identify_main_flag_verify_e = 0x40,
+ fss_identify_main_flag_version_e = 0x80,
+ };
+#endif // _di_fss_identify_main_flag_e_
+
+/**
+ * The fss identify main program settings.
+ *
+ * This is passed to the program-specific main entry point to designate program settings.
+ * These program settings are often processed from the program arguments (often called the command line arguments).
+ *
+ * flag: Flags passed to the main function.
+ *
+ * status: The main status code, generally used by the load settings and main functions.
+ *
+ * line_first: A string expected to represent either "\n" or NULL to allow for easy handling of when to print first new line or not.
+ * line_last: A string expected to represent either "\n" or NULL to allow for easy handling of when to print last new line or not.
+ */
+#ifndef _di_fss_identify_setting_t_
+ typedef struct {
+ uint16_t flag;
+
+ f_status_t status;
+
+ f_string_static_t line_first;
+ f_string_static_t line_last;
+ } fss_identify_setting_t;
+
+ #define fss_identify_setting_t_initialize \
+ { \
+ fss_identify_main_flag_none_e, \
+ F_none, \
+ f_string_static_t_initialize, \
+ f_string_static_t_initialize, \
+ }
+#endif // _di_fss_identify_setting_t_
+
+/**
+ * Delete the program main setting data.
+ *
+ * @param setting
+ * The program main setting data.
+ * This does not alter setting.status.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fss_identify_setting_delete_
+ extern f_status_t fss_identify_setting_delete(fss_identify_setting_t * const setting);
+#endif // _di_fss_identify_setting_delete_
+
+/**
+ * Perform the standard program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately retuns without doing anything.
+ *
+ * @param arguments
+ * The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ *
+ * This alters setting.status:
+ * F_none on success.
+ *
+ * Errors (with error bit) from: f_console_parameter_process().
+ * Errors (with error bit) from: fll_program_parameter_process_context().
+ *
+ * @see f_console_parameter_process()
+ * @see fll_program_parameter_process_context()
+ */
+#ifndef _di_fss_identify_setting_load_
+ extern void fss_identify_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_identify_setting_t * const setting);
+#endif // _di_fss_identify_setting_load_
+
+/**
+ * Perform the standard program setting unload process.
+ *
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * All buffers are deallocated.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: utf8_setting_delete().
+ *
+ * @see utf8_setting_delete()
+ */
+#ifndef _di_fss_identify_setting_unload_
+ extern f_status_t fss_identify_setting_unload(fll_program_data_t * const main, fss_identify_setting_t * const setting);
+#endif // _di_fss_identify_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern "C" {
#endif
-#ifndef _di_fss_identify_print_help_
- f_status_t fss_identify_print_help(const f_file_t file, const f_color_context_t context) {
-
- flockfile(file.stream);
-
- //if (!(setting->flag & XXX_main_flag_line_first_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- fll_program_print_help_header(file, context, fss_identify_program_name_long_s, fss_identify_program_version_s);
-
- fll_program_print_help_option_standard(file, context);
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, fss_identify_short_content_s, fss_identify_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print the Identifier content (the 4-digit hexidecimal type code).");
- fll_program_print_help_option(file, context, fss_identify_short_object_s, fss_identify_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Identifier object (the name).");
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, fss_identify_short_line_s, fss_identify_long_line_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print only the Identifier at the given line.");
- fll_program_print_help_option(file, context, fss_identify_short_name_s, fss_identify_long_name_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select FSS using this full or partial type name or code.");
- fll_program_print_help_option(file, context, fss_identify_short_total_s, fss_identify_long_total_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print the total Identifiers found.");
-
- fll_program_print_help_usage(file, context, fss_identify_program_name_s, fll_program_parameter_filenames_s);
-
- fl_print_format("%r The %[%r%r%] parameter refers to the file lines and not the lines in a given file.%r%r", file.stream, f_string_eol_s, context.set.notable, f_console_symbol_long_enable_s, fss_identify_long_line_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" If neither the %[%r%r%] nor", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_identify_long_object_s, context.set.notable);
- fl_print_format(" %[%r%r%] are specified, then the default behavior is to print both.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_identify_long_content_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When specifying the %[%r%r%] parameter, neither the", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_identify_long_total_s, context.set.notable);
- fl_print_format(" %[%r%r%] nor the", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_identify_long_object_s, context.set.notable);
- fl_print_format(" %[%r%r%] parameter may be specified.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_identify_long_content_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" An FSS file is identified by the following format: '%[# Object-Content%]'", file.stream, context.set.notable, context.set.notable);
- fl_print_format(" where the Object, is a machine-name representing the name and may only consist of \"word\" characters and the Content is a 4-digit hexidecimal number representing a particular variant of the Object.%r", file.stream, f_string_eol_s);
- fl_print_format(" This identifier, if provided, must exist on the first line in a file and must begin with the pound character: '#'.%r", file.stream, f_string_eol_s);
- fl_print_format(" Whitespace must follow this pound character.%r", file.stream, f_string_eol_s);
- fl_print_format(" There may be multiple Object and Content pairs, separated by white space, such as: \"# fss-0002 fss-0000 iki-0002\".%r", file.stream, f_string_eol_s);
-
- //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- f_file_stream_flush(file);
- funlockfile(file.stream);
-
- return F_none;
- }
-#endif // _di_fss_identify_print_help_
-
#ifndef _di_fss_identify_main_
- f_status_t fss_identify_main(fll_program_data_t * const main, const f_console_arguments_t arguments) {
+ f_status_t fss_identify_main(fll_program_data_t * const main, fss_identify_setting_t * const setting) {
f_status_t status = F_none;
status = F_none;
if (main->parameters.array[fss_identify_parameter_help_e].result == f_console_result_found_e) {
- fss_identify_print_help(main->output.to, main->context);
+ fss_identify_print_help(setting, main->message);
return F_none;
}
if (main->parameters.array[fss_identify_parameter_version_e].result == f_console_result_found_e) {
- fll_program_print_version(main->output.to, fss_identify_program_version_s);
+ fll_program_print_version(main->message, fss_identify_program_version_s);
return F_none;
}
if (!((++main->signal_check) % fss_identify_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_identify_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
#endif
/**
- * Print help.
- *
- * @param file
- * The file to print to.
- * @param context
- * The color context settings.
- *
- * @return
- * F_none on success.
- */
-#ifndef _di_fss_identify_print_help_
- extern f_status_t fss_identify_print_help(const f_file_t file, const f_color_context_t context);
-#endif // _di_fss_identify_print_help_
-
-/**
* Execute main program.
*
* If main.signal is non-zero, then this blocks and handles the following signals:
*
* @param main
* The main program data.
- * @param arguments
- * The parameters passed to the process.
+ * @param setting
+ * The main program settings.
*
- * @return
- * F_none on success.
+ * This alters setting.status:
+ * F_none on success.
+ * F_true on success when performing verification and verify passed.
+ * F_false on success when performing verification and verify failed.
+ * F_interrupt on (exit) signal received.
*
- * Status codes (with error bit) are returned on any problem.
+ * F_parameter (with error bit) if main is NULL or setting is NULL.
*/
#ifndef _di_fss_identify_main_
- extern f_status_t fss_identify_main(fll_program_data_t * const main, const f_console_arguments_t arguments);
+ extern f_status_t fss_identify_main(fll_program_data_t * const main, fss_identify_setting_t * const setting);
#endif // _di_fss_identify_main_
#ifdef __cplusplus
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
fll_program_data_t data = fll_program_data_t_initialize;
+ fss_identify_setting_t setting = fss_identify_setting_t_initialize;
f_console_parameter_t parameters[] = fss_identify_console_parameter_t_initialize;
data.parameters.array = parameters;
data.parameters.used = fss_identify_total_parameters_d;
+ data.environment = envp;
if (f_pipe_input_exists()) {
data.pipe = fll_program_data_pipe_input_e;
fll_program_standard_set_up(&data);
- const f_status_t status = fss_identify_main(&data, arguments);
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+
+ fss_identify_setting_load(arguments, &data, &setting);
+ }
+
+ fss_identify_main(&data, &setting);
+
+ fss_identify_setting_unload(&data, &setting);
fll_program_data_delete(&data);
fll_program_standard_set_down(&data);
- if (F_status_is_error(status)) return 1;
-
- return 0;
+ return F_status_is_error(status) ? 1 : 0;
}
--- /dev/null
+#include "fss_identify.h"
+#include "private-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fss_identify_print_help_
+ f_status_t fss_identify_print_help(fss_identify_setting_t * const setting, const fl_print_t print) {
+
+ f_file_stream_lock(print.to);
+
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+
+ fll_program_print_help_header(print, fss_identify_program_name_long_s, fss_identify_program_version_s);
+
+ fll_program_print_help_option_standard(print);
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, fss_identify_short_content_s, fss_identify_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print the Identifier content (the 4-digit hexidecimal type code).");
+ fll_program_print_help_option(print, fss_identify_short_object_s, fss_identify_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Identifier object (the name).");
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, fss_identify_short_line_s, fss_identify_long_line_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print only the Identifier at the given line.");
+ fll_program_print_help_option(print, fss_identify_short_name_s, fss_identify_long_name_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select FSS using this full or partial type name or code.");
+ fll_program_print_help_option(print, fss_identify_short_total_s, fss_identify_long_total_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print the total Identifiers found.");
+
+ fll_program_print_help_usage(print, fss_identify_program_name_s, fll_program_parameter_filenames_s);
+
+ fl_print_format("%r The %[%r%r%] parameter refers to the file lines and not the lines in a given file.%r%r", print.to.stream, f_string_eol_s, print.set->notable, f_console_symbol_long_enable_s, fss_identify_long_line_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" If neither the %[%r%r%] nor", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_identify_long_object_s, print.set->notable);
+ fl_print_format(" %[%r%r%] are specified, then the default behavior is to print both.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_identify_long_content_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When specifying the %[%r%r%] parameter, neither the", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_identify_long_total_s, print.set->notable);
+ fl_print_format(" %[%r%r%] nor the", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_identify_long_object_s, print.set->notable);
+ fl_print_format(" %[%r%r%] parameter may be specified.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_identify_long_content_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" An FSS file is identified by the following format: '%[# Object-Content%]'", print.to.stream, print.set->notable, print.set->notable);
+ fl_print_format(" where the Object, is a machine-name representing the name and may only consist of \"word\" characters and the Content is a 4-digit hexidecimal number representing a particular variant of the Object.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" This identifier, if provided, must exist on the first line in a file and must begin with the pound character: '#'.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" Whitespace must follow this pound character.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" There may be multiple Object and Content pairs, separated by white space, such as: \"# fss-0002 fss-0000 iki-0002\".%r", print.to.stream, f_string_eol_s);
+
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+
+ f_file_stream_flush(print.to);
+ f_file_stream_unlock(print.to);
+
+ return F_none;
+ }
+#endif // _di_fss_identify_print_help_
+
+#ifndef _di_fss_identify_print_line_first_
+ void fss_identify_print_line_first(fss_identify_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ }
+#endif // _di_fss_identify_print_line_first_
+
+#ifndef _di_fss_identify_print_line_last_
+ void fss_identify_print_line_last(fss_identify_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+ if (print.verbosity == f_console_verbosity_error_e && !F_status_is_error(setting->status)) return;
+ if (setting->flag & fss_identify_main_flag_verify_e) return;
+ if ((setting->flag & fss_identify_main_flag_file_to_e) && !F_status_is_error(setting->status)) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ }
+#endif // _di_fss_identify_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: UTF-8
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _fss_identify_print_h
+#define _fss_identify_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print help.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * The output structure to print to.
+ *
+ * @return
+ * F_none on success.
+ */
+#ifndef _di_fss_identify_print_help_
+ extern f_status_t fss_identify_print_help(fss_identify_setting_t * const setting, const fl_print_t print);
+#endif // _di_fss_identify_print_help_
+
+/**
+ * Print first new line, unless verbosity says otherwise.
+ *
+ * This is generally either the first line in the program or the first line printed before an error message.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_identify_print_line_first_
+ extern void fss_identify_print_line_first(fss_identify_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_identify_print_line_first_
+
+/**
+ * Print last new line when the main is complete, unless verbosity says otherwise.
+ *
+ * This is generally the very last line printed in the program.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_identify_print_line_last_
+ extern void fss_identify_print_line_last(fss_identify_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_identify_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _fss_identify_print_h
}
#endif // _di_fss_identify_data_delete_
-#ifndef _di_fss_identify_print_signal_received_
- void fss_identify_print_signal_received(fll_program_data_t * const main) {
-
- if (main->warning.verbosity != f_console_verbosity_verbose_e && main->warning.verbosity != f_console_verbosity_debug_e) return;
-
- // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
- fflush(main->warning.to.stream);
-
- flockfile(main->warning.to.stream);
-
- fl_print_format("%]%r%r%[Received signal code %]", main->warning.to.stream, main->context.set.reset, f_string_eol_s, f_string_eol_s, main->context.set.warning, main->context.set.warning);
- fl_print_format("%[%i%]", main->warning.to.stream, main->context.set.notable, main->signal_received, main->context.set.notable);
- fl_print_format("%[.%]%r", main->warning.to.stream, main->context.set.warning, main->context.set.warning, f_string_eol_s);
-
- funlockfile(main->warning.to.stream);
- }
-#endif // _di_fss_identify_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
extern void fss_identify_data_delete(fss_identify_data_t *data) F_attribute_visibility_internal_d;
#endif // _di_fss_identify_data_delete_
-/**
- * Print a message about a process signal being recieved, such as an interrupt signal.
- *
- * @param main
- * The main program data.
- */
-#ifndef _di_fss_identify_print_signal_received_
- extern void fss_identify_print_signal_received(fll_program_data_t * const main) F_attribute_visibility_internal_d;
-#endif // _di_fss_identify_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
do {
if (!((++main->signal_check) % fss_identify_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_identify_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library fss_identify.c common.c private-common.c private-identify.c private-print.c
+build_sources_library fss_identify.c common.c print.c private-common.c private-identify.c private-print.c
build_sources_program main.c
-build_sources_headers fss_identify.h common.h
+build_sources_headers fss_identify.h common.h print.h
build_script yes
build_shared yes
const f_string_static_t fss_payload_read_delimit_mode_name_lesser_s = macro_f_string_static_t_initialize(FSS_PAYLOAD_READ_delimit_mode_name_lesser_s, 0, FSS_PAYLOAD_READ_delimit_mode_name_lesser_s_length);
#endif // _di_fss_payload_read_delimit_mode_
+#ifndef _di_fss_payload_read_setting_delete_
+ f_status_t fss_payload_read_setting_delete(fss_payload_read_setting_t * const setting) {
+
+ if (!setting) return F_status_set_error(F_parameter);
+
+ return F_none;
+ }
+#endif // _di_fss_payload_read_setting_delete_
+
+#ifndef _di_fss_payload_read_setting_load_
+ void fss_payload_read_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_payload_read_setting_t * const setting) {
+
+ if (!main || !setting) return;
+
+ // Load parameters.
+ setting->status = f_console_parameter_process(arguments, &main->parameters);
+ if (F_status_is_error(setting->status)) return;
+
+ {
+ f_array_length_t choice = 0;
+ f_uint16s_t choices = f_uint16s_t_initialize;
+
+ // Identify and prioritize "color context" parameters.
+ {
+ uint16_t choices_array[3] = { fss_payload_read_parameter_no_color_e, fss_payload_read_parameter_light_e, fss_payload_read_parameter_dark_e };
+ choices.array = choices_array;
+ choices.used = 3;
+
+ const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
+
+ setting->status = fll_program_parameter_process_context(choices, modes, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_payload_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_context", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_payload_read_parameter_line_first_no_e].result == f_console_result_found_e) {
+ setting->line_first = f_string_empty_s;
+ }
+ else {
+ setting->line_first = f_string_eol_s;
+ }
+
+ if (main->parameters.array[fss_payload_read_parameter_line_last_no_e].result == f_console_result_found_e) {
+ setting->line_last = f_string_empty_s;
+ }
+ else {
+ setting->line_last = f_string_eol_s;
+ }
+
+ // Identify and prioritize "verbosity" parameters.
+ {
+ uint16_t choices_array[5] = { fss_payload_read_parameter_verbosity_quiet_e, fss_payload_read_parameter_verbosity_error_e, fss_payload_read_parameter_verbosity_verbose_e, fss_payload_read_parameter_verbosity_debug_e, fss_payload_read_parameter_verbosity_normal_e };
+ choices.array = choices_array;
+ choices.used = 5;
+
+ const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+
+ setting->status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_payload_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_verbosity", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_payload_read_parameter_help_e].result == f_console_result_found_e) {
+ setting->flag |= fss_payload_read_main_flag_help_e;
+
+ return;
+ }
+
+ if (main->parameters.array[fss_payload_read_parameter_version_e].result == f_console_result_found_e) {
+ setting->flag |= fss_payload_read_main_flag_version_e;
+
+ return;
+ }
+
+ // Identify and prioritize "from" mode parameters.
+ {
+ uint16_t choices_array[2] = { fss_payload_read_parameter_from_bytesequence_e, fss_payload_read_parameter_from_codepoint_e };
+ choices.array = choices_array;
+ choices.used = 2;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_payload_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_payload_read_parameter_from_bytesequence_e) {
+ if (setting->mode & fss_payload_read_mode_from_codepoint_e) {
+ setting->mode -= fss_payload_read_mode_from_codepoint_e;
+ }
+
+ setting->mode |= fss_payload_read_mode_from_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_payload_read_parameter_from_codepoint_e) {
+ if (setting->mode & fss_payload_read_mode_from_bytesequence_e) {
+ setting->mode -= fss_payload_read_mode_from_bytesequence_e;
+ }
+
+ setting->mode |= fss_payload_read_mode_from_codepoint_e;
+ }
+ }
+
+ // Identify and prioritize "to" mode parameters.
+ {
+ uint16_t choices_array[4] = { fss_payload_read_parameter_to_bytesequence_e, fss_payload_read_parameter_to_codepoint_e, fss_payload_read_parameter_to_combining_e, fss_payload_read_parameter_to_width_e };
+ choices.array = choices_array;
+ choices.used = 4;
+ choice = 1;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_payload_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_payload_read_parameter_to_bytesequence_e) {
+ if (setting->mode & fss_payload_read_mode_to_codepoint_e) {
+ setting->mode -= fss_payload_read_mode_to_codepoint_e;
+ }
+
+ if (setting->mode & fss_payload_read_mode_to_combining_e) {
+ setting->mode -= fss_payload_read_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_payload_read_mode_to_width_e) {
+ setting->mode -= fss_payload_read_mode_to_width_e;
+ }
+
+ setting->mode |= fss_payload_read_mode_to_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_payload_read_parameter_to_codepoint_e) {
+ if (setting->mode & fss_payload_read_mode_to_bytesequence_e) {
+ setting->mode -= fss_payload_read_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_payload_read_mode_to_combining_e) {
+ setting->mode -= fss_payload_read_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_payload_read_mode_to_width_e) {
+ setting->mode -= fss_payload_read_mode_to_width_e;
+ }
+
+ setting->mode |= fss_payload_read_mode_to_codepoint_e;
+ }
+ else if (choices.array[choice] == fss_payload_read_parameter_to_combining_e) {
+ if (setting->mode & fss_payload_read_mode_to_bytesequence_e) {
+ setting->mode -= fss_payload_read_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_payload_read_mode_to_codepoint_e) {
+ setting->mode -= fss_payload_read_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_payload_read_parameter_to_width_e].result == f_console_result_found_e) {
+ setting->mode |= fss_payload_read_mode_to_width_e;
+ }
+
+ setting->mode |= fss_payload_read_mode_to_combining_e;
+ }
+ else if (choices.array[choice] == fss_payload_read_parameter_to_width_e) {
+ if (setting->mode & fss_payload_read_mode_to_bytesequence_e) {
+ setting->mode -= fss_payload_read_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_payload_read_mode_to_codepoint_e) {
+ setting->mode -= fss_payload_read_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_payload_read_parameter_to_combining_e].result == f_console_result_found_e) {
+ setting->mode |= fss_payload_read_mode_to_combining_e;
+ }
+
+ setting->mode |= fss_payload_read_mode_to_width_e;
+ }
+ }
+ }
+
+ f_string_static_t * const args = main->parameters.arguments.array;
+
+ if (main->parameters.array[fss_payload_read_parameter_to_file_e].result == f_console_result_additional_e) {
+ if (main->parameters.array[fss_payload_read_parameter_to_file_e].values.used > 1) {
+ fss_payload_read_print_error_parameter_file_to_too_many(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+
+ if (args[main->parameters.array[fss_payload_read_parameter_to_file_e].values.array[0]].used) {
+ setting->path_files_to.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(1, &setting->path_files_to);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_to.array[setting->path_files_to.used].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[main->parameters.array[fss_payload_read_parameter_to_file_e].values.array[0]], &setting->path_files_to.array[0]);
+ if (F_status_is_error(setting->status)) return;
+
+ ++setting->path_files_to.used;
+
+ setting->status = f_file_stream_open(args[main->parameters.array[fss_payload_read_parameter_to_file_e].values.array[0]], f_file_open_mode_append_s, &main->output.to);
+
+ if (F_status_is_error(setting->status)) {
+ fll_error_file_print(main->error, F_status_set_fine(setting->status), "f_file_stream_open", F_true, args[main->parameters.array[fss_payload_read_parameter_to_file_e].values.array[0]], f_file_operation_open_s, fll_error_file_type_file_e);
+
+ return;
+ }
+
+ setting->flag |= fss_payload_read_main_flag_file_to_e;
+ }
+ else {
+ fss_payload_read_print_error_parameter_file_name_empty(main, setting, main->parameters.array[fss_payload_read_parameter_to_file_e].values.array[0]);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+ else if (main->parameters.array[fss_payload_read_parameter_to_file_e].result == f_console_result_found_e) {
+ fss_payload_read_print_error_no_value(main, setting, fss_payload_read_long_to_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ main->output.to = main->message.to;
+
+ if (setting->flag & fss_payload_read_main_flag_file_to_e) {
+ setting->flag -= fss_payload_read_main_flag_file_to_e;
+ }
+ }
+
+ if (main->parameters.array[fss_payload_read_parameter_from_file_e].result == f_console_result_additional_e) {
+ setting->path_files_from.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(main->parameters.array[fss_payload_read_parameter_from_file_e].values.used, &setting->path_files_from);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_from.used = main->parameters.array[fss_payload_read_parameter_from_file_e].values.used;
+
+ f_array_length_t i = 0;
+ f_array_length_t index = 0;
+
+ for (; i < setting->path_files_from.used; ++i) {
+
+ index = main->parameters.array[fss_payload_read_parameter_from_file_e].values.array[i];
+ setting->path_files_from.array[i].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[index], &setting->path_files_from.array[i]);
+ if (F_status_is_error(setting->status)) return;
+
+ if (args[index].used) {
+ if (f_file_exists(args[index], F_true) != F_true) {
+ fss_payload_read_print_error_parameter_file_not_found(main, setting, F_true, args[index]);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_file_found_not);
+ }
+ }
+ }
+ else {
+ fss_payload_read_print_error_parameter_file_name_empty(main, setting, index);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_parameter);
+ }
+ }
+ } // for
+
+ if (F_status_is_error(setting->status)) return;
+
+ setting->flag |= fss_payload_read_main_flag_file_from_e;
+ }
+ else if (main->parameters.array[fss_payload_read_parameter_from_file_e].result == f_console_result_found_e) {
+ fss_payload_read_print_error_no_value(main, setting, fss_payload_read_long_from_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ if (setting->flag & fss_payload_read_main_flag_file_from_e) {
+ setting->flag -= fss_payload_read_main_flag_file_from_e;
+ }
+ }
+
+ if (F_status_is_error(setting->status)) return;
+
+ if (main->parameters.array[fss_payload_read_parameter_from_file_e].result == f_console_result_none_e && !((main->pipe & fll_program_data_pipe_input_e) || main->parameters.remaining.used)) {
+ fss_payload_read_print_error_no_from(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+ }
+
+ if (!(setting->mode & fss_payload_read_mode_to_bytesequence_e)) {
+ if (main->parameters.array[fss_payload_read_parameter_separate_e].result == f_console_result_found_e || main->parameters.array[fss_payload_read_parameter_headers_e].result == f_console_result_found_e) {
+ setting->prepend = fss_payload_read_string_prepend_padding_s;
+ setting->append = f_string_eol_s;
+ }
+ else {
+ setting->prepend = f_string_space_s;
+ }
+ }
+
+ if (main->parameters.array[fss_payload_read_parameter_headers_e].result == f_console_result_found_e) {
+ setting->flag |= fss_payload_read_main_flag_header_e;
+ }
+
+ if (main->parameters.array[fss_payload_read_parameter_separate_e].result == f_console_result_found_e) {
+ setting->flag |= fss_payload_read_main_flag_separate_e;
+ }
+
+ if (main->parameters.array[fss_payload_read_parameter_strip_invalid_e].result == f_console_result_found_e) {
+ setting->flag |= fss_payload_read_main_flag_strip_invalid_e;
+ }
+
+ setting->valid_not = main->message.set->error;
+ }
+#endif // _di_fss_payload_read_setting_load_
+
+#ifndef _di_fss_payload_read_setting_unload_
+ f_status_t fss_payload_read_setting_unload(fll_program_data_t * const main, fss_payload_read_setting_t * const setting) {
+
+ if (!main || !setting) return F_status_set_error(F_parameter);
+
+ fss_payload_read_setting_delete(setting);
+
+ return F_none;
+ }
+#endif // _di_fss_payload_read_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
};
#endif // _di_fss_payload_read_delimit_modes_
+/**
+ * Flags used to represent flags passed to the main function.
+ *
+ * fss_payload_read_main_flag_*_e:
+ * - none: No modes in use.
+ * - file_from: Using a specified source file.
+ * - file_to: Using a specified destination file.
+ * - help: Print help.
+ * - header: Enable printing of headers.
+ * - separate: Enable printing of separators.
+ * - strip_invalid: Using strip invalid character mode.
+ * - verify: Using verify mode.
+ * - version: Print version.
+ */
+#ifndef _di_fss_payload_read_main_flag_e_
+ enum {
+ fss_payload_read_main_flag_none_e = 0x0,
+ fss_payload_read_main_flag_file_from_e = 0x1,
+ fss_payload_read_main_flag_file_to_e = 0x2,
+ fss_payload_read_main_flag_header_e = 0x4,
+ fss_payload_read_main_flag_help_e = 0x8,
+ fss_payload_read_main_flag_separate_e = 0x10,
+ fss_payload_read_main_flag_strip_invalid_e = 0x20,
+ fss_payload_read_main_flag_verify_e = 0x40,
+ fss_payload_read_main_flag_version_e = 0x80,
+ };
+#endif // _di_fss_payload_read_main_flag_e_
+
+/**
+ * The fss payload read main program settings.
+ *
+ * This is passed to the program-specific main entry point to designate program settings.
+ * These program settings are often processed from the program arguments (often called the command line arguments).
+ *
+ * flag: Flags passed to the main function.
+ *
+ * status: The main status code, generally used by the load settings and main functions.
+ *
+ * line_first: A string expected to represent either "\n" or NULL to allow for easy handling of when to print first new line or not.
+ * line_last: A string expected to represent either "\n" or NULL to allow for easy handling of when to print last new line or not.
+ */
+#ifndef _di_fss_payload_read_setting_t_
+ typedef struct {
+ uint16_t flag;
+
+ f_status_t status;
+
+ f_string_static_t line_first;
+ f_string_static_t line_last;
+ } fss_payload_read_setting_t;
+
+ #define fss_payload_read_setting_t_initialize \
+ { \
+ fss_payload_read_main_flag_none_e, \
+ F_none, \
+ f_string_static_t_initialize, \
+ f_string_static_t_initialize, \
+ }
+#endif // _di_fss_payload_read_setting_t_
+
+/**
+ * Delete the program main setting data.
+ *
+ * @param setting
+ * The program main setting data.
+ * This does not alter setting.status.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fss_payload_read_setting_delete_
+ extern f_status_t fss_payload_read_setting_delete(fss_payload_read_setting_t * const setting);
+#endif // _di_fss_payload_read_setting_delete_
+
+/**
+ * Perform the standard program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately retuns without doing anything.
+ *
+ * @param arguments
+ * The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ *
+ * This alters setting.status:
+ * F_none on success.
+ *
+ * Errors (with error bit) from: f_console_parameter_process().
+ * Errors (with error bit) from: fll_program_parameter_process_context().
+ *
+ * @see f_console_parameter_process()
+ * @see fll_program_parameter_process_context()
+ */
+#ifndef _di_fss_payload_read_setting_load_
+ extern void fss_payload_read_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_payload_read_setting_t * const setting);
+#endif // _di_fss_payload_read_setting_load_
+
+/**
+ * Perform the standard program setting unload process.
+ *
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * All buffers are deallocated.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: utf8_setting_delete().
+ *
+ * @see utf8_setting_delete()
+ */
+#ifndef _di_fss_payload_read_setting_unload_
+ extern f_status_t fss_payload_read_setting_unload(fll_program_data_t * const main, fss_payload_read_setting_t * const setting);
+#endif // _di_fss_payload_read_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
const f_string_static_t fss_payload_read_program_name_long_s = macro_f_string_static_t_initialize(FSS_PAYLOAD_READ_program_name_long_s, 0, FSS_PAYLOAD_READ_program_name_long_s_length);
#endif // _di_fss_payload_read_program_name_
-#ifndef _di_fss_payload_read_print_help_
- f_status_t fss_payload_read_print_help(const f_file_t file, const f_color_context_t context) {
-
- flockfile(file.stream);
-
- //if (!(setting->flag & XXX_main_flag_line_first_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- fll_program_print_help_header(file, context, fss_payload_read_program_name_long_s, fss_payload_read_program_version_s);
-
- fll_program_print_help_option_standard(file, context);
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, fss_payload_read_short_at_s, fss_payload_read_long_at_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric index.");
- fll_program_print_help_option(file, context, fss_payload_read_short_content_s, fss_payload_read_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Content (default).");
- fll_program_print_help_option(file, context, fss_payload_read_short_columns_s, fss_payload_read_long_columns_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of columns.");
- fll_program_print_help_option(file, context, fss_payload_read_short_delimit_s, fss_payload_read_long_delimit_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Designate how to handle applying delimits.");
- fll_program_print_help_option(file, context, fss_payload_read_short_depth_s, fss_payload_read_long_depth_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric depth.");
- fll_program_print_help_option(file, context, fss_payload_read_short_empty_s, fss_payload_read_long_empty_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Include empty Content when processing.");
- fll_program_print_help_option(file, context, fss_payload_read_short_line_s, fss_payload_read_long_line_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print only the Content at the given line.");
- fll_program_print_help_option(file, context, fss_payload_read_short_name_s, fss_payload_read_long_name_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object with this name.");
- fll_program_print_help_option(file, context, fss_payload_read_short_object_s, fss_payload_read_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Object.");
- fll_program_print_help_option(file, context, fss_payload_read_short_pipe_s, fss_payload_read_long_pipe_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print using the special pipe format.");
- fll_program_print_help_option(file, context, fss_payload_read_short_original_s, fss_payload_read_long_original_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print with the original quotes and escapes.");
- fll_program_print_help_option(file, context, fss_payload_read_short_select_s, fss_payload_read_long_select_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select sub-Content at this index.");
- fll_program_print_help_option(file, context, fss_payload_read_short_total_s, fss_payload_read_long_total_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of lines.");
- fll_program_print_help_option(file, context, fss_payload_read_short_trim_s, fss_payload_read_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names on select or print.");
-
- fll_program_print_help_usage(file, context, fss_payload_read_program_name_s, fll_program_parameter_filenames_s);
-
- fl_print_format("%r %[Notes:%]%r", file.stream, f_string_eol_s, context.set.important, context.set.important, f_string_eol_s);
-
- fl_print_format(" This program will print the Content associated with the given Object and Content main based on the FSS-000E Payload standard.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" All numeric positions (indexes) start at 0 instead of 1.%r", file.stream, f_string_eol_s);
- fl_print_format(" For example, a file of 17 lines would range from 0 to 16.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When using the %[%r%r%] option, an order of operations is enforced on the parameters.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_depth_s, context.set.notable, f_string_eol_s);
-
- fl_print_format(" When this order of operations is in effect, parameters to the right of a depth parameter are influenced by that depth parameter:%r", file.stream, f_string_eol_s);
-
- fl_print_format(" %[%r%r%]: An Object index at the specified depth.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_at_s, context.set.notable, f_string_eol_s);
- fl_print_format(" %[%r%r%]: A new depth within the specified depth, indexed from the root.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_depth_s, context.set.notable, f_string_eol_s);
- fl_print_format(" %[%r%r%]: An Object name at the specified depth.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_name_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%] must be in numeric order, but values in between may be skipped.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_depth_s, context.set.notable, f_string_eol_s);
- fl_print_format(" ('-d 0 -a 1 -d 2 -a 2' would specify index 1 at depth 0, any index at depth 1, and index 2 at depth 2.)%r", file.stream, f_string_eol_s);
- fl_print_format(" ('-d 2 -a 1 -d 0 -a 2' would be invalid because depth 2 is before depth 1.)%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%] selects a Content column.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_select_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" Specify both %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_object_s, context.set.notable);
- fl_print_format(" and the %[%r%r%] parameters to get the total objects.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_total_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When both %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_at_s, context.set.notable);
- fl_print_format(" and %[%r%r%] parameters are specified (at the same depth),", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_name_s, context.set.notable);
- fl_print_format(" the %[%r%r%] parameter value will be treated as a position relative to the specified", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_at_s, context.set.notable);
- fl_print_format(" %[%r%r%] parameter value.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_name_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" This program may support parameters, such as %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_depth_s, context.set.notable);
- fl_print_format(" or %[%r%r%], even if not supported by the standard.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_select_s, context.set.notable, f_string_eol_s);
- fl_print_format(" This is done to help ensure consistency for scripting.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" For parameters like %[%r%r%],", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_depth_s, context.set.notable);
- fl_print_format(" if the standard doesn't support nested Content, then only a depth of 0 would be valid.%r", file.stream, f_string_eol_s);
-
- fl_print_format(" For parameters like %[%r%r%],", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_select_s, context.set.notable);
- fl_print_format(" if the standard doesn't support multiple Content groups, then only a select of 0 would be valid.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_trim_s, context.set.notable);
- fl_print_format(" will remove leading and trailing white spaces when selecting objects or when printing objects.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When specifying both the %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_object_s, context.set.notable);
- fl_print_format(" parameter and the %[%r%r%] parameter, the entire Object and Content are printed, including the formatting.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_content_s, context.set.notable, f_string_eol_s);
- fl_print_format(" Both the Object and Content printed are already escaped.%r", file.stream, f_string_eol_s);
- fl_print_format(" Both the Object and Content are separated by a New Line character '\\n' (U+000A).%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameter %[%r%r%] accepts the following:%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_delimit_s, context.set.notable, f_string_eol_s);
- fl_print_format(" - %[%r%]: Do not apply delimits.%r", file.stream, context.set.notable, fss_payload_read_delimit_mode_name_none_s, context.set.notable, f_string_eol_s);
- fl_print_format(" - %[%r%]: (default) Apply all delimits.%r", file.stream, context.set.notable, fss_payload_read_delimit_mode_name_all_s, context.set.notable, f_string_eol_s);
- fl_print_format(" - %[%r%]: Apply delimits for Objects.%r", file.stream, context.set.notable, fss_payload_read_delimit_mode_name_object_s, context.set.notable, f_string_eol_s);
- fl_print_format(" - A number, 0 or greater: apply delimits for Content at the specified depth.%r", file.stream, f_string_eol_s);
- fl_print_format(" - A number, 0 or greater, followed by a %[%r%]: (such as '1+') apply delimits for Content at the specified depth and any greater depth (numerically).%r", file.stream, context.set.notable, fss_payload_read_delimit_mode_name_greater_s, context.set.notable, f_string_eol_s, f_string_eol_s);
- fl_print_format(" - A number, 0 or lesser, followed by a %[%r%]: (such as '1-') apply delimits for Content at the specified depth and any lesser depth (numerically).%r%r", file.stream, context.set.notable, fss_payload_read_delimit_mode_name_lesser_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The %[%r%r%] parameter may be specified multiple times to customize the delimit behavior.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_delimit_s, context.set.notable, f_string_eol_s);
-
- fl_print_format(" The %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_delimit_s, context.set.notable);
- fl_print_format(" values %[%r%]", file.stream, context.set.notable, fss_payload_read_delimit_mode_name_none_s, context.set.notable);
- fl_print_format(" and %[%r%],", file.stream, context.set.notable, fss_payload_read_delimit_mode_name_all_s, context.set.notable);
- fl_print_format(" overrule all other delimit values.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The parameters %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_columns_s, context.set.notable);
- fl_print_format(" and %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_select_s, context.set.notable);
- fl_print_format(" refer to a Content column.%r", file.stream, f_string_eol_s);
- fl_print_format(" The word \"column\" is being loosely defined to refer to a specific Content.%r", file.stream, f_string_eol_s);
- fl_print_format(" This is not to be confused with a depth.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" As an exceptional case, a %[%r%r%] of", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_depth_s, context.set.notable);
- fl_print_format(" %[1%] applies only to the explicit Object of", file.stream, context.set.notable, context.set.notable);
- fl_print_format(" '%[%r%]'.%r", file.stream, context.set.notable, f_fss_string_header_s, context.set.notable, f_string_eol_s);
- fl_print_format(" Content at this depth is processed as FSS-0001 Extended.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The Content of the explicit Object of", file.stream);
- fl_print_format(" '%[%r%]'", file.stream, context.set.notable, f_fss_string_payload_s, context.set.notable, f_string_eol_s);
- fl_print_format(" will not contain any Content close pipe control codes when using", file.stream);
- fl_print_format(" %[%r%r%].%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_read_long_pipe_s, context.set.notable, f_string_eol_s);
-
- //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- f_file_stream_flush(file);
- funlockfile(file.stream);
-
- return F_none;
- }
-#endif // _di_fss_payload_read_print_help_
-
#ifndef _di_fss_payload_read_main_
- f_status_t fss_payload_read_main(fll_program_data_t * const main, const f_console_arguments_t arguments) {
+ f_status_t fss_payload_read_main(fll_program_data_t * const main, fss_payload_read_setting_t * const setting) {
f_status_t status = F_none;
status = F_none;
if (main->parameters.array[fss_payload_read_parameter_help_e].result == f_console_result_found_e) {
- fss_payload_read_print_help(main->output.to, main->context);
+ fss_payload_read_print_help(setting, main->message);
return status;
}
if (main->parameters.array[fss_payload_read_parameter_version_e].result == f_console_result_found_e) {
- fll_program_print_version(main->output.to, fss_payload_read_program_version_s);
+ fll_program_print_version(main->message, fss_payload_read_program_version_s);
return status;
}
if (!((++main->signal_check) % fss_payload_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_payload_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
if (!((++main->signal_check) % fss_payload_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_payload_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
// The signal check is always performed on each pass.
if (size_file > fss_payload_read_block_max && fll_program_standard_signal_received(main)) {
- fss_payload_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
#endif
/**
- * Print help.
- *
- * @param file
- * The file to print to.
- * @param context
- * The color context settings.
- *
- * @return
- * F_none on success.
- */
-#ifndef _di_fss_payload_read_print_help_
- extern f_status_t fss_payload_read_print_help(const f_file_t file, const f_color_context_t context);
-#endif // _di_fss_payload_read_print_help_
-
-/**
* Execute main program.
*
* If main.signal is non-zero, then this blocks and handles the following signals:
* Status codes (with error bit) are returned on any problem.
*/
#ifndef _di_fss_payload_read_main_
- extern f_status_t fss_payload_read_main(fll_program_data_t * const main, const f_console_arguments_t arguments);
+ extern f_status_t fss_payload_read_main(fll_program_data_t * const main, fss_payload_read_setting_t * const setting);
#endif // _di_fss_payload_read_main_
#ifdef __cplusplus
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
fll_program_data_t data = fll_program_data_t_initialize;
+ fss_payload_read_setting_t setting = fss_payload_read_setting_t_initialize;
f_console_parameter_t parameters[] = fss_payload_read_console_parameter_t_initialize;
data.parameters.array = parameters;
data.parameters.used = fss_payload_read_total_parameters_d;
+ data.environment = envp;
if (f_pipe_input_exists()) {
data.pipe = fll_program_data_pipe_input_e;
fll_program_standard_set_up(&data);
- const f_status_t status = fss_payload_read_main(&data, arguments);
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+
+ fss_payload_read_setting_load(arguments, &data, &setting);
+ }
+
+ fss_payload_read_main(&data, &setting);
+
+ fss_payload_read_setting_unload(&data, &setting);
fll_program_data_delete(&data);
fll_program_standard_set_down(&data);
- if (F_status_is_error(status)) return 1;
-
- return 0;
+ return F_status_is_error(status) ? 1 : 0;
}
--- /dev/null
+#include "fss_payload_read.h"
+#include "private-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fss_payload_read_print_help_
+ f_status_t fss_payload_read_print_help(fss_payload_read_setting_t * const setting, const fl_print_t print) {
+
+ f_file_stream_lock(print.to);
+
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+
+ fll_program_print_help_header(print, fss_payload_read_program_name_long_s, fss_payload_read_program_version_s);
+
+ fll_program_print_help_option_standard(print);
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, fss_payload_read_short_at_s, fss_payload_read_long_at_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric index.");
+ fll_program_print_help_option(print, fss_payload_read_short_content_s, fss_payload_read_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Content (default).");
+ fll_program_print_help_option(print, fss_payload_read_short_columns_s, fss_payload_read_long_columns_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of columns.");
+ fll_program_print_help_option(print, fss_payload_read_short_delimit_s, fss_payload_read_long_delimit_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Designate how to handle applying delimits.");
+ fll_program_print_help_option(print, fss_payload_read_short_depth_s, fss_payload_read_long_depth_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object at this numeric depth.");
+ fll_program_print_help_option(print, fss_payload_read_short_empty_s, fss_payload_read_long_empty_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Include empty Content when processing.");
+ fll_program_print_help_option(print, fss_payload_read_short_line_s, fss_payload_read_long_line_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print only the Content at the given line.");
+ fll_program_print_help_option(print, fss_payload_read_short_name_s, fss_payload_read_long_name_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select Object with this name.");
+ fll_program_print_help_option(print, fss_payload_read_short_object_s, fss_payload_read_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the Object.");
+ fll_program_print_help_option(print, fss_payload_read_short_pipe_s, fss_payload_read_long_pipe_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print using the special pipe format.");
+ fll_program_print_help_option(print, fss_payload_read_short_original_s, fss_payload_read_long_original_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print with the original quotes and escapes.");
+ fll_program_print_help_option(print, fss_payload_read_short_select_s, fss_payload_read_long_select_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select sub-Content at this index.");
+ fll_program_print_help_option(print, fss_payload_read_short_total_s, fss_payload_read_long_total_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of lines.");
+ fll_program_print_help_option(print, fss_payload_read_short_trim_s, fss_payload_read_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names on select or print.");
+
+ fll_program_print_help_usage(print, fss_payload_read_program_name_s, fll_program_parameter_filenames_s);
+
+ fl_print_format("%r %[Notes:%]%r", print.to.stream, f_string_eol_s, print.set->important, print.set->important, f_string_eol_s);
+
+ fl_print_format(" This program will print the Content associated with the given Object and Content main based on the FSS-000E Payload standard.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" All numeric positions (indexes) start at 0 instead of 1.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" For example, a file of 17 lines would range from 0 to 16.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When using the %[%r%r%] option, an order of operations is enforced on the parameters.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_depth_s, print.set->notable, f_string_eol_s);
+
+ fl_print_format(" When this order of operations is in effect, parameters to the right of a depth parameter are influenced by that depth parameter:%r", print.to.stream, f_string_eol_s);
+
+ fl_print_format(" %[%r%r%]: An Object index at the specified depth.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_at_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" %[%r%r%]: A new depth within the specified depth, indexed from the root.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_depth_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" %[%r%r%]: An Object name at the specified depth.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_name_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%] must be in numeric order, but values in between may be skipped.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_depth_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" ('-d 0 -a 1 -d 2 -a 2' would specify index 1 at depth 0, any index at depth 1, and index 2 at depth 2.)%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" ('-d 2 -a 1 -d 0 -a 2' would be invalid because depth 2 is before depth 1.)%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%] selects a Content column.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_select_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" Specify both %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_object_s, print.set->notable);
+ fl_print_format(" and the %[%r%r%] parameters to get the total objects.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_total_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When both %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_at_s, print.set->notable);
+ fl_print_format(" and %[%r%r%] parameters are specified (at the same depth),", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_name_s, print.set->notable);
+ fl_print_format(" the %[%r%r%] parameter value will be treated as a position relative to the specified", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_at_s, print.set->notable);
+ fl_print_format(" %[%r%r%] parameter value.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_name_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" This program may support parameters, such as %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_depth_s, print.set->notable);
+ fl_print_format(" or %[%r%r%], even if not supported by the standard.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_select_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" This is done to help ensure consistency for scripting.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" For parameters like %[%r%r%],", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_depth_s, print.set->notable);
+ fl_print_format(" if the standard doesn't support nested Content, then only a depth of 0 would be valid.%r", print.to.stream, f_string_eol_s);
+
+ fl_print_format(" For parameters like %[%r%r%],", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_select_s, print.set->notable);
+ fl_print_format(" if the standard doesn't support multiple Content groups, then only a select of 0 would be valid.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_trim_s, print.set->notable);
+ fl_print_format(" will remove leading and trailing white spaces when selecting objects or when printing objects.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When specifying both the %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_object_s, print.set->notable);
+ fl_print_format(" parameter and the %[%r%r%] parameter, the entire Object and Content are printed, including the formatting.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_content_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" Both the Object and Content printed are already escaped.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" Both the Object and Content are separated by a New Line character '\\n' (U+000A).%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameter %[%r%r%] accepts the following:%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_delimit_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" - %[%r%]: Do not apply delimits.%r", print.to.stream, print.set->notable, fss_payload_read_delimit_mode_name_none_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" - %[%r%]: (default) Apply all delimits.%r", print.to.stream, print.set->notable, fss_payload_read_delimit_mode_name_all_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" - %[%r%]: Apply delimits for Objects.%r", print.to.stream, print.set->notable, fss_payload_read_delimit_mode_name_object_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" - A number, 0 or greater: apply delimits for Content at the specified depth.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" - A number, 0 or greater, followed by a %[%r%]: (such as '1+') apply delimits for Content at the specified depth and any greater depth (numerically).%r", print.to.stream, print.set->notable, fss_payload_read_delimit_mode_name_greater_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+ fl_print_format(" - A number, 0 or lesser, followed by a %[%r%]: (such as '1-') apply delimits for Content at the specified depth and any lesser depth (numerically).%r%r", print.to.stream, print.set->notable, fss_payload_read_delimit_mode_name_lesser_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The %[%r%r%] parameter may be specified multiple times to customize the delimit behavior.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_delimit_s, print.set->notable, f_string_eol_s);
+
+ fl_print_format(" The %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_delimit_s, print.set->notable);
+ fl_print_format(" values %[%r%]", print.to.stream, print.set->notable, fss_payload_read_delimit_mode_name_none_s, print.set->notable);
+ fl_print_format(" and %[%r%],", print.to.stream, print.set->notable, fss_payload_read_delimit_mode_name_all_s, print.set->notable);
+ fl_print_format(" overrule all other delimit values.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The parameters %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_columns_s, print.set->notable);
+ fl_print_format(" and %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_select_s, print.set->notable);
+ fl_print_format(" refer to a Content column.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" The word \"column\" is being loosely defined to refer to a specific Content.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" This is not to be confused with a depth.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" As an exceptional case, a %[%r%r%] of", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_depth_s, print.set->notable);
+ fl_print_format(" %[1%] applies only to the explicit Object of", print.to.stream, print.set->notable, print.set->notable);
+ fl_print_format(" '%[%r%]'.%r", print.to.stream, print.set->notable, f_fss_string_header_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" Content at this depth is processed as FSS-0001 Extended.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The Content of the explicit Object of", print.to.stream);
+ fl_print_format(" '%[%r%]'", print.to.stream, print.set->notable, f_fss_string_payload_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" will not contain any Content close pipe control codes when using", print.to.stream);
+ fl_print_format(" %[%r%r%].%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_read_long_pipe_s, print.set->notable, f_string_eol_s);
+
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+
+ f_file_stream_flush(print.to);
+ f_file_stream_unlock(print.to);
+
+ return F_none;
+ }
+#endif // _di_fss_payload_read_print_help_
+
+#ifndef _di_fss_payload_read_print_line_first_
+ void fss_payload_read_print_line_first(fss_payload_read_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ }
+#endif // _di_fss_payload_read_print_line_first_
+
+#ifndef _di_fss_payload_read_print_line_last_
+ void fss_payload_read_print_line_last(fss_payload_read_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+ if (print.verbosity == f_console_verbosity_error_e && !F_status_is_error(setting->status)) return;
+ if (setting->flag & fss_payload_read_main_flag_verify_e) return;
+ if ((setting->flag & fss_payload_read_main_flag_file_to_e) && !F_status_is_error(setting->status)) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ }
+#endif // _di_fss_payload_read_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: UTF-8
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _fss_payload_read_print_h
+#define _fss_payload_read_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print help.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * The output structure to print to.
+ *
+ * @return
+ * F_none on success.
+ */
+#ifndef _di_fss_payload_read_print_help_
+ extern f_status_t fss_payload_read_print_help(fss_payload_read_setting_t * const setting, const fl_print_t print);
+#endif // _di_fss_payload_read_print_help_
+
+/**
+ * Print first new line, unless verbosity says otherwise.
+ *
+ * This is generally either the first line in the program or the first line printed before an error message.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_payload_read_print_line_first_
+ extern void fss_payload_read_print_line_first(fss_payload_read_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_payload_read_print_line_first_
+
+/**
+ * Print last new line when the main is complete, unless verbosity says otherwise.
+ *
+ * This is generally the very last line printed in the program.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_payload_read_print_line_last_
+ extern void fss_payload_read_print_line_last(fss_payload_read_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_payload_read_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _fss_payload_read_print_h
}
#endif // _di_fss_payload_read_depths_resize_
-#ifndef _di_fss_payload_read_print_signal_received_
- void fss_payload_read_print_signal_received(fll_program_data_t * const main) {
-
- if (main->warning.verbosity != f_console_verbosity_verbose_e && main->warning.verbosity != f_console_verbosity_debug_e) return;
-
- // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
- fflush(main->warning.to.stream);
-
- flockfile(main->warning.to.stream);
-
- fl_print_format("%]%r%r%[Received signal code %]", main->warning.to.stream, main->context.set.reset, f_string_eol_s, f_string_eol_s, main->context.set.warning, main->context.set.warning);
- fl_print_format("%[%i%]", main->warning.to.stream, main->context.set.notable, main->signal_received, main->context.set.notable);
- fl_print_format("%[.%]%r", main->warning.to.stream, main->context.set.warning, main->context.set.warning, f_string_eol_s);
-
- funlockfile(main->warning.to.stream);
- }
-#endif // _di_fss_payload_read_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
extern f_status_t fss_payload_read_depths_resize(const f_array_length_t length, fss_payload_read_depths_t *depths) F_attribute_visibility_internal_d;
#endif // _di_fss_payload_read_depths_resize_
-/**
- * Print a message about a process signal being recieved, such as an interrupt signal.
- *
- * @param main
- * The main program data.
- */
-#ifndef _di_fss_payload_read_print_signal_received_
- extern void fss_payload_read_print_signal_received(fll_program_data_t * const main) F_attribute_visibility_internal_d;
-#endif // _di_fss_payload_read_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
if (!((++main->signal_check) % fss_payload_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_payload_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (!((++main->signal_check) % fss_payload_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_payload_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (!((++main->signal_check) % fss_payload_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_payload_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (!((++main->signal_check) % fss_payload_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_payload_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (!((++main->signal_check) % fss_payload_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_payload_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (!((++main->signal_check) % fss_payload_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_payload_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (!((++main->signal_check) % fss_payload_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_payload_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
if (!((++main->signal_check) % fss_payload_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_payload_read_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
return F_status_set_error(F_interrupt);
}
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library fss_payload_read.c common.c private-common.c private-print.c private-read.c
+build_sources_library fss_payload_read.c common.c print.c private-common.c private-print.c private-read.c
build_sources_program main.c
-build_sources_headers fss_payload_read.h common.h
+build_sources_headers fss_payload_read.h common.h print.h
build_script yes
build_shared yes
const f_string_static_t fss_payload_write_long_trim_s = macro_f_string_static_t_initialize(FSS_PAYLOAD_WRITE_long_trim_s, 0, FSS_PAYLOAD_WRITE_long_trim_s_length);
#endif // _di_fss_payload_write_parameters_
+#ifndef _di_fss_payload_write_setting_delete_
+ f_status_t fss_payload_write_setting_delete(fss_payload_write_setting_t * const setting) {
+
+ if (!setting) return F_status_set_error(F_parameter);
+
+ return F_none;
+ }
+#endif // _di_fss_payload_write_setting_delete_
+
+#ifndef _di_fss_payload_write_setting_load_
+ void fss_payload_write_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_payload_write_setting_t * const setting) {
+
+ if (!main || !setting) return;
+
+ // Load parameters.
+ setting->status = f_console_parameter_process(arguments, &main->parameters);
+ if (F_status_is_error(setting->status)) return;
+
+ {
+ f_array_length_t choice = 0;
+ f_uint16s_t choices = f_uint16s_t_initialize;
+
+ // Identify and prioritize "color context" parameters.
+ {
+ uint16_t choices_array[3] = { fss_payload_write_parameter_no_color_e, fss_payload_write_parameter_light_e, fss_payload_write_parameter_dark_e };
+ choices.array = choices_array;
+ choices.used = 3;
+
+ const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
+
+ setting->status = fll_program_parameter_process_context(choices, modes, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_payload_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_context", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_payload_write_parameter_line_first_no_e].result == f_console_result_found_e) {
+ setting->line_first = f_string_empty_s;
+ }
+ else {
+ setting->line_first = f_string_eol_s;
+ }
+
+ if (main->parameters.array[fss_payload_write_parameter_line_last_no_e].result == f_console_result_found_e) {
+ setting->line_last = f_string_empty_s;
+ }
+ else {
+ setting->line_last = f_string_eol_s;
+ }
+
+ // Identify and prioritize "verbosity" parameters.
+ {
+ uint16_t choices_array[5] = { fss_payload_write_parameter_verbosity_quiet_e, fss_payload_write_parameter_verbosity_error_e, fss_payload_write_parameter_verbosity_verbose_e, fss_payload_write_parameter_verbosity_debug_e, fss_payload_write_parameter_verbosity_normal_e };
+ choices.array = choices_array;
+ choices.used = 5;
+
+ const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+
+ setting->status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_payload_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_verbosity", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_payload_write_parameter_help_e].result == f_console_result_found_e) {
+ setting->flag |= fss_payload_write_main_flag_help_e;
+
+ return;
+ }
+
+ if (main->parameters.array[fss_payload_write_parameter_version_e].result == f_console_result_found_e) {
+ setting->flag |= fss_payload_write_main_flag_version_e;
+
+ return;
+ }
+
+ // Identify and prioritize "from" mode parameters.
+ {
+ uint16_t choices_array[2] = { fss_payload_write_parameter_from_bytesequence_e, fss_payload_write_parameter_from_codepoint_e };
+ choices.array = choices_array;
+ choices.used = 2;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_payload_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_payload_write_parameter_from_bytesequence_e) {
+ if (setting->mode & fss_payload_write_mode_from_codepoint_e) {
+ setting->mode -= fss_payload_write_mode_from_codepoint_e;
+ }
+
+ setting->mode |= fss_payload_write_mode_from_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_payload_write_parameter_from_codepoint_e) {
+ if (setting->mode & fss_payload_write_mode_from_bytesequence_e) {
+ setting->mode -= fss_payload_write_mode_from_bytesequence_e;
+ }
+
+ setting->mode |= fss_payload_write_mode_from_codepoint_e;
+ }
+ }
+
+ // Identify and prioritize "to" mode parameters.
+ {
+ uint16_t choices_array[4] = { fss_payload_write_parameter_to_bytesequence_e, fss_payload_write_parameter_to_codepoint_e, fss_payload_write_parameter_to_combining_e, fss_payload_write_parameter_to_width_e };
+ choices.array = choices_array;
+ choices.used = 4;
+ choice = 1;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ fss_payload_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == fss_payload_write_parameter_to_bytesequence_e) {
+ if (setting->mode & fss_payload_write_mode_to_codepoint_e) {
+ setting->mode -= fss_payload_write_mode_to_codepoint_e;
+ }
+
+ if (setting->mode & fss_payload_write_mode_to_combining_e) {
+ setting->mode -= fss_payload_write_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_payload_write_mode_to_width_e) {
+ setting->mode -= fss_payload_write_mode_to_width_e;
+ }
+
+ setting->mode |= fss_payload_write_mode_to_bytesequence_e;
+ }
+ else if (choices.array[choice] == fss_payload_write_parameter_to_codepoint_e) {
+ if (setting->mode & fss_payload_write_mode_to_bytesequence_e) {
+ setting->mode -= fss_payload_write_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_payload_write_mode_to_combining_e) {
+ setting->mode -= fss_payload_write_mode_to_combining_e;
+ }
+
+ if (setting->mode & fss_payload_write_mode_to_width_e) {
+ setting->mode -= fss_payload_write_mode_to_width_e;
+ }
+
+ setting->mode |= fss_payload_write_mode_to_codepoint_e;
+ }
+ else if (choices.array[choice] == fss_payload_write_parameter_to_combining_e) {
+ if (setting->mode & fss_payload_write_mode_to_bytesequence_e) {
+ setting->mode -= fss_payload_write_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_payload_write_mode_to_codepoint_e) {
+ setting->mode -= fss_payload_write_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_payload_write_parameter_to_width_e].result == f_console_result_found_e) {
+ setting->mode |= fss_payload_write_mode_to_width_e;
+ }
+
+ setting->mode |= fss_payload_write_mode_to_combining_e;
+ }
+ else if (choices.array[choice] == fss_payload_write_parameter_to_width_e) {
+ if (setting->mode & fss_payload_write_mode_to_bytesequence_e) {
+ setting->mode -= fss_payload_write_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & fss_payload_write_mode_to_codepoint_e) {
+ setting->mode -= fss_payload_write_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[fss_payload_write_parameter_to_combining_e].result == f_console_result_found_e) {
+ setting->mode |= fss_payload_write_mode_to_combining_e;
+ }
+
+ setting->mode |= fss_payload_write_mode_to_width_e;
+ }
+ }
+ }
+
+ f_string_static_t * const args = main->parameters.arguments.array;
+
+ if (main->parameters.array[fss_payload_write_parameter_to_file_e].result == f_console_result_additional_e) {
+ if (main->parameters.array[fss_payload_write_parameter_to_file_e].values.used > 1) {
+ fss_payload_write_print_error_parameter_file_to_too_many(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+
+ if (args[main->parameters.array[fss_payload_write_parameter_to_file_e].values.array[0]].used) {
+ setting->path_files_to.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(1, &setting->path_files_to);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_to.array[setting->path_files_to.used].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[main->parameters.array[fss_payload_write_parameter_to_file_e].values.array[0]], &setting->path_files_to.array[0]);
+ if (F_status_is_error(setting->status)) return;
+
+ ++setting->path_files_to.used;
+
+ setting->status = f_file_stream_open(args[main->parameters.array[fss_payload_write_parameter_to_file_e].values.array[0]], f_file_open_mode_append_s, &main->output.to);
+
+ if (F_status_is_error(setting->status)) {
+ fll_error_file_print(main->error, F_status_set_fine(setting->status), "f_file_stream_open", F_true, args[main->parameters.array[fss_payload_write_parameter_to_file_e].values.array[0]], f_file_operation_open_s, fll_error_file_type_file_e);
+
+ return;
+ }
+
+ setting->flag |= fss_payload_write_main_flag_file_to_e;
+ }
+ else {
+ fss_payload_write_print_error_parameter_file_name_empty(main, setting, main->parameters.array[fss_payload_write_parameter_to_file_e].values.array[0]);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+ else if (main->parameters.array[fss_payload_write_parameter_to_file_e].result == f_console_result_found_e) {
+ fss_payload_write_print_error_no_value(main, setting, fss_payload_write_long_to_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ main->output.to = main->message.to;
+
+ if (setting->flag & fss_payload_write_main_flag_file_to_e) {
+ setting->flag -= fss_payload_write_main_flag_file_to_e;
+ }
+ }
+
+ if (main->parameters.array[fss_payload_write_parameter_from_file_e].result == f_console_result_additional_e) {
+ setting->path_files_from.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(main->parameters.array[fss_payload_write_parameter_from_file_e].values.used, &setting->path_files_from);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_from.used = main->parameters.array[fss_payload_write_parameter_from_file_e].values.used;
+
+ f_array_length_t i = 0;
+ f_array_length_t index = 0;
+
+ for (; i < setting->path_files_from.used; ++i) {
+
+ index = main->parameters.array[fss_payload_write_parameter_from_file_e].values.array[i];
+ setting->path_files_from.array[i].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[index], &setting->path_files_from.array[i]);
+ if (F_status_is_error(setting->status)) return;
+
+ if (args[index].used) {
+ if (f_file_exists(args[index], F_true) != F_true) {
+ fss_payload_write_print_error_parameter_file_not_found(main, setting, F_true, args[index]);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_file_found_not);
+ }
+ }
+ }
+ else {
+ fss_payload_write_print_error_parameter_file_name_empty(main, setting, index);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_parameter);
+ }
+ }
+ } // for
+
+ if (F_status_is_error(setting->status)) return;
+
+ setting->flag |= fss_payload_write_main_flag_file_from_e;
+ }
+ else if (main->parameters.array[fss_payload_write_parameter_from_file_e].result == f_console_result_found_e) {
+ fss_payload_write_print_error_no_value(main, setting, fss_payload_write_long_from_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ if (setting->flag & fss_payload_write_main_flag_file_from_e) {
+ setting->flag -= fss_payload_write_main_flag_file_from_e;
+ }
+ }
+
+ if (F_status_is_error(setting->status)) return;
+
+ if (main->parameters.array[fss_payload_write_parameter_from_file_e].result == f_console_result_none_e && !((main->pipe & fll_program_data_pipe_input_e) || main->parameters.remaining.used)) {
+ fss_payload_write_print_error_no_from(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+ }
+
+ if (!(setting->mode & fss_payload_write_mode_to_bytesequence_e)) {
+ if (main->parameters.array[fss_payload_write_parameter_separate_e].result == f_console_result_found_e || main->parameters.array[fss_payload_write_parameter_headers_e].result == f_console_result_found_e) {
+ setting->prepend = fss_payload_write_string_prepend_padding_s;
+ setting->append = f_string_eol_s;
+ }
+ else {
+ setting->prepend = f_string_space_s;
+ }
+ }
+
+ if (main->parameters.array[fss_payload_write_parameter_headers_e].result == f_console_result_found_e) {
+ setting->flag |= fss_payload_write_main_flag_header_e;
+ }
+
+ if (main->parameters.array[fss_payload_write_parameter_separate_e].result == f_console_result_found_e) {
+ setting->flag |= fss_payload_write_main_flag_separate_e;
+ }
+
+ if (main->parameters.array[fss_payload_write_parameter_strip_invalid_e].result == f_console_result_found_e) {
+ setting->flag |= fss_payload_write_main_flag_strip_invalid_e;
+ }
+
+ setting->valid_not = main->message.set->error;
+ }
+#endif // _di_fss_payload_write_setting_load_
+
+#ifndef _di_fss_payload_write_setting_unload_
+ f_status_t fss_payload_write_setting_unload(fll_program_data_t * const main, fss_payload_write_setting_t * const setting) {
+
+ if (!main || !setting) return F_status_set_error(F_parameter);
+
+ fss_payload_write_setting_delete(setting);
+
+ return F_none;
+ }
+#endif // _di_fss_payload_write_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
#define fss_payload_write_total_parameters_d 21
#endif // _di_fss_payload_write_parameters_
+/**
+ * Flags used to represent flags passed to the main function.
+ *
+ * fss_payload_write_main_flag_*_e:
+ * - none: No modes in use.
+ * - file_from: Using a specified source file.
+ * - file_to: Using a specified destination file.
+ * - help: Print help.
+ * - header: Enable printing of headers.
+ * - separate: Enable printing of separators.
+ * - strip_invalid: Using strip invalid character mode.
+ * - verify: Using verify mode.
+ * - version: Print version.
+ */
+#ifndef _di_fss_payload_write_main_flag_e_
+ enum {
+ fss_payload_write_main_flag_none_e = 0x0,
+ fss_payload_write_main_flag_file_from_e = 0x1,
+ fss_payload_write_main_flag_file_to_e = 0x2,
+ fss_payload_write_main_flag_header_e = 0x4,
+ fss_payload_write_main_flag_help_e = 0x8,
+ fss_payload_write_main_flag_separate_e = 0x10,
+ fss_payload_write_main_flag_strip_invalid_e = 0x20,
+ fss_payload_write_main_flag_verify_e = 0x40,
+ fss_payload_write_main_flag_version_e = 0x80,
+ };
+#endif // _di_fss_payload_write_main_flag_e_
+
+/**
+ * The fss payload write main program settings.
+ *
+ * This is passed to the program-specific main entry point to designate program settings.
+ * These program settings are often processed from the program arguments (often called the command line arguments).
+ *
+ * flag: Flags passed to the main function.
+ *
+ * status: The main status code, generally used by the load settings and main functions.
+ *
+ * line_first: A string expected to represent either "\n" or NULL to allow for easy handling of when to print first new line or not.
+ * line_last: A string expected to represent either "\n" or NULL to allow for easy handling of when to print last new line or not.
+ */
+#ifndef _di_fss_payload_write_setting_t_
+ typedef struct {
+ uint16_t flag;
+
+ f_status_t status;
+
+ f_string_static_t line_first;
+ f_string_static_t line_last;
+ } fss_payload_write_setting_t;
+
+ #define fss_payload_write_setting_t_initialize \
+ { \
+ fss_payload_write_main_flag_none_e, \
+ F_none, \
+ f_string_static_t_initialize, \
+ f_string_static_t_initialize, \
+ }
+#endif // _di_fss_payload_write_setting_t_
+
+/**
+ * Delete the program main setting data.
+ *
+ * @param setting
+ * The program main setting data.
+ * This does not alter setting.status.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fss_payload_write_setting_delete_
+ extern f_status_t fss_payload_write_setting_delete(fss_payload_write_setting_t * const setting);
+#endif // _di_fss_payload_write_setting_delete_
+
+/**
+ * Perform the standard program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately retuns without doing anything.
+ *
+ * @param arguments
+ * The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ *
+ * This alters setting.status:
+ * F_none on success.
+ *
+ * Errors (with error bit) from: f_console_parameter_process().
+ * Errors (with error bit) from: fll_program_parameter_process_context().
+ *
+ * @see f_console_parameter_process()
+ * @see fll_program_parameter_process_context()
+ */
+#ifndef _di_fss_payload_write_setting_load_
+ extern void fss_payload_write_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_payload_write_setting_t * const setting);
+#endif // _di_fss_payload_write_setting_load_
+
+/**
+ * Perform the standard program setting unload process.
+ *
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * All buffers are deallocated.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: utf8_setting_delete().
+ *
+ * @see utf8_setting_delete()
+ */
+#ifndef _di_fss_payload_write_setting_unload_
+ extern f_status_t fss_payload_write_setting_unload(fll_program_data_t * const main, fss_payload_write_setting_t * const setting);
+#endif // _di_fss_payload_write_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
const f_string_static_t fss_payload_write_program_name_long_s = macro_f_string_static_t_initialize(FSS_PAYLOAD_WRITE_program_name_long_s, 0, FSS_PAYLOAD_WRITE_program_name_long_s_length);
#endif // _di_fss_payload_write_program_name_
-#ifndef _di_fss_payload_write_print_help_
- f_status_t fss_payload_write_print_help(const f_file_t file, const f_color_context_t context) {
-
- flockfile(file.stream);
-
- //if (!(setting->flag & XXX_main_flag_line_first_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- fll_program_print_help_header(file, context, fss_payload_write_program_name_long_s, fss_payload_write_program_version_s);
-
- fll_program_print_help_option_standard(file, context);
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, fss_payload_write_short_file_s, fss_payload_write_long_file_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a file to send data to.");
- fll_program_print_help_option(file, context, fss_payload_write_short_content_s, fss_payload_write_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "The Content to write.");
- fll_program_print_help_option(file, context, fss_payload_write_short_double_s, fss_payload_write_long_double_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use double quotes (default).");
- fll_program_print_help_option(file, context, fss_payload_write_short_ignore_s, fss_payload_write_long_ignore_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Ignore a given range within a Content.");
- fll_program_print_help_option(file, context, fss_payload_write_short_object_s, fss_payload_write_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The Object to write.");
- fll_program_print_help_option(file, context, fss_payload_write_short_partial_s, fss_payload_write_long_partial_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Do not write end of Object/Content character.");
- fll_program_print_help_option(file, context, fss_payload_write_short_prepend_s, fss_payload_write_long_prepend_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Prepend the given white space characters to the start of each multi-line Content.");
- fll_program_print_help_option(file, context, fss_payload_write_short_single_s, fss_payload_write_long_single_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use single quotes.");
- fll_program_print_help_option(file, context, fss_payload_write_short_trim_s, fss_payload_write_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names.");
-
- fll_program_print_help_usage(file, context, fss_payload_write_program_name_s, f_string_empty_s);
-
- fl_print_format("%r The pipe uses the Backspace character '%[\\b%]' (%[U+0008%]) to designate the start of a Content.%r", file.stream, f_string_eol_s, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" The pipe uses the Form Feed character '%[\\f%]' (%[U+000C%]) to designate the end of the last Content.%r", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" The pipe uses the Vertical Line character '%[\\v%]' (%[U+000B%]) is used to ignore a Content range, which does nothing in this program.%r", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" For the pipe, an Object is terminated by either a Backspace character '%[\\b%]' (%[U+0008%])", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable);
- fl_print_format(" or a Form Feed character '%[\\f%]' (%[U+000C%]).%r", file.stream, context.set.notable, context.set.notable, context.set.notable, context.set.notable, f_string_eol_s);
- fl_print_format(" The end of the pipe represents the end of any Object or Content.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The FSS-000E (Payload) specification does not support quoted names, therefore the parameters '%[%r%r%]'", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_write_long_single_s, context.set.notable);
- fl_print_format(" and '%[%r%r%]' do nothing.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_write_long_double_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" This program does not use the parameter '%[%r%r%]', which therefore does nothing.%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, fss_payload_write_long_ignore_s, context.set.notable, f_string_eol_s);
- fl_print_format(" This parameter requires two values.%r", file.stream, f_string_eol_s);
-
- //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- f_file_stream_flush(file);
- funlockfile(file.stream);
-
- return F_none;
- }
-#endif // _di_fss_payload_write_print_help_
-
#ifndef _di_fss_payload_write_main_
- f_status_t fss_payload_write_main(fll_program_data_t * const main, const f_console_arguments_t arguments) {
+ f_status_t fss_payload_write_main(fll_program_data_t * const main, fss_payload_write_setting_t * const setting) {
f_status_t status = F_none;
status = F_none;
if (main->parameters.array[fss_payload_write_parameter_help_e].result == f_console_result_found_e) {
- fss_payload_write_print_help(main->output.to, main->context);
+ fss_payload_write_print_help(setting, main->message);
return status;
}
if (main->parameters.array[fss_payload_write_parameter_version_e].result == f_console_result_found_e) {
- fll_program_print_version(main->output.to, fss_payload_write_program_version_s);
+ fll_program_print_version(main->message, fss_payload_write_program_version_s);
return status;
}
if (!((++main->signal_check) % fss_payload_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_payload_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
if (!((++main->signal_check) % fss_payload_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_payload_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
if (!((++main->signal_check) % fss_payload_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_payload_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
#endif
/**
- * Print help.
- *
- * @param file
- * The file to print to.
- * @param context
- * The color context settings.
- *
- * @return
- * F_none on success.
- */
-#ifndef _di_fss_payload_write_print_help_
- extern f_status_t fss_payload_write_print_help(const f_file_t file, const f_color_context_t context);
-#endif // _di_fss_payload_write_print_help_
-
-/**
* Execute main program.
*
* If main.signal is non-zero, then this blocks and handles the following signals:
*
* @param main
* The main program data.
- * @param arguments
- * The parameters passed to the process.
+ * @param setting
+ * The main program settings.
*
- * @return
- * F_none on success.
+ * This alters setting.status:
+ * F_none on success.
+ * F_true on success when performing verification and verify passed.
+ * F_false on success when performing verification and verify failed.
+ * F_interrupt on (exit) signal received.
*
- * Status codes (with error bit) are returned on any problem.
+ * F_parameter (with error bit) if main is NULL or setting is NULL.
*/
#ifndef _di_fss_payload_write_main_
- extern f_status_t fss_payload_write_main(fll_program_data_t * const main, const f_console_arguments_t arguments);
+ extern f_status_t fss_payload_write_main(fll_program_data_t * const main, fss_payload_write_setting_t * const setting);
#endif // _di_fss_payload_write_main_
#ifdef __cplusplus
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
fll_program_data_t data = fll_program_data_t_initialize;
+ fss_payload_write_setting_t setting = fss_payload_write_setting_t_initialize;
f_console_parameter_t parameters[] = fss_payload_write_console_parameter_t_initialize;
data.parameters.array = parameters;
data.parameters.used = fss_payload_write_total_parameters_d;
+ data.environment = envp;
if (f_pipe_input_exists()) {
data.pipe = fll_program_data_pipe_input_e;
fll_program_standard_set_up(&data);
- const f_status_t status = fss_payload_write_main(&data, arguments);
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+
+ fss_payload_write_setting_load(arguments, &data, &setting);
+ }
+
+ fss_payload_write_main(&data, &setting);
+
+ fss_payload_write_setting_unload(&data, &setting);
fll_program_data_delete(&data);
fll_program_standard_set_down(&data);
- if (F_status_is_error(status)) return 1;
-
- return 0;
+ return F_status_is_error(status) ? 1 : 0;
}
--- /dev/null
+#include "fss_payload_write.h"
+#include "private-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fss_payload_write_print_help_
+ f_status_t fss_payload_write_print_help(fss_payload_write_setting_t * const setting, const fl_print_t print) {
+
+ f_file_stream_lock(print.to);
+
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+
+ fll_program_print_help_header(print, fss_payload_write_program_name_long_s, fss_payload_write_program_version_s);
+
+ fll_program_print_help_option_standard(print);
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, fss_payload_write_short_file_s, fss_payload_write_long_file_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a file to send data to.");
+ fll_program_print_help_option(print, fss_payload_write_short_content_s, fss_payload_write_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "The Content to write.");
+ fll_program_print_help_option(print, fss_payload_write_short_double_s, fss_payload_write_long_double_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use double quotes (default).");
+ fll_program_print_help_option(print, fss_payload_write_short_ignore_s, fss_payload_write_long_ignore_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Ignore a given range within a Content.");
+ fll_program_print_help_option(print, fss_payload_write_short_object_s, fss_payload_write_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The Object to write.");
+ fll_program_print_help_option(print, fss_payload_write_short_partial_s, fss_payload_write_long_partial_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Do not write end of Object/Content character.");
+ fll_program_print_help_option(print, fss_payload_write_short_prepend_s, fss_payload_write_long_prepend_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Prepend the given white space characters to the start of each multi-line Content.");
+ fll_program_print_help_option(print, fss_payload_write_short_single_s, fss_payload_write_long_single_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use single quotes.");
+ fll_program_print_help_option(print, fss_payload_write_short_trim_s, fss_payload_write_long_trim_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Trim Object names.");
+
+ fll_program_print_help_usage(print, fss_payload_write_program_name_s, f_string_empty_s);
+
+ fl_print_format("%r The pipe uses the Backspace character '%[\\b%]' (%[U+0008%]) to designate the start of a Content.%r", print.to.stream, f_string_eol_s, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" The pipe uses the Form Feed character '%[\\f%]' (%[U+000C%]) to designate the end of the last Content.%r", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" The pipe uses the Vertical Line character '%[\\v%]' (%[U+000B%]) is used to ignore a Content range, which does nothing in this program.%r", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" For the pipe, an Object is terminated by either a Backspace character '%[\\b%]' (%[U+0008%])", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable);
+ fl_print_format(" or a Form Feed character '%[\\f%]' (%[U+000C%]).%r", print.to.stream, print.set->notable, print.set->notable, print.set->notable, print.set->notable, f_string_eol_s);
+ fl_print_format(" The end of the pipe represents the end of any Object or Content.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The FSS-000E (Payload) specification does not support quoted names, therefore the parameters '%[%r%r%]'", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_write_long_single_s, print.set->notable);
+ fl_print_format(" and '%[%r%r%]' do nothing.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_write_long_double_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" This program does not use the parameter '%[%r%r%]', which therefore does nothing.%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, fss_payload_write_long_ignore_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" This parameter requires two values.%r", print.to.stream, f_string_eol_s);
+
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+
+ f_file_stream_flush(print.to);
+ f_file_stream_unlock(print.to);
+
+ return F_none;
+ }
+#endif // _di_fss_payload_write_print_help_
+
+#ifndef _di_fss_payload_write_print_line_first_
+ void fss_payload_write_print_line_first(fss_payload_write_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ }
+#endif // _di_fss_payload_write_print_line_first_
+
+#ifndef _di_fss_payload_write_print_line_last_
+ void fss_payload_write_print_line_last(fss_payload_write_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+ if (print.verbosity == f_console_verbosity_error_e && !F_status_is_error(setting->status)) return;
+ if (setting->flag & fss_payload_write_main_flag_verify_e) return;
+ if ((setting->flag & fss_payload_write_main_flag_file_to_e) && !F_status_is_error(setting->status)) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ }
+#endif // _di_fss_payload_write_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: UTF-8
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _fss_payload_write_print_h
+#define _fss_payload_write_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print help.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * The output structure to print to.
+ *
+ * @return
+ * F_none on success.
+ */
+#ifndef _di_fss_payload_write_print_help_
+ extern f_status_t fss_payload_write_print_help(fss_payload_write_setting_t * const setting, const fl_print_t print);
+#endif // _di_fss_payload_write_print_help_
+
+/**
+ * Print first new line, unless verbosity says otherwise.
+ *
+ * This is generally either the first line in the program or the first line printed before an error message.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_payload_write_print_line_first_
+ extern void fss_payload_write_print_line_first(fss_payload_write_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_payload_write_print_line_first_
+
+/**
+ * Print last new line when the main is complete, unless verbosity says otherwise.
+ *
+ * This is generally the very last line printed in the program.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_payload_write_print_line_last_
+ extern void fss_payload_write_print_line_last(fss_payload_write_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_payload_write_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _fss_payload_write_print_h
extern "C" {
#endif
-#ifndef _di_fss_payload_write_print_signal_received_
- void fss_payload_write_print_signal_received(fll_program_data_t * const main) {
-
- if (main->warning.verbosity != f_console_verbosity_verbose_e && main->warning.verbosity != f_console_verbosity_debug_e) return;
-
- // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
- fflush(main->warning.to.stream);
-
- flockfile(main->warning.to.stream);
-
- fl_print_format("%]%r%r%[Received signal code %]", main->warning.to.stream, main->context.set.reset, f_string_eol_s, f_string_eol_s, main->context.set.warning, main->context.set.warning);
- fl_print_format("%[%i%]", main->warning.to.stream, main->context.set.notable, main->signal_received, main->context.set.notable);
- fl_print_format("%[.%]%r", main->warning.to.stream, main->context.set.warning, main->context.set.warning, f_string_eol_s);
-
- funlockfile(main->warning.to.stream);
- }
-#endif // _di_fss_payload_write_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
#define fss_payload_write_common_allocation_small_d 128
#endif // _di_fss_payload_write_common_
-/**
- * Print a message about a process signal being recieved, such as an interrupt signal.
- *
- * @param main
- * The main program data.
- */
-#ifndef _di_fss_payload_write_print_signal_received_
- extern void fss_payload_write_print_signal_received(fll_program_data_t * const main) F_attribute_visibility_internal_d;
-#endif // _di_fss_payload_write_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
if (!((++main->signal_check) % fss_payload_write_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_payload_write_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library fss_payload_write.c common.c private-common.c private-write.c
+build_sources_library fss_payload_write.c common.c print.c private-common.c private-write.c
build_sources_program main.c
-build_sources_headers fss_payload_write.h common.h
+build_sources_headers fss_payload_write.h common.h print.h
build_script yes
build_shared yes
const f_string_static_t fss_status_code_program_help_parameters_s = macro_f_string_static_t_initialize(FSS_STATUS_CODE_program_help_parameters_s, 0, FSS_STATUS_CODE_program_help_parameters_s_length);
#endif // _di_fss_status_code_program_help_parameters_
+#ifndef _di_fss_status_code_strings_
+ const f_string_static_t fss_status_code_failed_to_convert_s = macro_f_string_static_t_initialize(FSS_STATUS_CODE_failed_to_convert_s, 0, FSS_STATUS_CODE_failed_to_convert_s_length);
+ const f_string_static_t fss_status_code_invalid_number_s = macro_f_string_static_t_initialize(FSS_STATUS_CODE_invalid_number_s, 0, FSS_STATUS_CODE_invalid_number_s_length);
+ const f_string_static_t fss_status_code_invalid_name_s = macro_f_string_static_t_initialize(FSS_STATUS_CODE_invalid_number_s, 0, FSS_STATUS_CODE_invalid_number_s_length);
+ const f_string_static_t fss_status_code_invalid_main_s = macro_f_string_static_t_initialize(FSS_STATUS_CODE_invalid_main_s, 0, FSS_STATUS_CODE_invalid_main_s_length);
+ const f_string_static_t fss_status_code_out_of_range_s = macro_f_string_static_t_initialize(FSS_STATUS_CODE_out_of_range_s, 0, FSS_STATUS_CODE_out_of_range_s_length);
+ const f_string_static_t fss_status_code_unknown_code_s = macro_f_string_static_t_initialize(FSS_STATUS_CODE_unknown_code_s, 0, FSS_STATUS_CODE_unknown_code_s_length);
+ const f_string_static_t fss_status_code_unknown_name_s = macro_f_string_static_t_initialize(FSS_STATUS_CODE_unknown_name_s, 0, FSS_STATUS_CODE_unknown_name_s_length);
+#endif // _di_fss_status_code_strings_
+
#ifndef _di_fss_status_code_parameters_
const f_string_static_t fss_status_code_short_fine_s = macro_f_string_static_t_initialize(FSS_STATUS_CODE_short_fine_s, 0, FSS_STATUS_CODE_short_fine_s_length);
const f_string_static_t fss_status_code_short_warning_s = macro_f_string_static_t_initialize(FSS_STATUS_CODE_short_warning_s, 0, FSS_STATUS_CODE_short_warning_s_length);
const f_string_static_t fss_status_code_long_number_s = macro_f_string_static_t_initialize(FSS_STATUS_CODE_long_number_s, 0, FSS_STATUS_CODE_long_number_s_length);
#endif // _di_fss_status_code_parameters_
+#ifndef _di_fss_status_code_setting_delete_
+ f_status_t fss_status_code_setting_delete(fss_status_code_setting_t * const setting) {
+
+ if (!setting) return F_status_set_error(F_parameter);
+
+ return F_none;
+ }
+#endif // _di_fss_status_code_setting_delete_
+
+#ifndef _di_fss_status_code_setting_load_
+ void fss_status_code_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_status_code_setting_t * const setting) {
+
+ if (!main || !setting) return;
+
+ // Load parameters.
+ setting->status = f_console_parameter_process(arguments, &main->parameters);
+ if (F_status_is_error(setting->status)) return;
+
+ {
+ f_array_length_t choice = 0;
+ f_uint16s_t choices = f_uint16s_t_initialize;
+
+ // Identify and prioritize "color context" parameters.
+ {
+ uint16_t choices_array[3] = { fss_status_code_parameter_no_color_e, fss_status_code_parameter_light_e, fss_status_code_parameter_dark_e };
+ choices.array = choices_array;
+ choices.used = 3;
+
+ const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
+
+ setting->status = fll_program_parameter_process_context(choices, modes, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_status_code_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_context", F_true);
+ fss_status_code_print_line_last(setting, main->error, F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_status_code_parameter_line_first_no_e].result == f_console_result_found_e) {
+ setting->line_first = f_string_empty_s;
+ }
+ else {
+ setting->line_first = f_string_eol_s;
+ }
+
+ if (main->parameters.array[fss_status_code_parameter_line_last_no_e].result == f_console_result_found_e) {
+ setting->line_last = f_string_empty_s;
+ }
+ else {
+ setting->line_last = f_string_eol_s;
+ }
+
+ // Identify and prioritize "verbosity" parameters.
+ {
+ uint16_t choices_array[5] = { fss_status_code_parameter_verbosity_quiet_e, fss_status_code_parameter_verbosity_error_e, fss_status_code_parameter_verbosity_verbose_e, fss_status_code_parameter_verbosity_debug_e, fss_status_code_parameter_verbosity_normal_e };
+ choices.array = choices_array;
+ choices.used = 5;
+
+ const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+
+ setting->status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ fss_status_code_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_verbosity", F_true);
+ fss_status_code_print_line_last(setting, main->error, F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_status_code_parameter_help_e].result == f_console_result_found_e) {
+ setting->flag |= fss_status_code_main_flag_help_e;
+
+ return;
+ }
+
+ if (main->parameters.array[fss_status_code_parameter_version_e].result == f_console_result_found_e) {
+ setting->flag |= fss_status_code_main_flag_version_e;
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[fss_status_code_parameter_error_e].result == f_console_result_found_e) {
+ setting->flag |= fss_status_code_main_flag_error_e;
+ }
+
+ if (main->parameters.array[fss_status_code_parameter_fine_e].result == f_console_result_found_e) {
+ setting->flag |= fss_status_code_main_flag_fine_e;
+ }
+
+ if (main->parameters.array[fss_status_code_parameter_warning_e].result == f_console_result_found_e) {
+ setting->flag |= fss_status_code_main_flag_warning_e;
+ }
+
+ if (main->parameters.array[fss_status_code_parameter_number_e].result == f_console_result_found_e) {
+ setting->flag |= fss_status_code_main_flag_number_e;
+ }
+
+ if (setting->flag & fss_status_code_main_flag_error_e) {
+ if (setting->flag & fss_status_code_main_flag_warning_e) {
+ if (!(setting->flag & fss_status_code_main_flag_number_e)) {
+ fss_status_code_print_line_first(setting, main->error, F_true);
+ fss_status_code_print_error_cannot_error_warning_number(setting, main->error);
+ fss_status_code_print_line_last(setting, main->error, F_true);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+
+ if (setting->flag & fss_status_code_main_flag_fine_e) {
+ fss_status_code_print_line_first(setting, main->error, F_true);
+ fll_program_parameter_long_print_cannot_use_with(main->error, fss_status_code_long_error_s, fss_status_code_long_fine_s);
+ fss_status_code_print_line_last(setting, main->error, F_true);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+ else if (setting->flag & fss_status_code_main_flag_warning_e && setting->flag & fss_status_code_main_flag_fine_e) {
+ fss_status_code_print_line_first(setting, main->error, F_true);
+ fll_program_parameter_long_print_cannot_use_with(main->error, fss_status_code_long_warning_s, fss_status_code_long_fine_s);
+ fss_status_code_print_line_last(setting, main->error, F_true);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+
+ if (main->parameters.remaining.used == 0 && !(main->pipe & fll_program_data_pipe_input_e)) {
+ fss_status_code_print_line_first(setting, main->error, F_true);
+ fss_status_code_print_error_no_fss_status_codes(setting, main->error);
+ fss_status_code_print_line_last(setting, main->error, F_true);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+#endif // _di_fss_status_code_setting_load_
+
+#ifndef _di_fss_status_code_setting_unload_
+ f_status_t fss_status_code_setting_unload(fll_program_data_t * const main, fss_status_code_setting_t * const setting) {
+
+ if (!main || !setting) return F_status_set_error(F_parameter);
+
+ fss_status_code_setting_delete(setting);
+
+ return F_none;
+ }
+#endif // _di_fss_status_code_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
/**
* FLL - Level 3
*
- * Project: FSS Status code
+ * Project: FSS Status Code
* API Version: 0.7
* Licenses: lgpl-2.1-or-later
*
#endif // _di_fss_status_code_program_help_parameters_
/**
+ * Special strings used by this program.
+ */
+#ifndef _di_fss_status_code_strings_
+ #define FSS_STATUS_CODE_failed_to_convert_s "failed to convert"
+ #define FSS_STATUS_CODE_invalid_number_s "invalid number"
+ #define FSS_STATUS_CODE_invalid_name_s "invalid name"
+ #define FSS_STATUS_CODE_invalid_main_s "invalid main"
+ #define FSS_STATUS_CODE_out_of_range_s "out of range"
+ #define FSS_STATUS_CODE_unknown_code_s "unknown code"
+ #define FSS_STATUS_CODE_unknown_name_s "unknown name"
+
+ #define FSS_STATUS_CODE_failed_to_convert_s_length 17
+ #define FSS_STATUS_CODE_invalid_number_s_length 14
+ #define FSS_STATUS_CODE_invalid_name_s_length 12
+ #define FSS_STATUS_CODE_invalid_main_s_length 12
+ #define FSS_STATUS_CODE_out_of_range_s_length 12
+ #define FSS_STATUS_CODE_unknown_code_s_length 12
+ #define FSS_STATUS_CODE_unknown_name_s_length 12
+
+ extern const f_string_static_t fss_status_code_failed_to_convert_s;
+ extern const f_string_static_t fss_status_code_invalid_number_s;
+ extern const f_string_static_t fss_status_code_invalid_name_s;
+ extern const f_string_static_t fss_status_code_invalid_main_s;
+ extern const f_string_static_t fss_status_code_out_of_range_s;
+ extern const f_string_static_t fss_status_code_unknown_code_s;
+ extern const f_string_static_t fss_status_code_unknown_name_s;
+#endif // _di_fss_status_code_strings_
+
+/**
* The program defines.
*/
#ifndef _di_fss_status_code_defines_
}
#define fss_status_code_total_parameters_d 16
-#endif // _di_fss_status_code_defines_
+#endif // _di_fss_status_code_parameters_
+
+/**
+ * Flags used to represent flags passed to the main function.
+ *
+ * When number mode is not specified, then mode is "string" mode (there is no flag for "string" mode).
+ *
+ * fss_status_code_main_flag_*_e:
+ * - none: No modes in use.
+ * - error: Check if status is "error".
+ * - fine: Check if status is "fine".
+ * - help: Print help.
+ * - number: Operate in number mode.
+ * - version: Print version.
+ * - warning: Check if status is "warning".
+ */
+#ifndef _di_fss_status_code_main_flag_e_
+ enum {
+ fss_status_code_main_flag_none_e = 0x0,
+ fss_status_code_main_flag_error_e = 0x1,
+ fss_status_code_main_flag_fine_e = 0x2,
+ fss_status_code_main_flag_help_e = 0x4,
+ fss_status_code_main_flag_number_e = 0x8,
+ fss_status_code_main_flag_version_e = 0x10,
+ fss_status_code_main_flag_warning_e = 0x20,
+ };
+#endif // _di_fss_status_code_main_flag_e_
+
+/**
+ * The status code main program settings.
+ *
+ * This is passed to the program-specific main entry point to designate program settings.
+ * These program settings are often processed from the program arguments (often called the command line arguments).
+ *
+ * flag: Flags passed to the main function.
+ *
+ * status: The main status code, generally used by the load settings and main functions.
+ *
+ * line_first: A string expected to represent either "\n" or NULL to allow for easy handling of when to print first new line or not.
+ * line_last: A string expected to represent either "\n" or NULL to allow for easy handling of when to print last new line or not.
+ */
+#ifndef _di_fss_status_code_setting_t_
+ typedef struct {
+ uint16_t flag;
+
+ f_status_t status;
+
+ f_string_static_t line_first;
+ f_string_static_t line_last;
+ } fss_status_code_setting_t;
+
+ #define fss_status_code_setting_t_initialize \
+ { \
+ fss_status_code_main_flag_none_e, \
+ F_none, \
+ f_string_static_t_initialize, \
+ f_string_static_t_initialize, \
+ }
+#endif // _di_fss_status_code_setting_t_
+
+/**
+ * Delete the program main setting data.
+ *
+ * @param setting
+ * The program main setting data.
+ * This does not alter setting.status.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fss_status_code_setting_delete_
+ extern f_status_t fss_status_code_setting_delete(fss_status_code_setting_t * const setting);
+#endif // _di_fss_status_code_setting_delete_
+
+/**
+ * Perform the standard program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately retuns without doing anything.
+ *
+ * @param arguments
+ * The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ *
+ * This alters setting.status:
+ * F_none on success.
+ *
+ * Errors (with error bit) from: f_console_parameter_process().
+ * Errors (with error bit) from: fll_program_parameter_process_context().
+ *
+ * @see f_console_parameter_process()
+ * @see fll_program_parameter_process_context()
+ */
+#ifndef _di_fss_status_code_setting_load_
+ extern void fss_status_code_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, fss_status_code_setting_t * const setting);
+#endif // _di_fss_status_code_setting_load_
+
+/**
+ * Perform the standard program setting unload process.
+ *
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * All buffers are deallocated.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: utf8_setting_delete().
+ *
+ * @see utf8_setting_delete()
+ */
+#ifndef _di_fss_status_code_setting_unload_
+ extern f_status_t fss_status_code_setting_unload(fll_program_data_t * const main, fss_status_code_setting_t * const setting);
+#endif // _di_fss_status_code_setting_unload_
#ifdef __cplusplus
} // extern "C"
extern "C" {
#endif
-#ifndef _di_fss_status_code_print_help_
- f_status_t fss_status_code_print_help(const f_file_t file, const f_color_context_t context) {
-
- flockfile(file.stream);
-
- //if (!(setting->flag & XXX_main_flag_line_first_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- fll_program_print_help_header(file, context, fss_status_code_program_name_long_s, fss_status_code_program_version_s);
-
- fll_program_print_help_option_standard(file, context);
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, fss_status_code_short_fine_s, fss_status_code_long_fine_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print F_true or F_false if status code is neither an error nor a warning or print number with neither the error code nor the warning code bits set.");
- fll_program_print_help_option(file, context, fss_status_code_short_warning_s, fss_status_code_long_warning_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print F_true or F_false if status code is a warning or print number with warning code bit set.");
- fll_program_print_help_option(file, context, fss_status_code_short_error_s, fss_status_code_long_error_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print F_true or F_false if status code is an error or print number with error code bit set.");
- fll_program_print_help_option(file, context, fss_status_code_short_number_s, fss_status_code_long_number_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Convert status code name to number.");
-
- fll_program_print_help_usage(file, context, fss_status_code_program_name_s, fss_status_code_program_help_parameters_s);
-
- //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- f_file_stream_flush(file);
- funlockfile(file.stream);
-
- return F_none;
- }
-#endif // _di_fss_status_code_print_help_
-
#ifndef _di_fss_status_code_main_
- f_status_t fss_status_code_main(fll_program_data_t * const main, const f_console_arguments_t arguments) {
-
- f_status_t status = F_none;
-
- // Load parameters.
- status = f_console_parameter_process(arguments, &main->parameters);
- if (F_status_is_error(status)) return;
-
- {
- f_array_length_t choice = 0;
- f_uint16s_t choices = f_uint16s_t_initialize;
-
- // Identify and prioritize "color context" parameters.
- {
- uint16_t choices_array[3] = { fss_status_code_parameter_no_color_e, fss_status_code_parameter_light_e, fss_status_code_parameter_dark_e };
- choices.array = choices_array;
- choices.used = 3;
-
- const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
-
- status = fll_program_parameter_process_context(choices, modes, F_true, main);
-
- if (F_status_is_error(status)) {
- fll_error_print(main->error, F_status_set_fine(status), "fll_program_parameter_process_context", F_true);
-
- return;
- }
- }
+ void fss_status_code_main(fll_program_data_t * const main, fss_status_code_setting_t * const setting) {
- // Identify and prioritize "verbosity" parameters.
- {
- uint16_t choices_array[5] = { fss_status_code_parameter_verbosity_quiet_e, fss_status_code_parameter_verbosity_error_e, fss_status_code_parameter_verbosity_verbose_e, fss_status_code_parameter_verbosity_debug_e, fss_status_code_parameter_verbosity_normal_e };
- choices.array = choices_array;
- choices.used = 5;
+ if (!main || !setting) {
+ fss_status_code_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_parameter, "fss_status_code_main", F_true);
+ fss_status_code_print_line_last(setting, main->error, F_true);
- const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+ setting->status = F_status_set_error(F_parameter);
- status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
-
- if (F_status_is_error(status)) {
- fll_error_print(main->error, F_status_set_fine(status), "fll_program_parameter_process_verbosity", F_true);
-
- return;
- }
- }
+ return;
}
- f_string_static_t * const argv = main->parameters.arguments.array;
+ if (F_status_is_error(setting->status)) return;
- status = F_none;
+ setting->status = F_none;
- if (main->parameters.array[fss_status_code_parameter_help_e].result == f_console_result_found_e) {
- fss_status_code_print_help(main->output.to, main->context);
+ if (setting->flag & fss_status_code_main_flag_help_e) {
+ fss_status_code_print_help(setting, main->message);
- return F_none;
+ return;
}
- if (main->parameters.array[fss_status_code_parameter_version_e].result == f_console_result_found_e) {
- fll_program_print_version(main->output.to, fss_status_code_program_version_s);
+ if (setting->flag & fss_status_code_main_flag_version_e) {
+ fll_program_print_version(main->message, fss_status_code_program_version_s);
- return F_none;
- }
-
- if (main->parameters.array[fss_status_code_parameter_error_e].result == f_console_result_found_e) {
- if (main->parameters.array[fss_status_code_parameter_warning_e].result == f_console_result_found_e) {
- if (main->parameters.array[fss_status_code_parameter_number_e].result == f_console_result_none_e) {
- if (main->error.verbosity != f_console_verbosity_quiet_e) {
- flockfile(main->error.to.stream);
-
- fl_print_format("%r%[%QCannot specify the '%]", main->error.to.stream, f_string_eol_s, main->error.context, main->error.prefix, main->error.context);
- fl_print_format("%[%r%r%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, fss_status_code_long_error_s, main->error.notable);
- fl_print_format("%[' parameter with the '%]", main->error.to.stream, main->error.context, main->error.context);
- fl_print_format("%[%r%r%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, fss_status_code_long_warning_s, main->error.notable);
- fl_print_format("%[' parameter when not also specifying the '%]", main->error.to.stream, main->error.context, main->error.context);
- fl_print_format("%[%r%r%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, fss_status_code_long_number_s, main->error.notable);
- fl_print_format("%[' parameter.%]%r%r", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s, f_string_eol_s);
-
- funlockfile(main->error.to.stream);
- }
-
- return F_status_set_error(status);
- }
- }
-
- if (main->parameters.array[fss_status_code_parameter_fine_e].result == f_console_result_found_e) {
- if (main->error.verbosity != f_console_verbosity_quiet_e) {
- fll_program_parameter_long_print_cannot_use_with(main->error, fss_status_code_long_error_s, fss_status_code_long_fine_s);
- fll_print_dynamic_raw(f_string_eol_s, main->error.to.stream);
- }
-
- return F_status_set_error(status);
- }
- }
- else if (main->parameters.array[fss_status_code_parameter_warning_e].result == f_console_result_found_e && main->parameters.array[fss_status_code_parameter_fine_e].result == f_console_result_found_e) {
- if (main->error.verbosity != f_console_verbosity_quiet_e) {
- fll_program_parameter_long_print_cannot_use_with(main->error, fss_status_code_long_warning_s, fss_status_code_long_fine_s);
- fll_print_dynamic_raw(f_string_eol_s, main->error.to.stream);
- }
-
- return F_status_set_error(status);
- }
-
- if (main->parameters.remaining.used == 0 && !(main->pipe & fll_program_data_pipe_input_e)) {
- fll_print_format("%[You failed to specify an error code.%]%r", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s);
-
- return F_status_set_error(F_parameter);
+ return;
}
f_status_t status2 = F_none;
- if (main->parameters.array[fss_status_code_parameter_number_e].result == f_console_result_found_e) {
+ if (setting->flag & fss_status_code_main_flag_number_e) {
if (main->pipe & fll_program_data_pipe_input_e) {
// @todo call fss_status_code_process_number() here for all main from pipe that is space separated.
}
if (main->parameters.remaining.used) {
- flockfile(main->output.to.stream);
+ f_file_stream_lock(main->output.to);
for (f_array_length_t i = 0; i < main->parameters.remaining.used; ++i) {
if (!((++main->signal_check) % fss_status_code_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_status_code_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
- status = F_status_set_error(F_interrupt);
+ setting->status = F_status_set_error(F_signal);
break;
}
main->signal_check = 0;
}
- status2 = fss_status_code_process_number(main, argv[main->parameters.remaining.array[i]]);
+ status2 = fss_status_code_process_number(main, setting, main->parameters.arguments.array[main->parameters.remaining.array[i]]);
- if (F_status_is_error(status2) && status == F_none) {
- status = status2;
+ if (F_status_is_error(status2) && setting->status == F_none) {
+ setting->status = status2;
}
} // for
- funlockfile(main->output.to.stream);
+ f_file_stream_unlock(main->output.to);
}
}
- else if (main->parameters.array[fss_status_code_parameter_error_e].result == f_console_result_found_e || main->parameters.array[fss_status_code_parameter_warning_e].result == f_console_result_found_e || main->parameters.array[fss_status_code_parameter_fine_e].result == f_console_result_found_e) {
+ else if (setting->flag & fss_status_code_main_flag_error_e || setting->flag & fss_status_code_main_flag_warning_e || setting->flag & fss_status_code_main_flag_fine_e) {
if (main->pipe & fll_program_data_pipe_input_e) {
// @todo call fss_status_code_process_check() here for all main from pipe that is space separated.
}
if (main->parameters.remaining.used) {
- flockfile(main->output.to.stream);
+ f_file_stream_lock(main->output.to);
for (f_array_length_t i = 0; i < main->parameters.remaining.used; ++i) {
if (!((++main->signal_check) % fss_status_code_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_status_code_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
- status = F_status_set_error(F_interrupt);
+ setting->status = F_status_set_error(F_signal);
break;
}
main->signal_check = 0;
}
- status2 = fss_status_code_process_check(main, argv[main->parameters.remaining.array[i]]);
+ status2 = fss_status_code_process_check(main, setting, main->parameters.arguments.array[main->parameters.remaining.array[i]]);
- if (F_status_is_error(status2) && status == F_none) {
- status = status2;
+ if (F_status_is_error(status2) && setting->status == F_none) {
+ setting->status = status2;
}
} // for
- funlockfile(main->output.to.stream);
+ f_file_stream_unlock(main->output.to);
}
}
else {
}
if (main->parameters.remaining.used) {
- flockfile(main->output.to.stream);
+ f_file_stream_lock(main->output.to);
for (f_array_length_t i = 0; i < main->parameters.remaining.used; ++i) {
if (!((++main->signal_check) % fss_status_code_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- fss_status_code_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
- status = F_status_set_error(F_interrupt);
+ setting->status = F_status_set_error(F_signal);
break;
}
main->signal_check = 0;
}
- status2 = fss_status_code_process_normal(main, argv[main->parameters.remaining.array[i]]);
+ status2 = fss_status_code_process_normal(main, setting, main->parameters.arguments.array[main->parameters.remaining.array[i]]);
- if (F_status_is_error(status2) && status == F_none) {
- status = status2;
+ if (F_status_is_error(status2) && setting->status == F_none) {
+ setting->status = status2;
}
} // for
- funlockfile(main->output.to.stream);
+ f_file_stream_unlock(main->output.to);
}
}
- if (F_status_set_fine(status) == F_interrupt) {
- if (main->output.verbosity != f_console_verbosity_quiet_e) {
- fflush(main->output.to.stream);
-
- fll_print_dynamic_raw(f_string_eol_s, main->output.to.stream);
- }
+ if (F_status_is_error(setting->status)) {
+ fss_status_code_print_line_last(setting, main->error, F_true);
+ }
+ else if (setting->status != F_interrupt) {
+ fss_status_code_print_line_last(setting, main->message, F_true);
}
-
- return status;
}
#endif // _di_fss_status_code_main_
/**
* FLL - Level 3
*
- * Project: FSS
+ * Project: FSS Status Code
* API Version: 0.7
* Licenses: lgpl-2.1-or-later
*
// FSS Status Code includes.
#include <program/fss_status_code/common.h>
+#include <program/fss_status_code/print.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
- * Print help.
- *
- * @param file
- * The file to print to.
- * @param context
- * The color context settings.
- *
- * @return
- * F_none on success.
- */
-#ifndef _di_fss_status_code_print_help_
- extern f_status_t fss_status_code_print_help(const f_file_t file, const f_color_context_t context);
-#endif // _di_fss_status_code_print_help_
-
-/**
* Execute main program.
*
* If main.signal is non-zero, then this blocks and handles the following signals:
*
* @param main
* The main program data.
- * @param arguments
- * The parameters passed to the process.
+ * @param setting
+ * The main program settings.
*
- * @return
- * F_none on success.
+ * This alters setting.status:
+ * F_none on success.
+ * F_true on success when performing verification and verify passed.
+ * F_false on success when performing verification and verify failed.
+ * F_interrupt on (exit) signal received.
*
- * Status codes (with error bit) are returned on any problem.
+ * F_parameter (with error bit) if main is NULL or setting is NULL.
*/
#ifndef _di_fss_status_code_main_
- extern f_status_t fss_status_code_main(fll_program_data_t * const main, const f_console_arguments_t arguments);
+ extern void fss_status_code_main(fll_program_data_t * const main, fss_status_code_setting_t * const setting);
#endif // _di_fss_status_code_main_
#ifdef __cplusplus
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
fll_program_data_t data = fll_program_data_t_initialize;
+ fss_status_code_setting_t setting = fss_status_code_setting_t_initialize;
f_console_parameter_t parameters[] = fss_status_code_console_parameter_t_initialize;
data.parameters.array = parameters;
data.parameters.used = fss_status_code_total_parameters_d;
+ data.environment = envp;
if (f_pipe_input_exists()) {
data.pipe = fll_program_data_pipe_input_e;
fll_program_standard_set_up(&data);
- const f_status_t status = fss_status_code_main(&data, arguments);
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+
+ fss_status_code_setting_load(arguments, &data, &setting);
+ }
+
+ fss_status_code_main(&data, &setting);
+
+ fss_status_code_setting_unload(&data, &setting);
fll_program_data_delete(&data);
fll_program_standard_set_down(&data);
- if (F_status_is_error(status) || status == F_false) return 1;
-
- return 0;
+ return (F_status_is_error(setting.status) || setting.status == F_false) ? 1 : 0;
}
--- /dev/null
+#include "fss_status_code.h"
+#include "private-common.h"
+#include "print.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fss_status_code_print_error_cannot_error_warning_number_
+ void fss_status_code_print_error_cannot_error_warning_number(fss_status_code_setting_t * const setting, const fl_print_t print) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ f_file_stream_lock(print.to);
+
+ fl_print_format("%[%QCannot specify the '%]", print.to.stream, print.context, print.prefix, print.context);
+ fl_print_format("%[%r%r%]", print.to.stream, print.notable, f_console_symbol_long_enable_s, fss_status_code_long_error_s, print.notable);
+ fl_print_format("%[' parameter with the '%]", print.to.stream, print.context, print.context);
+ fl_print_format("%[%r%r%]", print.to.stream, print.notable, f_console_symbol_long_enable_s, fss_status_code_long_warning_s, print.notable);
+ fl_print_format("%[' parameter when not also specifying the '%]", print.to.stream, print.context, print.context);
+ fl_print_format("%[%r%r%]", print.to.stream, print.notable, f_console_symbol_long_enable_s, fss_status_code_long_number_s, print.notable);
+ fl_print_format("%[' parameter.%]%r", print.to.stream, print.context, print.context, f_string_eol_s);
+
+ f_file_stream_unlock(print.to);
+ }
+#endif // _di_fss_status_code_print_error_cannot_error_warning_number_
+
+#ifndef _di_fss_status_code_print_error_no_fss_status_codes_
+ void fss_status_code_print_error_no_fss_status_codes(fss_status_code_setting_t * const setting, const fl_print_t print) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ fll_print_format("%[No status code is specified.%]%r", print.to.stream, print.context, print.context, f_string_eol_s);
+ }
+#endif // _di_fss_status_code_print_error_no_fss_status_codes_
+
+#ifndef _di_fss_status_code_print_help_
+ f_status_t fss_status_code_print_help(fss_status_code_setting_t * const setting, const fl_print_t print) {
+
+ f_file_stream_lock(print.to);
+
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+
+ fll_program_print_help_header(print, fss_status_code_program_name_long_s, fss_status_code_program_version_s);
+
+ fll_program_print_help_option_standard(print);
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, fss_status_code_short_fine_s, fss_status_code_long_fine_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print F_true or F_false if status code is neither an error nor a warning or print number with neither the error code nor the warning code bits set.");
+ fll_program_print_help_option(print, fss_status_code_short_warning_s, fss_status_code_long_warning_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print F_true or F_false if status code is a warning or print number with warning code bit set.");
+ fll_program_print_help_option(print, fss_status_code_short_error_s, fss_status_code_long_error_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print F_true or F_false if status code is an error or print number with error code bit set.");
+ fll_program_print_help_option(print, fss_status_code_short_number_s, fss_status_code_long_number_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Convert status code name to number.");
+
+ fll_program_print_help_usage(print, fss_status_code_program_name_s, fss_status_code_program_help_parameters_s);
+
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+
+ f_file_stream_flush(print.to);
+ f_file_stream_unlock(print.to);
+
+ return F_none;
+ }
+#endif // _di_fss_status_code_print_help_
+
+#ifndef _di_fss_status_code_print_line_first_
+ void fss_status_code_print_line_first(fss_status_code_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ }
+#endif // _di_fss_status_code_print_line_first_
+
+#ifndef _di_fss_status_code_print_line_last_
+ void fss_status_code_print_line_last(fss_status_code_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+ if (print.verbosity == f_console_verbosity_error_e && !F_status_is_error(setting->status)) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ }
+#endif // _di_fss_status_code_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: FSS Status Code
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _fss_status_code_print_h
+#define _fss_status_code_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print an error message when error parameter and warning parameter are specified without number parameter.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ */
+#ifndef _di_fss_status_code_print_error_cannot_error_warning_number_
+ extern void fss_status_code_print_error_cannot_error_warning_number(fss_status_code_setting_t * const setting, const fl_print_t print);
+#endif // _di_fss_status_code_print_error_cannot_error_warning_number_
+
+/**
+ * Print an error message when no status codes are provided.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ */
+#ifndef _di_fss_status_code_print_error_no_fss_status_codes_
+ extern void fss_status_code_print_error_no_fss_status_codes(fss_status_code_setting_t * const setting, const fl_print_t print);
+#endif // _di_fss_status_code_print_error_no_fss_status_codes_
+
+/**
+ * Print help.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * The output structure to print to.
+ *
+ * @return
+ * F_none on success.
+ */
+#ifndef _di_fss_status_code_print_help_
+ extern f_status_t fss_status_code_print_help(fss_status_code_setting_t * const setting, const fl_print_t print);
+#endif // _di_fss_status_code_print_help_
+
+/**
+ * Print first new line, unless verbosity says otherwise.
+ *
+ * This is generally either the first line in the program or the first line printed before an error message.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_status_code_print_line_first_
+ extern void fss_status_code_print_line_first(fss_status_code_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_status_code_print_line_first_
+
+/**
+ * Print last new line when the main is complete, unless verbosity says otherwise.
+ *
+ * This is generally the very last line printed in the program.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_fss_status_code_print_line_last_
+ extern void fss_status_code_print_line_last(fss_status_code_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_fss_status_code_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _fss_status_code_print_h
extern "C" {
#endif
-#ifndef _di_fss_status_code_print_signal_received_
- void fss_status_code_print_signal_received(fll_program_data_t * const main) {
-
- if (main->warning.verbosity != f_console_verbosity_verbose_e && main->warning.verbosity != f_console_verbosity_debug_e) return;
-
- // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
- fflush(main->warning.to.stream);
-
- flockfile(main->warning.to.stream);
-
- fl_print_format("%]%r%r%[Received signal code %]", main->warning.to.stream, main->context.set.reset, f_string_eol_s, f_string_eol_s, main->context.set.warning, main->context.set.warning);
- fl_print_format("%[%i%]", main->warning.to.stream, main->context.set.notable, main->signal_received, main->context.set.notable);
- fl_print_format("%[.%]%r", main->warning.to.stream, main->context.set.warning, main->context.set.warning, f_string_eol_s);
-
- funlockfile(main->warning.to.stream);
- }
-#endif // _di_fss_status_code_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
extern "C" {
#endif
-/**
- * Print a message about a process signal being recieved, such as an interrupt signal.
- *
- * @param main
- * The main program data.
- */
-#ifndef _di_fss_status_code_print_signal_received_
- extern void fss_status_code_print_signal_received(fll_program_data_t * const main) F_attribute_visibility_internal_d;
-#endif // _di_fss_status_code_print_signal_received_
-
-/**
- * Print a message about a one parameter not being allowed to be used with another.
- *
- * @param main
- * The main program data.
- */
-#ifndef _di_fss_status_code_print_parameter_cannot_be_used_with_
- extern void fss_status_code_print_parameter_cannot_be_used_with(fll_program_data_t * const main) F_attribute_visibility_internal_d;
-#endif // _di_fss_status_code_print_parameter_cannot_be_used_with_
-
#ifdef __cplusplus
} // extern "C"
#endif
#endif
#ifndef _di_fss_status_code_process_check_
- f_status_t fss_status_code_process_check(fll_program_data_t * const main, const f_string_static_t value) {
+ f_status_t fss_status_code_process_check(fll_program_data_t * const main, fss_status_code_setting_t * const setting, const f_string_static_t value) {
f_number_unsigned_t number = 0;
{
- const f_status_t status = fss_status_code_convert_number(main, value, &number);
+ f_status_t status = fss_status_code_convert_number(main, setting, value, &number);
if (F_status_is_error(status)) return status;
}
- if (main->parameters.array[fss_status_code_parameter_error_e].result == f_console_result_found_e) {
- if (F_status_is_error(number)) {
- f_print_dynamic_raw(f_status_true_s, main->output.to.stream);
- }
- else {
- f_print_dynamic_raw(f_status_false_s, main->output.to.stream);
- }
-
- f_print_dynamic_raw(f_string_eol_s, main->output.to.stream);
+ if ((setting->flag & fss_status_code_main_flag_error_e) && F_status_is_error(number) || (setting->flag & fss_status_code_main_flag_warning_e) && F_status_is_warning(number) || (setting->flag & fss_status_code_main_flag_fine_e) && F_status_is_fine(number)) {
+ f_print_dynamic_raw(f_status_true_s, main->output.to.stream);
}
- else if (main->parameters.array[fss_status_code_parameter_warning_e].result == f_console_result_found_e) {
- if (F_status_is_warning(number)) {
- f_print_dynamic_raw(f_status_true_s, main->output.to.stream);
- }
- else {
- f_print_dynamic_raw(f_status_false_s, main->output.to.stream);
- }
-
- f_print_dynamic_raw(f_string_eol_s, main->output.to.stream);
+ else {
+ f_print_dynamic_raw(f_status_false_s, main->output.to.stream);
}
- else if (main->parameters.array[fss_status_code_parameter_fine_e].result == f_console_result_found_e) {
- if (F_status_is_fine(number)) {
- f_print_dynamic_raw(f_status_true_s, main->output.to.stream);
- }
- else {
- f_print_dynamic_raw(f_status_false_s, main->output.to.stream);
- }
- f_print_dynamic_raw(f_string_eol_s, main->output.to.stream);
- }
+ f_print_dynamic_raw(f_string_eol_s, main->output.to.stream);
return F_none;
}
#endif // _di_fss_status_code_process_check_
#ifndef _di_fss_status_code_process_number_
- f_status_t fss_status_code_process_number(fll_program_data_t * const main, const f_string_static_t value) {
+ f_status_t fss_status_code_process_number(fll_program_data_t * const main, fss_status_code_setting_t * const setting, const f_string_static_t value) {
f_status_t status = F_none;
status = fl_conversion_dynamic_to_unsigned_detect(fl_conversion_data_base_10_c, value, &number);
if (status == F_none) {
- fl_print_format("%[invalid name%]%r", main->output.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s);
+ fl_print_format("%[%r%]%r", main->output.to.stream, main->context.set.error, fss_status_code_invalid_name_s, main->context.set.error, f_string_eol_s);
return F_status_set_error(F_parameter);
}
if (status == F_data_not || F_status_set_fine(status) == F_parameter) {
- fl_print_format("%[invalid main%]%r", main->output.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s);
+ fl_print_format("%[%r%]%r", main->output.to.stream, main->context.set.error, fss_status_code_invalid_main_s, main->context.set.error, f_string_eol_s);
return status;
}
if (F_status_is_error(status)) {
if (F_status_set_fine(status) == F_data) {
- fl_print_format("%[unknown name%]%r", main->output.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s);
+ fl_print_format("%[%r%]%r", main->output.to.stream, main->context.set.error, fss_status_code_unknown_name_s, main->context.set.error, f_string_eol_s);
}
else {
- fl_print_format("%[failed to convert%]%r", main->output.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s);
+ fl_print_format("%[%r%]%r", main->output.to.stream, main->context.set.error, fss_status_code_failed_to_convert_s, main->context.set.error, f_string_eol_s);
}
return status;
}
if (status == F_data) {
- fl_print_format("%[unknown code%]%r", main->output.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s);
+ fl_print_format("%[%r%]%r", main->output.to.stream, main->context.set.error, fss_status_code_unknown_code_s, main->context.set.error, f_string_eol_s);
return F_none;
}
- if (main->parameters.array[fss_status_code_parameter_error_e].result == f_console_result_found_e) {
+ if (setting->flag & fss_status_code_main_flag_error_e) {
code = F_status_set_error(code);
}
- if (main->parameters.array[fss_status_code_parameter_warning_e].result == f_console_result_found_e) {
+ if (setting->flag & fss_status_code_main_flag_warning_e) {
code = F_status_set_warning(code);
}
#endif // _di_fss_status_code_process_number_
#ifndef _di_fss_status_code_process_normal_
- f_status_t fss_status_code_process_normal(fll_program_data_t * const main, const f_string_static_t value) {
+ f_status_t fss_status_code_process_normal(fll_program_data_t * const main, fss_status_code_setting_t * const setting, const f_string_static_t value) {
f_number_unsigned_t number = 0;
- f_status_t status = fss_status_code_convert_number(main, value, &number);
+ f_status_t status = fss_status_code_convert_number(main, setting, value, &number);
if (F_status_is_error(status)) return status;
f_string_static_t name = f_string_static_t_initialize;
if (F_status_is_error(status)) {
if (F_status_set_fine(status) == F_data) {
- fl_print_format("%[unknown code%]%r", main->output.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s);
+ fl_print_format("%[%r%]%r", main->output.to.stream, main->context.set.error, fss_status_code_unknown_code_s, main->context.set.error, f_string_eol_s);
}
else {
- fl_print_format("%[failed to convert%]%r", main->output.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s);
+ fl_print_format("%[%r%]%r", main->output.to.stream, main->context.set.error, fss_status_code_failed_to_convert_s, main->context.set.error, f_string_eol_s);
}
return status;
#endif // _di_fss_status_code_process_normal_
#ifndef _di_fss_status_code_convert_number_
- f_status_t fss_status_code_convert_number(fll_program_data_t * const main, const f_string_static_t value, f_number_unsigned_t *number) {
+ f_status_t fss_status_code_convert_number(fll_program_data_t * const main, fss_status_code_setting_t * const setting, const f_string_static_t value, f_number_unsigned_t *number) {
- f_status_t status = fl_conversion_dynamic_to_unsigned_detect(fl_conversion_data_base_10_c, value, number);
+ const f_status_t status = fl_conversion_dynamic_to_unsigned_detect(fl_conversion_data_base_10_c, value, number);
if (*number > F_status_size_max_with_bits_d) {
- fl_print_format("%[out of range%]%r", main->output.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s);
+ fl_print_format("%[%r%]%r", main->output.to.stream, main->context.set.error, fss_status_code_out_of_range_s, main->context.set.error, f_string_eol_s);
return F_status_set_error(F_number_overflow);
}
if (F_status_is_error(status)) {
if (F_status_set_fine(status) == F_number_negative) {
- fl_print_format("%[out of range%]%r", main->output.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s);
+ fl_print_format("%[%r%]%r", main->output.to.stream, main->context.set.error, fss_status_code_out_of_range_s, main->context.set.error, f_string_eol_s);
}
else {
- fl_print_format("%[invalid number%]%r", main->output.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s);
+ fl_print_format("%[%r%]%r", main->output.to.stream, main->context.set.error, fss_status_code_invalid_number_s, main->context.set.error, f_string_eol_s);
}
return status;
/**
* FLL - Level 3
*
- * Project: FSS
+ * Project: FSS Status Code
* API Version: 0.7
* Licenses: lgpl-2.1-or-later
*/
* F_number_overflow (with error bit) on integer overflow.
* F_complete_not_utf (with error bit) if an incomplete UTF-8 fragment is found.
*
- * Errors (with error bit) from: fss_status_code_convert_number().
+ * Errors (with error bit) from: fss_fss_status_code_convert_number().
*
- * @see fss_status_code_convert_number()
+ * @see fss_fss_status_code_convert_number()
*/
#ifndef _di_fss_status_code_process_check_
- extern f_status_t fss_status_code_process_check(fll_program_data_t * const main, const f_string_static_t value) F_attribute_visibility_internal_d;
+ extern f_status_t fss_status_code_process_check(fll_program_data_t * const main, fss_status_code_setting_t * const setting, const f_string_static_t value) F_attribute_visibility_internal_d;
#endif // _di_fss_status_code_process_check_
/**
* @see fll_fss_status_string_from()
*/
#ifndef _di_fss_status_code_process_number_
- extern f_status_t fss_status_code_process_number(fll_program_data_t * const main, const f_string_static_t value) F_attribute_visibility_internal_d;
+ extern f_status_t fss_status_code_process_number(fll_program_data_t * const main, fss_status_code_setting_t * const setting, const f_string_static_t value) F_attribute_visibility_internal_d;
#endif // _di_fss_status_code_process_number_
/**
* F_parameter (with error bit) if a parameter is invalid.
*
* Errors (with error bit) from: fll_fss_status_string_from().
- * Errors (with error bit) from: fss_status_code_convert_number().
+ * Errors (with error bit) from: fss_fss_status_code_convert_number().
*
* @see fll_fss_status_string_from()
- * @see fss_status_code_convert_number()
+ * @see fss_fss_status_code_convert_number()
*/
#ifndef _di_fss_status_code_process_normal_
- extern f_status_t fss_status_code_process_normal(fll_program_data_t * const main, const f_string_static_t value) F_attribute_visibility_internal_d;
+ extern f_status_t fss_status_code_process_normal(fll_program_data_t * const main, fss_status_code_setting_t * const setting, const f_string_static_t value) F_attribute_visibility_internal_d;
#endif // _di_fss_status_code_process_normal_
/**
* @see fl_console_parameter_to_number_unsigned()
*/
#ifndef _di_fss_status_code_convert_number_
- extern f_status_t fss_status_code_convert_number(fll_program_data_t * const main, const f_string_static_t value, f_number_unsigned_t *number) F_attribute_visibility_internal_d;
+ extern f_status_t fss_status_code_convert_number(fll_program_data_t * const main, fss_status_code_setting_t * const setting, const f_string_static_t value, f_number_unsigned_t *number) F_attribute_visibility_internal_d;
#endif // _di_fss_status_code_convert_number_
#ifdef __cplusplus
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library fss_status_code.c common.c private-common.c private-fss_status_code.c
+build_sources_library fss_status_code.c common.c print.c private-common.c private-fss_status_code.c
build_sources_program main.c
-build_sources_headers fss_status_code.h common.h
+build_sources_headers fss_status_code.h common.h print.h
build_script yes
build_shared yes
const f_string_static_t iki_read_substitution_with_s = macro_f_string_static_t_initialize(IKI_READ_substitution_with_s, 0, IKI_READ_substitution_with_s_length);
#endif // _di_iki_read_substitution_t_
+#ifndef _di_iki_read_setting_delete_
+ f_status_t iki_read_setting_delete(iki_read_setting_t * const setting) {
+
+ if (!setting) return F_status_set_error(F_parameter);
+
+ return F_none;
+ }
+#endif // _di_iki_read_setting_delete_
+
+#ifndef _di_iki_read_setting_load_
+ void iki_read_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, iki_read_setting_t * const setting) {
+
+ if (!main || !setting) return;
+
+ // Load parameters.
+ setting->status = f_console_parameter_process(arguments, &main->parameters);
+ if (F_status_is_error(setting->status)) return;
+
+ {
+ f_array_length_t choice = 0;
+ f_uint16s_t choices = f_uint16s_t_initialize;
+
+ // Identify and prioritize "color context" parameters.
+ {
+ uint16_t choices_array[3] = { iki_read_parameter_no_color_e, iki_read_parameter_light_e, iki_read_parameter_dark_e };
+ choices.array = choices_array;
+ choices.used = 3;
+
+ const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
+
+ setting->status = fll_program_parameter_process_context(choices, modes, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ iki_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_context", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[iki_read_parameter_line_first_no_e].result == f_console_result_found_e) {
+ setting->line_first = f_string_empty_s;
+ }
+ else {
+ setting->line_first = f_string_eol_s;
+ }
+
+ if (main->parameters.array[iki_read_parameter_line_last_no_e].result == f_console_result_found_e) {
+ setting->line_last = f_string_empty_s;
+ }
+ else {
+ setting->line_last = f_string_eol_s;
+ }
+
+ // Identify and prioritize "verbosity" parameters.
+ {
+ uint16_t choices_array[5] = { iki_read_parameter_verbosity_quiet_e, iki_read_parameter_verbosity_error_e, iki_read_parameter_verbosity_verbose_e, iki_read_parameter_verbosity_debug_e, iki_read_parameter_verbosity_normal_e };
+ choices.array = choices_array;
+ choices.used = 5;
+
+ const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+
+ setting->status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ iki_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_verbosity", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[iki_read_parameter_help_e].result == f_console_result_found_e) {
+ setting->flag |= iki_read_main_flag_help_e;
+
+ return;
+ }
+
+ if (main->parameters.array[iki_read_parameter_version_e].result == f_console_result_found_e) {
+ setting->flag |= iki_read_main_flag_version_e;
+
+ return;
+ }
+
+ // Identify and prioritize "from" mode parameters.
+ {
+ uint16_t choices_array[2] = { iki_read_parameter_from_bytesequence_e, iki_read_parameter_from_codepoint_e };
+ choices.array = choices_array;
+ choices.used = 2;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ iki_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == iki_read_parameter_from_bytesequence_e) {
+ if (setting->mode & iki_read_mode_from_codepoint_e) {
+ setting->mode -= iki_read_mode_from_codepoint_e;
+ }
+
+ setting->mode |= iki_read_mode_from_bytesequence_e;
+ }
+ else if (choices.array[choice] == iki_read_parameter_from_codepoint_e) {
+ if (setting->mode & iki_read_mode_from_bytesequence_e) {
+ setting->mode -= iki_read_mode_from_bytesequence_e;
+ }
+
+ setting->mode |= iki_read_mode_from_codepoint_e;
+ }
+ }
+
+ // Identify and prioritize "to" mode parameters.
+ {
+ uint16_t choices_array[4] = { iki_read_parameter_to_bytesequence_e, iki_read_parameter_to_codepoint_e, iki_read_parameter_to_combining_e, iki_read_parameter_to_width_e };
+ choices.array = choices_array;
+ choices.used = 4;
+ choice = 1;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ iki_read_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == iki_read_parameter_to_bytesequence_e) {
+ if (setting->mode & iki_read_mode_to_codepoint_e) {
+ setting->mode -= iki_read_mode_to_codepoint_e;
+ }
+
+ if (setting->mode & iki_read_mode_to_combining_e) {
+ setting->mode -= iki_read_mode_to_combining_e;
+ }
+
+ if (setting->mode & iki_read_mode_to_width_e) {
+ setting->mode -= iki_read_mode_to_width_e;
+ }
+
+ setting->mode |= iki_read_mode_to_bytesequence_e;
+ }
+ else if (choices.array[choice] == iki_read_parameter_to_codepoint_e) {
+ if (setting->mode & iki_read_mode_to_bytesequence_e) {
+ setting->mode -= iki_read_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & iki_read_mode_to_combining_e) {
+ setting->mode -= iki_read_mode_to_combining_e;
+ }
+
+ if (setting->mode & iki_read_mode_to_width_e) {
+ setting->mode -= iki_read_mode_to_width_e;
+ }
+
+ setting->mode |= iki_read_mode_to_codepoint_e;
+ }
+ else if (choices.array[choice] == iki_read_parameter_to_combining_e) {
+ if (setting->mode & iki_read_mode_to_bytesequence_e) {
+ setting->mode -= iki_read_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & iki_read_mode_to_codepoint_e) {
+ setting->mode -= iki_read_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[iki_read_parameter_to_width_e].result == f_console_result_found_e) {
+ setting->mode |= iki_read_mode_to_width_e;
+ }
+
+ setting->mode |= iki_read_mode_to_combining_e;
+ }
+ else if (choices.array[choice] == iki_read_parameter_to_width_e) {
+ if (setting->mode & iki_read_mode_to_bytesequence_e) {
+ setting->mode -= iki_read_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & iki_read_mode_to_codepoint_e) {
+ setting->mode -= iki_read_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[iki_read_parameter_to_combining_e].result == f_console_result_found_e) {
+ setting->mode |= iki_read_mode_to_combining_e;
+ }
+
+ setting->mode |= iki_read_mode_to_width_e;
+ }
+ }
+ }
+
+ f_string_static_t * const args = main->parameters.arguments.array;
+
+ if (main->parameters.array[iki_read_parameter_to_file_e].result == f_console_result_additional_e) {
+ if (main->parameters.array[iki_read_parameter_to_file_e].values.used > 1) {
+ iki_read_print_error_parameter_file_to_too_many(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+
+ if (args[main->parameters.array[iki_read_parameter_to_file_e].values.array[0]].used) {
+ setting->path_files_to.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(1, &setting->path_files_to);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_to.array[setting->path_files_to.used].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[main->parameters.array[iki_read_parameter_to_file_e].values.array[0]], &setting->path_files_to.array[0]);
+ if (F_status_is_error(setting->status)) return;
+
+ ++setting->path_files_to.used;
+
+ setting->status = f_file_stream_open(args[main->parameters.array[iki_read_parameter_to_file_e].values.array[0]], f_file_open_mode_append_s, &main->output.to);
+
+ if (F_status_is_error(setting->status)) {
+ fll_error_file_print(main->error, F_status_set_fine(setting->status), "f_file_stream_open", F_true, args[main->parameters.array[iki_read_parameter_to_file_e].values.array[0]], f_file_operation_open_s, fll_error_file_type_file_e);
+
+ return;
+ }
+
+ setting->flag |= iki_read_main_flag_file_to_e;
+ }
+ else {
+ iki_read_print_error_parameter_file_name_empty(main, setting, main->parameters.array[iki_read_parameter_to_file_e].values.array[0]);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+ else if (main->parameters.array[iki_read_parameter_to_file_e].result == f_console_result_found_e) {
+ iki_read_print_error_no_value(main, setting, iki_read_long_to_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ main->output.to = main->message.to;
+
+ if (setting->flag & iki_read_main_flag_file_to_e) {
+ setting->flag -= iki_read_main_flag_file_to_e;
+ }
+ }
+
+ if (main->parameters.array[iki_read_parameter_from_file_e].result == f_console_result_additional_e) {
+ setting->path_files_from.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(main->parameters.array[iki_read_parameter_from_file_e].values.used, &setting->path_files_from);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_from.used = main->parameters.array[iki_read_parameter_from_file_e].values.used;
+
+ f_array_length_t i = 0;
+ f_array_length_t index = 0;
+
+ for (; i < setting->path_files_from.used; ++i) {
+
+ index = main->parameters.array[iki_read_parameter_from_file_e].values.array[i];
+ setting->path_files_from.array[i].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[index], &setting->path_files_from.array[i]);
+ if (F_status_is_error(setting->status)) return;
+
+ if (args[index].used) {
+ if (f_file_exists(args[index], F_true) != F_true) {
+ iki_read_print_error_parameter_file_not_found(main, setting, F_true, args[index]);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_file_found_not);
+ }
+ }
+ }
+ else {
+ iki_read_print_error_parameter_file_name_empty(main, setting, index);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_parameter);
+ }
+ }
+ } // for
+
+ if (F_status_is_error(setting->status)) return;
+
+ setting->flag |= iki_read_main_flag_file_from_e;
+ }
+ else if (main->parameters.array[iki_read_parameter_from_file_e].result == f_console_result_found_e) {
+ iki_read_print_error_no_value(main, setting, iki_read_long_from_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ if (setting->flag & iki_read_main_flag_file_from_e) {
+ setting->flag -= iki_read_main_flag_file_from_e;
+ }
+ }
+
+ if (F_status_is_error(setting->status)) return;
+
+ if (main->parameters.array[iki_read_parameter_from_file_e].result == f_console_result_none_e && !((main->pipe & fll_program_data_pipe_input_e) || main->parameters.remaining.used)) {
+ iki_read_print_error_no_from(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+ }
+
+ if (!(setting->mode & iki_read_mode_to_bytesequence_e)) {
+ if (main->parameters.array[iki_read_parameter_separate_e].result == f_console_result_found_e || main->parameters.array[iki_read_parameter_headers_e].result == f_console_result_found_e) {
+ setting->prepend = iki_read_string_prepend_padding_s;
+ setting->append = f_string_eol_s;
+ }
+ else {
+ setting->prepend = f_string_space_s;
+ }
+ }
+
+ if (main->parameters.array[iki_read_parameter_headers_e].result == f_console_result_found_e) {
+ setting->flag |= iki_read_main_flag_header_e;
+ }
+
+ if (main->parameters.array[iki_read_parameter_separate_e].result == f_console_result_found_e) {
+ setting->flag |= iki_read_main_flag_separate_e;
+ }
+
+ if (main->parameters.array[iki_read_parameter_strip_invalid_e].result == f_console_result_found_e) {
+ setting->flag |= iki_read_main_flag_strip_invalid_e;
+ }
+
+ setting->valid_not = main->message.set->error;
+ }
+#endif // _di_iki_read_setting_load_
+
+#ifndef _di_iki_read_setting_unload_
+ f_status_t iki_read_setting_unload(fll_program_data_t * const main, iki_read_setting_t * const setting) {
+
+ if (!main || !setting) return F_status_set_error(F_parameter);
+
+ iki_read_setting_delete(setting);
+
+ return F_none;
+ }
+#endif // _di_iki_read_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
#define macro_iki_read_substitutions_t_adjust(status, replacements, length) macro_f_memory_structure_adjust(status, replacements, iki_read_substitution_t, length)
#endif // _di_iki_read_substitutions_t_
+/**
+ * Flags used to represent flags passed to the main function.
+ *
+ * iki_read_main_flag_*_e:
+ * - none: No modes in use.
+ * - file_from: Using a specified source file.
+ * - file_to: Using a specified destination file.
+ * - help: Print help.
+ * - header: Enable printing of headers.
+ * - separate: Enable printing of separators.
+ * - strip_invalid: Using strip invalid character mode.
+ * - verify: Using verify mode.
+ * - version: Print version.
+ */
+#ifndef _di_iki_read_main_flag_e_
+ enum {
+ iki_read_main_flag_none_e = 0x0,
+ iki_read_main_flag_file_from_e = 0x1,
+ iki_read_main_flag_file_to_e = 0x2,
+ iki_read_main_flag_header_e = 0x4,
+ iki_read_main_flag_help_e = 0x8,
+ iki_read_main_flag_separate_e = 0x10,
+ iki_read_main_flag_strip_invalid_e = 0x20,
+ iki_read_main_flag_verify_e = 0x40,
+ iki_read_main_flag_version_e = 0x80,
+ };
+#endif // _di_iki_read_main_flag_e_
+
+/**
+ * The iki read main program settings.
+ *
+ * This is passed to the program-specific main entry point to designate program settings.
+ * These program settings are often processed from the program arguments (often called the command line arguments).
+ *
+ * flag: Flags passed to the main function.
+ *
+ * status: The main status code, generally used by the load settings and main functions.
+ *
+ * line_first: A string expected to represent either "\n" or NULL to allow for easy handling of when to print first new line or not.
+ * line_last: A string expected to represent either "\n" or NULL to allow for easy handling of when to print last new line or not.
+ */
+#ifndef _di_iki_read_setting_t_
+ typedef struct {
+ uint16_t flag;
+
+ f_status_t status;
+
+ f_string_static_t line_first;
+ f_string_static_t line_last;
+ } iki_read_setting_t;
+
+ #define iki_read_setting_t_initialize \
+ { \
+ iki_read_main_flag_none_e, \
+ F_none, \
+ f_string_static_t_initialize, \
+ f_string_static_t_initialize, \
+ }
+#endif // _di_iki_read_setting_t_
+
+/**
+ * Delete the program main setting data.
+ *
+ * @param setting
+ * The program main setting data.
+ * This does not alter setting.status.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_iki_read_setting_delete_
+ extern f_status_t iki_read_setting_delete(iki_read_setting_t * const setting);
+#endif // _di_iki_read_setting_delete_
+
+/**
+ * Perform the standard program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately retuns without doing anything.
+ *
+ * @param arguments
+ * The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ *
+ * This alters setting.status:
+ * F_none on success.
+ *
+ * Errors (with error bit) from: f_console_parameter_process().
+ * Errors (with error bit) from: fll_program_parameter_process_context().
+ *
+ * @see f_console_parameter_process()
+ * @see fll_program_parameter_process_context()
+ */
+#ifndef _di_iki_read_setting_load_
+ extern void iki_read_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, iki_read_setting_t * const setting);
+#endif // _di_iki_read_setting_load_
+
+/**
+ * Perform the standard program setting unload process.
+ *
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * All buffers are deallocated.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: utf8_setting_delete().
+ *
+ * @see utf8_setting_delete()
+ */
+#ifndef _di_iki_read_setting_unload_
+ extern f_status_t iki_read_setting_unload(fll_program_data_t * const main, iki_read_setting_t * const setting);
+#endif // _di_iki_read_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern "C" {
#endif
-#ifndef _di_iki_read_print_help_
- f_status_t iki_read_print_help(const f_file_t file, const f_color_context_t context) {
-
- flockfile(file.stream);
-
- //if (!(setting->flag & XXX_main_flag_line_first_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- fll_program_print_help_header(file, context, iki_read_program_name_long_s, iki_read_program_version_s);
-
- fll_program_print_help_option_standard(file, context);
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, iki_read_short_at_s, iki_read_long_at_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select variable at this numeric index.");
- fll_program_print_help_option(file, context, iki_read_short_line_s, iki_read_long_line_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print only the variables at the given line within the file.");
- fll_program_print_help_option(file, context, iki_read_short_name_s, iki_read_long_name_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select variables with this name.");
- fll_program_print_help_option(file, context, iki_read_short_whole_s, iki_read_long_whole_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print all of the data instead of just the IKI variable data.");
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, iki_read_short_content_s, iki_read_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print the variable value (aka: content) (default)");
- fll_program_print_help_option(file, context, iki_read_short_literal_s, iki_read_long_literal_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print the entire variable (aka: object, content, and syntax).");
- fll_program_print_help_option(file, context, iki_read_short_object_s, iki_read_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the variable name (aka: object).");
- fll_program_print_help_option(file, context, iki_read_short_total_s, iki_read_long_total_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of variables.");
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, iki_read_short_replace_s, iki_read_long_replace_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Simple substitution, replacing the variable for the given name with the given string.");
- fll_program_print_help_option(file, context, iki_read_short_substitute_s, iki_read_long_substitute_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Substitute the variable for the given name and matching content value with the given string.");
- fll_program_print_help_option(file, context, iki_read_short_wrap_s, iki_read_long_wrap_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Prepend and append strings for the given name.");
-
- fll_program_print_help_usage(file, context, iki_read_program_name_s, fll_program_parameter_filenames_s);
-
- fl_print_format("%r %[Notes:%]%r", file.stream, f_string_eol_s, context.set.important, context.set.important, f_string_eol_s);
- fl_print_format(" This program will find and print variables, vocabularies, or content following the IKI standard, without focusing on any particular vocabulary specification.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The %[%r%r%] option requires 2 additional parameters:", file.stream, context.set.notable, f_console_symbol_long_enable_s, iki_read_long_replace_s, context.set.notable);
- fl_print_format(" %[<%]%r%[>%]", file.stream, context.set.notable, context.set.notable, iki_read_substitution_vocabulary_s, context.set.notable, context.set.notable);
- fl_print_format(" %[<%]%r%[>%].%r", file.stream, context.set.notable, context.set.notable, iki_read_substitution_with_s, context.set.notable, context.set.notable, f_string_eol_s);
-
- fl_print_format(" %[%r%]: The name of the vocabulary whose content is to be substituted.%r", file.stream, context.set.notable, iki_read_substitution_vocabulary_s, context.set.notable, f_string_eol_s);
- fl_print_format(" %[%r%]: The new string to use as the substitute.%r%r", file.stream, context.set.notable, iki_read_substitution_with_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The vocabulary is case-sensitive and must exactly match.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The %[%r%r%] option requires 3 additional parameters:", file.stream, context.set.notable, f_console_symbol_long_enable_s, iki_read_long_substitute_s, context.set.notable);
- fl_print_format(" %[<%]%r%[>%]", file.stream, context.set.notable, context.set.notable, iki_read_substitution_vocabulary_s, context.set.notable, context.set.notable);
- fl_print_format(" %[<%]%r%[>%]", file.stream, context.set.notable, context.set.notable, iki_read_substitution_replace_s, context.set.notable, context.set.notable);
- fl_print_format(" %[<%]%r%[>%].%r", file.stream, context.set.notable, context.set.notable, iki_read_substitution_with_s, context.set.notable, context.set.notable, f_string_eol_s);
-
- fl_print_format(" %[%r%]: The name of the vocabulary whose content is to be substituted.%r", file.stream, context.set.notable, iki_read_substitution_vocabulary_s, context.set.notable, f_string_eol_s);
- fl_print_format(" %[%r%]: The content matching this exact string will be substituted.%r", file.stream, context.set.notable, iki_read_substitution_replace_s, context.set.notable, f_string_eol_s);
- fl_print_format(" %[%r%]: The new string to use as the substitute.%r%r", file.stream, context.set.notable, iki_read_substitution_with_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The vocabulary and replacement are case-sensitive and must exactly match.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The %[%r%r%] option requires 3 additional parameters:", file.stream, context.set.notable, f_console_symbol_long_enable_s, iki_read_long_wrap_s, context.set.notable);
- fl_print_format(" %[<%]%r%[>%]", file.stream, context.set.notable, context.set.notable, iki_read_substitution_vocabulary_s, context.set.notable, context.set.notable);
- fl_print_format(" %[<%]%r%[>%]", file.stream, context.set.notable, context.set.notable, iki_read_substitution_before_s, context.set.notable, context.set.notable);
- fl_print_format(" %[<%]%r%[>%].%r", file.stream, context.set.notable, context.set.notable, iki_read_substitution_after_s, context.set.notable, context.set.notable, f_string_eol_s);
-
- fl_print_format(" %[%r%]: The name of the vocabulary whose content is to be wrapped.%r", file.stream, context.set.notable, iki_read_substitution_vocabulary_s, context.set.notable, f_string_eol_s);
- fl_print_format(" %[%r%]: The string to prepend.%r", file.stream, context.set.notable, iki_read_substitution_before_s, context.set.notable, f_string_eol_s);
- fl_print_format(" %[%r%]: The string to append.%r%r", file.stream, context.set.notable, iki_read_substitution_after_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The vocabulary is case-sensitive and must exactly match.%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The difference between %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, iki_read_long_replace_s, context.set.notable);
- fl_print_format(" and %[%r%r%] is that the", file.stream, context.set.notable, f_console_symbol_long_enable_s, iki_read_long_substitute_s, context.set.notable);
- fl_print_format(" %[%r%r%] option substitutes all matching vocabulary names and the", file.stream, context.set.notable, f_console_symbol_long_enable_s, iki_read_long_replace_s, context.set.notable);
- fl_print_format(" %[%r%r%] option substitutes all matching vocabulary names that must also have the given matching content.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, iki_read_long_substitute_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, iki_read_long_substitute_s, context.set.notable);
- fl_print_format(" option takes priority over the %[%r%r%] option when matching the same variable.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, iki_read_long_replace_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The %[%r%r%]", file.stream, context.set.notable, f_console_symbol_long_enable_s, iki_read_long_wrap_s, context.set.notable);
- fl_print_format(" option is ignored when the %[%r%r%] option is matching the same variable.%r%r", file.stream, context.set.notable, f_console_symbol_long_enable_s, iki_read_long_substitute_s, context.set.notable, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" The default behavior is to only display content portion of the IKI variable.%r", file.stream, f_string_eol_s);
-
- //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- f_file_stream_flush(file);
- funlockfile(file.stream);
-
- return F_none;
- }
-#endif // _di_iki_read_print_help_
-
#ifndef _di_iki_read_main_
- f_status_t iki_read_main(fll_program_data_t * const main, const f_console_arguments_t arguments) {
+ f_status_t iki_read_main(fll_program_data_t * const main, iki_read_setting_t * const setting) {
f_status_t status = F_none;
status = F_none;
if (main->parameters.array[iki_read_parameter_help_e].result == f_console_result_found_e) {
- iki_read_print_help(main->output.to, main->context);
+ iki_read_print_help(setting, main->message);
iki_read_data_delete(&data);
}
if (main->parameters.array[iki_read_parameter_version_e].result == f_console_result_found_e) {
- fll_program_print_version(main->output.to, iki_read_program_version_s);
+ fll_program_print_version(main->message, iki_read_program_version_s);
iki_read_data_delete(&data);
if (!((++main->signal_check) % iki_read_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- iki_read_print_signal_received(&data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
// The signal check is always performed on each pass.
if (size_file > iki_read_block_max && fll_program_standard_signal_received(main)) {
- iki_read_print_signal_received(&data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
#endif
/**
- * Print help.
- *
- * @param file
- * The file to print to.
- * @param context
- * The color context settings.
- *
- * @return
- * F_none on success.
- */
-#ifndef _di_iki_read_print_help_
- extern f_status_t iki_read_print_help(const f_file_t file, const f_color_context_t context);
-#endif // _di_iki_read_print_help_
-
-/**
* Execute main program.
*
* If main.signal is non-zero, then this blocks and handles the following signals:
*
* @param main
* The main program data.
- * @param arguments
- * The parameters passed to the process.
+ * @param setting
+ * The main program settings.
*
- * @return
- * F_none on success.
+ * This alters setting.status:
+ * F_none on success.
+ * F_true on success when performing verification and verify passed.
+ * F_false on success when performing verification and verify failed.
+ * F_interrupt on (exit) signal received.
*
- * Status codes (with error bit) are returned on any problem.
+ * F_parameter (with error bit) if main is NULL or setting is NULL.
*/
#ifndef _di_iki_read_main_
- extern f_status_t iki_read_main(fll_program_data_t * const main, const f_console_arguments_t arguments);
+ extern f_status_t iki_read_main(fll_program_data_t * const main, iki_read_setting_t * const setting);
#endif // _di_iki_read_main_
#ifdef __cplusplus
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
fll_program_data_t data = fll_program_data_t_initialize;
+ iki_read_setting_t setting = iki_read_setting_t_initialize;
f_console_parameter_t parameters[] = iki_read_console_parameter_t_initialize;
data.parameters.array = parameters;
data.parameters.used = iki_read_total_parameters_d;
+ data.environment = envp;
if (f_pipe_input_exists()) {
data.pipe = fll_program_data_pipe_input_e;
fll_program_standard_set_up(&data);
- const f_status_t status = iki_read_main(&data, arguments);
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+
+ iki_read_setting_load(arguments, &data, &setting);
+ }
+
+ iki_read_main(&data, &setting);
+
+ iki_read_setting_unload(&data, &setting);
fll_program_data_delete(&data);
fll_program_standard_set_down(&data);
- if (F_status_is_error(status)) return 1;
-
- return 0;
+ return F_status_is_error(status) ? 1 : 0;
}
--- /dev/null
+#include "iki_read.h"
+#include "private-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_iki_read_print_help_
+ f_status_t iki_read_print_help(iki_read_setting_t * const setting, const fl_print_t print) {
+
+ f_file_stream_lock(print.to);
+
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+
+ fll_program_print_help_header(print, iki_read_program_name_long_s, iki_read_program_version_s);
+
+ fll_program_print_help_option_standard(print);
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, iki_read_short_at_s, iki_read_long_at_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select variable at this numeric index.");
+ fll_program_print_help_option(print, iki_read_short_line_s, iki_read_long_line_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print only the variables at the given line within the file.");
+ fll_program_print_help_option(print, iki_read_short_name_s, iki_read_long_name_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select variables with this name.");
+ fll_program_print_help_option(print, iki_read_short_whole_s, iki_read_long_whole_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print all of the data instead of just the IKI variable data.");
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, iki_read_short_content_s, iki_read_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print the variable value (aka: content) (default)");
+ fll_program_print_help_option(print, iki_read_short_literal_s, iki_read_long_literal_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print the entire variable (aka: object, content, and syntax).");
+ fll_program_print_help_option(print, iki_read_short_object_s, iki_read_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the variable name (aka: object).");
+ fll_program_print_help_option(print, iki_read_short_total_s, iki_read_long_total_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of variables.");
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, iki_read_short_replace_s, iki_read_long_replace_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Simple substitution, replacing the variable for the given name with the given string.");
+ fll_program_print_help_option(print, iki_read_short_substitute_s, iki_read_long_substitute_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Substitute the variable for the given name and matching content value with the given string.");
+ fll_program_print_help_option(print, iki_read_short_wrap_s, iki_read_long_wrap_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Prepend and append strings for the given name.");
+
+ fll_program_print_help_usage(print, iki_read_program_name_s, fll_program_parameter_filenames_s);
+
+ fl_print_format("%r %[Notes:%]%r", print.to.stream, f_string_eol_s, print.set->important, print.set->important, f_string_eol_s);
+ fl_print_format(" This program will find and print variables, vocabularies, or content following the IKI standard, without focusing on any particular vocabulary specification.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The %[%r%r%] option requires 2 additional parameters:", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, iki_read_long_replace_s, print.set->notable);
+ fl_print_format(" %[<%]%r%[>%]", print.to.stream, print.set->notable, print.set->notable, iki_read_substitution_vocabulary_s, print.set->notable, print.set->notable);
+ fl_print_format(" %[<%]%r%[>%].%r", print.to.stream, print.set->notable, print.set->notable, iki_read_substitution_with_s, print.set->notable, print.set->notable, f_string_eol_s);
+
+ fl_print_format(" %[%r%]: The name of the vocabulary whose content is to be substituted.%r", print.to.stream, print.set->notable, iki_read_substitution_vocabulary_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" %[%r%]: The new string to use as the substitute.%r%r", print.to.stream, print.set->notable, iki_read_substitution_with_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The vocabulary is case-sensitive and must exactly match.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The %[%r%r%] option requires 3 additional parameters:", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, iki_read_long_substitute_s, print.set->notable);
+ fl_print_format(" %[<%]%r%[>%]", print.to.stream, print.set->notable, print.set->notable, iki_read_substitution_vocabulary_s, print.set->notable, print.set->notable);
+ fl_print_format(" %[<%]%r%[>%]", print.to.stream, print.set->notable, print.set->notable, iki_read_substitution_replace_s, print.set->notable, print.set->notable);
+ fl_print_format(" %[<%]%r%[>%].%r", print.to.stream, print.set->notable, print.set->notable, iki_read_substitution_with_s, print.set->notable, print.set->notable, f_string_eol_s);
+
+ fl_print_format(" %[%r%]: The name of the vocabulary whose content is to be substituted.%r", print.to.stream, print.set->notable, iki_read_substitution_vocabulary_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" %[%r%]: The content matching this exact string will be substituted.%r", print.to.stream, print.set->notable, iki_read_substitution_replace_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" %[%r%]: The new string to use as the substitute.%r%r", print.to.stream, print.set->notable, iki_read_substitution_with_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The vocabulary and replacement are case-sensitive and must exactly match.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The %[%r%r%] option requires 3 additional parameters:", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, iki_read_long_wrap_s, print.set->notable);
+ fl_print_format(" %[<%]%r%[>%]", print.to.stream, print.set->notable, print.set->notable, iki_read_substitution_vocabulary_s, print.set->notable, print.set->notable);
+ fl_print_format(" %[<%]%r%[>%]", print.to.stream, print.set->notable, print.set->notable, iki_read_substitution_before_s, print.set->notable, print.set->notable);
+ fl_print_format(" %[<%]%r%[>%].%r", print.to.stream, print.set->notable, print.set->notable, iki_read_substitution_after_s, print.set->notable, print.set->notable, f_string_eol_s);
+
+ fl_print_format(" %[%r%]: The name of the vocabulary whose content is to be wrapped.%r", print.to.stream, print.set->notable, iki_read_substitution_vocabulary_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" %[%r%]: The string to prepend.%r", print.to.stream, print.set->notable, iki_read_substitution_before_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" %[%r%]: The string to append.%r%r", print.to.stream, print.set->notable, iki_read_substitution_after_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The vocabulary is case-sensitive and must exactly match.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The difference between %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, iki_read_long_replace_s, print.set->notable);
+ fl_print_format(" and %[%r%r%] is that the", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, iki_read_long_substitute_s, print.set->notable);
+ fl_print_format(" %[%r%r%] option substitutes all matching vocabulary names and the", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, iki_read_long_replace_s, print.set->notable);
+ fl_print_format(" %[%r%r%] option substitutes all matching vocabulary names that must also have the given matching content.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, iki_read_long_substitute_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, iki_read_long_substitute_s, print.set->notable);
+ fl_print_format(" option takes priority over the %[%r%r%] option when matching the same variable.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, iki_read_long_replace_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The %[%r%r%]", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, iki_read_long_wrap_s, print.set->notable);
+ fl_print_format(" option is ignored when the %[%r%r%] option is matching the same variable.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, iki_read_long_substitute_s, print.set->notable, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" The default behavior is to only display content portion of the IKI variable.%r", print.to.stream, f_string_eol_s);
+
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+
+ f_file_stream_flush(print.to);
+ f_file_stream_unlock(print.to);
+
+ return F_none;
+ }
+#endif // _di_iki_read_print_help_
+
+#ifndef _di_iki_read_print_line_first_
+ void iki_read_print_line_first(iki_read_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ }
+#endif // _di_iki_read_print_line_first_
+
+#ifndef _di_iki_read_print_line_last_
+ void iki_read_print_line_last(iki_read_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+ if (print.verbosity == f_console_verbosity_error_e && !F_status_is_error(setting->status)) return;
+ if (setting->flag & iki_read_main_flag_verify_e) return;
+ if ((setting->flag & iki_read_main_flag_file_to_e) && !F_status_is_error(setting->status)) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ }
+#endif // _di_iki_read_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: UTF-8
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _iki_read_print_h
+#define _iki_read_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print help.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * The output structure to print to.
+ *
+ * @return
+ * F_none on success.
+ */
+#ifndef _di_iki_read_print_help_
+ extern f_status_t iki_read_print_help(iki_read_setting_t * const setting, const fl_print_t print);
+#endif // _di_iki_read_print_help_
+
+/**
+ * Print first new line, unless verbosity says otherwise.
+ *
+ * This is generally either the first line in the program or the first line printed before an error message.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_iki_read_print_line_first_
+ extern void iki_read_print_line_first(iki_read_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_iki_read_print_line_first_
+
+/**
+ * Print last new line when the main is complete, unless verbosity says otherwise.
+ *
+ * This is generally the very last line printed in the program.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_iki_read_print_line_last_
+ extern void iki_read_print_line_last(iki_read_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_iki_read_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _iki_read_print_h
#endif
#ifndef _di_iki_read_data_delete_
- f_status_t iki_read_data_delete(iki_read_data_t * const data) {
+ f_status_t iki_read_data_delete(fll_program_data_t * const main, status_code_setting_t * const setting, iki_read_data_t * const data) {
f_string_dynamic_resize(0, &data->buffer);
}
#endif // _di_iki_read_data_delete_
-#ifndef _di_iki_read_print_signal_received_
- void iki_read_print_signal_received(iki_read_data_t * const data) {
-
- if (data->main->warning.verbosity != f_console_verbosity_verbose_e && data->main->warning.verbosity != f_console_verbosity_debug_e) return;
-
- // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
- fflush(data->main->warning.to.stream);
-
- flockfile(data->main->warning.to.stream);
-
- fl_print_format("%]%r%r%[Received signal code %]", data->main->warning.to.stream, data->main->context.set.reset, f_string_eol_s, f_string_eol_s, data->main->context.set.warning, data->main->context.set.warning);
- fl_print_format("%[%i%]", data->main->warning.to.stream, data->main->context.set.notable, data->main->signal_received, data->main->context.set.notable);
- fl_print_format("%[.%]%r", data->main->warning.to.stream, data->main->context.set.warning, data->main->context.set.warning, f_string_eol_s);
-
- funlockfile(data->main->warning.to.stream);
- }
-#endif // _di_iki_read_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
* F_none on success.
*/
#ifndef _di_iki_read_data_delete_
- extern f_status_t iki_read_data_delete(iki_read_data_t * const data) F_attribute_visibility_internal_d;
+ extern f_status_t iki_read_data_delete(fll_program_data_t * const main, status_code_setting_t * const setting, iki_read_data_t * const data) F_attribute_visibility_internal_d;
#endif // _di_iki_read_data_delete_
-/**
- * Print a message about a process signal being recieved, such as an interrupt signal.
- *
- * @param data
- * The program data.
- */
-#ifndef _di_iki_read_print_signal_received_
- extern void iki_read_print_signal_received(iki_read_data_t * const data) F_attribute_visibility_internal_d;
-#endif // _di_iki_read_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
#endif
#ifndef _di_iki_read_substitutions_print_
- void iki_read_substitutions_print(iki_read_data_t * const data, const f_iki_data_t iki_data, const f_string_ranges_t ranges, const iki_read_substitution_t replacement, const iki_read_substitution_t wraps, const iki_read_substitutions_t substitutions, const f_array_length_t index, const bool content_only) {
+ void iki_read_substitutions_print(fll_program_data_t * const main, status_code_setting_t * const setting, iki_read_data_t * const data, const f_iki_data_t iki_data, const f_string_ranges_t ranges, const iki_read_substitution_t replacement, const iki_read_substitution_t wraps, const iki_read_substitutions_t substitutions, const f_array_length_t index, const bool content_only) {
uint8_t matched = F_false;
f_array_length_t at = 0;
* Set to FALSE to print the entire variable when printing substituted text.
*/
#ifndef _di_iki_read_substitutions_print_
- extern void iki_read_substitutions_print(iki_read_data_t * const data, const f_iki_data_t iki_data, const f_string_ranges_t ranges, const iki_read_substitution_t replacement, const iki_read_substitution_t wraps, const iki_read_substitutions_t substitutions, const f_array_length_t index, const bool content_only) F_attribute_visibility_internal_d;
+ extern void iki_read_substitutions_print(fll_program_data_t * const main, status_code_setting_t * const setting, iki_read_data_t * const data, const f_iki_data_t iki_data, const f_string_ranges_t ranges, const iki_read_substitution_t replacement, const iki_read_substitution_t wraps, const iki_read_substitutions_t substitutions, const f_array_length_t index, const bool content_only) F_attribute_visibility_internal_d;
#endif // _di_iki_read_substitutions_print_
#ifdef __cplusplus
#endif
#ifndef _di_iki_read_process_at_
- f_status_t iki_read_process_at(iki_read_data_t * const data, f_string_range_t *range) {
+ f_status_t iki_read_process_at(fll_program_data_t * const main, status_code_setting_t * const setting, iki_read_data_t * const data, f_string_range_t *range) {
if (data->main->parameters.array[iki_read_parameter_line_e].result != f_console_result_additional_e) {
return F_false;
if (!((++data->main->signal_check) % iki_read_signal_check_d)) {
if (fll_program_standard_signal_received(data->main)) {
- iki_read_print_signal_received(data);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
f_string_dynamic_resize(0, &name);
* Status codes (with error bit) are returned on any problem.
*/
#ifndef _di_iki_read_process_at_
- extern f_status_t iki_read_process_at(iki_read_data_t * const data, f_string_range_t *range) F_attribute_visibility_internal_d;
+ extern f_status_t iki_read_process_at(fll_program_data_t * const main, status_code_setting_t * const setting, iki_read_data_t * const data, f_string_range_t *range) F_attribute_visibility_internal_d;
#endif // _di_iki_read_process_at_
/**
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library iki_read.c common.c private-common.c private-print.c private-read.c
+build_sources_library iki_read.c common.c print.c private-common.c private-print.c private-read.c
build_sources_program main.c
-build_sources_headers iki_read.h common.h
+build_sources_headers iki_read.h common.h print.h
build_script yes
build_shared yes
const f_string_static_t iki_write_long_single_s = macro_f_string_static_t_initialize(IKI_WRITE_long_single_s, 0, IKI_WRITE_long_single_s_length);
#endif // _di_iki_write_parameters_
+#ifndef _di_iki_write_setting_delete_
+ f_status_t iki_write_setting_delete(iki_write_setting_t * const setting) {
+
+ if (!setting) return F_status_set_error(F_parameter);
+
+ return F_none;
+ }
+#endif // _di_iki_write_setting_delete_
+
+#ifndef _di_iki_write_setting_load_
+ void iki_write_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, iki_write_setting_t * const setting) {
+
+ if (!main || !setting) return;
+
+ // Load parameters.
+ setting->status = f_console_parameter_process(arguments, &main->parameters);
+ if (F_status_is_error(setting->status)) return;
+
+ {
+ f_array_length_t choice = 0;
+ f_uint16s_t choices = f_uint16s_t_initialize;
+
+ // Identify and prioritize "color context" parameters.
+ {
+ uint16_t choices_array[3] = { iki_write_parameter_no_color_e, iki_write_parameter_light_e, iki_write_parameter_dark_e };
+ choices.array = choices_array;
+ choices.used = 3;
+
+ const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
+
+ setting->status = fll_program_parameter_process_context(choices, modes, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ iki_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_context", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[iki_write_parameter_line_first_no_e].result == f_console_result_found_e) {
+ setting->line_first = f_string_empty_s;
+ }
+ else {
+ setting->line_first = f_string_eol_s;
+ }
+
+ if (main->parameters.array[iki_write_parameter_line_last_no_e].result == f_console_result_found_e) {
+ setting->line_last = f_string_empty_s;
+ }
+ else {
+ setting->line_last = f_string_eol_s;
+ }
+
+ // Identify and prioritize "verbosity" parameters.
+ {
+ uint16_t choices_array[5] = { iki_write_parameter_verbosity_quiet_e, iki_write_parameter_verbosity_error_e, iki_write_parameter_verbosity_verbose_e, iki_write_parameter_verbosity_debug_e, iki_write_parameter_verbosity_normal_e };
+ choices.array = choices_array;
+ choices.used = 5;
+
+ const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+
+ setting->status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ iki_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_verbosity", F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[iki_write_parameter_help_e].result == f_console_result_found_e) {
+ setting->flag |= iki_write_main_flag_help_e;
+
+ return;
+ }
+
+ if (main->parameters.array[iki_write_parameter_version_e].result == f_console_result_found_e) {
+ setting->flag |= iki_write_main_flag_version_e;
+
+ return;
+ }
+
+ // Identify and prioritize "from" mode parameters.
+ {
+ uint16_t choices_array[2] = { iki_write_parameter_from_bytesequence_e, iki_write_parameter_from_codepoint_e };
+ choices.array = choices_array;
+ choices.used = 2;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ iki_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == iki_write_parameter_from_bytesequence_e) {
+ if (setting->mode & iki_write_mode_from_codepoint_e) {
+ setting->mode -= iki_write_mode_from_codepoint_e;
+ }
+
+ setting->mode |= iki_write_mode_from_bytesequence_e;
+ }
+ else if (choices.array[choice] == iki_write_parameter_from_codepoint_e) {
+ if (setting->mode & iki_write_mode_from_bytesequence_e) {
+ setting->mode -= iki_write_mode_from_bytesequence_e;
+ }
+
+ setting->mode |= iki_write_mode_from_codepoint_e;
+ }
+ }
+
+ // Identify and prioritize "to" mode parameters.
+ {
+ uint16_t choices_array[4] = { iki_write_parameter_to_bytesequence_e, iki_write_parameter_to_codepoint_e, iki_write_parameter_to_combining_e, iki_write_parameter_to_width_e };
+ choices.array = choices_array;
+ choices.used = 4;
+ choice = 1;
+
+ setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
+
+ if (F_status_is_error(setting->status)) {
+ iki_write_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+
+ return;
+ }
+
+ if (choices.array[choice] == iki_write_parameter_to_bytesequence_e) {
+ if (setting->mode & iki_write_mode_to_codepoint_e) {
+ setting->mode -= iki_write_mode_to_codepoint_e;
+ }
+
+ if (setting->mode & iki_write_mode_to_combining_e) {
+ setting->mode -= iki_write_mode_to_combining_e;
+ }
+
+ if (setting->mode & iki_write_mode_to_width_e) {
+ setting->mode -= iki_write_mode_to_width_e;
+ }
+
+ setting->mode |= iki_write_mode_to_bytesequence_e;
+ }
+ else if (choices.array[choice] == iki_write_parameter_to_codepoint_e) {
+ if (setting->mode & iki_write_mode_to_bytesequence_e) {
+ setting->mode -= iki_write_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & iki_write_mode_to_combining_e) {
+ setting->mode -= iki_write_mode_to_combining_e;
+ }
+
+ if (setting->mode & iki_write_mode_to_width_e) {
+ setting->mode -= iki_write_mode_to_width_e;
+ }
+
+ setting->mode |= iki_write_mode_to_codepoint_e;
+ }
+ else if (choices.array[choice] == iki_write_parameter_to_combining_e) {
+ if (setting->mode & iki_write_mode_to_bytesequence_e) {
+ setting->mode -= iki_write_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & iki_write_mode_to_codepoint_e) {
+ setting->mode -= iki_write_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[iki_write_parameter_to_width_e].result == f_console_result_found_e) {
+ setting->mode |= iki_write_mode_to_width_e;
+ }
+
+ setting->mode |= iki_write_mode_to_combining_e;
+ }
+ else if (choices.array[choice] == iki_write_parameter_to_width_e) {
+ if (setting->mode & iki_write_mode_to_bytesequence_e) {
+ setting->mode -= iki_write_mode_to_bytesequence_e;
+ }
+
+ if (setting->mode & iki_write_mode_to_codepoint_e) {
+ setting->mode -= iki_write_mode_to_codepoint_e;
+ }
+
+ // --to_width may be specified with --to_combining.
+ if (main->parameters.array[iki_write_parameter_to_combining_e].result == f_console_result_found_e) {
+ setting->mode |= iki_write_mode_to_combining_e;
+ }
+
+ setting->mode |= iki_write_mode_to_width_e;
+ }
+ }
+ }
+
+ f_string_static_t * const args = main->parameters.arguments.array;
+
+ if (main->parameters.array[iki_write_parameter_to_file_e].result == f_console_result_additional_e) {
+ if (main->parameters.array[iki_write_parameter_to_file_e].values.used > 1) {
+ iki_write_print_error_parameter_file_to_too_many(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+
+ if (args[main->parameters.array[iki_write_parameter_to_file_e].values.array[0]].used) {
+ setting->path_files_to.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(1, &setting->path_files_to);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_to.array[setting->path_files_to.used].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[main->parameters.array[iki_write_parameter_to_file_e].values.array[0]], &setting->path_files_to.array[0]);
+ if (F_status_is_error(setting->status)) return;
+
+ ++setting->path_files_to.used;
+
+ setting->status = f_file_stream_open(args[main->parameters.array[iki_write_parameter_to_file_e].values.array[0]], f_file_open_mode_append_s, &main->output.to);
+
+ if (F_status_is_error(setting->status)) {
+ fll_error_file_print(main->error, F_status_set_fine(setting->status), "f_file_stream_open", F_true, args[main->parameters.array[iki_write_parameter_to_file_e].values.array[0]], f_file_operation_open_s, fll_error_file_type_file_e);
+
+ return;
+ }
+
+ setting->flag |= iki_write_main_flag_file_to_e;
+ }
+ else {
+ iki_write_print_error_parameter_file_name_empty(main, setting, main->parameters.array[iki_write_parameter_to_file_e].values.array[0]);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+ else if (main->parameters.array[iki_write_parameter_to_file_e].result == f_console_result_found_e) {
+ iki_write_print_error_no_value(main, setting, iki_write_long_to_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ main->output.to = main->message.to;
+
+ if (setting->flag & iki_write_main_flag_file_to_e) {
+ setting->flag -= iki_write_main_flag_file_to_e;
+ }
+ }
+
+ if (main->parameters.array[iki_write_parameter_from_file_e].result == f_console_result_additional_e) {
+ setting->path_files_from.used = 0;
+
+ setting->status = f_string_dynamics_increase_by(main->parameters.array[iki_write_parameter_from_file_e].values.used, &setting->path_files_from);
+ if (F_status_is_error(setting->status)) return;
+
+ setting->path_files_from.used = main->parameters.array[iki_write_parameter_from_file_e].values.used;
+
+ f_array_length_t i = 0;
+ f_array_length_t index = 0;
+
+ for (; i < setting->path_files_from.used; ++i) {
+
+ index = main->parameters.array[iki_write_parameter_from_file_e].values.array[i];
+ setting->path_files_from.array[i].used = 0;
+
+ setting->status = f_string_dynamic_append_nulless(main->parameters.arguments.array[index], &setting->path_files_from.array[i]);
+ if (F_status_is_error(setting->status)) return;
+
+ if (args[index].used) {
+ if (f_file_exists(args[index], F_true) != F_true) {
+ iki_write_print_error_parameter_file_not_found(main, setting, F_true, args[index]);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_file_found_not);
+ }
+ }
+ }
+ else {
+ iki_write_print_error_parameter_file_name_empty(main, setting, index);
+
+ if (F_status_is_error_not(setting->status)) {
+ setting->status = F_status_set_error(F_parameter);
+ }
+ }
+ } // for
+
+ if (F_status_is_error(setting->status)) return;
+
+ setting->flag |= iki_write_main_flag_file_from_e;
+ }
+ else if (main->parameters.array[iki_write_parameter_from_file_e].result == f_console_result_found_e) {
+ iki_write_print_error_no_value(main, setting, iki_write_long_from_file_s);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ else {
+ if (setting->flag & iki_write_main_flag_file_from_e) {
+ setting->flag -= iki_write_main_flag_file_from_e;
+ }
+ }
+
+ if (F_status_is_error(setting->status)) return;
+
+ if (main->parameters.array[iki_write_parameter_from_file_e].result == f_console_result_none_e && !((main->pipe & fll_program_data_pipe_input_e) || main->parameters.remaining.used)) {
+ iki_write_print_error_no_from(main, setting);
+
+ setting->status = F_status_set_error(F_parameter);
+ }
+
+ if (!(setting->mode & iki_write_mode_to_bytesequence_e)) {
+ if (main->parameters.array[iki_write_parameter_separate_e].result == f_console_result_found_e || main->parameters.array[iki_write_parameter_headers_e].result == f_console_result_found_e) {
+ setting->prepend = iki_write_string_prepend_padding_s;
+ setting->append = f_string_eol_s;
+ }
+ else {
+ setting->prepend = f_string_space_s;
+ }
+ }
+
+ if (main->parameters.array[iki_write_parameter_headers_e].result == f_console_result_found_e) {
+ setting->flag |= iki_write_main_flag_header_e;
+ }
+
+ if (main->parameters.array[iki_write_parameter_separate_e].result == f_console_result_found_e) {
+ setting->flag |= iki_write_main_flag_separate_e;
+ }
+
+ if (main->parameters.array[iki_write_parameter_strip_invalid_e].result == f_console_result_found_e) {
+ setting->flag |= iki_write_main_flag_strip_invalid_e;
+ }
+
+ setting->valid_not = main->message.set->error;
+ }
+#endif // _di_iki_write_setting_load_
+
+#ifndef _di_iki_write_setting_unload_
+ f_status_t iki_write_setting_unload(fll_program_data_t * const main, iki_write_setting_t * const setting) {
+
+ if (!main || !setting) return F_status_set_error(F_parameter);
+
+ iki_write_setting_delete(setting);
+
+ return F_none;
+ }
+#endif // _di_iki_write_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
#define iki_write_total_parameters_d 17
#endif // _di_iki_write_parameters_
+/**
+ * Flags used to represent flags passed to the main function.
+ *
+ * iki_write_main_flag_*_e:
+ * - none: No modes in use.
+ * - file_from: Using a specified source file.
+ * - file_to: Using a specified destination file.
+ * - help: Print help.
+ * - header: Enable printing of headers.
+ * - separate: Enable printing of separators.
+ * - strip_invalid: Using strip invalid character mode.
+ * - verify: Using verify mode.
+ * - version: Print version.
+ */
+#ifndef _di_iki_write_main_flag_e_
+ enum {
+ iki_write_main_flag_none_e = 0x0,
+ iki_write_main_flag_file_from_e = 0x1,
+ iki_write_main_flag_file_to_e = 0x2,
+ iki_write_main_flag_header_e = 0x4,
+ iki_write_main_flag_help_e = 0x8,
+ iki_write_main_flag_separate_e = 0x10,
+ iki_write_main_flag_strip_invalid_e = 0x20,
+ iki_write_main_flag_verify_e = 0x40,
+ iki_write_main_flag_version_e = 0x80,
+ };
+#endif // _di_iki_write_main_flag_e_
+
+/**
+ * The iki write main program settings.
+ *
+ * This is passed to the program-specific main entry point to designate program settings.
+ * These program settings are often processed from the program arguments (often called the command line arguments).
+ *
+ * flag: Flags passed to the main function.
+ *
+ * status: The main status code, generally used by the load settings and main functions.
+ *
+ * line_first: A string expected to represent either "\n" or NULL to allow for easy handling of when to print first new line or not.
+ * line_last: A string expected to represent either "\n" or NULL to allow for easy handling of when to print last new line or not.
+ */
+#ifndef _di_iki_write_setting_t_
+ typedef struct {
+ uint16_t flag;
+
+ f_status_t status;
+
+ f_string_static_t line_first;
+ f_string_static_t line_last;
+ } iki_write_setting_t;
+
+ #define iki_write_setting_t_initialize \
+ { \
+ iki_write_main_flag_none_e, \
+ F_none, \
+ f_string_static_t_initialize, \
+ f_string_static_t_initialize, \
+ }
+#endif // _di_iki_write_setting_t_
+
+/**
+ * Delete the program main setting data.
+ *
+ * @param setting
+ * The program main setting data.
+ * This does not alter setting.status.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_iki_write_setting_delete_
+ extern f_status_t iki_write_setting_delete(iki_write_setting_t * const setting);
+#endif // _di_iki_write_setting_delete_
+
+/**
+ * Perform the standard program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately retuns without doing anything.
+ *
+ * @param arguments
+ * The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ *
+ * This alters setting.status:
+ * F_none on success.
+ *
+ * Errors (with error bit) from: f_console_parameter_process().
+ * Errors (with error bit) from: fll_program_parameter_process_context().
+ *
+ * @see f_console_parameter_process()
+ * @see fll_program_parameter_process_context()
+ */
+#ifndef _di_iki_write_setting_load_
+ extern void iki_write_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, iki_write_setting_t * const setting);
+#endif // _di_iki_write_setting_load_
+
+/**
+ * Perform the standard program setting unload process.
+ *
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * All buffers are deallocated.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: utf8_setting_delete().
+ *
+ * @see utf8_setting_delete()
+ */
+#ifndef _di_iki_write_setting_unload_
+ extern f_status_t iki_write_setting_unload(fll_program_data_t * const main, iki_write_setting_t * const setting);
+#endif // _di_iki_write_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
extern "C" {
#endif
-#ifndef _di_iki_write_print_help_
- f_status_t iki_write_print_help(const f_file_t file, const f_color_context_t context) {
-
- flockfile(file.stream);
-
- //if (!(setting->flag & XXX_main_flag_line_first_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- fll_program_print_help_header(file, context, iki_write_program_name_long_s, iki_write_program_version_s);
-
- fll_program_print_help_option(file, context, f_console_standard_short_help_s, f_console_standard_long_help_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print this help message.");
- fll_program_print_help_option(file, context, f_console_standard_short_dark_s, f_console_standard_long_dark_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Output using colors that show up better on dark backgrounds.");
- fll_program_print_help_option(file, context, f_console_standard_short_light_s, f_console_standard_long_light_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Output using colors that show up better on light backgrounds.");
- fll_program_print_help_option(file, context, f_console_standard_short_no_color_s, f_console_standard_long_no_color_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, "Do not print using color.");
- fll_program_print_help_option(file, context, f_console_standard_short_quiet_s, f_console_standard_long_quiet_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Decrease verbosity, silencing most output.");
- fll_program_print_help_option(file, context, f_console_standard_short_error_s, f_console_standard_long_error_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Decrease verbosity, using only error output.");
- fll_program_print_help_option(file, context, f_console_standard_short_normal_s, f_console_standard_long_normal_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Set verbosity to normal.");
- fll_program_print_help_option(file, context, f_console_standard_short_verbose_s, f_console_standard_long_verbose_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Increase verbosity beyond normal output.");
- fll_program_print_help_option(file, context, f_console_standard_short_debug_s, f_console_standard_long_debug_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Enable debugging, significantly increasing verbosity beyond normal output.");
- fll_program_print_help_option(file, context, f_console_standard_short_version_s, f_console_standard_long_version_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Print only the version number.");
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, iki_write_short_file_s, iki_write_long_file_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a file to send data to.");
- fll_program_print_help_option(file, context, iki_write_short_content_s, iki_write_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "The Content to write.");
- fll_program_print_help_option(file, context, iki_write_short_double_s, iki_write_long_double_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use double quotes (default).");
- fll_program_print_help_option(file, context, iki_write_short_object_s, iki_write_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The Object to write.");
- fll_program_print_help_option(file, context, iki_write_short_single_s, iki_write_long_single_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use single quotes.");
-
- fll_program_print_help_usage(file, context, iki_write_program_name_s, f_string_empty_s);
-
- fl_print_format("%r %[Notes:%]%r", file.stream, f_string_eol_s, context.set.important, context.set.important, f_string_eol_s);
- fl_print_format(" This program will accept Object and Content strings to generate an IKI string, such as %[object:\"content\"%].%r", file.stream, context.set.notable, context.set.notable, f_string_eol_s);
-
- fl_print_format(" Each object must have a Content (and each Content must have an Object).%r%r", file.stream, f_string_eol_s, f_string_eol_s);
-
- fl_print_format(" When piping main to this program, a single form-feed character (\\f) must be used to separate each Object from each Content.%r", file.stream, f_string_eol_s);
- fl_print_format(" Furthermore, each Object must be followed by a Content.%r", file.stream, f_string_eol_s);
-
- //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- f_file_stream_flush(file);
- funlockfile(file.stream);
-
- return F_none;
- }
-#endif // _di_iki_write_print_help_
-
#ifndef _di_iki_write_main_
- f_status_t iki_write_main(fll_program_data_t * const main, const f_console_arguments_t arguments) {
+ f_status_t iki_write_main(fll_program_data_t * const main, iki_write_setting_t * const setting) {
f_status_t status = F_none;
status = F_none;
if (main->parameters.array[iki_write_parameter_help_e].result == f_console_result_found_e) {
- iki_write_print_help(main->output.to, main->context);
+ iki_write_print_help(setting, main->message);
iki_write_data_delete(&data);
}
if (main->parameters.array[iki_write_parameter_version_e].result == f_console_result_found_e) {
- fll_program_print_version(main->output.to, iki_write_program_version_s);
+ fll_program_print_version(main->message, iki_write_program_version_s);
iki_write_data_delete(&data);
}
if (main->parameters.array[iki_write_parameter_file_e].result == f_console_result_additional_e) {
- f_file_stream_flush(file);
+ f_file_stream_flush(output);
f_file_stream_close(&file);
}
#endif
/**
- * Print help.
- *
- * @param file
- * The file to print to.
- * @param context
- * The color context settings.
- *
- * @return
- * F_none on success.
- */
-#ifndef _di_iki_write_print_help_
- extern f_status_t iki_write_print_help(const f_file_t file, const f_color_context_t context);
-#endif // _di_iki_write_print_help_
-
-/**
* Execute main program.
*
* If main.signal is non-zero, then this blocks and handles the following signals:
*
* @param main
* The main program data.
- * @param arguments
- * The parameters passed to the process.
+ * @param setting
+ * The main program settings.
*
- * @return
- * F_none on success.
+ * This alters setting.status:
+ * F_none on success.
+ * F_true on success when performing verification and verify passed.
+ * F_false on success when performing verification and verify failed.
+ * F_interrupt on (exit) signal received.
*
- * Status codes (with error bit) are returned on any problem.
+ * F_parameter (with error bit) if main is NULL or setting is NULL.
*/
#ifndef _di_iki_write_main_
- extern f_status_t iki_write_main(fll_program_data_t * const main, const f_console_arguments_t arguments);
+ extern f_status_t iki_write_main(fll_program_data_t * const main, iki_write_setting_t * const setting);
#endif // _di_iki_write_main_
#ifdef __cplusplus
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
fll_program_data_t data = fll_program_data_t_initialize;
+ iki_write_setting_t setting = iki_write_setting_t_initialize;
f_console_parameter_t parameters[] = iki_write_console_parameter_t_initialize;
data.parameters.array = parameters;
data.parameters.used = iki_write_total_parameters_d;
+ data.environment = envp;
if (f_pipe_input_exists()) {
data.pipe = fll_program_data_pipe_input_e;
fll_program_standard_set_up(&data);
- const f_status_t status = iki_write_main(&data, arguments);
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+
+ iki_write_setting_load(arguments, &data, &setting);
+ }
+
+ iki_write_main(&data, &setting);
+
+ iki_write_setting_unload(&data, &setting);
fll_program_data_delete(&data);
fll_program_standard_set_down(&data);
- if (F_status_is_error(status)) return 1;
-
- return 0;
+ return F_status_is_error(status) ? 1 : 0;
}
--- /dev/null
+#include "iki_write.h"
+#include "private-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_iki_write_print_help_
+ f_status_t iki_write_print_help(iki_write_setting_t * const setting, const fl_print_t print) {
+
+ f_file_stream_lock(print.to);
+
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+
+ fll_program_print_help_header(print, iki_write_program_name_long_s, iki_write_program_version_s);
+
+ fll_program_print_help_option(print, f_console_standard_short_help_s, f_console_standard_long_help_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print this help message.");
+ fll_program_print_help_option(print, f_console_standard_short_dark_s, f_console_standard_long_dark_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Output using colors that show up better on dark backgrounds.");
+ fll_program_print_help_option(print, f_console_standard_short_light_s, f_console_standard_long_light_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Output using colors that show up better on light backgrounds.");
+ fll_program_print_help_option(print, f_console_standard_short_no_color_s, f_console_standard_long_no_color_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, "Do not print using color.");
+ fll_program_print_help_option(print, f_console_standard_short_quiet_s, f_console_standard_long_quiet_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Decrease verbosity, silencing most output.");
+ fll_program_print_help_option(print, f_console_standard_short_error_s, f_console_standard_long_error_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Decrease verbosity, using only error output.");
+ fll_program_print_help_option(print, f_console_standard_short_normal_s, f_console_standard_long_normal_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Set verbosity to normal.");
+ fll_program_print_help_option(print, f_console_standard_short_verbose_s, f_console_standard_long_verbose_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Increase verbosity beyond normal output.");
+ fll_program_print_help_option(print, f_console_standard_short_debug_s, f_console_standard_long_debug_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Enable debugging, significantly increasing verbosity beyond normal output.");
+ fll_program_print_help_option(print, f_console_standard_short_version_s, f_console_standard_long_version_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Print only the version number.");
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, iki_write_short_file_s, iki_write_long_file_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a file to send data to.");
+ fll_program_print_help_option(print, iki_write_short_content_s, iki_write_long_content_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "The Content to write.");
+ fll_program_print_help_option(print, iki_write_short_double_s, iki_write_long_double_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use double quotes (default).");
+ fll_program_print_help_option(print, iki_write_short_object_s, iki_write_long_object_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The Object to write.");
+ fll_program_print_help_option(print, iki_write_short_single_s, iki_write_long_single_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use single quotes.");
+
+ fll_program_print_help_usage(print, iki_write_program_name_s, f_string_empty_s);
+
+ fl_print_format("%r %[Notes:%]%r", print.to.stream, f_string_eol_s, print.set->important, print.set->important, f_string_eol_s);
+ fl_print_format(" This program will accept Object and Content strings to generate an IKI string, such as %[object:\"content\"%].%r", print.to.stream, print.set->notable, print.set->notable, f_string_eol_s);
+
+ fl_print_format(" Each object must have a Content (and each Content must have an Object).%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
+
+ fl_print_format(" When piping main to this program, a single form-feed character (\\f) must be used to separate each Object from each Content.%r", print.to.stream, f_string_eol_s);
+ fl_print_format(" Furthermore, each Object must be followed by a Content.%r", print.to.stream, f_string_eol_s);
+
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+
+ f_file_stream_flush(print.to);
+ f_file_stream_unlock(print.to);
+
+ return F_none;
+ }
+#endif // _di_iki_write_print_help_
+
+#ifndef _di_iki_write_print_line_first_
+ void iki_write_print_line_first(iki_write_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ }
+#endif // _di_iki_write_print_line_first_
+
+#ifndef _di_iki_write_print_line_last_
+ void iki_write_print_line_last(iki_write_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+ if (print.verbosity == f_console_verbosity_error_e && !F_status_is_error(setting->status)) return;
+ if (setting->flag & iki_write_main_flag_verify_e) return;
+ if ((setting->flag & iki_write_main_flag_file_to_e) && !F_status_is_error(setting->status)) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ }
+#endif // _di_iki_write_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: UTF-8
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _iki_write_print_h
+#define _iki_write_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print help.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * The output structure to print to.
+ *
+ * @return
+ * F_none on success.
+ */
+#ifndef _di_iki_write_print_help_
+ extern f_status_t iki_write_print_help(iki_write_setting_t * const setting, const fl_print_t print);
+#endif // _di_iki_write_print_help_
+
+/**
+ * Print first new line, unless verbosity says otherwise.
+ *
+ * This is generally either the first line in the program or the first line printed before an error message.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_iki_write_print_line_first_
+ extern void iki_write_print_line_first(iki_write_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_iki_write_print_line_first_
+
+/**
+ * Print last new line when the main is complete, unless verbosity says otherwise.
+ *
+ * This is generally the very last line printed in the program.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_iki_write_print_line_last_
+ extern void iki_write_print_line_last(iki_write_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_iki_write_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _iki_write_print_h
}
#endif // _di_iki_write_data_delete_
-#ifndef _di_iki_write_print_signal_received_
- void iki_write_print_signal_received(iki_write_data_t * const data) {
-
- if (data->main->warning.verbosity != f_console_verbosity_verbose_e && data->main->warning.verbosity != f_console_verbosity_debug_e) return;
-
- // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
- fflush(data->main->warning.to.stream);
-
- flockfile(data->main->warning.to.stream);
-
- fl_print_format("%]%r%r%[Received signal code %]", data->main->warning.to.stream, data->main->context.set.reset, f_string_eol_s, f_string_eol_s, data->main->context.set.warning, data->main->context.set.warning);
- fl_print_format("%[%i%]", data->main->warning.to.stream, data->main->context.set.notable, data->main->signal, data->main->context.set.notable);
- fl_print_format("%[.%]%r", data->main->warning.to.stream, data->main->context.set.warning, data->main->context.set.warning, f_string_eol_s);
-
- funlockfile(data->main->warning.to.stream);
- }
-#endif // _di_iki_write_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
extern void iki_write_data_delete(iki_write_data_t *data) F_attribute_visibility_internal_d;
#endif // _di_iki_write_data_delete_
-/**
- * Print a message about a process signal being recieved, such as an interrupt signal.
- *
- * @param data
- * The program data.
- */
-#ifndef _di_iki_write_print_signal_received_
- extern void iki_write_print_signal_received(iki_write_data_t * const data) F_attribute_visibility_internal_d;
-#endif // _di_iki_write_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
#endif
#ifndef _di_iki_write_process_
- f_status_t iki_write_process(iki_write_data_t * const data, const f_file_t output, const f_string_static_t object, const f_string_static_t content, f_string_dynamic_t *escaped) {
+ f_status_t iki_write_process(fll_program_data_t * const main, status_code_setting_t * const setting, iki_write_data_t * const data, const f_file_t output, const f_string_static_t object, const f_string_static_t content, f_string_dynamic_t *escaped) {
if (!object.used) {
if (data->main->error.verbosity != f_console_verbosity_quiet_e) {
* F_failure (with error bit) for any othe failure.
*/
#ifndef _di_iki_write_process_
- extern f_status_t iki_write_process(iki_write_data_t * const data, const f_file_t output, const f_string_static_t object, const f_string_static_t content, f_string_dynamic_t *escaped) F_attribute_visibility_internal_d;
+ extern f_status_t iki_write_process(fll_program_data_t * const main, status_code_setting_t * const setting, iki_write_data_t * const data, const f_file_t output, const f_string_static_t object, const f_string_static_t content, f_string_dynamic_t *escaped) F_attribute_visibility_internal_d;
#endif // _di_iki_write_process_
#ifdef __cplusplus
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library iki_write.c common.c private-common.c private-write.c
+build_sources_library iki_write.c common.c print.c private-common.c private-write.c
build_sources_program main.c
-build_sources_headers iki_write.h common.h
+build_sources_headers iki_write.h common.h print.h
build_script yes
build_shared yes
const f_string_static_t status_code_program_help_parameters_s = macro_f_string_static_t_initialize(STATUS_CODE_program_help_parameters_s, 0, STATUS_CODE_program_help_parameters_s_length);
#endif // _di_status_code_program_help_parameters_
+#ifndef _di_status_code_strings_
+ const f_string_static_t status_code_failed_to_convert_s = macro_f_string_static_t_initialize(STATUS_CODE_failed_to_convert_s, 0, STATUS_CODE_failed_to_convert_s_length);
+ const f_string_static_t status_code_invalid_number_s = macro_f_string_static_t_initialize(STATUS_CODE_invalid_number_s, 0, STATUS_CODE_invalid_number_s_length);
+ const f_string_static_t status_code_invalid_name_s = macro_f_string_static_t_initialize(STATUS_CODE_invalid_number_s, 0, STATUS_CODE_invalid_number_s_length);
+ const f_string_static_t status_code_invalid_main_s = macro_f_string_static_t_initialize(STATUS_CODE_invalid_main_s, 0, STATUS_CODE_invalid_main_s_length);
+ const f_string_static_t status_code_out_of_range_s = macro_f_string_static_t_initialize(STATUS_CODE_out_of_range_s, 0, STATUS_CODE_out_of_range_s_length);
+ const f_string_static_t status_code_unknown_code_s = macro_f_string_static_t_initialize(STATUS_CODE_unknown_code_s, 0, STATUS_CODE_unknown_code_s_length);
+ const f_string_static_t status_code_unknown_name_s = macro_f_string_static_t_initialize(STATUS_CODE_unknown_name_s, 0, STATUS_CODE_unknown_name_s_length);
+#endif // _di_status_code_strings_
+
#ifndef _di_status_code_parameters_
const f_string_static_t status_code_short_fine_s = macro_f_string_static_t_initialize(STATUS_CODE_short_fine_s, 0, STATUS_CODE_short_fine_s_length);
const f_string_static_t status_code_short_warning_s = macro_f_string_static_t_initialize(STATUS_CODE_short_warning_s, 0, STATUS_CODE_short_warning_s_length);
const f_string_static_t status_code_long_number_s = macro_f_string_static_t_initialize(STATUS_CODE_long_number_s, 0, STATUS_CODE_long_number_s_length);
#endif // _di_status_code_parameters_
+#ifndef _di_status_code_setting_delete_
+ f_status_t status_code_setting_delete(status_code_setting_t * const setting) {
+
+ if (!setting) return F_status_set_error(F_parameter);
+
+ return F_none;
+ }
+#endif // _di_status_code_setting_delete_
+
+#ifndef _di_status_code_setting_load_
+ void status_code_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, status_code_setting_t * const setting) {
+
+ if (!main || !setting) return;
+
+ // Load parameters.
+ setting->status = f_console_parameter_process(arguments, &main->parameters);
+ if (F_status_is_error(setting->status)) return;
+
+ {
+ f_array_length_t choice = 0;
+ f_uint16s_t choices = f_uint16s_t_initialize;
+
+ // Identify and prioritize "color context" parameters.
+ {
+ uint16_t choices_array[3] = { status_code_parameter_no_color_e, status_code_parameter_light_e, status_code_parameter_dark_e };
+ choices.array = choices_array;
+ choices.used = 3;
+
+ const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
+
+ setting->status = fll_program_parameter_process_context(choices, modes, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ status_code_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_context", F_true);
+ status_code_print_line_last(setting, main->error, F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[status_code_parameter_line_first_no_e].result == f_console_result_found_e) {
+ setting->line_first = f_string_empty_s;
+ }
+ else {
+ setting->line_first = f_string_eol_s;
+ }
+
+ if (main->parameters.array[status_code_parameter_line_last_no_e].result == f_console_result_found_e) {
+ setting->line_last = f_string_empty_s;
+ }
+ else {
+ setting->line_last = f_string_eol_s;
+ }
+
+ // Identify and prioritize "verbosity" parameters.
+ {
+ uint16_t choices_array[5] = { status_code_parameter_verbosity_quiet_e, status_code_parameter_verbosity_error_e, status_code_parameter_verbosity_verbose_e, status_code_parameter_verbosity_debug_e, status_code_parameter_verbosity_normal_e };
+ choices.array = choices_array;
+ choices.used = 5;
+
+ const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+
+ setting->status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
+
+ if (F_status_is_error(setting->status)) {
+ status_code_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_verbosity", F_true);
+ status_code_print_line_last(setting, main->error, F_true);
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[status_code_parameter_help_e].result == f_console_result_found_e) {
+ setting->flag |= status_code_main_flag_help_e;
+
+ return;
+ }
+
+ if (main->parameters.array[status_code_parameter_version_e].result == f_console_result_found_e) {
+ setting->flag |= status_code_main_flag_version_e;
+
+ return;
+ }
+ }
+
+ if (main->parameters.array[status_code_parameter_error_e].result == f_console_result_found_e) {
+ setting->flag |= status_code_main_flag_error_e;
+ }
+
+ if (main->parameters.array[status_code_parameter_fine_e].result == f_console_result_found_e) {
+ setting->flag |= status_code_main_flag_fine_e;
+ }
+
+ if (main->parameters.array[status_code_parameter_warning_e].result == f_console_result_found_e) {
+ setting->flag |= status_code_main_flag_warning_e;
+ }
+
+ if (main->parameters.array[status_code_parameter_number_e].result == f_console_result_found_e) {
+ setting->flag |= status_code_main_flag_number_e;
+ }
+
+ if (setting->flag & status_code_main_flag_error_e) {
+ if (setting->flag & status_code_main_flag_warning_e) {
+ if (!(setting->flag & status_code_main_flag_number_e)) {
+ status_code_print_line_first(setting, main->error, F_true);
+ status_code_print_error_cannot_error_warning_number(setting, main->error);
+ status_code_print_line_last(setting, main->error, F_true);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+
+ if (setting->flag & status_code_main_flag_fine_e) {
+ status_code_print_line_first(setting, main->error, F_true);
+ fll_program_parameter_long_print_cannot_use_with(main->error, status_code_long_error_s, status_code_long_fine_s);
+ status_code_print_line_last(setting, main->error, F_true);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+ else if (setting->flag & status_code_main_flag_warning_e && setting->flag & status_code_main_flag_fine_e) {
+ status_code_print_line_first(setting, main->error, F_true);
+ fll_program_parameter_long_print_cannot_use_with(main->error, status_code_long_warning_s, status_code_long_fine_s);
+ status_code_print_line_last(setting, main->error, F_true);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+
+ if (main->parameters.remaining.used == 0 && !(main->pipe & fll_program_data_pipe_input_e)) {
+ status_code_print_line_first(setting, main->error, F_true);
+ status_code_print_error_no_status_codes(setting, main->error);
+ status_code_print_line_last(setting, main->error, F_true);
+
+ setting->status = F_status_set_error(F_parameter);
+
+ return;
+ }
+ }
+#endif // _di_status_code_setting_load_
+
+#ifndef _di_status_code_setting_unload_
+ f_status_t status_code_setting_unload(fll_program_data_t * const main, status_code_setting_t * const setting) {
+
+ if (!main || !setting) return F_status_set_error(F_parameter);
+
+ status_code_setting_delete(setting);
+
+ return F_none;
+ }
+#endif // _di_status_code_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
#endif // _di_status_code_program_help_parameters_
/**
+ * Special strings used by this program.
+ */
+#ifndef _di_status_code_strings_
+ #define STATUS_CODE_failed_to_convert_s "failed to convert"
+ #define STATUS_CODE_invalid_number_s "invalid number"
+ #define STATUS_CODE_invalid_name_s "invalid name"
+ #define STATUS_CODE_invalid_main_s "invalid main"
+ #define STATUS_CODE_out_of_range_s "out of range"
+ #define STATUS_CODE_unknown_code_s "unknown code"
+ #define STATUS_CODE_unknown_name_s "unknown name"
+
+ #define STATUS_CODE_failed_to_convert_s_length 17
+ #define STATUS_CODE_invalid_number_s_length 14
+ #define STATUS_CODE_invalid_name_s_length 12
+ #define STATUS_CODE_invalid_main_s_length 12
+ #define STATUS_CODE_out_of_range_s_length 12
+ #define STATUS_CODE_unknown_code_s_length 12
+ #define STATUS_CODE_unknown_name_s_length 12
+
+ extern const f_string_static_t status_code_failed_to_convert_s;
+ extern const f_string_static_t status_code_invalid_number_s;
+ extern const f_string_static_t status_code_invalid_name_s;
+ extern const f_string_static_t status_code_invalid_main_s;
+ extern const f_string_static_t status_code_out_of_range_s;
+ extern const f_string_static_t status_code_unknown_code_s;
+ extern const f_string_static_t status_code_unknown_name_s;
+#endif // _di_status_code_strings_
+
+/**
* The program defines.
*/
#ifndef _di_status_code_defines_
#define status_code_total_parameters_d 16
#endif // _di_status_code_parameters_
+/**
+ * Flags used to represent flags passed to the main function.
+ *
+ * When number mode is not specified, then mode is "string" mode (there is no flag for "string" mode).
+ *
+ * status_code_main_flag_*_e:
+ * - none: No modes in use.
+ * - error: Check if status is "error".
+ * - fine: Check if status is "fine".
+ * - help: Print help.
+ * - number: Operate in number mode.
+ * - version: Print version.
+ * - warning: Check if status is "warning".
+ */
+#ifndef _di_status_code_main_flag_e_
+ enum {
+ status_code_main_flag_none_e = 0x0,
+ status_code_main_flag_error_e = 0x1,
+ status_code_main_flag_fine_e = 0x2,
+ status_code_main_flag_help_e = 0x4,
+ status_code_main_flag_number_e = 0x8,
+ status_code_main_flag_version_e = 0x10,
+ status_code_main_flag_warning_e = 0x20,
+ };
+#endif // _di_status_code_main_flag_e_
+
+/**
+ * The status code main program settings.
+ *
+ * This is passed to the program-specific main entry point to designate program settings.
+ * These program settings are often processed from the program arguments (often called the command line arguments).
+ *
+ * flag: Flags passed to the main function.
+ *
+ * status: The main status code, generally used by the load settings and main functions.
+ *
+ * line_first: A string expected to represent either "\n" or NULL to allow for easy handling of when to print first new line or not.
+ * line_last: A string expected to represent either "\n" or NULL to allow for easy handling of when to print last new line or not.
+ */
+#ifndef _di_status_code_setting_t_
+ typedef struct {
+ uint16_t flag;
+
+ f_status_t status;
+
+ f_string_static_t line_first;
+ f_string_static_t line_last;
+ } status_code_setting_t;
+
+ #define status_code_setting_t_initialize \
+ { \
+ status_code_main_flag_none_e, \
+ F_none, \
+ f_string_static_t_initialize, \
+ f_string_static_t_initialize, \
+ }
+#endif // _di_status_code_setting_t_
+
+/**
+ * Delete the program main setting data.
+ *
+ * @param setting
+ * The program main setting data.
+ * This does not alter setting.status.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_status_code_setting_delete_
+ extern f_status_t status_code_setting_delete(status_code_setting_t * const setting);
+#endif // _di_status_code_setting_delete_
+
+/**
+ * Perform the standard program setting load process.
+ *
+ * This prints error messages as appropriate.
+ *
+ * If either main or setting is NULL, then this immediately retuns without doing anything.
+ *
+ * @param arguments
+ * The parameters passed to the process (often referred to as command line arguments).
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ *
+ * This alters setting.status:
+ * F_none on success.
+ *
+ * Errors (with error bit) from: f_console_parameter_process().
+ * Errors (with error bit) from: fll_program_parameter_process_context().
+ *
+ * @see f_console_parameter_process()
+ * @see fll_program_parameter_process_context()
+ */
+#ifndef _di_status_code_setting_load_
+ extern void status_code_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, status_code_setting_t * const setting);
+#endif // _di_status_code_setting_load_
+
+/**
+ * Perform the standard program setting unload process.
+ *
+ * @param main
+ * The main program data.
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * All buffers are deallocated.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: utf8_setting_delete().
+ *
+ * @see utf8_setting_delete()
+ */
+#ifndef _di_status_code_setting_unload_
+ extern f_status_t status_code_setting_unload(fll_program_data_t * const main, status_code_setting_t * const setting);
+#endif // _di_status_code_setting_unload_
+
#ifdef __cplusplus
} // extern "C"
#endif
int main(const int argc, const f_string_t *argv, const f_string_t *envp) {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
fll_program_data_t data = fll_program_data_t_initialize;
+ status_code_setting_t setting = status_code_setting_t_initialize;
f_console_parameter_t parameters[] = status_code_console_parameter_t_initialize;
data.parameters.array = parameters;
data.parameters.used = status_code_total_parameters_d;
+ data.environment = envp;
if (f_pipe_input_exists()) {
data.pipe = fll_program_data_pipe_input_e;
fll_program_standard_set_up(&data);
- const f_status_t status = status_code_main(&data, arguments);
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+
+ status_code_setting_load(arguments, &data, &setting);
+ }
+
+ status_code_main(&data, &setting);
+
+ status_code_setting_unload(&data, &setting);
fll_program_data_delete(&data);
fll_program_standard_set_down(&data);
- if (F_status_is_error(status)) return 1;
-
- return 0;
+ return (F_status_is_error(setting.status) || setting.status == F_false) ? 1 : 0;
}
--- /dev/null
+#include "status_code.h"
+#include "private-common.h"
+#include "print.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_status_code_print_error_cannot_error_warning_number_
+ void status_code_print_error_cannot_error_warning_number(status_code_setting_t * const setting, const fl_print_t print) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ f_file_stream_lock(print.to);
+
+ fl_print_format("%[%QCannot specify the '%]", print.to.stream, print.context, print.prefix, print.context);
+ fl_print_format("%[%r%r%]", print.to.stream, print.notable, f_console_symbol_long_enable_s, status_code_long_error_s, print.notable);
+ fl_print_format("%[' parameter with the '%]", print.to.stream, print.context, print.context);
+ fl_print_format("%[%r%r%]", print.to.stream, print.notable, f_console_symbol_long_enable_s, status_code_long_warning_s, print.notable);
+ fl_print_format("%[' parameter when not also specifying the '%]", print.to.stream, print.context, print.context);
+ fl_print_format("%[%r%r%]", print.to.stream, print.notable, f_console_symbol_long_enable_s, status_code_long_number_s, print.notable);
+ fl_print_format("%[' parameter.%]%r", print.to.stream, print.context, print.context, f_string_eol_s);
+
+ f_file_stream_unlock(print.to);
+ }
+#endif // _di_status_code_print_error_cannot_error_warning_number_
+
+#ifndef _di_status_code_print_error_no_status_codes_
+ void status_code_print_error_no_status_codes(status_code_setting_t * const setting, const fl_print_t print) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ fll_print_format("%[No status code is specified.%]%r", print.to.stream, print.context, print.context, f_string_eol_s);
+ }
+#endif // _di_status_code_print_error_no_status_codes_
+
+#ifndef _di_status_code_print_help_
+ f_status_t status_code_print_help(status_code_setting_t * const setting, const fl_print_t print) {
+
+ f_file_stream_lock(print.to);
+
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+
+ fll_program_print_help_header(print, status_code_program_name_long_s, status_code_program_version_s);
+
+ fll_program_print_help_option_standard(print);
+
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
+
+ fll_program_print_help_option(print, status_code_short_fine_s, status_code_long_fine_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print F_true or F_false if status code is neither an error nor a warning or print number with neither the error code nor the warning code bits set.");
+ fll_program_print_help_option(print, status_code_short_warning_s, status_code_long_warning_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print F_true or F_false if status code is a warning or print number with warning code bit set.");
+ fll_program_print_help_option(print, status_code_short_error_s, status_code_long_error_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print F_true or F_false if status code is an error or print number with error code bit set.");
+ fll_program_print_help_option(print, status_code_short_number_s, status_code_long_number_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Convert status code name to number.");
+
+ fll_program_print_help_usage(print, status_code_program_name_s, status_code_program_help_parameters_s);
+
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+
+ f_file_stream_flush(print.to);
+ f_file_stream_unlock(print.to);
+
+ return F_none;
+ }
+#endif // _di_status_code_print_help_
+
+#ifndef _di_status_code_print_line_first_
+ void status_code_print_line_first(status_code_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
+ }
+ }
+#endif // _di_status_code_print_line_first_
+
+#ifndef _di_status_code_print_line_last_
+ void status_code_print_line_last(status_code_setting_t * const setting, const fl_print_t print, const bool lock) {
+
+ if (print.verbosity == f_console_verbosity_quiet_e) return;
+ if (print.verbosity == f_console_verbosity_error_e && !F_status_is_error(setting->status)) return;
+
+ if (lock) {
+ fll_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ else {
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
+ }
+ }
+#endif // _di_status_code_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: Status Code
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ */
+#ifndef _status_code_print_h
+#define _status_code_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print an error message when error parameter and warning parameter are specified without number parameter.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ */
+#ifndef _di_status_code_print_error_cannot_error_warning_number_
+ extern void status_code_print_error_cannot_error_warning_number(status_code_setting_t * const setting, const fl_print_t print);
+#endif // _di_status_code_print_error_cannot_error_warning_number_
+
+/**
+ * Print an error message when no status codes are provided.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ */
+#ifndef _di_status_code_print_error_no_status_codes_
+ extern void status_code_print_error_no_status_codes(status_code_setting_t * const setting, const fl_print_t print);
+#endif // _di_status_code_print_error_no_status_codes_
+
+/**
+ * Print help.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * The output structure to print to.
+ *
+ * @return
+ * F_none on success.
+ */
+#ifndef _di_status_code_print_help_
+ extern f_status_t status_code_print_help(status_code_setting_t * const setting, const fl_print_t print);
+#endif // _di_status_code_print_help_
+
+/**
+ * Print first new line, unless verbosity says otherwise.
+ *
+ * This is generally either the first line in the program or the first line printed before an error message.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_status_code_print_line_first_
+ extern void status_code_print_line_first(status_code_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_status_code_print_line_first_
+
+/**
+ * Print last new line when the main is complete, unless verbosity says otherwise.
+ *
+ * This is generally the very last line printed in the program.
+ *
+ * @param setting
+ * The main program settings.
+ * This does not alter setting.status.
+ * @param print
+ * Designates the how and where to print.
+ * @param lock
+ * If TRUE, then lock the stream.
+ * If FALSE, then do not lock or unlock the stream.
+ */
+#ifndef _di_status_code_print_line_last_
+ extern void status_code_print_line_last(status_code_setting_t * const setting, const fl_print_t print, const bool lock);
+#endif // _di_status_code_print_line_last_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _status_code_print_h
extern "C" {
#endif
-#ifndef _di_status_code_print_signal_received_
- void status_code_print_signal_received(fll_program_data_t * const main) {
-
- if (main->warning.verbosity != f_console_verbosity_verbose_e && main->warning.verbosity != f_console_verbosity_debug_e) return;
-
- // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
- fflush(main->warning.to.stream);
-
- flockfile(main->warning.to.stream);
-
- fl_print_format("%]%r%r%[Received signal code %]", main->warning.to.stream, main->context.set.reset, f_string_eol_s, f_string_eol_s, main->context.set.warning, main->context.set.warning);
- fl_print_format("%[%i%]", main->warning.to.stream, main->context.set.notable, main->signal_received, main->context.set.notable);
- fl_print_format("%[.%]%r", main->warning.to.stream, main->context.set.warning, main->context.set.warning, f_string_eol_s);
-
- funlockfile(main->warning.to.stream);
- }
-#endif // _di_status_code_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
extern "C" {
#endif
-/**
- * Print a message about a process signal being recieved, such as an interrupt signal.
- *
- * @param main
- * The main program data.
- */
-#ifndef _di_status_code_print_signal_received_
- extern void status_code_print_signal_received(fll_program_data_t * const main) F_attribute_visibility_internal_d;
-#endif // _di_status_code_print_signal_received_
-
#ifdef __cplusplus
} // extern "C"
#endif
#endif
#ifndef _di_status_code_process_check_
- f_status_t status_code_process_check(fll_program_data_t * const main, const f_string_static_t value) {
+ f_status_t status_code_process_check(fll_program_data_t * const main, status_code_setting_t * const setting, const f_string_static_t value) {
f_number_unsigned_t number = 0;
- f_status_t status = status_code_convert_number(main, value, &number);
- if (F_status_is_error(status)) return status;
-
- if (main->parameters.array[status_code_parameter_error_e].result == f_console_result_found_e) {
- if (F_status_is_error(number)) {
- f_print_dynamic_raw(f_status_true_s, main->output.to.stream);
- }
- else {
- f_print_dynamic_raw(f_status_false_s, main->output.to.stream);
- }
-
- f_print_dynamic_raw(f_string_eol_s, main->output.to.stream);
+ {
+ f_status_t status = status_code_convert_number(main, setting, value, &number);
+ if (F_status_is_error(status)) return status;
}
- else if (main->parameters.array[status_code_parameter_warning_e].result == f_console_result_found_e) {
- if (F_status_is_warning(number)) {
- f_print_dynamic_raw(f_status_true_s, main->output.to.stream);
- }
- else {
- f_print_dynamic_raw(f_status_false_s, main->output.to.stream);
- }
- f_print_dynamic_raw(f_string_eol_s, main->output.to.stream);
+ if ((setting->flag & status_code_main_flag_error_e) && F_status_is_error(number) || (setting->flag & status_code_main_flag_warning_e) && F_status_is_warning(number) || (setting->flag & status_code_main_flag_fine_e) && F_status_is_fine(number)) {
+ f_print_dynamic_raw(f_status_true_s, main->output.to.stream);
}
- else if (main->parameters.array[status_code_parameter_fine_e].result == f_console_result_found_e) {
- if (F_status_is_fine(number)) {
- f_print_dynamic_raw(f_status_true_s, main->output.to.stream);
- }
- else {
- f_print_dynamic_raw(f_status_false_s, main->output.to.stream);
- }
-
- f_print_dynamic_raw(f_string_eol_s, main->output.to.stream);
+ else {
+ f_print_dynamic_raw(f_status_false_s, main->output.to.stream);
}
+ f_print_dynamic_raw(f_string_eol_s, main->output.to.stream);
+
return F_none;
}
#endif // _di_status_code_process_check_
#ifndef _di_status_code_process_number_
- f_status_t status_code_process_number(fll_program_data_t * const main, const f_string_static_t value) {
+ f_status_t status_code_process_number(fll_program_data_t * const main, status_code_setting_t * const setting, const f_string_static_t value) {
f_status_t status = F_none;
status = fl_conversion_dynamic_to_unsigned_detect(fl_conversion_data_base_10_c, value, &number);
if (status == F_none) {
- fl_print_format("%[invalid name%]%r", main->output.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s);
+ fl_print_format("%[%r%]%r", main->output.to.stream, main->context.set.error, status_code_invalid_name_s, main->context.set.error, f_string_eol_s);
return F_status_set_error(F_parameter);
}
if (status == F_data_not || F_status_set_fine(status) == F_parameter) {
- fl_print_format("%[invalid main%]%r", main->output.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s);
+ fl_print_format("%[%r%]%r", main->output.to.stream, main->context.set.error, status_code_invalid_main_s, main->context.set.error, f_string_eol_s);
return status;
}
if (F_status_is_error(status)) {
if (F_status_set_fine(status) == F_data) {
- fl_print_format("%[unknown name%]%r", main->output.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s);
+ fl_print_format("%[%r%]%r", main->output.to.stream, main->context.set.error, status_code_unknown_name_s, main->context.set.error, f_string_eol_s);
}
else {
- fl_print_format("%[failed to convert%]%r", main->output.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s);
+ fl_print_format("%[%r%]%r", main->output.to.stream, main->context.set.error, status_code_failed_to_convert_s, main->context.set.error, f_string_eol_s);
}
return status;
}
if (status == F_data) {
- fl_print_format("%[unknown code%]%r", main->output.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s);
+ fl_print_format("%[%r%]%r", main->output.to.stream, main->context.set.error, status_code_unknown_code_s, main->context.set.error, f_string_eol_s);
return F_none;
}
- if (main->parameters.array[status_code_parameter_error_e].result == f_console_result_found_e) {
+ if (setting->flag & status_code_main_flag_error_e) {
code = F_status_set_error(code);
}
- if (main->parameters.array[status_code_parameter_warning_e].result == f_console_result_found_e) {
+ if (setting->flag & status_code_main_flag_warning_e) {
code = F_status_set_warning(code);
}
#endif // _di_status_code_process_number_
#ifndef _di_status_code_process_normal_
- f_status_t status_code_process_normal(fll_program_data_t * const main, const f_string_static_t value) {
+ f_status_t status_code_process_normal(fll_program_data_t * const main, status_code_setting_t * const setting, const f_string_static_t value) {
f_number_unsigned_t number = 0;
- f_status_t status = status_code_convert_number(main, value, &number);
+ f_status_t status = status_code_convert_number(main, setting, value, &number);
if (F_status_is_error(status)) return status;
f_string_static_t name = f_string_static_t_initialize;
if (F_status_is_error(status)) {
if (F_status_set_fine(status) == F_data) {
- fl_print_format("%[unknown code%]%r", main->output.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s);
+ fl_print_format("%[%r%]%r", main->output.to.stream, main->context.set.error, status_code_unknown_code_s, main->context.set.error, f_string_eol_s);
}
else {
- fl_print_format("%[failed to convert%]%r", main->output.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s);
+ fl_print_format("%[%r%]%r", main->output.to.stream, main->context.set.error, status_code_failed_to_convert_s, main->context.set.error, f_string_eol_s);
}
return status;
#endif // _di_status_code_process_normal_
#ifndef _di_status_code_convert_number_
- f_status_t status_code_convert_number(fll_program_data_t * const main, const f_string_static_t value, f_number_unsigned_t *number) {
+ f_status_t status_code_convert_number(fll_program_data_t * const main, status_code_setting_t * const setting, const f_string_static_t value, f_number_unsigned_t *number) {
- f_status_t status = fl_conversion_dynamic_to_unsigned_detect(fl_conversion_data_base_10_c, value, number);
+ const f_status_t status = fl_conversion_dynamic_to_unsigned_detect(fl_conversion_data_base_10_c, value, number);
if (*number > F_status_size_max_with_bits_d) {
- fl_print_format("%[out of range%]%r", main->output.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s);
+ fl_print_format("%[%r%]%r", main->output.to.stream, main->context.set.error, status_code_out_of_range_s, main->context.set.error, f_string_eol_s);
return F_status_set_error(F_number_overflow);
}
if (F_status_is_error(status)) {
if (F_status_set_fine(status) == F_number_negative) {
- fl_print_format("%[out of range%]%r", main->output.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s);
+ fl_print_format("%[%r%]%r", main->output.to.stream, main->context.set.error, status_code_out_of_range_s, main->context.set.error, f_string_eol_s);
}
else {
- fl_print_format("%[invalid number%]%r", main->output.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s);
+ fl_print_format("%[%r%]%r", main->output.to.stream, main->context.set.error, status_code_invalid_number_s, main->context.set.error, f_string_eol_s);
}
return status;
* @see fss_status_code_convert_number()
*/
#ifndef _di_status_code_process_check_
- extern f_status_t status_code_process_check(fll_program_data_t * const main, const f_string_static_t value) F_attribute_visibility_internal_d;
+ extern f_status_t status_code_process_check(fll_program_data_t * const main, status_code_setting_t * const setting, const f_string_static_t value) F_attribute_visibility_internal_d;
#endif // _di_status_code_process_check_
/**
* @see fll_fss_status_string_from()
*/
#ifndef _di_status_code_process_number_
- extern f_status_t status_code_process_number(fll_program_data_t * const main, const f_string_static_t value) F_attribute_visibility_internal_d;
+ extern f_status_t status_code_process_number(fll_program_data_t * const main, status_code_setting_t * const setting, const f_string_static_t value) F_attribute_visibility_internal_d;
#endif // _di_status_code_process_number_
/**
* @see fss_status_code_convert_number()
*/
#ifndef _di_status_code_process_normal_
- extern f_status_t status_code_process_normal(fll_program_data_t * const main, const f_string_static_t value) F_attribute_visibility_internal_d;
+ extern f_status_t status_code_process_normal(fll_program_data_t * const main, status_code_setting_t * const setting, const f_string_static_t value) F_attribute_visibility_internal_d;
#endif // _di_status_code_process_normal_
/**
* @see fl_console_parameter_to_number_unsigned()
*/
#ifndef _di_status_code_convert_number_
- extern f_status_t status_code_convert_number(fll_program_data_t * const main, const f_string_static_t value, f_number_unsigned_t *number) F_attribute_visibility_internal_d;
+ extern f_status_t status_code_convert_number(fll_program_data_t * const main, status_code_setting_t * const setting, const f_string_static_t value, f_number_unsigned_t *number) F_attribute_visibility_internal_d;
#endif // _di_status_code_convert_number_
#ifdef __cplusplus
extern "C" {
#endif
-#ifndef _di_status_code_print_help_
- f_status_t status_code_print_help(const f_file_t file, const f_color_context_t context) {
-
- flockfile(file.stream);
-
- //if (!(setting->flag & XXX_main_flag_line_first_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- fll_program_print_help_header(file, context, status_code_program_name_long_s, status_code_program_version_s);
-
- fll_program_print_help_option_standard(file, context);
-
- f_print_dynamic_raw(f_string_eol_s, file.stream);
-
- fll_program_print_help_option(file, context, status_code_short_fine_s, status_code_long_fine_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print F_true or F_false if status code is neither an error nor a warning or print number with neither the error code nor the warning code bits set.");
- fll_program_print_help_option(file, context, status_code_short_warning_s, status_code_long_warning_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print F_true or F_false if status code is a warning or print number with warning code bit set.");
- fll_program_print_help_option(file, context, status_code_short_error_s, status_code_long_error_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print F_true or F_false if status code is an error or print number with error code bit set.");
- fll_program_print_help_option(file, context, status_code_short_number_s, status_code_long_number_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Convert status code name to number.");
-
- fll_program_print_help_usage(file, context, status_code_program_name_s, status_code_program_help_parameters_s);
-
- //if (!(setting->flag & XXX_main_flag_line_last_no_e)) {
- f_print_dynamic_raw(f_string_eol_s, file.stream);
- //}
-
- f_file_stream_flush(file);
- funlockfile(file.stream);
-
- return F_none;
- }
-#endif // _di_status_code_print_help_
-
#ifndef _di_status_code_main_
- f_status_t status_code_main(fll_program_data_t * const main, const f_console_arguments_t arguments) {
-
- f_status_t status = F_none;
-
- // Load parameters.
- status = f_console_parameter_process(arguments, &main->parameters);
- if (F_status_is_error(status)) return;
-
- {
- f_array_length_t choice = 0;
- f_uint16s_t choices = f_uint16s_t_initialize;
-
- // Identify and prioritize "color context" parameters.
- {
- uint16_t choices_array[3] = { status_code_parameter_no_color_e, status_code_parameter_light_e, status_code_parameter_dark_e };
- choices.array = choices_array;
- choices.used = 3;
-
- const uint8_t modes[3] = { f_color_mode_color_not_e, f_color_mode_light_e, f_color_mode_dark_e };
-
- status = fll_program_parameter_process_context(choices, modes, F_true, main);
-
- if (F_status_is_error(status)) {
- fll_error_print(main->error, F_status_set_fine(status), "fll_program_parameter_process_context", F_true);
-
- return;
- }
- }
+ void status_code_main(fll_program_data_t * const main, status_code_setting_t * const setting) {
- // Identify and prioritize "verbosity" parameters.
- {
- uint16_t choices_array[5] = { status_code_parameter_verbosity_quiet_e, status_code_parameter_verbosity_error_e, status_code_parameter_verbosity_verbose_e, status_code_parameter_verbosity_debug_e, status_code_parameter_verbosity_normal_e };
- choices.array = choices_array;
- choices.used = 5;
+ if (!main || !setting) {
+ status_code_print_line_first(setting, main->error, F_true);
+ fll_error_print(main->error, F_parameter, "status_code_main", F_true);
+ status_code_print_line_last(setting, main->error, F_true);
- const uint8_t verbosity[5] = { f_console_verbosity_quiet_e, f_console_verbosity_error_e, f_console_verbosity_verbose_e, f_console_verbosity_debug_e, f_console_verbosity_normal_e };
+ setting->status = F_status_set_error(F_parameter);
- status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
-
- if (F_status_is_error(status)) {
- fll_error_print(main->error, F_status_set_fine(status), "fll_program_parameter_process_verbosity", F_true);
-
- return;
- }
- }
+ return;
}
- f_string_static_t * const argv = main->parameters.arguments.array;
+ if (F_status_is_error(setting->status)) return;
- status = F_none;
+ setting->status = F_none;
- if (main->parameters.array[status_code_parameter_help_e].result == f_console_result_found_e) {
- status_code_print_help(main->output.to, main->context);
+ if (setting->flag & status_code_main_flag_help_e) {
+ status_code_print_help(setting, main->message);
- return F_none;
+ return;
}
- if (main->parameters.array[status_code_parameter_version_e].result == f_console_result_found_e) {
- fll_program_print_version(main->output.to, status_code_program_version_s);
+ if (setting->flag & status_code_main_flag_version_e) {
+ fll_program_print_version(main->message, status_code_program_version_s);
- return F_none;
- }
-
- if (main->parameters.array[status_code_parameter_error_e].result == f_console_result_found_e) {
- if (main->parameters.array[status_code_parameter_warning_e].result == f_console_result_found_e) {
- if (main->parameters.array[status_code_parameter_number_e].result == f_console_result_none_e) {
- if (main->error.verbosity != f_console_verbosity_quiet_e) {
- flockfile(main->error.to.stream);
-
- fl_print_format("%r%[%QCannot specify the '%]", main->error.to.stream, f_string_eol_s, main->error.context, main->error.prefix, main->error.context);
- fl_print_format("%[%r%r%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, status_code_long_error_s, main->error.notable);
- fl_print_format("%[' parameter with the '%]", main->error.to.stream, main->error.context, main->error.context);
- fl_print_format("%[%r%r%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, status_code_long_warning_s, main->error.notable);
- fl_print_format("%[' parameter when not also specifying the '%]", main->error.to.stream, main->error.context, main->error.context);
- fl_print_format("%[%r%r%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, status_code_long_number_s, main->error.notable);
- fl_print_format("%[' parameter.%]%r%r", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s, f_string_eol_s);
-
- funlockfile(main->error.to.stream);
- }
-
- return F_status_set_error(status);
- }
- }
-
- if (main->parameters.array[status_code_parameter_fine_e].result == f_console_result_found_e) {
- if (main->error.verbosity != f_console_verbosity_quiet_e) {
- fll_program_parameter_long_print_cannot_use_with(main->error, status_code_long_error_s, status_code_long_fine_s);
- fll_print_dynamic_raw(f_string_eol_s, main->error.to.stream);
- }
-
- return F_status_set_error(status);
- }
- }
- else if (main->parameters.array[status_code_parameter_warning_e].result == f_console_result_found_e && main->parameters.array[status_code_parameter_fine_e].result == f_console_result_found_e) {
- if (main->error.verbosity != f_console_verbosity_quiet_e) {
- fll_program_parameter_long_print_cannot_use_with(main->error, status_code_long_warning_s, status_code_long_fine_s);
- fll_print_dynamic_raw(f_string_eol_s, main->error.to.stream);
- }
-
- return F_status_set_error(status);
- }
-
- if (main->parameters.remaining.used == 0 && !(main->pipe & fll_program_data_pipe_input_e)) {
- fll_print_format("%[You failed to specify a status code.%]%r", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s);
-
- return F_status_set_error(F_parameter);
+ return;
}
f_status_t status2 = F_none;
- if (main->parameters.array[status_code_parameter_number_e].result == f_console_result_found_e) {
+ if (setting->flag & status_code_main_flag_number_e) {
if (main->pipe & fll_program_data_pipe_input_e) {
// @todo call status_code_process_number() here for all main from pipe that is space separated.
}
if (main->parameters.remaining.used) {
- flockfile(main->output.to.stream);
+ f_file_stream_lock(main->output.to);
for (f_array_length_t i = 0; i < main->parameters.remaining.used; ++i) {
if (!((++main->signal_check) % status_code_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- status_code_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
- status = F_status_set_error(F_signal);
+ setting->status = F_status_set_error(F_signal);
break;
}
main->signal_check = 0;
}
- status2 = status_code_process_number(main, argv[main->parameters.remaining.array[i]]);
+ status2 = status_code_process_number(main, setting, main->parameters.arguments.array[main->parameters.remaining.array[i]]);
- if (F_status_is_error(status2) && status == F_none) {
- status = status2;
+ if (F_status_is_error(status2) && setting->status == F_none) {
+ setting->status = status2;
}
} // for
- funlockfile(main->output.to.stream);
+ f_file_stream_unlock(main->output.to);
}
}
- else if (main->parameters.array[status_code_parameter_error_e].result == f_console_result_found_e || main->parameters.array[status_code_parameter_warning_e].result == f_console_result_found_e || main->parameters.array[status_code_parameter_fine_e].result == f_console_result_found_e) {
+ else if (setting->flag & status_code_main_flag_error_e || setting->flag & status_code_main_flag_warning_e || setting->flag & status_code_main_flag_fine_e) {
if (main->pipe & fll_program_data_pipe_input_e) {
// @todo call status_code_process_check() here for all main from pipe that is space separated.
}
if (main->parameters.remaining.used) {
- flockfile(main->output.to.stream);
+ f_file_stream_lock(main->output.to);
for (f_array_length_t i = 0; i < main->parameters.remaining.used; ++i) {
if (!((++main->signal_check) % status_code_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- status_code_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
- status = F_status_set_error(F_signal);
+ setting->status = F_status_set_error(F_signal);
break;
}
main->signal_check = 0;
}
- status2 = status_code_process_check(main, argv[main->parameters.remaining.array[i]]);
+ status2 = status_code_process_check(main, setting, main->parameters.arguments.array[main->parameters.remaining.array[i]]);
- if (F_status_is_error(status2) && status == F_none) {
- status = status2;
+ if (F_status_is_error(status2) && setting->status == F_none) {
+ setting->status = status2;
}
} // for
- funlockfile(main->output.to.stream);
+ f_file_stream_unlock(main->output.to);
}
}
else {
}
if (main->parameters.remaining.used) {
- flockfile(main->output.to.stream);
+ f_file_stream_lock(main->output.to);
for (f_array_length_t i = 0; i < main->parameters.remaining.used; ++i) {
if (!((++main->signal_check) % status_code_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- status_code_print_signal_received(main);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
- status = F_status_set_error(F_signal);
+ setting->status = F_status_set_error(F_signal);
break;
}
main->signal_check = 0;
}
- status2 = status_code_process_normal(main, argv[main->parameters.remaining.array[i]]);
+ status2 = status_code_process_normal(main, setting, main->parameters.arguments.array[main->parameters.remaining.array[i]]);
- if (F_status_is_error(status2) && status == F_none) {
- status = status2;
+ if (F_status_is_error(status2) && setting->status == F_none) {
+ setting->status = status2;
}
} // for
- funlockfile(main->output.to.stream);
+ f_file_stream_unlock(main->output.to);
}
}
- if (F_status_set_fine(status) == F_interrupt) {
- if (main->output.verbosity != f_console_verbosity_quiet_e) {
- fflush(main->output.to.stream);
-
- fll_print_dynamic_raw(f_string_eol_s, main->output.to.stream);
- }
+ if (F_status_is_error(setting->status)) {
+ status_code_print_line_last(setting, main->error, F_true);
+ }
+ else if (setting->status != F_interrupt) {
+ status_code_print_line_last(setting, main->message, F_true);
}
-
- return status;
}
#endif // _di_status_code_main_
// Status Code includes.
#include <program/status_code/common.h>
+#include <program/status_code/print.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
- * Print help.
- *
- * @param file
- * The file to print to.
- * @param context
- * The color context settings.
- *
- * @return
- * F_none on success.
- */
-#ifndef _di_status_code_print_help_
- extern f_status_t status_code_print_help(const f_file_t file, const f_color_context_t context);
-#endif // _di_status_code_print_help_
-
-/**
* Execute main program.
*
* If main.signal is non-zero, then this blocks and handles the following signals:
*
* @param main
* The main program data.
- * @param arguments
- * The parameters passed to the process.
+ * @param setting
+ * The main program settings.
*
- * @return
- * F_none on success.
+ * This alters setting.status:
+ * F_none on success.
+ * F_true on success when performing verification and verify passed.
+ * F_false on success when performing verification and verify failed.
+ * F_interrupt on (exit) signal received.
*
- * Status codes (with error bit) are returned on any problem.
+ * F_parameter (with error bit) if main is NULL or setting is NULL.
*/
#ifndef _di_status_code_main_
- extern f_status_t status_code_main(fll_program_data_t * const main, const f_console_arguments_t arguments);
+ extern void status_code_main(fll_program_data_t * const main, status_code_setting_t * const setting);
#endif // _di_status_code_main_
#ifdef __cplusplus
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library status_code.c common.c private-common.c private-status_code.c
+build_sources_library status_code.c common.c print.c private-common.c private-status_code.c
build_sources_program main.c
-build_sources_headers status_code.h common.h
+build_sources_headers status_code.h common.h print.h
build_script yes
build_shared yes
#ifndef _di_utf8_setting_delete_
f_status_t utf8_setting_delete(utf8_setting_t * const setting) {
+ if (!setting) return F_status_set_error(F_parameter);
+
+ f_string_dynamic_resize(0, &setting->buffer);
+ f_string_dynamic_resize(0, &setting->text);
+
f_string_dynamics_resize(0, &setting->path_files_from);
f_string_dynamics_resize(0, &setting->path_files_to);
#ifndef _di_utf8_setting_load_
void utf8_setting_load(const f_console_arguments_t arguments, fll_program_data_t * const main, utf8_setting_t * const setting) {
+ if (!main || !setting) return;
+
// Load parameters.
setting->status = f_console_parameter_process(arguments, &main->parameters);
if (F_status_is_error(setting->status)) return;
setting->status = fll_program_parameter_process_context(choices, modes, F_true, main);
if (F_status_is_error(setting->status)) {
+ utf8_print_line_first(setting, main->error, F_true);
fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_context", F_true);
+ utf8_print_line_last(setting, main->error, F_true);
return;
}
setting->status = fll_program_parameter_process_verbosity(choices, verbosity, F_true, main);
if (F_status_is_error(setting->status)) {
+ utf8_print_line_first(setting, main->error, F_true);
fll_error_print(main->error, F_status_set_fine(setting->status), "fll_program_parameter_process_verbosity", F_true);
+ utf8_print_line_last(setting, main->error, F_true);
return;
}
setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
if (F_status_is_error(setting->status)) {
+ utf8_print_line_first(setting, main->error, F_true);
fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+ utf8_print_line_last(setting, main->error, F_true);
return;
}
setting->status = f_console_parameter_prioritize_right(main->parameters, choices, &choice);
if (F_status_is_error(setting->status)) {
+ utf8_print_line_first(setting, main->error, F_true);
fll_error_print(main->error, F_status_set_fine(setting->status), "f_console_parameter_prioritize_right", F_true);
+ utf8_print_line_last(setting, main->error, F_true);
return;
}
#ifndef _di_utf8_setting_unload_
f_status_t utf8_setting_unload(fll_program_data_t * const main, utf8_setting_t * const setting) {
- f_string_dynamic_resize(0, &setting->buffer);
- f_string_dynamic_resize(0, &setting->text);
+ if (!main || !setting) return F_status_set_error(F_parameter);
+
+ utf8_setting_delete(setting);
return F_none;
}
#endif // _di_utf8_main_flag_e_
/**
- * The UTF-8 main program settings.
+ * The utf8 main program settings.
*
* This is passed to the program-specific main entry point to designate program settings.
* These program settings are often processed from the program arguments (often called the command line arguments).
* The program main setting data.
* This does not alter setting.status.
*
- * Assumed to always be non-NULL.
- *
* @return
* F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
*/
#ifndef _di_utf8_setting_delete_
extern f_status_t utf8_setting_delete(utf8_setting_t * const setting);
*
* This prints error messages as appropriate.
*
+ * If either main or setting is NULL, then this immediately retuns without doing anything.
+ *
* @param arguments
* The parameters passed to the process (often referred to as command line arguments).
* @param main
* The main program data.
- *
- * Assumed to always be non-NULL.
* @param setting
* The main program settings.
*
- * Assumed to always be non-NULL.
- *
* This alters setting.status:
* F_none on success.
*
*
* @param main
* The main program data.
- *
- * Assumed to always be non-NULL.
* @param setting
* The main program settings.
* This does not alter setting.status.
* All buffers are deallocated.
*
- * Assumed to always be non-NULL.
- *
* @return
* F_none on success.
+ *
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors (with error bit) from: utf8_setting_delete().
+ *
+ * @see utf8_setting_delete()
*/
#ifndef _di_utf8_setting_unload_
extern f_status_t utf8_setting_unload(fll_program_data_t * const main, utf8_setting_t * const setting);
utf8_setting_unload(&data, &setting);
- utf8_setting_delete(&setting);
-
fll_program_data_delete(&data);
fll_program_standard_set_down(&data);
- return F_status_is_error(setting.status) || setting.status == F_false ? 1 : 0;
+ return (F_status_is_error(setting.status) || setting.status == F_false) ? 1 : 0;
}
if (main->error.verbosity == f_console_verbosity_quiet_e) return;
- flockfile(main->error.to.stream);
+ f_file_stream_lock(main->error.to);
utf8_print_line_first(setting, main->error, F_false);
fl_print_format("%[%r%r%]", main->error.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, parameter, main->context.set.notable);
fl_print_format("%[' is specified, but no value was given.%]%r", main->error.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s);
- funlockfile(main->error.to.stream);
+ f_file_stream_unlock(main->error.to);
}
#endif // _di_utf8_print_error_no_value_
if (main->error.verbosity == f_console_verbosity_quiet_e) return;
- flockfile(main->error.to.stream);
+ f_file_stream_lock(main->error.to);
utf8_print_line_first(setting, main->error, F_false);
fl_print_format("%[%ul%]", main->error.to.stream, main->context.set.notable, index, main->context.set.notable);
fl_print_format("%[.%]%r", main->error.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s);
- funlockfile(main->error.to.stream);
+ f_file_stream_unlock(main->error.to);
}
#endif // _di_utf8_print_error_parameter_file_name_empty_
if (main->error.verbosity == f_console_verbosity_quiet_e) return;
- flockfile(main->error.to.stream);
+ f_file_stream_lock(main->error.to);
utf8_print_line_first(setting, main->error, F_false);
fl_print_format("%[%Q%]", main->error.to.stream, main->context.set.notable, name, main->context.set.notable);
fl_print_format("%['.%]%r", main->error.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s);
- funlockfile(main->error.to.stream);
+ f_file_stream_unlock(main->error.to);
}
#endif // _di_utf8_print_error_parameter_file_not_found_
#endif // _di_utf8_print_flush_
#ifndef _di_utf8_print_help_
- f_status_t utf8_print_help(utf8_setting_t * const setting, const f_file_t output, const f_color_context_t context) {
+ f_status_t utf8_print_help(utf8_setting_t * const setting, const fl_print_t print) {
- flockfile(output.stream);
+ f_file_stream_lock(print.to);
- f_print_dynamic_raw(setting->line_first, output.stream);
+ f_print_dynamic_raw(setting->line_first, print.to.stream);
- fll_program_print_help_header(output, context, utf8_program_name_long_s, utf8_program_version_s);
+ fll_program_print_help_header(print, utf8_program_name_long_s, utf8_program_version_s);
- fll_program_print_help_option_standard(output, context);
+ fll_program_print_help_option_standard(print);
- f_print_dynamic_raw(f_string_eol_s, output.stream);
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
- fll_program_print_help_option(output, context, utf8_short_from_bytesequence_s, utf8_long_from_bytesequence_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "The expected input format is byte sequence (character data).");
- fll_program_print_help_option(output, context, utf8_short_from_codepoint_s, utf8_long_from_codepoint_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The expected input format is codepoint (such as U+0000).");
- fll_program_print_help_option(output, context, utf8_short_from_file_s, utf8_long_from_file_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use the given output as the input source.");
+ fll_program_print_help_option(print, utf8_short_from_bytesequence_s, utf8_long_from_bytesequence_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "The expected input format is byte sequence (character data).");
+ fll_program_print_help_option(print, utf8_short_from_codepoint_s, utf8_long_from_codepoint_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The expected input format is codepoint (such as U+0000).");
+ fll_program_print_help_option(print, utf8_short_from_file_s, utf8_long_from_file_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use the given print.to as the input source.");
- f_print_dynamic_raw(f_string_eol_s, output.stream);
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
- fll_program_print_help_option(output, context, utf8_short_to_bytesequence_s, utf8_long_to_bytesequence_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "The output format is byte sequence (character data).");
- fll_program_print_help_option(output, context, utf8_short_to_codepoint_s, utf8_long_to_codepoint_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The output format is codepoint (such as U+0000).");
- fll_program_print_help_option(output, context, utf8_short_to_combining_s, utf8_long_to_combining_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The output format is to print whether or not character is combining or not.");
- fll_program_print_help_option(output, context, utf8_short_to_file_s, utf8_long_to_file_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use the given output as the output destination.");
- fll_program_print_help_option(output, context, utf8_short_to_width_s, utf8_long_to_width_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The output format is to print the width of a character (either 0, 1, or 2).");
+ fll_program_print_help_option(print, utf8_short_to_bytesequence_s, utf8_long_to_bytesequence_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "The print.to format is byte sequence (character data).");
+ fll_program_print_help_option(print, utf8_short_to_codepoint_s, utf8_long_to_codepoint_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The print.to format is codepoint (such as U+0000).");
+ fll_program_print_help_option(print, utf8_short_to_combining_s, utf8_long_to_combining_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The print.to format is to print whether or not character is combining or not.");
+ fll_program_print_help_option(print, utf8_short_to_file_s, utf8_long_to_file_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use the given print.to as the print.to destination.");
+ fll_program_print_help_option(print, utf8_short_to_width_s, utf8_long_to_width_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The print.to format is to print the width of a character (either 0, 1, or 2).");
- f_print_dynamic_raw(f_string_eol_s, output.stream);
+ f_print_dynamic_raw(f_string_eol_s, print.to.stream);
- fll_program_print_help_option(output, context, utf8_short_headers_s, utf8_long_headers_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print headers for each section (pipe, output, or parameter).");
- fll_program_print_help_option(output, context, utf8_short_separate_s, utf8_long_separate_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Separate characters by newlines (implied when printing headers).");
- fll_program_print_help_option(output, context, utf8_short_strip_invalid_s, utf8_long_strip_invalid_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Strip invalid Unicode characters (do not print invalid sequences).");
- fll_program_print_help_option(output, context, utf8_short_verify_s, utf8_long_verify_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Only perform verification of valid sequences.");
+ fll_program_print_help_option(print, utf8_short_headers_s, utf8_long_headers_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print headers for each section (pipe, file, or parameter).");
+ fll_program_print_help_option(print, utf8_short_separate_s, utf8_long_separate_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Separate characters by newlines (implied when printing headers).");
+ fll_program_print_help_option(print, utf8_short_strip_invalid_s, utf8_long_strip_invalid_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Strip invalid Unicode characters (do not print invalid sequences).");
+ fll_program_print_help_option(print, utf8_short_verify_s, utf8_long_verify_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Only perform verification of valid sequences.");
- fll_program_print_help_usage(output, context, utf8_program_name_s, utf8_program_help_parameters_s);
+ fll_program_print_help_usage(print, utf8_program_name_s, utf8_program_help_parameters_s);
- fl_print_format("%r The default behavior is to assume the expected input is byte sequence from the command line to be output to the screen as codepoints.%r%r", output.stream, f_string_eol_s, f_string_eol_s, f_string_eol_s);
+ fl_print_format("%r The default behavior is to assume the expected input is byte sequence from the command line to be print.to to the screen as codepoints.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s, f_string_eol_s);
- fl_print_format(" Multiple input sources are allowed but only a single output destination is allowed.%r%r", output.stream, f_string_eol_s, f_string_eol_s);
+ fl_print_format(" Multiple input sources are allowed but only a single print.to destination is allowed.%r%r", print.to.stream, f_string_eol_s, f_string_eol_s);
- fl_print_format(" When using the parameter '%[%r%r%]', no data is printed and 0 is returned if valid or 1 is returned if invalid.%r%r", output.stream, context.set.notable, f_console_symbol_long_enable_s, utf8_long_verify_s, context.set.notable, f_string_eol_s, f_string_eol_s);
+ fl_print_format(" When using the parameter '%[%r%r%]', no data is printed and 0 is returned if valid or 1 is returned if invalid.%r%r", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, utf8_long_verify_s, print.set->notable, f_string_eol_s, f_string_eol_s);
- fl_print_format(" When using the parameter '%[%r%r%]' with the parameter ", output.stream, context.set.notable, f_console_symbol_long_enable_s, utf8_long_to_combining_s, context.set.notable);
- fl_print_format("'%[%r%r%]', the ", output.stream, context.set.notable, f_console_symbol_long_enable_s, utf8_long_to_width_s, context.set.notable);
- fl_print_format("'%[%r%]' character is printed to represent the combining and the digits are used to represent widths.%r", output.stream, context.set.notable, utf8_string_combining_is_s, context.set.notable, f_string_eol_s);
- fl_print_format(" The combining characters should be considered 1-width by themselves or 0-width when combined.%r", output.stream, f_string_eol_s);
+ fl_print_format(" When using the parameter '%[%r%r%]' with the parameter ", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, utf8_long_to_combining_s, print.set->notable);
+ fl_print_format("'%[%r%r%]', the ", print.to.stream, print.set->notable, f_console_symbol_long_enable_s, utf8_long_to_width_s, print.set->notable);
+ fl_print_format("'%[%r%]' character is printed to represent the combining and the digits are used to represent widths.%r", print.to.stream, print.set->notable, utf8_string_combining_is_s, print.set->notable, f_string_eol_s);
+ fl_print_format(" The combining characters should be considered 1-width by themselves or 0-width when combined.%r", print.to.stream, f_string_eol_s);
- f_print_dynamic_raw(setting->line_last, output.stream);
+ f_print_dynamic_raw(setting->line_last, print.to.stream);
- f_file_stream_flush(output);
- funlockfile(output.stream);
+ f_file_stream_flush(print.to);
+ f_file_stream_unlock(print.to);
return F_none;
}
}
#endif // _di_utf8_print_section_header_pipe_
-#ifndef _di_utf8_print_signal_received_
- void utf8_print_signal_received(fll_program_data_t * const main, utf8_setting_t * const setting, const f_status_t signal) {
-
- if (main->warning.verbosity != f_console_verbosity_verbose_e && main->warning.verbosity != f_console_verbosity_debug_e) {
- return;
- }
-
- flockfile(main->warning.to.stream);
-
- // Must flush and reset color because the interrupt may have interrupted the middle of a print function.
- f_file_stream_flush(main->warning.to);
-
- fl_print_format("%]", main->warning.to.stream, main->context.set.reset);
-
- utf8_print_line_first(setting, main->warning, F_false);
-
- fl_print_format("%r%[Received signal code %]", main->warning.to.stream, f_string_eol_s, main->context.set.warning, main->context.set.warning);
- fl_print_format("%[%i%]", main->warning.to.stream, main->context.set.notable, signal, main->context.set.notable);
- fl_print_format("%[.%]%r", main->warning.to.stream, main->context.set.warning, main->context.set.warning, f_string_eol_s);
-
- funlockfile(main->warning.to.stream);
- }
-#endif // _di_utf8_print_signal_received_
-
#ifndef _di_utf8_print_width_
void utf8_print_width(fll_program_data_t * const main, utf8_setting_t * const setting, const f_string_static_t sequence) {
* @param setting
* The main program settings.
* This does not alter setting.status.
- * @param output
- * The file to print to.
- * @param context
- * The color context settings.
+ * @param print
+ * The output structure to print to.
*
* @return
* F_none on success.
- * F_true on success and validation passed.
- * F_false on success and validation failed.
*/
#ifndef _di_utf8_print_help_
- extern f_status_t utf8_print_help(utf8_setting_t * const setting, const f_file_t output, const f_color_context_t context);
+ extern f_status_t utf8_print_help(utf8_setting_t * const setting, const fl_print_t print);
#endif // _di_utf8_print_help_
/**
* The main program settings.
* This does not alter setting.status.
* @param print
- * Designates how the how and where to print.
+ * Designates the how and where to print.
* @param lock
* If TRUE, then lock the stream.
* If FALSE, then do not lock or unlock the stream.
* The main program settings.
* This does not alter setting.status.
* @param print
- * Designates how the how and where to print.
+ * Designates the how and where to print.
* @param lock
* If TRUE, then lock the stream.
* If FALSE, then do not lock or unlock the stream.
#endif // _di_utf8_print_section_header_pipe_
/**
- * Print a message about a process signal being recieved, such as an interrupt signal.
- *
- * @param main
- * The main program data.
- * @param setting
- * The main program settings.
- *
- * Assumed to always be non-NULL.
- * @param signal
- * The signal code received.
- */
-#ifndef _di_utf8_print_signal_received_
- extern void utf8_print_signal_received(fll_program_data_t * const main, utf8_setting_t * const setting, const f_status_t signal);
-#endif // _di_utf8_print_signal_received_
-
-/**
* Print the width of the given character.
*
* @param main
if (!((++main->signal_check) % utf8_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- utf8_print_signal_received(main, setting, status);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_status_set_error(F_interrupt);
if (!((++main->signal_check) % utf8_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- utf8_print_signal_received(main, setting, status);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_interrupt;
if (!((++main->signal_check) % utf8_signal_check_d)) {
if (fll_program_standard_signal_received(main)) {
- utf8_print_signal_received(main, setting, status);
+ fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received);
status = F_interrupt;
fll_error_print(main->error, F_parameter, "utf8_main", F_true);
utf8_print_line_last(setting, main->error, F_true);
- return;
- }
-
- if (F_status_is_error(setting->status)) {
- utf8_print_line_last(setting, main->error, F_true);
+ setting->status = F_status_set_error(F_parameter);
return;
}
+ if (F_status_is_error(setting->status)) return;
+
setting->status = F_none;
if (setting->flag & utf8_main_flag_help_e) {
- utf8_print_help(setting, main->message.to, main->context);
+ utf8_print_help(setting, main->message);
return;
}
if (setting->flag & utf8_main_flag_version_e) {
- fll_program_print_version(main->message.to, utf8_program_version_s);
+ fll_program_print_version(main->message, utf8_program_version_s);
return;
}