Skip to content

Commit

Permalink
Merge branch 'icu_mode'
Browse files Browse the repository at this point in the history
  • Loading branch information
elfmz committed Dec 3, 2024
2 parents 1af0cec + e1fd2b4 commit 1d5b787
Show file tree
Hide file tree
Showing 21 changed files with 259 additions and 245 deletions.
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ if(${CMAKE_VERSION} VERSION_LESS "3.1.0")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif()

if("${ICU_MODE}" STREQUAL "runtime")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DRUNTIME_ICU")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DRUNTIME_ICU")
endif()

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fPIC -Wno-unused-function -D_FILE_OFFSET_BITS=64") # -fsanitize=address
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -std=c99 -fPIC -Wno-unused-function -D_FILE_OFFSET_BITS=64") # -fsanitize=address
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ See also [Community packages & binaries](#community_bins)
* `libneon27-dev` (or later, _optional_ - needed for **NetRocks/WebDAV**)
* `libarchive-dev` (_optional_ - needed for better archives support in **multiarc**)
* `libunrar-dev` (_optional_ - needed for RAR archives support in **multiarc**, see `-DUNRAR` command line option)
* `libicu-dev` (_optional_ - needed if used non-default ICU_MODE, see `-DICU_MODE` command line option)
* `python3-dev` (_optional_ - needed for **python plugins** support, see `-DPYTHON` command line option)
* `python3-cffi` (_optional_ - needed for **python plugins** support, see `-DPYTHON` command line option)
* `cmake` ( >= 3.2.2 )
Expand Down Expand Up @@ -201,6 +202,12 @@ To force-disable TTY|X and TTY|Xi backends: add argument `-DTTYX=no`; to disable
To eliminate libuchardet requirement to reduce far2l dependencies by cost of losing automatic charset detection functionality: add `-DUSEUCD=no`
By default far2l uses pre-generated "hardcoded" UNICODE characters properties. But this can be changed by specifying -DICU_MODE when configuring cmake:
`-DICU_MODE=prebuilt` - is a described above default implementaion. Most dependency-less option.
`-DICU_MODE=build` - re-generate characters properties during build by using libicu available on build system, but it still not required to be present on target.
`-DICU_MODE=runtime` - obtain properties at runtime (that can be bit slower) using libicu that required to be present on target system.
To build with Python plugin: add argument `-DPYTHON=yes`
but you must have installed additional packages within yours system:
`python3-dev`,
Expand Down
4 changes: 2 additions & 2 deletions WinPort/WinCompat.h
Original file line number Diff line number Diff line change
Expand Up @@ -406,8 +406,8 @@ typedef struct _CHAR_INFO {
#define CI_SET_WCATTR(CI, WC, ATTR) {(CI).Char.UnicodeChar = (COMP_CHAR)(uint32_t)(WC); (CI).Attributes = (DWORD64)ATTR;}

#define CI_USING_COMPOSITE_CHAR(CI) ( ((CI).Char.UnicodeChar & COMPOSITE_CHAR_MARK) != 0 )
#define CI_FULL_WIDTH_CHAR(CI) ( (!CI_USING_COMPOSITE_CHAR(CI) && IsCharFullWidth((CI).Char.UnicodeChar)) \
|| (CI_USING_COMPOSITE_CHAR(CI) && IsCharFullWidth(*WINPORT(CompositeCharLookup)((CI).Char.UnicodeChar))))
#define CI_FULL_WIDTH_CHAR(CI) ( (!CI_USING_COMPOSITE_CHAR(CI) && CharClasses((CI).Char.UnicodeChar).FullWidth()) \
|| (CI_USING_COMPOSITE_CHAR(CI) && CharClasses(*WINPORT(CompositeCharLookup)((CI).Char.UnicodeChar)).FullWidth()))

#define GET_RGB_FORE(ATTR) ((DWORD)(((ATTR) >> 16) & 0xffffff))
#define GET_RGB_BACK(ATTR) ((DWORD)(((ATTR) >> 40) & 0xffffff))
Expand Down
2 changes: 0 additions & 2 deletions WinPort/WinPortDecl.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,6 @@
// not implemented
WINPORT_DECL_DEF(GetDriveType, UINT, (LPCWSTR lpRootPathName))
#endif
WINPORT_DECL_DEF(GetTempFileName, UINT,( LPCWSTR path, LPCWSTR prefix, UINT unique, LPWSTR buffer ))
WINPORT_DECL_DEF(GetFullPathName, DWORD, (LPCTSTR lpFileName, DWORD nBufferLength, LPTSTR lpBuffer, LPTSTR *lpFilePart))

WINPORT_DECL_DEF(EvaluateAttributes, DWORD,( uint32_t unix_mode, const WCHAR *name ))
WINPORT_DECL_DEF(EvaluateAttributesA, DWORD,( uint32_t unix_mode, const char *name ))
Expand Down
94 changes: 0 additions & 94 deletions WinPort/src/APIFiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -972,98 +972,4 @@ extern "C"
return TRUE;
}

WINPORT_DECL(GetTempFileName, UINT,( LPCWSTR path, LPCWSTR prefix, UINT unique, LPWSTR buffer ))
{
static const WCHAR formatW[] = {'%','x','.','t','m','p',0};
int i;
LPWSTR p;
DWORD attr;

if ( !path || !buffer )
{
WINPORT(SetLastError)( ERROR_INVALID_PARAMETER );
return 0;
}

/* ensure that the provided directory exists */
attr = WINPORT(GetFileAttributes)(path);
if (attr == INVALID_FILE_ATTRIBUTES || !(attr & FILE_ATTRIBUTE_DIRECTORY))
{
WINPORT(SetLastError)( ERROR_DIRECTORY );
return 0;
}

size_t path_len = wcslen(path);
if (path_len>=MAX_PATH) {
WINPORT(SetLastError)( ERROR_INVALID_NAME);
return 0;
}
wcscpy( buffer, path );
p = buffer + path_len;

/* add a \, if there isn't one */
if ((p == buffer) || (p[-1] !=GOOD_SLASH)) *p++ = GOOD_SLASH;

if (prefix)
for (i = 3; (i > 0) && (*prefix); i--) *p++ = *prefix++;

unique &= 0xffff;

if (unique) swprintf( p, MAX_PATH - 1 - (p - buffer), formatW, unique );
else
{
/* get a "random" unique number and try to create the file */
UINT num = WINPORT(GetTickCount)() & 0xffff;
static UINT last;

/* avoid using the same name twice in a short interval */
if (last - num < 10) num = last + 1;
if (!num) num = 1;
unique = num;
std::string path_mb;
do {
swprintf( p, MAX_PATH - 1 - (p - buffer), formatW, unique );
Wide2MB(buffer, path_mb);
int fd = sdc_open(path_mb.c_str(), O_RDWR | O_CREAT | O_EXCL, 0640);
if (fd != -1) {
/* We created it */
sdc_close(fd);
last = unique;
break;
}
int err = errno;
if (err != EEXIST && err != EBUSY && err != ETXTBSY)
break; /* No need to go on */
if (!(++unique & 0xffff)) unique = 1;
} while (unique != num);
}

return unique;
}

WINPORT_DECL(GetFullPathName, DWORD,
(LPCTSTR lpFileName, DWORD nBufferLength, LPTSTR lpBuffer, LPTSTR *lpFilePart))
{
std::wstring full_name;
if (*lpFileName!=GOOD_SLASH) {
WCHAR cd[MAX_PATH+1] = {0};
WINPORT(GetCurrentDirectory)( MAX_PATH, cd);
full_name = cd;
if (*lpFileName!='.') {
full_name+=GOOD_SLASH;
full_name+= lpFileName;
} else
full_name+= lpFileName + 1;
} else
full_name = lpFileName;
if (nBufferLength<=full_name.size())
return full_name.size() + 1;

memcpy(lpBuffer, full_name.c_str(), (full_name.size() + 1) * sizeof(WCHAR));
if (lpFilePart) {
WCHAR *slash = wcsrchr(lpBuffer, GOOD_SLASH);
*lpFilePart = slash ? slash + 1 : lpBuffer;
}
return full_name.size();
}
}
25 changes: 13 additions & 12 deletions WinPort/src/ConsoleOutput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -407,14 +407,15 @@ SHORT ConsoleOutput::ModifySequenceEntityAt(SequenceModifier &sm, COORD pos, SMA
SHORT out = 1;

switch (sm.kind) {
case SequenceModifier::SM_WRITE_STR:
if (IsCharPrefix(*sm.str)) {
case SequenceModifier::SM_WRITE_STR: {
CharClasses cc(*sm.str);
if (cc.Prefix()) {
out = 0;
CI_SET_WCHAR(ch, *sm.str);
// surrogate pairs not used for UTF32, so dont need to do special tricks to keep it,
// so let following normal character to overwrite abnormal surrogate pair prefixx

} else if (IsCharSuffix(*sm.str) && _prev_pos.X >= 0) {
} else if (_prev_pos.X >= 0 && cc.Suffix()) {
out = 0;
if (!_buf.Read(ch, _prev_pos)) {
return false;
Expand All @@ -429,34 +430,34 @@ SHORT ConsoleOutput::ModifySequenceEntityAt(SequenceModifier &sm, COORD pos, SMA
tmp+= *sm.str;
CI_SET_COMPOSITE(ch, tmp.c_str());

} else if (*sm.str == L'\t' && (_mode & ENABLE_PROCESSED_OUTPUT) != 0) {
CI_SET_WCHAR(ch, L' ');

} else {
CI_SET_WCHAR(ch, *sm.str);
if ((_mode&ENABLE_PROCESSED_OUTPUT)!=0 && ch.Char.UnicodeChar==L'\t') {
CI_SET_WCHAR(ch, L' ');
}
if (IsCharFullWidth(ch.Char.UnicodeChar)) {
if (cc.FullWidth()) {
// fprintf(stderr, "IsCharFullWidth: %lc [0x%llx]\n",
// (WCHAR)ch.Char.UnicodeChar, (unsigned long long)ch.Char.UnicodeChar);
out = 2;
}
}
CI_SET_ATTR(ch, _attributes);
_prev_pos = pos;
break;
} break;

case SequenceModifier::SM_FILL_CHAR:
case SequenceModifier::SM_FILL_CHAR: {
if (!_buf.Read(ch, pos))
return out;

CI_SET_WCHAR(ch, sm.chr);
break;
} break;

case SequenceModifier::SM_FILL_ATTR:
case SequenceModifier::SM_FILL_ATTR: {
if (!_buf.Read(ch, pos))
return out;

CI_SET_ATTR(ch, sm.attr);
break;
} break;
}

if (_buf.Write(ch, pos) == ConsoleBuffer::WR_MODIFIED) {
Expand Down
3 changes: 0 additions & 3 deletions WinPort/windows.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,6 @@
#define FindNextFile WINPORT(FindNextFile)
#define FindClose WINPORT(FindClose)

#define GetTempFileName WINPORT(GetTempFileName)
#define GetFullPathName WINPORT(GetFullPathName)

#define EvaluateAttributes WINPORT(Sleep)

#define Sleep WINPORT(Sleep)
Expand Down
18 changes: 10 additions & 8 deletions far2l/src/ViewerPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ int PlainViewerPrinter::Length(const wchar_t *str, int limit)
int out;
for (out = 0; *str && limit != 0; ++str, --limit) {
if (!ShouldSkip(*str)) {
if (IsCharFullWidth(*str))
CharClasses cc(*str);
if (cc.FullWidth())
out+= 2;
else if (!IsCharXxxfix(*str))
else if (!cc.Xxxfix())
++out;
}
}
Expand All @@ -56,12 +57,13 @@ void PlainViewerPrinter::Print(int skip_len, int print_len, const wchar_t *str)
SetColor(_selection ? FarColorToReal(COL_VIEWERSELECTEDTEXT) : _color);

for(; skip_len > 0 && *str; ++str) {
if (ShouldSkip(*str))
;
else if (IsCharFullWidth(*str))
skip_len-= 2;
else if (!IsCharXxxfix(*str))
skip_len--;
if (!ShouldSkip(*str)) {
CharClasses cc(*str);
if (cc.FullWidth())
skip_len-= 2;
else if (!cc.Xxxfix())
skip_len--;
}
}

while (print_len > 0) {
Expand Down
18 changes: 10 additions & 8 deletions far2l/src/console/interf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ void Text(const WCHAR *Str, size_t Length)
CI_SET_WCHAR(BufPtr[nCells], Str[i]);
}
CI_SET_ATTR(BufPtr[nCells], CurColor);
if (IsCharFullWidth(Str[i])) {
if (CharClasses(Str[i]).FullWidth()) {
++nCells;
CI_SET_WCATTR(BufPtr[nCells], 0, CurColor);
}
Expand Down Expand Up @@ -610,7 +610,7 @@ void TextEx(const WCHAR *Str, size_t Length)

// CI_SET_ATTR(BufPtr[nCells], CurColor);

if (IsCharFullWidth(Str[i])) {
if (CharClasses(Str[i]).FullWidth()) {
++nCells;
CI_SET_WCATTR(BufPtr[nCells], 0, CurColor);
}
Expand Down Expand Up @@ -1163,9 +1163,10 @@ int HiStrCellsCount(const wchar_t *Str)

Length+= Count / 2;
} else {
if (IsCharFullWidth(*Str))
CharClasses cc(*Str);
if (cc.FullWidth())
Length+= 2;
else if (!IsCharXxxfix(*Str))
else if (!cc.Xxxfix())
Length+= 1;
Str++;
}
Expand Down Expand Up @@ -1206,9 +1207,10 @@ int HiFindRealPos(const wchar_t *Str, int Pos, BOOL ShowAmp)
}
}

if (IsCharFullWidth(*Str))
CharClasses cc(*Str);
if (cc.FullWidth())
VisPos+= 2;
else if (!IsCharXxxfix(*Str))
else if (!cc.Xxxfix())
VisPos+= 1;
Str++;
RealPos++;
Expand Down Expand Up @@ -1243,7 +1245,7 @@ int HiFindNextVisualPos(const wchar_t *Str, int Pos, int Direct)
return Pos - 2;
}

if (Pos > 1 && IsCharFullWidth(Str[Pos - 1]))
if (Pos > 1 && CharClasses(Str[Pos - 1]).FullWidth())
return Pos - 2;

return Pos - 1;
Expand All @@ -1263,7 +1265,7 @@ int HiFindNextVisualPos(const wchar_t *Str, int Pos, int Direct)

return Pos + 2;
} else {
return IsCharFullWidth(*Str) ? Pos + 2 : Pos + 1;
return CharClasses(*Str).FullWidth() ? Pos + 2 : Pos + 1;
}
}
}
Expand Down
Loading

0 comments on commit 1d5b787

Please sign in to comment.