Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
doxverilog
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
doxverilog
Commits
7d933a9f
Commit
7d933a9f
authored
Oct 21, 2014
by
Dimitri van Heesch
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Reverted back to old string implementation. New one needs more work.
parent
869ff348
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
1583 additions
and
779 deletions
+1583
-779
qcstring.cpp
qtools/qcstring.cpp
+381
-239
qcstring.h
qtools/qcstring.h
+247
-539
qtools.pro.in
qtools/qtools.pro.in
+2
-1
scstring.cpp
qtools/scstring.cpp
+798
-0
scstring.h
qtools/scstring.h
+155
-0
No files found.
qtools/qcstring.cpp
View file @
7d933a9f
...
...
@@ -3,8 +3,8 @@
* Copyright (C) 1997-2004 by Dimitri van Heesch.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation under the terms of the GNU General Public License is hereby
* granted. No representations are made about the suitability of this software
* documentation under the terms of the GNU General Public License is hereby
* granted. No representations are made about the suitability of this software
* for any purpose. It is provided "as is" without express or implied warranty.
* See the GNU General Public License for more details.
*
...
...
@@ -24,148 +24,281 @@
#include <qregexp.h>
#include <qdatastream.h>
QCString
&
QCString
::
sprintf
(
const
char
*
format
,
...
)
QCString
::
QCString
(
int
size
)
{
va_list
ap
;
va_start
(
ap
,
format
);
const
int
minlen
=
256
;
if
(
length
()
<
minlen
)
resize
(
minlen
);
vsnprintf
(
data
(),
minlen
,
format
,
ap
);
resize
(
strlen
(
data
())
+
1
);
va_end
(
ap
);
if
(
size
>
0
)
{
m_data
=
(
char
*
)
malloc
(
size
);
if
(
m_data
)
{
if
(
size
>
1
)
memset
(
m_data
,
' '
,
size
-
1
);
m_data
[
size
-
1
]
=
'\0'
;
}
}
else
{
m_data
=
0
;
}
}
QCString
::
QCString
(
const
QCString
&
s
)
{
duplicate
(
s
);
}
QCString
::
QCString
(
const
char
*
str
)
{
duplicate
(
str
);
}
QCString
::
QCString
(
const
char
*
str
,
uint
maxlen
)
{
uint
l
;
if
(
str
&&
(
l
=
QMIN
(
qstrlen
(
str
),
maxlen
)
))
{
m_data
=
(
char
*
)
malloc
(
l
+
1
);
strncpy
(
m_data
,
str
,
l
+
1
);
m_data
[
l
]
=
'\0'
;
}
else
{
m_data
=
0
;
}
}
QCString
::~
QCString
()
{
if
(
m_data
)
free
(
m_data
);
m_data
=
0
;
}
QCString
&
QCString
::
assign
(
const
char
*
str
)
{
if
(
m_data
)
free
(
m_data
);
duplicate
(
str
);
return
*
this
;
}
int
QCString
::
find
(
char
c
,
int
index
,
bool
cs
)
const
bool
QCString
::
resize
(
uint
newlen
)
{
if
(
index
<
0
||
index
>=
(
int
)
length
())
return
-
1
;
// index outside string
register
const
char
*
pos
;
if
(
cs
)
if
(
newlen
==
0
)
{
if
(
m_data
)
{
free
(
m_data
);
m_data
=
0
;
}
return
TRUE
;
}
if
(
m_data
==
0
)
// newlen>0
{
pos
=
strchr
(
data
()
+
index
,
c
);
m_data
=
(
char
*
)
malloc
(
newlen
);
}
else
{
pos
=
data
()
+
index
;
c
=
tolower
((
unsigned
char
)
c
);
while
(
*
pos
&&
tolower
((
unsigned
char
)
*
pos
)
!=
c
)
pos
++
;
if
(
!*
pos
&&
c
)
pos
=
0
;
// not found
m_data
=
(
char
*
)
realloc
(
m_data
,
newlen
);
}
return
pos
?
(
int
)(
pos
-
data
())
:
-
1
;
if
(
m_data
==
0
)
return
FALSE
;
m_data
[
newlen
-
1
]
=
'\0'
;
return
TRUE
;
}
int
QCString
::
find
(
const
char
*
str
,
int
index
,
bool
cs
)
const
bool
QCString
::
fill
(
char
c
,
int
len
)
{
int
l
=
length
();
if
(
index
<
0
||
index
>=
l
)
return
-
1
;
// index outside string
if
(
!
str
)
return
-
1
;
// no string to search for
if
(
!*
str
)
return
index
;
// empty string matching at index
register
char
*
pos
;
if
(
cs
)
// case sensitive
uint
l
=
length
();
if
(
len
<
0
)
len
=
l
;
if
((
uint
)
len
!=
l
)
{
pos
=
strstr
(
data
()
+
index
,
str
);
if
(
m_data
)
free
(
m_data
);
if
(
len
>
0
)
{
m_data
=
(
char
*
)
malloc
(
len
+
1
);
if
(
m_data
==
0
)
return
FALSE
;
m_data
[
len
]
=
'\0'
;
}
else
{
m_data
=
0
;
}
}
else
// case insensitive
if
(
len
>
0
)
{
pos
=
data
();
int
len
=
strlen
(
str
);
while
(
*
pos
)
uint
i
;
for
(
i
=
0
;
i
<
(
uint
)
len
;
i
++
)
m_data
[
i
]
=
c
;
}
return
TRUE
;
}
QCString
&
QCString
::
sprintf
(
const
char
*
format
,
...
)
{
va_list
ap
;
va_start
(
ap
,
format
);
uint
l
=
length
();
const
uint
minlen
=
256
;
if
(
l
<
minlen
)
{
if
(
m_data
)
m_data
=
(
char
*
)
realloc
(
m_data
,
minlen
);
else
m_data
=
(
char
*
)
malloc
(
minlen
);
}
vsprintf
(
m_data
,
format
,
ap
);
resize
(
qstrlen
(
m_data
)
+
1
);
// truncate
va_end
(
ap
);
return
*
this
;
}
int
QCString
::
find
(
char
c
,
int
index
,
bool
cs
)
const
{
uint
len
=
length
();
if
(
m_data
==
0
||
(
uint
)
index
>
len
)
// index outside string
return
-
1
;
register
const
char
*
d
;
if
(
cs
)
// case sensitive
{
d
=
strchr
(
m_data
+
index
,
c
);
}
else
{
d
=
m_data
+
index
;
c
=
tolower
(
(
uchar
)
c
);
while
(
*
d
&&
tolower
((
uchar
)
*
d
)
!=
c
)
d
++
;
if
(
!*
d
&&
c
)
// not found
d
=
0
;
}
return
d
?
(
int
)(
d
-
m_data
)
:
-
1
;
}
int
QCString
::
find
(
const
char
*
str
,
int
index
,
bool
cs
)
const
{
uint
l
=
length
();
if
(
m_data
==
0
||
(
uint
)
index
>
l
)
// index outside string
return
-
1
;
if
(
!
str
)
// no search string
return
-
1
;
if
(
!*
str
)
// zero-length search string
return
index
;
register
const
char
*
d
;
if
(
cs
)
// case sensitive
{
d
=
strstr
(
m_data
+
index
,
str
);
}
else
// case insensitive
{
d
=
m_data
+
index
;
int
len
=
qstrlen
(
str
);
while
(
*
d
)
{
if
(
strncasecmp
(
pos
,
str
,
len
)
==
0
)
break
;
pos
++
;
if
(
qstrnicmp
(
d
,
str
,
len
)
==
0
)
break
;
d
++
;
}
if
(
!*
pos
)
pos
=
0
;
// not found
if
(
!*
d
)
// not found
d
=
0
;
}
return
pos
?
(
int
)(
pos
-
data
()
)
:
-
1
;
return
d
?
(
int
)(
d
-
m_data
)
:
-
1
;
}
int
QCString
::
find
(
const
QCString
&
str
,
int
index
,
bool
cs
)
const
int
QCString
::
find
(
const
QCString
&
str
,
int
index
,
bool
cs
)
const
{
return
find
(
str
.
data
(),
index
,
cs
);
}
int
QCString
::
find
(
const
QRegExp
&
rx
,
int
index
)
const
{
QString
d
=
QString
::
fromLatin1
(
data
()
);
QString
d
=
QString
::
fromLatin1
(
m_data
);
return
d
.
find
(
rx
,
index
);
}
int
QCString
::
findRev
(
char
c
,
int
index
,
bool
cs
)
const
{
// printf("QCString::findRev(%d,%d,%d)\n",c,index,cs);
const
char
*
b
=
data
();
const
char
*
pos
;
int
len
=
length
();
if
(
len
==
0
)
return
-
1
;
// empty string
if
(
index
<
0
)
// start from end
const
char
*
b
=
m_data
;
const
char
*
d
;
uint
len
=
length
();
if
(
b
==
0
)
return
-
1
;
// empty string
if
(
index
<
0
)
// neg index ==> start from end
{
if
(
cs
)
if
(
len
==
0
)
return
-
1
;
if
(
cs
)
{
pos
=
strrchr
(
b
,
c
);
return
pos
?
(
int
)(
pos
-
b
)
:
-
1
;
d
=
strrchr
(
b
,
c
);
return
d
?
(
int
)(
d
-
b
)
:
-
1
;
}
index
=
len
;
}
else
if
(
index
>
len
)
// bad index
{
index
=
len
;
}
else
if
(
(
uint
)
index
>
len
)
// bad index
{
return
-
1
;
}
pos
=
b
+
index
;
if
(
cs
)
d
=
b
+
index
;
if
(
cs
)
// case sensitive
{
while
(
pos
>=
b
&&
*
pos
!=
c
)
pos
--
;
}
else
while
(
d
>=
b
&&
*
d
!=
c
)
d
--
;
}
else
// case insensitive
{
c
=
tolower
((
unsigned
char
)
c
);
while
(
pos
>=
b
&&
tolower
((
unsigned
char
)
*
pos
)
!=
c
)
pos
--
;
c
=
tolower
(
(
uchar
)
c
);
while
(
d
>=
b
&&
tolower
((
uchar
)
*
d
)
!=
c
)
d
--
;
}
//printf("pos=%p b=%p diff=%d\n",pos,b,(int)(pos-b));
return
pos
>=
b
?
(
int
)(
pos
-
b
)
:
-
1
;
return
d
>=
b
?
(
int
)(
d
-
b
)
:
-
1
;
}
int
QCString
::
findRev
(
const
char
*
str
,
int
index
,
bool
cs
)
const
{
int
slen
=
strlen
(
str
);
int
len
=
length
();
if
(
index
<
0
)
index
=
len
-
slen
;
// start from end
else
if
(
index
>
len
)
return
-
1
;
// bad index
else
if
(
index
+
slen
>
len
)
index
=
len
-
slen
;
// str would be too long
if
(
index
<
0
)
return
-
1
;
// no match possible
register
char
*
pos
=
data
()
+
index
;
if
(
cs
)
// case sensitive
{
for
(
int
i
=
index
;
i
>=
0
;
i
--
)
if
(
strncmp
(
pos
--
,
str
,
slen
)
==
0
)
return
i
;
}
else
// case insensitive
{
for
(
int
i
=
index
;
i
>=
0
;
i
--
)
if
(
strncasecmp
(
pos
,
str
,
slen
)
==
0
)
return
i
;
int
slen
=
qstrlen
(
str
);
uint
len
=
length
();
if
(
index
<
0
)
// neg index ==> start from end
index
=
len
-
slen
;
else
if
(
(
uint
)
index
>
len
)
// bad index
return
-
1
;
else
if
(
(
uint
)(
index
+
slen
)
>
len
)
// str would be too long
index
=
len
-
slen
;
if
(
index
<
0
)
return
-
1
;
register
char
*
d
=
m_data
+
index
;
if
(
cs
)
// case sensitive
{
for
(
int
i
=
index
;
i
>=
0
;
i
--
)
if
(
qstrncmp
(
d
--
,
str
,
slen
)
==
0
)
return
i
;
}
else
// case insensitive
{
for
(
int
i
=
index
;
i
>=
0
;
i
--
)
if
(
qstrnicmp
(
d
--
,
str
,
slen
)
==
0
)
return
i
;
}
return
-
1
;
}
int
QCString
::
findRev
(
const
QRegExp
&
rx
,
int
index
)
const
{
QString
d
=
QString
::
fromLatin1
(
data
()
);
QString
d
=
QString
::
fromLatin1
(
m_data
);
return
d
.
findRev
(
rx
,
index
);
}
int
QCString
::
contains
(
char
c
,
bool
cs
)
const
{
if
(
length
()
==
0
)
return
0
;
int
count
=
0
;
const
char
*
pos
=
data
();
if
(
cs
)
{
while
(
*
pos
)
if
(
*
pos
++
==
c
)
count
++
;
}
else
{
c
=
tolower
((
unsigned
char
)
c
);
while
(
*
pos
)
{
if
(
tolower
((
unsigned
char
)
*
pos
)
==
c
)
count
++
;
pos
++
;
int
count
=
0
;
char
*
d
=
m_data
;
if
(
!
d
)
return
0
;
if
(
cs
)
// case sensitive
{
while
(
*
d
)
if
(
*
d
++
==
c
)
count
++
;
}
else
// case insensitive
{
c
=
tolower
(
(
uchar
)
c
);
while
(
*
d
)
{
if
(
tolower
((
uchar
)
*
d
)
==
c
)
count
++
;
d
++
;
}
}
return
count
;
...
...
@@ -173,106 +306,96 @@ int QCString::contains( char c, bool cs ) const
int
QCString
::
contains
(
const
char
*
str
,
bool
cs
)
const
{
if
(
str
==
0
||
length
()
==
0
)
return
0
;
int
count
=
0
;
const
char
*
pos
=
data
();
int
len
=
strlen
(
str
);
while
(
*
pos
)
int
count
=
0
;
char
*
d
=
data
();
if
(
!
d
)
return
0
;
int
len
=
qstrlen
(
str
);
while
(
*
d
)
// counts overlapping strings
{
if
(
cs
)
if
(
cs
)
{
if
(
strncmp
(
pos
,
str
,
len
)
==
0
)
count
++
;
}
else
if
(
qstrncmp
(
d
,
str
,
len
)
==
0
)
count
++
;
}
else
{
if
(
strncasecmp
(
pos
,
str
,
len
)
==
0
)
count
++
;
if
(
qstrnicmp
(
d
,
str
,
len
)
==
0
)
count
++
;
}
pos
++
;
d
++
;
}
return
count
;
}
int
QCString
::
contains
(
const
QRegExp
&
rx
)
const
{
QString
d
=
QString
::
fromLatin1
(
data
()
);
{
QString
d
=
QString
::
fromLatin1
(
m_data
);
return
d
.
contains
(
rx
);
}
bool
QCString
::
stripPrefix
(
const
char
*
prefix
)
{
if
(
prefix
==
0
||
length
()
==
0
)
return
FALSE
;
int
len
=
strlen
(
prefix
);
if
(
strncmp
(
prefix
,
data
(),
len
)
==
0
)
{
int
newlen
=
length
()
-
len
+
1
;
qmemmove
(
data
(),
data
()
+
len
,
newlen
);
resize
(
newlen
);
return
TRUE
;
}
return
FALSE
;
}
QCString
QCString
::
left
(
uint
len
)
const
{
if
(
isEmpty
())
if
(
isEmpty
()
)
{
return
QCString
();
}
else
if
(
len
>=
length
())
}
else
if
(
len
>=
length
()
)
{
return
QCString
(
data
())
;
}
else
return
*
this
;
}
else
{
QCString
s
(
len
+
1
);
memcpy
(
s
.
data
(),
data
(),
len
);
strncpy
(
s
.
data
(),
m_data
,
len
);
*
(
s
.
data
()
+
len
)
=
'\0'
;
return
s
;
}
}
QCString
QCString
::
right
(
uint
len
)
const
{
if
(
isEmpty
())
if
(
isEmpty
()
)
{
return
QCString
();
}
else
}
else
{
int
l
=
length
();
if
(
(
int
)
len
>
l
)
len
=
l
;
c
onst
char
*
pos
=
data
()
+
(
l
-
len
);
return
QCString
(
pos
);
}
u
int
l
=
length
();
if
(
len
>
l
)
len
=
l
;
c
har
*
p
=
m_data
+
(
l
-
len
);
return
QCString
(
p
);
}
}
QCString
QCString
::
mid
(
uint
index
,
uint
len
)
const
{
int
slen
=
length
();
if
(
len
==
0xffffffff
)
len
=
slen
-
index
;
if
(
isEmpty
()
||
(
int
)
index
>=
slen
)
u
int
slen
=
length
();
if
(
len
==
0xffffffff
)
len
=
slen
-
index
;
if
(
isEmpty
()
||
index
>=
slen
)
{
return
QCString
();
}
else
}
else
{
register
char
*
p
=
data
()
+
index
;
QCString
s
(
len
+
1
);
memcpy
(
s
.
data
(),
p
,
len
);
QCString
s
(
len
+
1
);
strncpy
(
s
.
data
(),
p
,
len
);
*
(
s
.
data
()
+
len
)
=
'\0'
;
return
s
;
}
}
QCString
QCString
::
lower
()
const
{
if
(
length
()
==
0
)
return
QCString
();
QCString
s
(
data
());
register
char
*
pos
=
s
.
data
();
if
(
pos
)
QCString
s
(
m_data
);
register
char
*
p
=
s
.
data
();
if
(
p
)
{
while
(
*
pos
)
while
(
*
p
)
{
*
p
os
=
tolower
((
unsigned
char
)
*
pos
);
p
os
++
;
*
p
=
tolower
((
uchar
)
*
p
);
p
++
;
}
}
return
s
;
...
...
@@ -280,44 +403,41 @@ QCString QCString::lower() const
QCString
QCString
::
upper
()
const
{
if
(
length
()
==
0
)
return
QCString
();
QCString
s
(
data
());
register
char
*
pos
=
s
.
data
();
if
(
pos
)
{
while
(
*
pos
)
{
*
pos
=
toupper
((
unsigned
char
)
*
pos
);
pos
++
;
QCString
s
(
m_data
);
register
char
*
p
=
s
.
data
();
if
(
p
)
{
while
(
*
p
)
{
*
p
=
toupper
((
uchar
)
*
p
);
p
++
;
}
}
return
s
;
}
QCString
QCString
::
stripWhiteSpace
()
const
QCString
QCString
::
stripWhiteSpace
()
const
{
if
(
isEmpty
()
)
// nothing to do
return
*
this
;
register
char
*
s
=
data
()
;
register
char
*
s
=
m_data
;
int
reslen
=
length
();
if
(
!
isspace
((
uchar
)
s
[
0
])
&&
!
isspace
((
uchar
)
s
[
reslen
-
1
])
)
return
*
this
;
// returns a copy
if
(
!
isspace
((
uchar
)
s
[
0
])
&&
!
isspace
((
uchar
)
s
[
reslen
-
1
])
)
return
*
this
;
// returns a copy
QCString
result
(
s
);
s
=
result
.
data
();
s
=
result
.
data
();
int
start
=
0
;
int
end
=
reslen
-
1
;
while
(
isspace
((
uchar
)
s
[
start
])
)
// skip white space from start
start
++
;
if
(
s
[
start
]
==
'\0'
)
start
++
;
if
(
s
[
start
]
==
'\0'
)
{
// only white space
return
QCString
();
}
while
(
end
&&
isspace
((
uchar
)
s
[
end
])
)
// skip white space from end
end
--
;
end
-=
start
-
1
;
q
memmove
(
result
.
data
(),
&
s
[
start
],
end
);
memmove
(
result
.
data
(),
&
s
[
start
],
end
);
result
.
resize
(
end
+
1
);
return
result
;
}
...
...
@@ -331,7 +451,7 @@ QCString QCString::simplifyWhiteSpace() const
char
*
from
=
data
();
char
*
to
=
result
.
data
();
char
*
first
=
to
;
while
(
TRUE
)
while
(
TRUE
)
{
while
(
*
from
&&
isspace
((
uchar
)
*
from
)
)
from
++
;
...
...
@@ -349,66 +469,84 @@ QCString QCString::simplifyWhiteSpace() const
return
result
;
}
QCString
&
QCString
::
assign
(
const
char
*
str
)
{
return
operator
=
(
str
);
}
QCString
&
QCString
::
insert
(
uint
index
,
const
char
*
s
)
{
{
int
len
=
s
?
qstrlen
(
s
)
:
0
;
if
(
len
==
0
)
return
*
this
;
int
olen
=
length
();
int
nlen
=
olen
+
len
;
if
((
int
)
index
>=
olen
)
{
resize
(
nlen
+
index
-
olen
+
1
);
memset
(
data
()
+
olen
,
' '
,
index
-
olen
);
memcpy
(
data
()
+
index
,
s
,
len
+
1
);
}
else
{
resize
(
nlen
+
1
);
qmemmove
(
data
()
+
index
+
len
,
data
()
+
index
,
olen
-
index
+
1
);
memcpy
(
data
()
+
index
,
s
,
len
);
if
(
len
==
0
)
return
*
this
;
uint
olen
=
length
();
int
nlen
=
olen
+
len
;
if
(
index
>=
olen
)
// insert after end of string
{
m_data
=
(
char
*
)
realloc
(
m_data
,
nlen
+
index
-
olen
+
1
);
if
(
m_data
)
{
memset
(
m_data
+
olen
,
' '
,
index
-
olen
);
memcpy
(
m_data
+
index
,
s
,
len
+
1
);
}
}
else
if
(
(
m_data
=
(
char
*
)
realloc
(
m_data
,
nlen
+
1
))
)
// normal insert
{
memmove
(
m_data
+
index
+
len
,
m_data
+
index
,
olen
-
index
+
1
);
memcpy
(
m_data
+
index
,
s
,
len
);
}
return
*
this
;
}
QCString
&
QCString
::
insert
(
uint
index
,
char
c
)
QCString
&
QCString
::
insert
(
uint
index
,
char
c
)
// insert char
{
char
buf
[
2
];
buf
[
0
]
=
c
;
buf
[
1
]
=
'\0'
;
return
insert
(
index
,
buf
);
}
QCString
&
QCString
::
append
(
const
char
*
s
)
QCString
&
QCString
::
operator
+=
(
const
char
*
str
)
{
return
operator
+=
(
s
);
if
(
!
str
)
return
*
this
;
// nothing to append
uint
len1
=
length
();
uint
len2
=
qstrlen
(
str
);
char
*
newData
=
(
char
*
)
realloc
(
m_data
,
len1
+
len2
+
1
);
if
(
newData
)
{
m_data
=
newData
;
memcpy
(
m_data
+
len1
,
str
,
len2
+
1
);
}
return
*
this
;
}
QCString
&
QCString
::
prepend
(
const
char
*
s
)
QCString
&
QCString
::
operator
+=
(
char
c
)
{
return
insert
(
0
,
s
);
uint
len
=
length
();
char
*
newData
=
(
char
*
)
realloc
(
m_data
,
length
()
+
2
);
if
(
newData
)
{
m_data
=
newData
;
m_data
[
len
]
=
c
;
m_data
[
len
+
1
]
=
'\0'
;
}
return
*
this
;
}
QCString
&
QCString
::
remove
(
uint
index
,
uint
len
)
{
uint
olen
=
length
();
if
(
index
+
len
>=
olen
)
// range problems
{
{
if
(
index
<
olen
)
// index ok
{
{
resize
(
index
+
1
);
}
}
else
if
(
len
!=
0
)
}
else
if
(
len
!=
0
)
{
qmemmove
(
data
()
+
index
,
data
()
+
index
+
len
,
olen
-
index
-
len
+
1
);
memmove
(
m_data
+
index
,
m_data
+
index
+
len
,
olen
-
index
-
len
+
1
);
resize
(
olen
-
len
+
1
);
}
return
*
this
;
}
QCString
&
QCString
::
replace
(
uint
index
,
uint
len
,
const
char
*
s
)
QCString
&
QCString
::
replace
(
uint
index
,
uint
len
,
const
char
*
s
)
{
remove
(
index
,
len
);
insert
(
index
,
s
);
...
...
@@ -417,85 +555,65 @@ QCString &QCString::replace( uint index, uint len, const char *s)
QCString
&
QCString
::
replace
(
const
QRegExp
&
rx
,
const
char
*
str
)
{
QString
d
=
QString
::
fromLatin1
(
data
()
);
QString
d
=
QString
::
fromLatin1
(
m_data
);
QString
r
=
QString
::
fromLatin1
(
str
);
d
.
replace
(
rx
,
r
);
operator
=
(
d
.
ascii
()
);
return
*
this
;
}
short
QCString
::
toShort
(
bool
*
ok
)
const
{
QString
s
(
data
());
return
s
.
toShort
(
ok
);
}
ushort
QCString
::
toUShort
(
bool
*
ok
)
const
{
QString
s
(
data
());
return
s
.
toUShort
(
ok
);
}
int
QCString
::
toInt
(
bool
*
ok
)
const
{
QString
s
(
data
());
return
s
.
toInt
(
ok
);
}
uint
QCString
::
toUInt
(
bool
*
ok
)
const
{
QString
s
(
data
());
return
s
.
toUInt
(
ok
);
}
long
QCString
::
toLong
(
bool
*
ok
)
const
long
QCString
::
toLong
(
bool
*
ok
)
const
{
QString
s
(
data
()
);
QString
s
(
m_data
);
return
s
.
toLong
(
ok
);
}
ulong
QCString
::
toULong
(
bool
*
ok
)
const
ulong
QCString
::
toULong
(
bool
*
ok
)
const
{
QString
s
(
data
()
);
QString
s
(
m_data
);
return
s
.
toULong
(
ok
);
}
QCString
&
QCString
::
setNum
(
short
n
)
short
QCString
::
toShort
(
bool
*
ok
)
const
{
return
setNum
((
long
)
n
);
QString
s
(
m_data
);
return
s
.
toShort
(
ok
);
}
QCString
&
QCString
::
setNum
(
ushort
n
)
ushort
QCString
::
toUShort
(
bool
*
ok
)
const
{
return
setNum
((
ulong
)
n
);
QString
s
(
m_data
);
return
s
.
toUShort
(
ok
);
}
QCString
&
QCString
::
setNum
(
int
n
)
int
QCString
::
toInt
(
bool
*
ok
)
const
{
return
setNum
((
long
)
n
);
QString
s
(
m_data
);
return
s
.
toInt
(
ok
);
}
QCString
&
QCString
::
setNum
(
uint
n
)
uint
QCString
::
toUInt
(
bool
*
ok
)
const
{
return
setNum
((
ulong
)
n
);
QString
s
(
m_data
);
return
s
.
toUInt
(
ok
);
}
QCString
&
QCString
::
setNum
(
long
n
)
QCString
&
QCString
::
setNum
(
long
n
)
{
char
buf
[
20
];
register
char
*
p
=
&
buf
[
19
];
bool
neg
;
if
(
n
<
0
)
if
(
n
<
0
)
{
neg
=
TRUE
;
n
=
-
n
;
}
else
}
else
{
neg
=
FALSE
;
}
*
p
=
'\0'
;
do
do
{
*--
p
=
((
int
)(
n
%
10
))
+
'0'
;
n
/=
10
;
...
...
@@ -505,12 +623,12 @@ QCString &QCString::setNum(long n)
return
*
this
;
}
QCString
&
QCString
::
setNum
(
ulong
n
)
QCString
&
QCString
::
setNum
(
ulong
n
)
{
char
buf
[
20
];
register
char
*
p
=
&
buf
[
19
];
*
p
=
'\0'
;
do
do
{
*--
p
=
((
int
)(
n
%
10
))
+
'0'
;
n
/=
10
;
...
...
@@ -519,7 +637,31 @@ QCString &QCString::setNum( ulong n)
return
*
this
;
}
//-------------------------------------------------
void
QCString
::
msg_index
(
uint
index
)
{
#if defined(CHECK_RANGE)
qWarning
(
"QCString::at: Absolute index %d out of range"
,
index
);
#else
Q_UNUSED
(
index
)
#endif
}
bool
QCString
::
stripPrefix
(
const
char
*
prefix
)
{
if
(
prefix
==
0
)
return
FALSE
;
uint
plen
=
qstrlen
(
prefix
);
if
(
m_data
&&
qstrncmp
(
prefix
,
m_data
,
plen
)
==
0
)
// prefix matches
{
uint
len
=
qstrlen
(
m_data
);
uint
newlen
=
len
-
plen
+
1
;
qmemmove
(
m_data
,
m_data
+
plen
,
newlen
);
resize
(
newlen
);
return
TRUE
;
}
return
FALSE
;
}
//---------------------------------------------------------------------------
void
*
qmemmove
(
void
*
dst
,
const
void
*
src
,
uint
len
)
{
...
...
qtools/qcstring.h
View file @
7d933a9f
/****************************************************************************
**
**
** Copyright (C) 1997-2004 by Dimitri van Heesch.
** Definition of the extended char array operations,
** and QByteArray and QCString classes
**
** Permission to use, copy, modify, and distribute this software and its
** documentation under the terms of the GNU General Public License is hereby
** granted. No representations are made about the suitability of this software
** for any purpose. It is provided "as is" without express or implied warranty.
** See the GNU General Public License for more details.
** Created : 920609
**
** Note: this is a reimplementation of the qcstring.h that came with
** an Qt version 2.2.3. For short strings it stores the string data inside
** the object. For long strings it uses a separate array with reference counting.
** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
**
** This file is part of the tools module of the Qt GUI Toolkit.
**
** This file may be distributed under the terms of the Q Public License
** as defined by Trolltech AS of Norway and appearing in the file
** LICENSE.QPL included in the packaging of this file.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
** licenses may use this file in accordance with the Qt Commercial License
** Agreement provided with the Software.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
** information about Qt Commercial License Agreements.
** See http://www.trolltech.com/qpl/ for QPL licensing information.
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
...
...
@@ -21,7 +43,6 @@
#include "qarray.h"
#endif // QT_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
...
...
@@ -33,7 +54,6 @@
#include <strings.h>
#endif
#include <assert.h>
class
QGString
;
...
...
@@ -57,6 +77,7 @@ inline char *hack_strrchr( const char *s, int c )
#define strrchr(s,c) hack_strrchr((s),(c))
#endif
/*****************************************************************************
Safe and portable C string functions; extensions to standard string.h
*****************************************************************************/
...
...
@@ -106,6 +127,39 @@ Q_EXPORT int qstricmp( const char *str1, const char *str2 );
Q_EXPORT
int
qstrnicmp
(
const
char
*
str1
,
const
char
*
str2
,
uint
len
);
#if 0
// ### TODO for 3.0: these and the cstr* functions should be used if
// !defined(QT_CLEAN_NAMESPACE)
// We want to keep source compatibility for 2.x
// ### TODO for 4.0: completely remove these and the cstr* functions
#if !defined(QT_GENUINE_STR)
#undef strlen
#define strlen qstrlen
#undef strcpy
#define strcpy qstrcpy
#undef strcmp
#define strcmp qstrcmp
#undef strncmp
#define strncmp qstrncmp
#undef stricmp
#define stricmp qstricmp
#undef strnicmp
#define strnicmp qstrnicmp
#endif
#endif
// qChecksum: Internet checksum
Q_EXPORT
Q_UINT16
qChecksum
(
const
char
*
s
,
uint
len
);
/*****************************************************************************
QByteArray class
*****************************************************************************/
...
...
@@ -115,6 +169,7 @@ template class Q_EXPORT QArray<char>;
#endif
typedef
QArray
<
char
>
QByteArray
;
/*****************************************************************************
QByteArray stream functions
*****************************************************************************/
...
...
@@ -126,541 +181,143 @@ Q_EXPORT QDataStream &operator>>( QDataStream &, QByteArray & );
class
QRegExp
;
/** This is an alternative implementation of QCString. It provides basically
* the same functions but uses reference counting and copy on write.
* the same functions but uses less memory for administration. This class
* is just a wrapper around a plain C string requiring only 4 bytes "overhead".
* QCString features sharing of data and stores the string length, but
* requires 4 + 12 bytes for this (even for the empty string). As doxygen
* uses a LOT of string during a run it saves a lot of memory to use a
* more memory efficient implementation at the cost of relatively low
* runtime overhead.
*/
class
QCString
class
QCString
{
public
:
/** creates an empty string */
QCString
()
{
}
/** destroys the string */
~
QCString
()
{
}
/** makes a copy of a string. */
QCString
(
const
QCString
&
s
)
:
m_rep
(
s
.
m_rep
)
{
}
/** creates a string with room for size characters
* @param[in] size the number of character to allocate (including the 0-terminator)
*/
QCString
(
int
size
)
:
m_rep
(
size
)
{
}
/** creates a string from a plain C string.
* @param[in] str A zero terminated C string. When 0 an empty string is created.
*/
QCString
(
const
char
*
str
)
:
m_rep
(
str
)
{
}
/** creates a string from \a str and copies over the first \a maxlen characters. */
QCString
(
const
char
*
str
,
uint
maxlen
)
:
m_rep
(
str
,
maxlen
)
{
}
/** replaces the contents by that of string \a s. */
QCString
&
operator
=
(
const
QCString
&
s
)
{
m_rep
=
s
.
m_rep
;
return
*
this
;
}
/** replaces the contents by that of C string \a str. */
QCString
&
operator
=
(
const
char
*
str
)
{
m_rep
=
str
;
return
*
this
;
}
/** Returns TRUE iff the string is empty. Equivalent to isEmpty(). */
bool
isNull
()
const
{
return
m_rep
.
isEmpty
();
}
/** Returns TRUE iff the string is empty */
bool
isEmpty
()
const
{
return
m_rep
.
isEmpty
();
}
/** Returns the length of the string, excluding the 0-terminator. Equivalent to size(). */
uint
length
()
const
{
return
m_rep
.
length
();
}
/** Returns the length of the string, excluding the 0-terminator. */
uint
size
()
const
{
return
m_rep
.
length
();
}
/** Returns a pointer to the contents of the string in the form of a 0-terminated C string */
char
*
data
()
const
{
return
m_rep
.
data
();
}
/** Resizes the string to hold \a newlen characters
* (this value should include the 0-terminator). If the string is enlarged the contents will
* be left unmodified.
*/
bool
resize
(
uint
newlen
)
{
m_rep
.
resize
(
newlen
);
return
TRUE
;
}
/** Truncates the string at position \a pos. */
bool
truncate
(
uint
pos
)
{
return
resize
(
pos
+
1
);
}
/** Fills a string with a predefined character
* @param[in] c the character used to fill the string with.
* @param[in] len the number of character to fill. Use -1 to fill the whole string.
* @note the string will be resized to contain \a len characters. The contents of the
* string will be lost.
*/
bool
fill
(
char
c
,
int
len
=
-
1
)
{
m_rep
.
fill
(
c
,
len
);
return
TRUE
;
}
/** Returns a deep copy of the string. */
QCString
copy
()
const
{
if
(
length
()
==
0
)
return
QCString
();
QCString
cs
(
length
()
+
1
);
memcpy
(
cs
.
data
(),
data
(),
length
());
return
cs
;
}
QCString
&
sprintf
(
const
char
*
format
,
...
);
int
find
(
char
c
,
int
index
=
0
,
bool
cs
=
TRUE
)
const
;
int
find
(
const
char
*
str
,
int
index
=
0
,
bool
cs
=
TRUE
)
const
;
int
find
(
const
QCString
&
str
,
int
index
=
0
,
bool
cs
=
TRUE
)
const
;
int
find
(
const
QRegExp
&
rx
,
int
index
=
0
)
const
;
int
findRev
(
char
c
,
int
index
=-
1
,
bool
cs
=
TRUE
)
const
;
int
findRev
(
const
char
*
str
,
int
index
=-
1
,
bool
cs
=
TRUE
)
const
;
int
findRev
(
const
QRegExp
&
rx
,
int
index
=-
1
)
const
;
int
contains
(
char
c
,
bool
cs
=
TRUE
)
const
;
int
contains
(
const
char
*
str
,
bool
cs
=
TRUE
)
const
;
int
contains
(
const
QRegExp
&
rx
)
const
;
bool
stripPrefix
(
const
char
*
prefix
);
QCString
left
(
uint
len
)
const
;
QCString
right
(
uint
len
)
const
;
QCString
mid
(
uint
index
,
uint
len
=
0xffffffff
)
const
;
QCString
lower
()
const
;
QCString
upper
()
const
;
QCString
stripWhiteSpace
()
const
;
QCString
simplifyWhiteSpace
()
const
;
QCString
&
assign
(
const
char
*
str
);
QCString
&
insert
(
uint
index
,
const
char
*
s
);
QCString
&
insert
(
uint
index
,
char
c
);
QCString
&
append
(
const
char
*
s
);
QCString
&
prepend
(
const
char
*
s
);
QCString
&
remove
(
uint
index
,
uint
len
);
QCString
&
replace
(
uint
index
,
uint
len
,
const
char
*
s
);
QCString
&
replace
(
const
QRegExp
&
rx
,
const
char
*
str
);
short
toShort
(
bool
*
ok
=
0
)
const
;
ushort
toUShort
(
bool
*
ok
=
0
)
const
;
int
toInt
(
bool
*
ok
=
0
)
const
;
uint
toUInt
(
bool
*
ok
=
0
)
const
;
long
toLong
(
bool
*
ok
=
0
)
const
;
ulong
toULong
(
bool
*
ok
=
0
)
const
;
QCString
&
setNum
(
short
n
);
QCString
&
setNum
(
ushort
n
);
QCString
&
setNum
(
int
n
);
QCString
&
setNum
(
uint
n
);
QCString
&
setNum
(
long
n
);
QCString
&
setNum
(
ulong
n
);
/** Converts the string to a plain C string */
operator
const
char
*
()
const
{
return
(
const
char
*
)
data
();
}
/** Appends string \a str to this string and returns a reference to the result. */
QCString
&
operator
+=
(
const
char
*
str
)
{
if
(
!
str
)
return
*
this
;
int
len1
=
length
();
int
len2
=
strlen
(
str
);
resize
(
len1
+
len2
+
1
);
memcpy
(
data
()
+
len1
,
str
,
len2
);
return
*
this
;
}
/** Appends character \a c to this string and returns a reference to the result. */
QCString
&
operator
+=
(
char
c
)
{
int
len
=
length
();
resize
(
len
+
2
);
data
()[
len
]
=
c
;
return
*
this
;
}
/** Returns a reference to the character at index \a i. */
char
&
at
(
uint
i
)
const
{
return
m_rep
.
at
(
i
);
}
/** Indexing operator. Equavalent to at(). */
char
&
operator
[](
int
i
)
const
{
return
m_rep
.
at
((
uint
)
i
);
}
QCString
()
:
m_data
(
0
)
{}
// make null string
QCString
(
const
QCString
&
s
);
QCString
(
int
size
);
QCString
(
const
char
*
str
);
QCString
(
const
char
*
str
,
uint
maxlen
);
~
QCString
();
QCString
&
operator
=
(
const
QCString
&
s
);
// deep copy
QCString
&
operator
=
(
const
char
*
str
);
// deep copy
bool
isNull
()
const
;
bool
isEmpty
()
const
;
uint
length
()
const
;
uint
size
()
const
{
return
m_data
?
length
()
+
1
:
0
;
}
char
*
data
()
const
{
return
m_data
;
}
bool
resize
(
uint
newlen
);
bool
truncate
(
uint
pos
);
bool
fill
(
char
c
,
int
len
=
-
1
);
QCString
copy
()
const
;
QCString
&
sprintf
(
const
char
*
format
,
...
);
int
find
(
char
c
,
int
index
=
0
,
bool
cs
=
TRUE
)
const
;
int
find
(
const
char
*
str
,
int
index
=
0
,
bool
cs
=
TRUE
)
const
;
int
find
(
const
QCString
&
str
,
int
index
=
0
,
bool
cs
=
TRUE
)
const
;
int
find
(
const
QRegExp
&
,
int
index
=
0
)
const
;
int
findRev
(
char
c
,
int
index
=-
1
,
bool
cs
=
TRUE
)
const
;
int
findRev
(
const
char
*
str
,
int
index
=-
1
,
bool
cs
=
TRUE
)
const
;
int
findRev
(
const
QRegExp
&
,
int
index
=-
1
)
const
;
int
contains
(
char
c
,
bool
cs
=
TRUE
)
const
;
int
contains
(
const
char
*
str
,
bool
cs
=
TRUE
)
const
;
int
contains
(
const
QRegExp
&
)
const
;
bool
stripPrefix
(
const
char
*
prefix
);
QCString
left
(
uint
len
)
const
;
QCString
right
(
uint
len
)
const
;
QCString
mid
(
uint
index
,
uint
len
=
0xffffffff
)
const
;
QCString
lower
()
const
;
QCString
upper
()
const
;
QCString
stripWhiteSpace
()
const
;
QCString
simplifyWhiteSpace
()
const
;
QCString
&
assign
(
const
char
*
str
);
QCString
&
insert
(
uint
index
,
const
char
*
);
QCString
&
insert
(
uint
index
,
char
);
QCString
&
append
(
const
char
*
s
);
QCString
&
prepend
(
const
char
*
s
);
QCString
&
remove
(
uint
index
,
uint
len
);
QCString
&
replace
(
uint
index
,
uint
len
,
const
char
*
);
QCString
&
replace
(
const
QRegExp
&
,
const
char
*
);
short
toShort
(
bool
*
ok
=
0
)
const
;
ushort
toUShort
(
bool
*
ok
=
0
)
const
;
int
toInt
(
bool
*
ok
=
0
)
const
;
uint
toUInt
(
bool
*
ok
=
0
)
const
;
long
toLong
(
bool
*
ok
=
0
)
const
;
ulong
toULong
(
bool
*
ok
=
0
)
const
;
QCString
&
setNum
(
short
);
QCString
&
setNum
(
ushort
);
QCString
&
setNum
(
int
);
QCString
&
setNum
(
uint
);
QCString
&
setNum
(
long
);
QCString
&
setNum
(
ulong
);
QCString
&
setNum
(
float
,
char
f
=
'g'
,
int
prec
=
6
);
QCString
&
setNum
(
double
,
char
f
=
'g'
,
int
prec
=
6
);
operator
const
char
*
()
const
;
QCString
&
operator
+=
(
const
char
*
str
);
QCString
&
operator
+=
(
char
c
);
char
&
at
(
uint
index
)
const
;
char
&
operator
[](
int
i
)
const
{
return
at
(
i
);
}
private
:
static
void
msg_index
(
uint
);
void
duplicate
(
const
QCString
&
s
);
void
duplicate
(
const
char
*
str
);
QCString
&
duplicate
(
const
char
*
str
,
int
);
struct
LSData
;
// long string representation
struct
LongStringRep
{
uchar
isShort
:
1
;
// should be shared with ShortStringRep
uchar
:
7
;
LSData
*
d
;
};
#define SHORT_STR_CAPACITY ((int)sizeof(LongStringRep)-1)
#define SHORT_STR_MAX_LEN (SHORT_STR_CAPACITY-1)
// short string representation
struct
ShortStringRep
{
uchar
isShort
:
1
;
// should be shared with LongStringRep
uchar
len
:
7
;
char
str
[
SHORT_STR_CAPACITY
];
// size including 0-terminator
};
// ref counting string header
struct
LSHeader
{
int
len
;
// length of string without 0 terminator
int
refCount
;
// -1=leaked, 0=one ref & non-cost, n>0, n+1 refs, const
};
// ref counting string data and methods
struct
LSData
:
public
LSHeader
{
char
*
toStr
()
{
return
(
char
*
)(
this
+
1
);
// string data starts after the header
}
// creates a LSData item with room for size bytes (which includes the 0 terminator!)
// if size is zero, an empty string will be created.
static
LSData
*
create
(
int
size
)
{
LSData
*
data
;
data
=
(
LSData
*
)
malloc
(
sizeof
(
LSHeader
)
+
size
);
data
->
len
=
size
-
1
;
data
->
refCount
=
0
;
data
->
toStr
()[
size
-
1
]
=
0
;
return
data
;
}
// remove out reference to the data. Frees memory if no more users
void
dispose
()
{
if
(
--
refCount
<
0
)
free
(
this
);
}
// resizes LSData so it can hold size bytes (which includes the 0 terminator!)
// Since this is for long strings only, size should be > SHORT_STR_CAPACITY
static
LSData
*
resize
(
LSData
*
d
,
int
size
)
{
if
(
d
->
len
>
0
&&
d
->
refCount
==
0
)
// non-const, non-empty
{
d
=
(
LSData
*
)
realloc
(
d
,
sizeof
(
LSHeader
)
+
size
);
d
->
len
=
size
-
1
;
d
->
toStr
()[
size
-
1
]
=
0
;
return
d
;
}
else
// need to make a copy
{
LSData
*
newData
=
LSData
::
create
(
size
);
int
len
=
d
->
len
;
if
(
len
>=
size
)
len
=
size
-
1
;
memcpy
(
newData
->
toStr
(),
d
->
toStr
(),
len
);
newData
->
toStr
()[
len
]
=
0
;
d
->
dispose
();
return
newData
;
}
}
};
class
StringRep
{
public
:
StringRep
()
{
u
.
s
.
isShort
=
TRUE
;
u
.
s
.
len
=
0
;
}
~
StringRep
()
{
if
(
!
u
.
s
.
isShort
)
{
u
.
l
.
d
->
dispose
();
}
}
StringRep
(
const
StringRep
&
s
)
{
if
(
&
s
!=
this
)
{
u
=
s
.
u
;
if
(
!
u
.
s
.
isShort
)
{
u
.
l
.
d
->
refCount
++
;
}
}
}
StringRep
(
int
size
)
{
u
.
s
.
isShort
=
size
<=
SHORT_STR_CAPACITY
;
if
(
size
<=
SHORT_STR_CAPACITY
)
// init short string
{
if
(
size
>
0
)
{
u
.
s
.
len
=
size
-
1
;
u
.
s
.
str
[
size
-
1
]
=
'\0'
;
}
else
{
u
.
s
.
len
=
0
;
}
}
else
// int long string
{
u
.
l
.
d
=
LSData
::
create
(
size
);
}
}
StringRep
(
const
char
*
str
)
{
if
(
str
)
{
int
len
=
strlen
(
str
);
u
.
s
.
isShort
=
len
<
SHORT_STR_CAPACITY
;
if
(
len
<
SHORT_STR_CAPACITY
)
{
u
.
s
.
len
=
len
;
memcpy
(
u
.
s
.
str
,
str
,
len
+
1
);
}
else
{
u
.
l
.
d
=
LSData
::
create
(
len
+
1
);
memcpy
(
u
.
l
.
d
->
toStr
(),
str
,
u
.
l
.
d
->
len
);
}
}
else
// create empty string
{
u
.
s
.
isShort
=
TRUE
;
u
.
s
.
len
=
0
;
}
}
StringRep
(
const
char
*
str
,
uint
maxlen
)
{
if
(
str
&&
maxlen
>
0
)
{
uint
len
=
strlen
(
str
);
if
(
len
>
maxlen
)
len
=
maxlen
;
u
.
s
.
isShort
=
len
<=
SHORT_STR_MAX_LEN
;
if
(
u
.
s
.
isShort
)
{
u
.
s
.
len
=
len
;
memcpy
(
u
.
s
.
str
,
str
,
len
);
u
.
s
.
str
[
len
]
=
'\0'
;
}
else
{
u
.
l
.
d
=
LSData
::
create
(
len
+
1
);
memcpy
(
u
.
l
.
d
->
toStr
(),
str
,
len
);
}
}
else
// create empty string
{
u
.
s
.
isShort
=
TRUE
;
u
.
s
.
len
=
0
;
}
}
StringRep
&
operator
=
(
const
StringRep
&
s
)
{
if
(
&
s
!=
this
)
{
if
(
!
u
.
s
.
isShort
)
{
u
.
l
.
d
->
dispose
();
}
if
(
s
.
u
.
s
.
isShort
)
// copy by value
{
u
.
s
=
s
.
u
.
s
;
}
else
// copy by reference
{
u
.
l
.
isShort
=
FALSE
;
u
.
l
.
d
=
s
.
u
.
l
.
d
;
u
.
l
.
d
->
refCount
++
;
}
}
return
*
this
;
}
StringRep
&
operator
=
(
const
char
*
str
)
{
if
(
!
u
.
s
.
isShort
)
{
u
.
l
.
d
->
dispose
();
}
if
(
str
)
{
int
len
=
strlen
(
str
);
u
.
s
.
isShort
=
len
<=
SHORT_STR_MAX_LEN
;
if
(
len
<
SHORT_STR_CAPACITY
)
{
u
.
s
.
len
=
len
;
memcpy
(
u
.
s
.
str
,
str
,
len
+
1
);
}
else
{
u
.
l
.
d
=
LSData
::
create
(
len
+
1
);
memcpy
(
u
.
l
.
d
->
toStr
(),
str
,
u
.
l
.
d
->
len
);
}
}
else
{
u
.
s
.
isShort
=
TRUE
;
u
.
s
.
len
=
0
;
}
return
*
this
;
}
bool
isEmpty
()
const
{
return
u
.
s
.
isShort
&&
u
.
s
.
len
==
0
;
}
uint
length
()
const
{
return
u
.
s
.
isShort
?
u
.
s
.
len
:
u
.
l
.
d
->
len
;
}
char
*
data
()
const
{
if
(
u
.
s
.
isShort
)
{
return
u
.
s
.
len
==
0
?
0
:
(
char
*
)
u
.
s
.
str
;
}
else
{
return
u
.
l
.
d
->
len
==
0
?
0
:
u
.
l
.
d
->
toStr
();
}
}
char
&
at
(
int
i
)
const
{
if
(
u
.
s
.
isShort
)
{
return
(
char
&
)
u
.
s
.
str
[
i
];
}
else
{
return
u
.
l
.
d
->
toStr
()[
i
];
}
}
bool
resize
(
uint
newlen
)
{
if
(
u
.
s
.
isShort
&&
newlen
<=
SHORT_STR_CAPACITY
)
// resize short string
{
if
(
newlen
>
0
)
{
u
.
s
.
len
=
newlen
-
1
;
u
.
s
.
str
[
newlen
-
1
]
=
'\0'
;
}
else
// string becomes empty
{
u
.
s
.
len
=
0
;
}
}
else
if
(
u
.
s
.
isShort
)
// turn short string into long string
{
StringRep
tmp
=
*
this
;
u
.
s
.
isShort
=
FALSE
;
u
.
l
.
d
=
LSData
::
create
(
newlen
);
if
(
tmp
.
u
.
s
.
len
>
0
)
{
memcpy
(
u
.
l
.
d
->
toStr
(),
tmp
.
u
.
s
.
str
,
tmp
.
u
.
s
.
len
+
1
);
}
else
{
u
.
l
.
d
->
toStr
()[
0
]
=
'\0'
;
}
}
else
if
(
!
u
.
s
.
isShort
&&
newlen
<=
SHORT_STR_CAPACITY
)
// turn long string into short string
{
if
(
newlen
>
0
)
{
StringRep
tmp
(
newlen
);
// copy short part into tmp buffer
memcpy
(
tmp
.
u
.
s
.
str
,
u
.
l
.
d
->
toStr
(),
newlen
-
1
);
tmp
.
u
.
s
.
str
[
newlen
-
1
]
=
'\0'
;
u
.
l
.
d
->
dispose
();
u
.
s
=
tmp
.
u
.
s
;
}
else
{
u
.
l
.
d
->
dispose
();
u
.
s
.
isShort
=
TRUE
;
u
.
s
.
len
=
0
;
}
}
else
// resize long string
{
u
.
l
.
d
=
u
.
l
.
d
->
resize
(
u
.
l
.
d
,
newlen
);
}
return
TRUE
;
}
bool
fill
(
char
c
,
int
len
)
{
if
(
len
<
0
)
len
=
length
();
if
(
len
!=
(
int
)
length
())
{
if
(
len
>
0
)
{
resize
(
len
+
1
);
}
else
{
if
(
!
u
.
s
.
isShort
)
{
u
.
l
.
d
->
dispose
();
}
u
.
s
.
isShort
=
TRUE
;
u
.
s
.
len
=
0
;
}
}
if
(
len
>
0
)
{
memset
(
data
(),
c
,
len
);
}
return
TRUE
;
}
private
:
union
{
ShortStringRep
s
;
LongStringRep
l
;
}
u
;
};
StringRep
m_rep
;
char
*
m_data
;
};
inline
char
&
QCString
::
at
(
uint
index
)
const
{
return
m_data
[
index
];
}
inline
void
QCString
::
duplicate
(
const
QCString
&
s
)
{
if
(
!
s
.
isEmpty
())
{
uint
l
=
(
uint
)
strlen
(
s
.
data
());
m_data
=
(
char
*
)
malloc
(
l
+
1
);
if
(
m_data
)
memcpy
(
m_data
,
s
.
data
(),
l
+
1
);
}
else
{
m_data
=
0
;
}
}
inline
void
QCString
::
duplicate
(
const
char
*
str
)
{
if
(
str
&&
str
[
0
]
!=
'\0'
)
{
uint
l
=
(
uint
)
strlen
(
str
);
m_data
=
(
char
*
)
malloc
(
l
+
1
);
if
(
m_data
)
memcpy
(
m_data
,
str
,
l
+
1
);
}
else
{
m_data
=
0
;
}
}
inline
QCString
&
QCString
::
duplicate
(
const
char
*
str
,
int
)
{
if
(
m_data
==
str
)
return
*
this
;
if
(
m_data
)
free
(
m_data
);
duplicate
(
str
);
return
*
this
;
}
/*****************************************************************************
QCString stream functions
*****************************************************************************/
...
...
@@ -669,6 +326,56 @@ Q_EXPORT QDataStream &operator<<( QDataStream &, const QCString & );
Q_EXPORT
QDataStream
&
operator
>>
(
QDataStream
&
,
QCString
&
);
#endif
/*****************************************************************************
QCString inline functions
*****************************************************************************/
inline
QCString
&
QCString
::
operator
=
(
const
QCString
&
s
)
{
return
(
QCString
&
)
assign
(
s
);
}
inline
QCString
&
QCString
::
operator
=
(
const
char
*
str
)
{
return
(
QCString
&
)
duplicate
(
str
,
qstrlen
(
str
)
+
1
);
}
inline
bool
QCString
::
isNull
()
const
{
return
data
()
==
0
;
}
inline
bool
QCString
::
isEmpty
()
const
{
return
data
()
==
0
||
*
data
()
==
'\0'
;
}
inline
uint
QCString
::
length
()
const
{
return
qstrlen
(
data
()
);
}
inline
bool
QCString
::
truncate
(
uint
pos
)
{
return
resize
(
pos
+
1
);
}
inline
QCString
QCString
::
copy
()
const
{
return
QCString
(
data
()
);
}
inline
QCString
&
QCString
::
prepend
(
const
char
*
s
)
{
return
insert
(
0
,
s
);
}
inline
QCString
&
QCString
::
append
(
const
char
*
s
)
{
return
operator
+=
(
s
);
}
inline
QCString
&
QCString
::
setNum
(
short
n
)
{
return
setNum
((
long
)
n
);
}
inline
QCString
&
QCString
::
setNum
(
ushort
n
)
{
return
setNum
((
ulong
)
n
);
}
inline
QCString
&
QCString
::
setNum
(
int
n
)
{
return
setNum
((
long
)
n
);
}
inline
QCString
&
QCString
::
setNum
(
uint
n
)
{
return
setNum
((
ulong
)
n
);
}
inline
QCString
&
QCString
::
setNum
(
float
n
,
char
f
,
int
prec
)
{
return
setNum
((
double
)
n
,
f
,
prec
);
}
inline
QCString
::
operator
const
char
*
()
const
{
return
(
const
char
*
)
data
();
}
/*****************************************************************************
QCString non-member operators
*****************************************************************************/
...
...
@@ -769,4 +476,5 @@ inline const char *qPrint(const QCString &s)
if
(
!
s
.
isEmpty
())
return
s
.
data
();
else
return
""
;
}
#endif // QCSTRING_H
qtools/qtools.pro.in
View file @
7d933a9f
...
...
@@ -7,6 +7,7 @@ HEADERS = qarray.h \
qcollection.h \
qconfig.h \
qcstring.h \
scstring.h \
qdatastream.h \
qdatetime.h \
qdict.h \
...
...
@@ -53,7 +54,7 @@ HEADERS = qarray.h \
SOURCES = qbuffer.cpp \
qcollection.cpp \
q
cstring.cpp \
s
cstring.cpp \
qdatastream.cpp \
qdatetime.cpp \
qdir.cpp \
...
...
qtools/scstring.cpp
0 → 100644
View file @
7d933a9f
/******************************************************************************
*
* Copyright (C) 1997-2004 by Dimitri van Heesch.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation under the terms of the GNU General Public License is hereby
* granted. No representations are made about the suitability of this software
* for any purpose. It is provided "as is" without express or implied warranty.
* See the GNU General Public License for more details.
*
* Documents produced by Doxygen are derivative works derived from the
* input used in their production; they are not affected by this license.
*
*/
// with this switch you can choose between the original qcstring implementation,
// which implicitly shares data so copying is faster, but requires at least 12 bytes, and
// the new implementation in this file, which has a smaller footprint (only 4 bytes for
// an empty string), but always copies strings.
#define SMALLSTRING
#include "qcstring.h"
#ifndef SMALLSTRING
#include "qcstring.cpp"
#else
#define SCString QCString
#include <qstring.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>
#include <qregexp.h>
#include <qdatastream.h>
SCString
::
SCString
(
int
size
)
{
if
(
size
>
0
)
{
m_data
=
(
char
*
)
malloc
(
size
);
if
(
m_data
)
{
if
(
size
>
1
)
memset
(
m_data
,
' '
,
size
-
1
);
m_data
[
size
-
1
]
=
'\0'
;
}
}
else
{
m_data
=
0
;
}
}
SCString
::
SCString
(
const
SCString
&
s
)
{
duplicate
(
s
);
}
SCString
::
SCString
(
const
char
*
str
)
{
duplicate
(
str
);
}
SCString
::
SCString
(
const
char
*
str
,
uint
maxlen
)
{
uint
l
;
if
(
str
&&
(
l
=
QMIN
(
qstrlen
(
str
),
maxlen
)
))
{
m_data
=
(
char
*
)
malloc
(
l
+
1
);
strncpy
(
m_data
,
str
,
l
+
1
);
m_data
[
l
]
=
'\0'
;
}
else
{
m_data
=
0
;
}
}
SCString
::~
SCString
()
{
if
(
m_data
)
free
(
m_data
);
m_data
=
0
;
}
SCString
&
SCString
::
assign
(
const
char
*
str
)
{
if
(
m_data
==
str
)
return
*
this
;
if
(
m_data
)
free
(
m_data
);
duplicate
(
str
);
return
*
this
;
}
bool
SCString
::
resize
(
uint
newlen
)
{
if
(
newlen
==
0
)
{
if
(
m_data
)
{
free
(
m_data
);
m_data
=
0
;
}
return
TRUE
;
}
if
(
m_data
==
0
)
// newlen>0
{
m_data
=
(
char
*
)
malloc
(
newlen
);
}
else
{
m_data
=
(
char
*
)
realloc
(
m_data
,
newlen
);
}
if
(
m_data
==
0
)
return
FALSE
;
m_data
[
newlen
-
1
]
=
'\0'
;
return
TRUE
;
}
bool
SCString
::
fill
(
char
c
,
int
len
)
{
uint
l
=
length
();
if
(
len
<
0
)
len
=
l
;
if
((
uint
)
len
!=
l
)
{
if
(
m_data
)
free
(
m_data
);
if
(
len
>
0
)
{
m_data
=
(
char
*
)
malloc
(
len
+
1
);
if
(
m_data
==
0
)
return
FALSE
;
m_data
[
len
]
=
'\0'
;
}
else
{
m_data
=
0
;
}
}
if
(
len
>
0
)
{
uint
i
;
for
(
i
=
0
;
i
<
(
uint
)
len
;
i
++
)
m_data
[
i
]
=
c
;
}
return
TRUE
;
}
SCString
&
SCString
::
sprintf
(
const
char
*
format
,
...
)
{
va_list
ap
;
va_start
(
ap
,
format
);
uint
l
=
length
();
const
uint
minlen
=
4095
;
if
(
l
<
minlen
)
{
if
(
m_data
)
m_data
=
(
char
*
)
realloc
(
m_data
,
minlen
+
1
);
else
m_data
=
(
char
*
)
malloc
(
minlen
+
1
);
m_data
[
minlen
]
=
'\0'
;
}
vsnprintf
(
m_data
,
minlen
,
format
,
ap
);
resize
(
qstrlen
(
m_data
)
+
1
);
// truncate
va_end
(
ap
);
return
*
this
;
}
int
SCString
::
find
(
char
c
,
int
index
,
bool
cs
)
const
{
uint
len
=
length
();
if
(
m_data
==
0
||
(
uint
)
index
>
len
)
// index outside string
return
-
1
;
register
const
char
*
d
;
if
(
cs
)
// case sensitive
{
d
=
strchr
(
m_data
+
index
,
c
);
}
else
{
d
=
m_data
+
index
;
c
=
tolower
(
(
uchar
)
c
);
while
(
*
d
&&
tolower
((
uchar
)
*
d
)
!=
c
)
d
++
;
if
(
!*
d
&&
c
)
// not found
d
=
0
;
}
return
d
?
(
int
)(
d
-
m_data
)
:
-
1
;
}
int
SCString
::
find
(
const
char
*
str
,
int
index
,
bool
cs
)
const
{
uint
l
=
length
();
if
(
m_data
==
0
||
(
uint
)
index
>
l
)
// index outside string
return
-
1
;
if
(
!
str
)
// no search string
return
-
1
;
if
(
!*
str
)
// zero-length search string
return
index
;
register
const
char
*
d
;
if
(
cs
)
// case sensitive
{
d
=
strstr
(
m_data
+
index
,
str
);
}
else
// case insensitive
{
d
=
m_data
+
index
;
int
len
=
qstrlen
(
str
);
while
(
*
d
)
{
if
(
qstrnicmp
(
d
,
str
,
len
)
==
0
)
break
;
d
++
;
}
if
(
!*
d
)
// not found
d
=
0
;
}
return
d
?
(
int
)(
d
-
m_data
)
:
-
1
;
}
int
SCString
::
find
(
const
QCString
&
str
,
int
index
,
bool
cs
)
const
{
return
find
(
str
.
data
(),
index
,
cs
);
}
int
SCString
::
find
(
const
QRegExp
&
rx
,
int
index
)
const
{
QString
d
=
QString
::
fromLatin1
(
m_data
);
return
d
.
find
(
rx
,
index
);
}
int
SCString
::
findRev
(
char
c
,
int
index
,
bool
cs
)
const
{
const
char
*
b
=
m_data
;
const
char
*
d
;
uint
len
=
length
();
if
(
b
==
0
)
return
-
1
;
// empty string
if
(
index
<
0
)
// neg index ==> start from end
{
if
(
len
==
0
)
return
-
1
;
if
(
cs
)
{
d
=
strrchr
(
b
,
c
);
return
d
?
(
int
)(
d
-
b
)
:
-
1
;
}
index
=
len
;
}
else
if
(
(
uint
)
index
>
len
)
// bad index
{
return
-
1
;
}
d
=
b
+
index
;
if
(
cs
)
// case sensitive
{
while
(
d
>=
b
&&
*
d
!=
c
)
d
--
;
}
else
// case insensitive
{
c
=
tolower
(
(
uchar
)
c
);
while
(
d
>=
b
&&
tolower
((
uchar
)
*
d
)
!=
c
)
d
--
;
}
return
d
>=
b
?
(
int
)(
d
-
b
)
:
-
1
;
}
int
SCString
::
findRev
(
const
char
*
str
,
int
index
,
bool
cs
)
const
{
int
slen
=
qstrlen
(
str
);
uint
len
=
length
();
if
(
index
<
0
)
// neg index ==> start from end
index
=
len
-
slen
;
else
if
(
(
uint
)
index
>
len
)
// bad index
return
-
1
;
else
if
(
(
uint
)(
index
+
slen
)
>
len
)
// str would be too long
index
=
len
-
slen
;
if
(
index
<
0
)
return
-
1
;
register
char
*
d
=
m_data
+
index
;
if
(
cs
)
// case sensitive
{
for
(
int
i
=
index
;
i
>=
0
;
i
--
)
if
(
qstrncmp
(
d
--
,
str
,
slen
)
==
0
)
return
i
;
}
else
// case insensitive
{
for
(
int
i
=
index
;
i
>=
0
;
i
--
)
if
(
qstrnicmp
(
d
--
,
str
,
slen
)
==
0
)
return
i
;
}
return
-
1
;
}
int
SCString
::
findRev
(
const
QRegExp
&
rx
,
int
index
)
const
{
QString
d
=
QString
::
fromLatin1
(
m_data
);
return
d
.
findRev
(
rx
,
index
);
}
int
SCString
::
contains
(
char
c
,
bool
cs
)
const
{
int
count
=
0
;
char
*
d
=
m_data
;
if
(
!
d
)
return
0
;
if
(
cs
)
// case sensitive
{
while
(
*
d
)
if
(
*
d
++
==
c
)
count
++
;
}
else
// case insensitive
{
c
=
tolower
(
(
uchar
)
c
);
while
(
*
d
)
{
if
(
tolower
((
uchar
)
*
d
)
==
c
)
count
++
;
d
++
;
}
}
return
count
;
}
int
SCString
::
contains
(
const
char
*
str
,
bool
cs
)
const
{
int
count
=
0
;
char
*
d
=
data
();
if
(
!
d
)
return
0
;
int
len
=
qstrlen
(
str
);
while
(
*
d
)
// counts overlapping strings
{
if
(
cs
)
{
if
(
qstrncmp
(
d
,
str
,
len
)
==
0
)
count
++
;
}
else
{
if
(
qstrnicmp
(
d
,
str
,
len
)
==
0
)
count
++
;
}
d
++
;
}
return
count
;
}
int
SCString
::
contains
(
const
QRegExp
&
rx
)
const
{
QString
d
=
QString
::
fromLatin1
(
m_data
);
return
d
.
contains
(
rx
);
}
SCString
SCString
::
left
(
uint
len
)
const
{
if
(
isEmpty
()
)
{
return
SCString
();
}
else
if
(
len
>=
length
()
)
{
return
*
this
;
}
else
{
SCString
s
(
len
+
1
);
strncpy
(
s
.
data
(),
m_data
,
len
);
*
(
s
.
data
()
+
len
)
=
'\0'
;
return
s
;
}
}
SCString
SCString
::
right
(
uint
len
)
const
{
if
(
isEmpty
()
)
{
return
SCString
();
}
else
{
uint
l
=
length
();
if
(
len
>
l
)
len
=
l
;
char
*
p
=
m_data
+
(
l
-
len
);
return
SCString
(
p
);
}
}
SCString
SCString
::
mid
(
uint
index
,
uint
len
)
const
{
uint
slen
=
length
();
if
(
len
==
0xffffffff
)
len
=
slen
-
index
;
if
(
isEmpty
()
||
index
>=
slen
)
{
return
SCString
();
}
else
{
register
char
*
p
=
data
()
+
index
;
SCString
s
(
len
+
1
);
strncpy
(
s
.
data
(),
p
,
len
);
*
(
s
.
data
()
+
len
)
=
'\0'
;
return
s
;
}
}
SCString
SCString
::
lower
()
const
{
SCString
s
(
m_data
);
register
char
*
p
=
s
.
data
();
if
(
p
)
{
while
(
*
p
)
{
*
p
=
tolower
((
uchar
)
*
p
);
p
++
;
}
}
return
s
;
}
SCString
SCString
::
upper
()
const
{
SCString
s
(
m_data
);
register
char
*
p
=
s
.
data
();
if
(
p
)
{
while
(
*
p
)
{
*
p
=
toupper
((
uchar
)
*
p
);
p
++
;
}
}
return
s
;
}
SCString
SCString
::
stripWhiteSpace
()
const
{
if
(
isEmpty
()
)
// nothing to do
return
*
this
;
register
char
*
s
=
m_data
;
int
reslen
=
length
();
if
(
!
isspace
((
uchar
)
s
[
0
])
&&
!
isspace
((
uchar
)
s
[
reslen
-
1
])
)
return
*
this
;
// returns a copy
SCString
result
(
s
);
s
=
result
.
data
();
int
start
=
0
;
int
end
=
reslen
-
1
;
while
(
isspace
((
uchar
)
s
[
start
])
)
// skip white space from start
start
++
;
if
(
s
[
start
]
==
'\0'
)
{
// only white space
return
SCString
();
}
while
(
end
&&
isspace
((
uchar
)
s
[
end
])
)
// skip white space from end
end
--
;
end
-=
start
-
1
;
memmove
(
result
.
data
(),
&
s
[
start
],
end
);
result
.
resize
(
end
+
1
);
return
result
;
}
SCString
SCString
::
simplifyWhiteSpace
()
const
{
if
(
isEmpty
()
)
// nothing to do
return
*
this
;
SCString
result
(
length
()
+
1
);
char
*
from
=
data
();
char
*
to
=
result
.
data
();
char
*
first
=
to
;
while
(
TRUE
)
{
while
(
*
from
&&
isspace
((
uchar
)
*
from
)
)
from
++
;
while
(
*
from
&&
!
isspace
((
uchar
)
*
from
)
)
*
to
++
=
*
from
++
;
if
(
*
from
)
*
to
++
=
0x20
;
// ' '
else
break
;
}
if
(
to
>
first
&&
*
(
to
-
1
)
==
0x20
)
to
--
;
*
to
=
'\0'
;
result
.
resize
(
(
int
)((
long
)
to
-
(
long
)
result
.
data
())
+
1
);
return
result
;
}
SCString
&
SCString
::
insert
(
uint
index
,
const
char
*
s
)
{
int
len
=
qstrlen
(
s
);
if
(
len
==
0
)
return
*
this
;
uint
olen
=
length
();
int
nlen
=
olen
+
len
;
if
(
index
>=
olen
)
// insert after end of string
{
m_data
=
(
char
*
)
realloc
(
m_data
,
nlen
+
index
-
olen
+
1
);
if
(
m_data
)
{
memset
(
m_data
+
olen
,
' '
,
index
-
olen
);
memcpy
(
m_data
+
index
,
s
,
len
+
1
);
}
}
else
if
(
(
m_data
=
(
char
*
)
realloc
(
m_data
,
nlen
+
1
))
)
// normal insert
{
memmove
(
m_data
+
index
+
len
,
m_data
+
index
,
olen
-
index
+
1
);
memcpy
(
m_data
+
index
,
s
,
len
);
}
return
*
this
;
}
SCString
&
SCString
::
insert
(
uint
index
,
char
c
)
// insert char
{
char
buf
[
2
];
buf
[
0
]
=
c
;
buf
[
1
]
=
'\0'
;
return
insert
(
index
,
buf
);
}
SCString
&
SCString
::
operator
+=
(
const
char
*
str
)
{
if
(
!
str
)
return
*
this
;
// nothing to append
uint
len1
=
length
();
uint
len2
=
qstrlen
(
str
);
char
*
newData
=
(
char
*
)
realloc
(
m_data
,
len1
+
len2
+
1
);
if
(
newData
)
{
m_data
=
newData
;
memcpy
(
m_data
+
len1
,
str
,
len2
+
1
);
}
return
*
this
;
}
SCString
&
SCString
::
operator
+=
(
char
c
)
{
uint
len
=
length
();
char
*
newData
=
(
char
*
)
realloc
(
m_data
,
length
()
+
2
);
if
(
newData
)
{
m_data
=
newData
;
m_data
[
len
]
=
c
;
m_data
[
len
+
1
]
=
'\0'
;
}
return
*
this
;
}
SCString
&
SCString
::
remove
(
uint
index
,
uint
len
)
{
uint
olen
=
length
();
if
(
index
+
len
>=
olen
)
// range problems
{
if
(
index
<
olen
)
// index ok
{
resize
(
index
+
1
);
}
}
else
if
(
len
!=
0
)
{
memmove
(
m_data
+
index
,
m_data
+
index
+
len
,
olen
-
index
-
len
+
1
);
resize
(
olen
-
len
+
1
);
}
return
*
this
;
}
SCString
&
SCString
::
replace
(
uint
index
,
uint
len
,
const
char
*
s
)
{
remove
(
index
,
len
);
insert
(
index
,
s
);
return
*
this
;
}
SCString
&
SCString
::
replace
(
const
QRegExp
&
rx
,
const
char
*
str
)
{
QString
d
=
QString
::
fromLatin1
(
m_data
);
QString
r
=
QString
::
fromLatin1
(
str
);
d
.
replace
(
rx
,
r
);
return
assign
(
d
.
ascii
());
}
long
SCString
::
toLong
(
bool
*
ok
)
const
{
QString
s
(
m_data
);
return
s
.
toLong
(
ok
);
}
ulong
SCString
::
toULong
(
bool
*
ok
)
const
{
QString
s
(
m_data
);
return
s
.
toULong
(
ok
);
}
short
SCString
::
toShort
(
bool
*
ok
)
const
{
QString
s
(
m_data
);
return
s
.
toShort
(
ok
);
}
ushort
SCString
::
toUShort
(
bool
*
ok
)
const
{
QString
s
(
m_data
);
return
s
.
toUShort
(
ok
);
}
int
SCString
::
toInt
(
bool
*
ok
)
const
{
QString
s
(
m_data
);
return
s
.
toInt
(
ok
);
}
uint
SCString
::
toUInt
(
bool
*
ok
)
const
{
QString
s
(
m_data
);
return
s
.
toUInt
(
ok
);
}
SCString
&
SCString
::
setNum
(
long
n
)
{
char
buf
[
20
];
register
char
*
p
=
&
buf
[
19
];
bool
neg
;
if
(
n
<
0
)
{
neg
=
TRUE
;
n
=
-
n
;
}
else
{
neg
=
FALSE
;
}
*
p
=
'\0'
;
do
{
*--
p
=
((
int
)(
n
%
10
))
+
'0'
;
n
/=
10
;
}
while
(
n
);
if
(
neg
)
*--
p
=
'-'
;
operator
=
(
p
);
return
*
this
;
}
SCString
&
SCString
::
setNum
(
ulong
n
)
{
char
buf
[
20
];
register
char
*
p
=
&
buf
[
19
];
*
p
=
'\0'
;
do
{
*--
p
=
((
int
)(
n
%
10
))
+
'0'
;
n
/=
10
;
}
while
(
n
);
operator
=
(
p
);
return
*
this
;
}
void
SCString
::
msg_index
(
uint
index
)
{
#if defined(CHECK_RANGE)
qWarning
(
"SCString::at: Absolute index %d out of range"
,
index
);
#else
Q_UNUSED
(
index
)
#endif
}
bool
SCString
::
stripPrefix
(
const
char
*
prefix
)
{
if
(
prefix
==
0
)
return
FALSE
;
uint
plen
=
qstrlen
(
prefix
);
if
(
m_data
&&
qstrncmp
(
prefix
,
m_data
,
plen
)
==
0
)
// prefix matches
{
uint
len
=
qstrlen
(
m_data
);
uint
newlen
=
len
-
plen
+
1
;
qmemmove
(
m_data
,
m_data
+
plen
,
newlen
);
resize
(
newlen
);
return
TRUE
;
}
return
FALSE
;
}
//---------------------------------------------------------------------------
void
*
qmemmove
(
void
*
dst
,
const
void
*
src
,
uint
len
)
{
register
char
*
d
;
register
char
*
s
;
if
(
dst
>
src
)
{
d
=
(
char
*
)
dst
+
len
-
1
;
s
=
(
char
*
)
src
+
len
-
1
;
while
(
len
--
)
*
d
--
=
*
s
--
;
}
else
if
(
dst
<
src
)
{
d
=
(
char
*
)
dst
;
s
=
(
char
*
)
src
;
while
(
len
--
)
*
d
++
=
*
s
++
;
}
return
dst
;
}
char
*
qstrdup
(
const
char
*
str
)
{
if
(
!
str
)
return
0
;
char
*
dst
=
new
char
[
strlen
(
str
)
+
1
];
CHECK_PTR
(
dst
);
return
strcpy
(
dst
,
str
);
}
char
*
qstrncpy
(
char
*
dst
,
const
char
*
src
,
uint
len
)
{
if
(
!
src
)
return
0
;
strncpy
(
dst
,
src
,
len
);
if
(
len
>
0
)
dst
[
len
-
1
]
=
'\0'
;
return
dst
;
}
int
qstricmp
(
const
char
*
str1
,
const
char
*
str2
)
{
register
const
uchar
*
s1
=
(
const
uchar
*
)
str1
;
register
const
uchar
*
s2
=
(
const
uchar
*
)
str2
;
int
res
;
uchar
c
;
if
(
!
s1
||
!
s2
)
return
s1
==
s2
?
0
:
(
int
)((
long
)
s2
-
(
long
)
s1
);
for
(
;
!
(
res
=
(
c
=
tolower
(
*
s1
))
-
tolower
(
*
s2
));
s1
++
,
s2
++
)
if
(
!
c
)
// strings are equal
break
;
return
res
;
}
int
qstrnicmp
(
const
char
*
str1
,
const
char
*
str2
,
uint
len
)
{
register
const
uchar
*
s1
=
(
const
uchar
*
)
str1
;
register
const
uchar
*
s2
=
(
const
uchar
*
)
str2
;
int
res
;
uchar
c
;
if
(
!
s1
||
!
s2
)
return
(
int
)((
long
)
s2
-
(
long
)
s1
);
for
(
;
len
--
;
s1
++
,
s2
++
)
{
if
(
(
res
=
(
c
=
tolower
(
*
s1
))
-
tolower
(
*
s2
))
)
return
res
;
if
(
!
c
)
// strings are equal
break
;
}
return
0
;
}
#ifndef QT_NO_DATASTREAM
QDataStream
&
operator
<<
(
QDataStream
&
s
,
const
QByteArray
&
a
)
{
return
s
.
writeBytes
(
a
.
data
(),
a
.
size
()
);
}
QDataStream
&
operator
>>
(
QDataStream
&
s
,
QByteArray
&
a
)
{
Q_UINT32
len
;
s
>>
len
;
// read size of array
if
(
len
==
0
||
s
.
eof
()
)
{
// end of file reached
a
.
resize
(
0
);
return
s
;
}
if
(
!
a
.
resize
(
(
uint
)
len
)
)
{
// resize array
#if defined(CHECK_NULL)
qWarning
(
"QDataStream: Not enough memory to read QByteArray"
);
#endif
len
=
0
;
}
if
(
len
>
0
)
// not null array
s
.
readRawBytes
(
a
.
data
(),
(
uint
)
len
);
return
s
;
}
QDataStream
&
operator
<<
(
QDataStream
&
s
,
const
SCString
&
str
)
{
return
s
.
writeBytes
(
str
.
data
(),
str
.
size
()
);
}
QDataStream
&
operator
>>
(
QDataStream
&
s
,
SCString
&
str
)
{
Q_UINT32
len
;
s
>>
len
;
// read size of string
if
(
len
==
0
||
s
.
eof
()
)
{
// end of file reached
str
.
resize
(
0
);
return
s
;
}
if
(
!
str
.
resize
(
(
uint
)
len
))
{
// resize string
#if defined(CHECK_NULL)
qWarning
(
"QDataStream: Not enough memory to read QCString"
);
#endif
len
=
0
;
}
if
(
len
>
0
)
// not null array
s
.
readRawBytes
(
str
.
data
(),
(
uint
)
len
);
return
s
;
}
#endif //QT_NO_DATASTREAM
#endif
qtools/scstring.h
0 → 100644
View file @
7d933a9f
/******************************************************************************
*
* Copyright (C) 1997-2004 by Dimitri van Heesch.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation under the terms of the GNU General Public License is hereby
* granted. No representations are made about the suitability of this software
* for any purpose. It is provided "as is" without express or implied warranty.
* See the GNU General Public License for more details.
*
* Documents produced by Doxygen are derivative works derived from the
* input used in their production; they are not affected by this license.
*
*/
#ifndef SCSTRING_H
#define SCSTRING_H
#include <stdlib.h>
class
QRegExp
;
/** This is an alternative implementation of QCString. It provides basically
* the same functions but uses less memory for administration. This class
* is just a wrapper around a plain C string requiring only 4 bytes "overhead".
* QCString features sharing of data and stores the string length, but
* requires 4 + 12 bytes for this (even for the empty string). As doxygen
* uses a LOT of string during a run it saves a lot of memory to use a
* more memory efficient implementation at the cost of relatively low
* runtime overhead.
*/
class
SCString
{
public
:
SCString
()
:
m_data
(
0
)
{}
// make null string
SCString
(
const
SCString
&
s
);
SCString
(
int
size
);
SCString
(
const
char
*
str
);
SCString
(
const
char
*
str
,
uint
maxlen
);
~
SCString
();
SCString
&
operator
=
(
const
SCString
&
s
);
// deep copy
SCString
&
operator
=
(
const
char
*
str
);
// deep copy
bool
isNull
()
const
;
bool
isEmpty
()
const
;
uint
length
()
const
;
uint
size
()
const
{
return
m_data
?
length
()
+
1
:
0
;
}
char
*
data
()
const
{
return
m_data
;
}
bool
resize
(
uint
newlen
);
bool
truncate
(
uint
pos
);
bool
fill
(
char
c
,
int
len
=
-
1
);
SCString
copy
()
const
;
SCString
&
sprintf
(
const
char
*
format
,
...
);
int
find
(
char
c
,
int
index
=
0
,
bool
cs
=
TRUE
)
const
;
int
find
(
const
char
*
str
,
int
index
=
0
,
bool
cs
=
TRUE
)
const
;
int
find
(
const
QRegExp
&
,
int
index
=
0
)
const
;
int
find
(
const
QCString
&
str
,
int
index
,
bool
cs
)
const
;
int
findRev
(
char
c
,
int
index
=-
1
,
bool
cs
=
TRUE
)
const
;
int
findRev
(
const
char
*
str
,
int
index
=-
1
,
bool
cs
=
TRUE
)
const
;
int
findRev
(
const
QRegExp
&
,
int
index
=-
1
)
const
;
int
contains
(
char
c
,
bool
cs
=
TRUE
)
const
;
int
contains
(
const
char
*
str
,
bool
cs
=
TRUE
)
const
;
int
contains
(
const
QRegExp
&
)
const
;
bool
stripPrefix
(
const
char
*
prefix
);
SCString
left
(
uint
len
)
const
;
SCString
right
(
uint
len
)
const
;
SCString
mid
(
uint
index
,
uint
len
=
0xffffffff
)
const
;
SCString
lower
()
const
;
SCString
upper
()
const
;
SCString
stripWhiteSpace
()
const
;
SCString
simplifyWhiteSpace
()
const
;
SCString
&
assign
(
const
char
*
str
);
SCString
&
insert
(
uint
index
,
const
char
*
);
SCString
&
insert
(
uint
index
,
char
);
SCString
&
append
(
const
char
*
s
);
SCString
&
prepend
(
const
char
*
s
);
SCString
&
remove
(
uint
index
,
uint
len
);
SCString
&
replace
(
uint
index
,
uint
len
,
const
char
*
);
SCString
&
replace
(
const
QRegExp
&
,
const
char
*
);
short
toShort
(
bool
*
ok
=
0
)
const
;
ushort
toUShort
(
bool
*
ok
=
0
)
const
;
int
toInt
(
bool
*
ok
=
0
)
const
;
uint
toUInt
(
bool
*
ok
=
0
)
const
;
long
toLong
(
bool
*
ok
=
0
)
const
;
ulong
toULong
(
bool
*
ok
=
0
)
const
;
SCString
&
setNum
(
short
);
SCString
&
setNum
(
ushort
);
SCString
&
setNum
(
int
);
SCString
&
setNum
(
uint
);
SCString
&
setNum
(
long
);
SCString
&
setNum
(
ulong
);
QCString
&
setNum
(
float
,
char
f
=
'g'
,
int
prec
=
6
);
QCString
&
setNum
(
double
,
char
f
=
'g'
,
int
prec
=
6
);
operator
const
char
*
()
const
;
SCString
&
operator
+=
(
const
char
*
str
);
SCString
&
operator
+=
(
char
c
);
char
&
at
(
uint
index
)
const
;
char
&
operator
[](
int
i
)
const
{
return
at
(
i
);
}
private
:
static
void
msg_index
(
uint
);
void
duplicate
(
const
SCString
&
s
);
void
duplicate
(
const
char
*
str
);
SCString
&
duplicate
(
const
char
*
str
,
int
);
char
*
m_data
;
};
inline
char
&
SCString
::
at
(
uint
index
)
const
{
return
m_data
[
index
];
}
inline
void
SCString
::
duplicate
(
const
SCString
&
s
)
{
if
(
!
s
.
isEmpty
())
{
uint
l
=
strlen
(
s
.
data
());
m_data
=
(
char
*
)
malloc
(
l
+
1
);
if
(
m_data
)
memcpy
(
m_data
,
s
.
data
(),
l
+
1
);
}
else
m_data
=
0
;
}
inline
void
SCString
::
duplicate
(
const
char
*
str
)
{
if
(
str
&&
str
[
0
]
!=
'\0'
)
{
uint
l
=
strlen
(
str
);
m_data
=
(
char
*
)
malloc
(
l
+
1
);
if
(
m_data
)
memcpy
(
m_data
,
str
,
l
+
1
);
}
else
m_data
=
0
;
}
inline
SCString
&
SCString
::
duplicate
(
const
char
*
str
,
int
)
{
if
(
m_data
)
free
(
m_data
);
duplicate
(
str
);
return
*
this
;
}
#endif
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