Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
4026ef63
Commit
4026ef63
authored
Jul 22, 2021
by
Max Kellermann
Committed by
Max Kellermann
Aug 27, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
util/StringAPI: use [[gnu::]] attributes
parent
b282682b
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
42 additions
and
46 deletions
+42
-46
StringAPI.hxx
src/util/StringAPI.hxx
+21
-23
WStringAPI.hxx
src/util/WStringAPI.hxx
+21
-23
No files found.
src/util/StringAPI.hxx
View file @
4026ef63
/*
/*
* Copyright 2010-20
19
Max Kellermann <max.kellermann@gmail.com>
* Copyright 2010-20
21
Max Kellermann <max.kellermann@gmail.com>
*
*
* Redistribution and use in source and binary forms, with or without
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* modification, are permitted provided that the following conditions
...
@@ -30,71 +30,69 @@
...
@@ -30,71 +30,69 @@
#ifndef STRING_API_HXX
#ifndef STRING_API_HXX
#define STRING_API_HXX
#define STRING_API_HXX
#include "Compiler.h"
#include <cstring>
#include <cstring>
#ifdef _UNICODE
#ifdef _UNICODE
#include "WStringAPI.hxx"
#include "WStringAPI.hxx"
#endif
#endif
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
size_t
static
inline
size_t
StringLength
(
const
char
*
p
)
noexcept
StringLength
(
const
char
*
p
)
noexcept
{
{
return
strlen
(
p
);
return
strlen
(
p
);
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
const
char
*
static
inline
const
char
*
StringFind
(
const
char
*
haystack
,
const
char
*
needle
)
noexcept
StringFind
(
const
char
*
haystack
,
const
char
*
needle
)
noexcept
{
{
return
strstr
(
haystack
,
needle
);
return
strstr
(
haystack
,
needle
);
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
char
*
static
inline
char
*
StringFind
(
char
*
haystack
,
char
needle
,
size_t
size
)
noexcept
StringFind
(
char
*
haystack
,
char
needle
,
size_t
size
)
noexcept
{
{
return
(
char
*
)
std
::
memchr
(
haystack
,
needle
,
size
);
return
(
char
*
)
std
::
memchr
(
haystack
,
needle
,
size
);
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
const
char
*
static
inline
const
char
*
StringFind
(
const
char
*
haystack
,
char
needle
,
size_t
size
)
noexcept
StringFind
(
const
char
*
haystack
,
char
needle
,
size_t
size
)
noexcept
{
{
return
(
const
char
*
)
std
::
memchr
(
haystack
,
needle
,
size
);
return
(
const
char
*
)
std
::
memchr
(
haystack
,
needle
,
size
);
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
const
char
*
static
inline
const
char
*
StringFind
(
const
char
*
haystack
,
char
needle
)
noexcept
StringFind
(
const
char
*
haystack
,
char
needle
)
noexcept
{
{
return
std
::
strchr
(
haystack
,
needle
);
return
std
::
strchr
(
haystack
,
needle
);
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
char
*
static
inline
char
*
StringFind
(
char
*
haystack
,
char
needle
)
noexcept
StringFind
(
char
*
haystack
,
char
needle
)
noexcept
{
{
return
std
::
strchr
(
haystack
,
needle
);
return
std
::
strchr
(
haystack
,
needle
);
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
const
char
*
static
inline
const
char
*
StringFindLast
(
const
char
*
haystack
,
char
needle
)
noexcept
StringFindLast
(
const
char
*
haystack
,
char
needle
)
noexcept
{
{
return
std
::
strrchr
(
haystack
,
needle
);
return
std
::
strrchr
(
haystack
,
needle
);
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
char
*
static
inline
char
*
StringFindLast
(
char
*
haystack
,
char
needle
)
noexcept
StringFindLast
(
char
*
haystack
,
char
needle
)
noexcept
{
{
return
std
::
strrchr
(
haystack
,
needle
);
return
std
::
strrchr
(
haystack
,
needle
);
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
const
char
*
static
inline
const
char
*
StringFindLast
(
const
char
*
haystack
,
char
needle
,
size_t
size
)
noexcept
StringFindLast
(
const
char
*
haystack
,
char
needle
,
size_t
size
)
noexcept
{
{
...
@@ -115,7 +113,7 @@ StringFindLast(const char *haystack, char needle, size_t size) noexcept
...
@@ -115,7 +113,7 @@ StringFindLast(const char *haystack, char needle, size_t size) noexcept
#endif
#endif
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
const
char
*
static
inline
const
char
*
StringFindAny
(
const
char
*
haystack
,
const
char
*
accept
)
noexcept
StringFindAny
(
const
char
*
haystack
,
const
char
*
accept
)
noexcept
{
{
...
@@ -128,14 +126,14 @@ StringToken(char *str, const char *delim) noexcept
...
@@ -128,14 +126,14 @@ StringToken(char *str, const char *delim) noexcept
return
strtok
(
str
,
delim
);
return
strtok
(
str
,
delim
);
}
}
gcc_nonnull_all
[[
gnu
::
nonnull
]]
static
inline
void
static
inline
void
UnsafeCopyString
(
char
*
dest
,
const
char
*
src
)
noexcept
UnsafeCopyString
(
char
*
dest
,
const
char
*
src
)
noexcept
{
{
strcpy
(
dest
,
src
);
strcpy
(
dest
,
src
);
}
}
gcc_returns_nonnull
gcc_nonnull_all
[[
gnu
::
returns_nonnull
]]
[[
gnu
::
nonnull
]]
static
inline
char
*
static
inline
char
*
UnsafeCopyStringP
(
char
*
dest
,
const
char
*
src
)
noexcept
UnsafeCopyStringP
(
char
*
dest
,
const
char
*
src
)
noexcept
{
{
...
@@ -148,14 +146,14 @@ UnsafeCopyStringP(char *dest, const char *src) noexcept
...
@@ -148,14 +146,14 @@ UnsafeCopyStringP(char *dest, const char *src) noexcept
#endif
#endif
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
int
static
inline
int
StringCompare
(
const
char
*
a
,
const
char
*
b
)
noexcept
StringCompare
(
const
char
*
a
,
const
char
*
b
)
noexcept
{
{
return
strcmp
(
a
,
b
);
return
strcmp
(
a
,
b
);
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
int
static
inline
int
StringCompare
(
const
char
*
a
,
const
char
*
b
,
size_t
n
)
noexcept
StringCompare
(
const
char
*
a
,
const
char
*
b
,
size_t
n
)
noexcept
{
{
...
@@ -165,7 +163,7 @@ StringCompare(const char *a, const char *b, size_t n) noexcept
...
@@ -165,7 +163,7 @@ StringCompare(const char *a, const char *b, size_t n) noexcept
/**
/**
* Checks whether #a and #b are equal.
* Checks whether #a and #b are equal.
*/
*/
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
bool
static
inline
bool
StringIsEqual
(
const
char
*
a
,
const
char
*
b
)
noexcept
StringIsEqual
(
const
char
*
a
,
const
char
*
b
)
noexcept
{
{
...
@@ -175,28 +173,28 @@ StringIsEqual(const char *a, const char *b) noexcept
...
@@ -175,28 +173,28 @@ StringIsEqual(const char *a, const char *b) noexcept
/**
/**
* Checks whether #a and #b are equal.
* Checks whether #a and #b are equal.
*/
*/
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
bool
static
inline
bool
StringIsEqual
(
const
char
*
a
,
const
char
*
b
,
size_t
length
)
noexcept
StringIsEqual
(
const
char
*
a
,
const
char
*
b
,
size_t
length
)
noexcept
{
{
return
strncmp
(
a
,
b
,
length
)
==
0
;
return
strncmp
(
a
,
b
,
length
)
==
0
;
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
bool
static
inline
bool
StringIsEqualIgnoreCase
(
const
char
*
a
,
const
char
*
b
)
noexcept
StringIsEqualIgnoreCase
(
const
char
*
a
,
const
char
*
b
)
noexcept
{
{
return
strcasecmp
(
a
,
b
)
==
0
;
return
strcasecmp
(
a
,
b
)
==
0
;
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
bool
static
inline
bool
StringIsEqualIgnoreCase
(
const
char
*
a
,
const
char
*
b
,
size_t
size
)
noexcept
StringIsEqualIgnoreCase
(
const
char
*
a
,
const
char
*
b
,
size_t
size
)
noexcept
{
{
return
strncasecmp
(
a
,
b
,
size
)
==
0
;
return
strncasecmp
(
a
,
b
,
size
)
==
0
;
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
int
static
inline
int
StringCollate
(
const
char
*
a
,
const
char
*
b
)
noexcept
StringCollate
(
const
char
*
a
,
const
char
*
b
)
noexcept
{
{
...
@@ -207,7 +205,7 @@ StringCollate(const char *a, const char *b) noexcept
...
@@ -207,7 +205,7 @@ StringCollate(const char *a, const char *b) noexcept
* Copy the string to a new allocation. The return value must be
* Copy the string to a new allocation. The return value must be
* freed with free().
* freed with free().
*/
*/
gcc_malloc
gcc_returns_nonnull
gcc_nonnull_all
[[
gnu
::
malloc
]]
[[
gnu
::
returns_nonnull
]]
[[
gnu
::
nonnull
]]
static
inline
char
*
static
inline
char
*
DuplicateString
(
const
char
*
p
)
noexcept
DuplicateString
(
const
char
*
p
)
noexcept
{
{
...
...
src/util/WStringAPI.hxx
View file @
4026ef63
/*
/*
* Copyright 2010-20
18
Max Kellermann <max.kellermann@gmail.com>
* Copyright 2010-20
21
Max Kellermann <max.kellermann@gmail.com>
*
*
* Redistribution and use in source and binary forms, with or without
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* modification, are permitted provided that the following conditions
...
@@ -30,67 +30,65 @@
...
@@ -30,67 +30,65 @@
#ifndef WSTRING_API_HXX
#ifndef WSTRING_API_HXX
#define WSTRING_API_HXX
#define WSTRING_API_HXX
#include "Compiler.h"
#include <cwchar>
#include <cwchar>
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
size_t
static
inline
size_t
StringLength
(
const
wchar_t
*
p
)
noexcept
StringLength
(
const
wchar_t
*
p
)
noexcept
{
{
return
wcslen
(
p
);
return
wcslen
(
p
);
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
const
wchar_t
*
static
inline
const
wchar_t
*
StringFind
(
const
wchar_t
*
haystack
,
const
wchar_t
*
needle
)
noexcept
StringFind
(
const
wchar_t
*
haystack
,
const
wchar_t
*
needle
)
noexcept
{
{
return
wcsstr
(
haystack
,
needle
);
return
wcsstr
(
haystack
,
needle
);
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
const
wchar_t
*
static
inline
const
wchar_t
*
StringFind
(
const
wchar_t
*
haystack
,
wchar_t
needle
,
size_t
size
)
noexcept
StringFind
(
const
wchar_t
*
haystack
,
wchar_t
needle
,
size_t
size
)
noexcept
{
{
return
std
::
wmemchr
(
haystack
,
needle
,
size
);
return
std
::
wmemchr
(
haystack
,
needle
,
size
);
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
wchar_t
*
static
inline
wchar_t
*
StringFind
(
wchar_t
*
haystack
,
wchar_t
needle
,
size_t
size
)
noexcept
StringFind
(
wchar_t
*
haystack
,
wchar_t
needle
,
size_t
size
)
noexcept
{
{
return
std
::
wmemchr
(
haystack
,
needle
,
size
);
return
std
::
wmemchr
(
haystack
,
needle
,
size
);
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
const
wchar_t
*
static
inline
const
wchar_t
*
StringFind
(
const
wchar_t
*
haystack
,
wchar_t
needle
)
noexcept
StringFind
(
const
wchar_t
*
haystack
,
wchar_t
needle
)
noexcept
{
{
return
wcschr
(
haystack
,
needle
);
return
wcschr
(
haystack
,
needle
);
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
wchar_t
*
static
inline
wchar_t
*
StringFind
(
wchar_t
*
haystack
,
wchar_t
needle
)
noexcept
StringFind
(
wchar_t
*
haystack
,
wchar_t
needle
)
noexcept
{
{
return
wcschr
(
haystack
,
needle
);
return
wcschr
(
haystack
,
needle
);
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
const
wchar_t
*
static
inline
const
wchar_t
*
StringFindLast
(
const
wchar_t
*
haystack
,
wchar_t
needle
)
noexcept
StringFindLast
(
const
wchar_t
*
haystack
,
wchar_t
needle
)
noexcept
{
{
return
wcsrchr
(
haystack
,
needle
);
return
wcsrchr
(
haystack
,
needle
);
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
wchar_t
*
static
inline
wchar_t
*
StringFindLast
(
wchar_t
*
haystack
,
wchar_t
needle
)
noexcept
StringFindLast
(
wchar_t
*
haystack
,
wchar_t
needle
)
noexcept
{
{
return
wcsrchr
(
haystack
,
needle
);
return
wcsrchr
(
haystack
,
needle
);
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
const
wchar_t
*
static
inline
const
wchar_t
*
StringFindLast
(
const
wchar_t
*
haystack
,
wchar_t
needle
,
size_t
size
)
noexcept
StringFindLast
(
const
wchar_t
*
haystack
,
wchar_t
needle
,
size_t
size
)
noexcept
{
{
...
@@ -105,21 +103,21 @@ StringFindLast(const wchar_t *haystack, wchar_t needle, size_t size) noexcept
...
@@ -105,21 +103,21 @@ StringFindLast(const wchar_t *haystack, wchar_t needle, size_t size) noexcept
return
nullptr
;
return
nullptr
;
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
const
wchar_t
*
static
inline
const
wchar_t
*
StringFindAny
(
const
wchar_t
*
haystack
,
const
wchar_t
*
accept
)
noexcept
StringFindAny
(
const
wchar_t
*
haystack
,
const
wchar_t
*
accept
)
noexcept
{
{
return
wcspbrk
(
haystack
,
accept
);
return
wcspbrk
(
haystack
,
accept
);
}
}
gcc_nonnull_all
[[
gnu
::
nonnull
]]
static
inline
void
static
inline
void
UnsafeCopyString
(
wchar_t
*
dest
,
const
wchar_t
*
src
)
noexcept
UnsafeCopyString
(
wchar_t
*
dest
,
const
wchar_t
*
src
)
noexcept
{
{
wcscpy
(
dest
,
src
);
wcscpy
(
dest
,
src
);
}
}
gcc_returns_nonnull
gcc_nonnull_all
[[
gnu
::
returns_nonnull
]]
[[
gnu
::
nonnull
]]
static
inline
wchar_t
*
static
inline
wchar_t
*
UnsafeCopyStringP
(
wchar_t
*
dest
,
const
wchar_t
*
src
)
noexcept
UnsafeCopyStringP
(
wchar_t
*
dest
,
const
wchar_t
*
src
)
noexcept
{
{
...
@@ -134,14 +132,14 @@ UnsafeCopyStringP(wchar_t *dest, const wchar_t *src) noexcept
...
@@ -134,14 +132,14 @@ UnsafeCopyStringP(wchar_t *dest, const wchar_t *src) noexcept
#endif
#endif
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
int
static
inline
int
StringCompare
(
const
wchar_t
*
a
,
const
wchar_t
*
b
)
noexcept
StringCompare
(
const
wchar_t
*
a
,
const
wchar_t
*
b
)
noexcept
{
{
return
wcscmp
(
a
,
b
);
return
wcscmp
(
a
,
b
);
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
int
static
inline
int
StringCompare
(
const
wchar_t
*
a
,
const
wchar_t
*
b
,
size_t
n
)
noexcept
StringCompare
(
const
wchar_t
*
a
,
const
wchar_t
*
b
,
size_t
n
)
noexcept
{
{
...
@@ -154,7 +152,7 @@ StringCompare(const wchar_t *a, const wchar_t *b, size_t n) noexcept
...
@@ -154,7 +152,7 @@ StringCompare(const wchar_t *a, const wchar_t *b, size_t n) noexcept
* @param str2 String 2
* @param str2 String 2
* @return True if equal, False otherwise
* @return True if equal, False otherwise
*/
*/
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
bool
static
inline
bool
StringIsEqual
(
const
wchar_t
*
str1
,
const
wchar_t
*
str2
)
noexcept
StringIsEqual
(
const
wchar_t
*
str1
,
const
wchar_t
*
str2
)
noexcept
{
{
...
@@ -164,14 +162,14 @@ StringIsEqual(const wchar_t *str1, const wchar_t *str2) noexcept
...
@@ -164,14 +162,14 @@ StringIsEqual(const wchar_t *str1, const wchar_t *str2) noexcept
/**
/**
* Checks whether #a and #b are equal.
* Checks whether #a and #b are equal.
*/
*/
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
bool
static
inline
bool
StringIsEqual
(
const
wchar_t
*
a
,
const
wchar_t
*
b
,
size_t
length
)
noexcept
StringIsEqual
(
const
wchar_t
*
a
,
const
wchar_t
*
b
,
size_t
length
)
noexcept
{
{
return
wcsncmp
(
a
,
b
,
length
)
==
0
;
return
wcsncmp
(
a
,
b
,
length
)
==
0
;
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
bool
static
inline
bool
StringIsEqualIgnoreCase
(
const
wchar_t
*
a
,
const
wchar_t
*
b
)
noexcept
StringIsEqualIgnoreCase
(
const
wchar_t
*
a
,
const
wchar_t
*
b
)
noexcept
{
{
...
@@ -182,7 +180,7 @@ StringIsEqualIgnoreCase(const wchar_t *a, const wchar_t *b) noexcept
...
@@ -182,7 +180,7 @@ StringIsEqualIgnoreCase(const wchar_t *a, const wchar_t *b) noexcept
#endif
#endif
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
bool
static
inline
bool
StringIsEqualIgnoreCase
(
const
wchar_t
*
a
,
const
wchar_t
*
b
,
StringIsEqualIgnoreCase
(
const
wchar_t
*
a
,
const
wchar_t
*
b
,
size_t
size
)
noexcept
size_t
size
)
noexcept
...
@@ -194,14 +192,14 @@ StringIsEqualIgnoreCase(const wchar_t *a, const wchar_t *b,
...
@@ -194,14 +192,14 @@ StringIsEqualIgnoreCase(const wchar_t *a, const wchar_t *b,
#endif
#endif
}
}
gcc_pure
gcc_nonnull_all
[[
gnu
::
pure
]]
[[
gnu
::
nonnull
]]
static
inline
int
static
inline
int
StringCollate
(
const
wchar_t
*
a
,
const
wchar_t
*
b
)
noexcept
StringCollate
(
const
wchar_t
*
a
,
const
wchar_t
*
b
)
noexcept
{
{
return
wcscoll
(
a
,
b
);
return
wcscoll
(
a
,
b
);
}
}
gcc_malloc
gcc_returns_nonnull
gcc_nonnull_all
[[
gnu
::
malloc
]]
[[
gnu
::
returns_nonnull
]]
[[
gnu
::
nonnull
]]
static
inline
wchar_t
*
static
inline
wchar_t
*
DuplicateString
(
const
wchar_t
*
p
)
noexcept
DuplicateString
(
const
wchar_t
*
p
)
noexcept
{
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment