|
|
| version 1.323, 2020/12/20 20:45:24 | version 1.329, 2023/11/16 23:54:55 |
|---|---|
| Line 1 | Line 1 |
| /** @file | /** @file |
| Parser: commonly functions. | Parser: commonly functions. |
| Copyright (c) 2000-2020 Art. Lebedev Studio (http://www.artlebedev.com) | Copyright (c) 2000-2023 Art. Lebedev Studio (http://www.artlebedev.com) |
| Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) | Authors: Konstantin Morshnev <moko@design.ru>, Alexandr Petrosian <paf@design.ru> |
| */ | */ |
| #include "pa_common.h" | #include "pa_common.h" |
| Line 116 struct File_read_action_info { | Line 116 struct File_read_action_info { |
| static void file_read_action(struct stat& finfo, int f, const String& file_spec, void *context) { | static void file_read_action(struct stat& finfo, int f, const String& file_spec, void *context) { |
| File_read_action_info& info = *static_cast<File_read_action_info *>(context); | File_read_action_info& info = *static_cast<File_read_action_info *>(context); |
| size_t to_read_size = check_file_size(info.limit && info.limit < finfo.st_size ? info.limit : finfo.st_size, &file_spec); | size_t to_read_size = check_file_size(info.limit && info.limit < (size_t)finfo.st_size ? info.limit : (size_t)finfo.st_size, &file_spec); |
| if(to_read_size) { | if(to_read_size) { |
| if(info.offset) | if(info.offset) |
| pa_lseek(f, info.offset, SEEK_SET); // seek never fails as POSIX allows the file offset to be set beyond the EOF | pa_lseek(f, info.offset, SEEK_SET); // seek never fails as POSIX allows the file offset to be set beyond the EOF |
| Line 286 bool file_read_action_under_lock(const S | Line 286 bool file_read_action_under_lock(const S |
| } | } |
| void create_dir_for_file(const String& file_spec) { | void create_dir_for_file(const String& file_spec) { |
| size_t pos_after=1; | const char *str=file_spec.taint_cstr(String::L_FILE_SPEC); |
| size_t pos_before; | if(str[0]){ |
| while((pos_before=file_spec.pos('/', pos_after))!=STRING_NOT_FOUND) { | const char *pos=str+1; |
| pa_mkdir(file_spec.mid(0, pos_before).taint_cstr(String::L_FILE_SPEC), 0775); | while((pos=strchr(pos,'/')) && pos[1]) { // to avoid trailing /, see #1166 |
| pos_after=pos_before+1; | pa_mkdir(pa_strdup(str,pos-str), 0775); |
| pos++; | |
| } | |
| } | } |
| } | } |
| Line 652 char* rsplit(char* string, char delim) { | Line 654 char* rsplit(char* string, char delim) { |
| return NULL; | return NULL; |
| } | } |
| void pa_strncpy(char *dst, const char *src, size_t n){ | |
| size_t left = n; | |
| if (left != 0 && src) { | |
| while (--left != 0) { | |
| if ((*dst++ = *src++) == '\0') | |
| return; | |
| } | |
| } | |
| if (n != 0) | |
| *dst = '\0'; | |
| } | |
| #define STRCAT_STEP(str, len) if(str) { memcpy(ptr, str, len); ptr += len; } | #define STRCAT_STEP(str, len) if(str) { memcpy(ptr, str, len); ptr += len; } |
| char *pa_strcat(const char *a, const char *b, const char *c) { | char *pa_strcat(const char *a, const char *b, const char *c) { |
| Line 748 const char* format(double value, const c | Line 763 const char* format(double value, const c |
| if(fmt && strlen(fmt)){ | if(fmt && strlen(fmt)){ |
| switch(format_type(fmt)){ | switch(format_type(fmt)){ |
| case FormatDouble: | case FormatDouble: |
| size=snprintf(local_buf, sizeof(local_buf), fmt, value); | size=snprintf(local_buf, sizeof(local_buf), fmt, value); |
| break; | |
| case FormatInt: | |
| size=snprintf(local_buf, sizeof(local_buf), fmt, (int)value); | |
| break; | break; |
| case FormatUInt: | case FormatUInt: |
| size=snprintf(local_buf, sizeof(local_buf), fmt, (uint)value); | if(value >= 0){ // on Apple M1 (uint)<negative value> is 0 |
| size=snprintf(local_buf, sizeof(local_buf), fmt, clip2uint(value)); | |
| break; | |
| } | |
| case FormatInt: | |
| size=snprintf(local_buf, sizeof(local_buf), fmt, clip2int(value)); | |
| break; | break; |
| case FormatInvalid: | case FormatInvalid: |
| throw Exception(PARSER_RUNTIME, 0, "Incorrect format string '%s' was specified.", fmt); | throw Exception(PARSER_RUNTIME, 0, "Incorrect format string '%s' was specified.", fmt); |
| } | } |
| } else | } else |
| size=snprintf(local_buf, sizeof(local_buf), "%d", (int)value); | size=snprintf(local_buf, sizeof(local_buf), "%d", clip2int(value)); |
| if(size < 0 || size >= MAX_NUMBER-1){ // on win32 we manually reduce max size while printing | if(size < 0 || size >= MAX_NUMBER-1){ // on win32 we manually reduce max size while printing |
| throw Exception(PARSER_RUNTIME, 0, "Error occurred white executing snprintf with format string '%s'.", fmt); | throw Exception(PARSER_RUNTIME, 0, "Error occurred white executing snprintf with format string '%s'.", fmt); |
| Line 897 size_t strpos(const char *str, const cha | Line 914 size_t strpos(const char *str, const cha |
| return (p==0)?STRING_NOT_FOUND:p-str; | return (p==0)?STRING_NOT_FOUND:p-str; |
| } | } |
| int remove_crlf(char* start, char* end) { | size_t remove_crlf(char* start, char* end) { |
| char* from=start; | char* from=start; |
| char* to=start; | char* to=start; |
| bool skip=false; | bool skip=false; |