Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Tobias Hunger
qt-creator
Commits
027b52a2
Commit
027b52a2
authored
Mar 11, 2009
by
Oswald Buddenhagen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sync variable expansion and list splitting with qmake
parent
5bc97eb1
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
115 additions
and
120 deletions
+115
-120
src/shared/proparser/profileevaluator.cpp
src/shared/proparser/profileevaluator.cpp
+94
-88
src/shared/proparser/proparserutils.h
src/shared/proparser/proparserutils.h
+21
-32
No files found.
src/shared/proparser/profileevaluator.cpp
View file @
027b52a2
...
...
@@ -978,11 +978,9 @@ QString ProFileEvaluator::Private::currentDirectory() const
QStringList
ProFileEvaluator
::
Private
::
expandVariableReferences
(
const
QString
&
str
)
{
bool
fOK
;
bool
*
ok
=
&
fOK
;
QStringList
ret
;
if
(
ok
)
*
ok
=
true
;
//
if (ok)
//
*ok = true;
if
(
str
.
isEmpty
())
return
ret
;
...
...
@@ -998,7 +996,10 @@ QStringList ProFileEvaluator::Private::expandVariableReferences(const QString &s
const
ushort
DOT
=
'.'
;
const
ushort
SPACE
=
' '
;
const
ushort
TAB
=
'\t'
;
const
ushort
SINGLEQUOTE
=
'\''
;
const
ushort
DOUBLEQUOTE
=
'"'
;
ushort
unicode
,
quote
=
0
;
const
QChar
*
str_data
=
str
.
data
();
const
int
str_len
=
str
.
length
();
...
...
@@ -1008,126 +1009,105 @@ QStringList ProFileEvaluator::Private::expandVariableReferences(const QString &s
int
replaced
=
0
;
QString
current
;
for
(
int
i
=
0
;
i
<
str_len
;
++
i
)
{
u
short
c
=
str_data
[
i
].
unicode
();
u
nicode
=
str_data
[
i
].
unicode
();
const
int
start_var
=
i
;
if
(
c
==
BACKSLASH
)
{
bool
escape
=
false
;
const
char
*
symbols
=
"[]{}()$
\\
"
;
for
(
const
char
*
s
=
symbols
;
*
s
;
++
s
)
{
if
(
str_data
[
i
+
1
]
==
(
ushort
)
*
s
)
{
i
++
;
escape
=
true
;
if
(
!
(
replaced
++
))
current
=
str
.
left
(
start_var
);
current
.
append
(
str
.
at
(
i
));
break
;
}
}
if
(
!
escape
&&
replaced
)
current
.
append
(
QChar
(
c
));
continue
;
}
if
(
c
==
SPACE
||
c
==
TAB
)
{
c
=
0
;
if
(
!
current
.
isEmpty
())
{
unquote
(
&
current
);
ret
.
append
(
current
);
current
.
clear
();
}
}
else
if
(
c
==
DOLLAR
&&
str_len
>
i
+
2
)
{
c
=
str_data
[
++
i
].
unicode
();
if
(
c
==
DOLLAR
)
{
if
(
unicode
==
DOLLAR
&&
str_len
>
i
+
2
)
{
unicode
=
str_data
[
++
i
].
unicode
();
if
(
unicode
==
DOLLAR
)
{
term
=
0
;
var
.
clear
();
args
.
clear
();
enum
{
VAR
,
ENVIRON
,
FUNCTION
,
PROPERTY
}
var_type
=
VAR
;
c
=
str_data
[
++
i
].
unicode
();
if
(
c
==
LSQUARE
)
{
c
=
str_data
[
++
i
].
unicode
();
unicode
=
str_data
[
++
i
].
unicode
();
if
(
unicode
==
LSQUARE
)
{
unicode
=
str_data
[
++
i
].
unicode
();
term
=
RSQUARE
;
var_type
=
PROPERTY
;
}
else
if
(
c
==
LCURLY
)
{
c
=
str_data
[
++
i
].
unicode
();
}
else
if
(
unicode
==
LCURLY
)
{
unicode
=
str_data
[
++
i
].
unicode
();
var_type
=
VAR
;
term
=
RCURLY
;
}
else
if
(
c
==
LPAREN
)
{
c
=
str_data
[
++
i
].
unicode
();
}
else
if
(
unicode
==
LPAREN
)
{
unicode
=
str_data
[
++
i
].
unicode
();
var_type
=
ENVIRON
;
term
=
RPAREN
;
}
while
(
1
)
{
if
(
!
(
c
&
(
0xFF
<<
8
))
&&
c
!=
DOT
&&
c
!=
UNDERSCORE
&&
(
c
<
'a'
||
c
>
'z'
)
&&
(
c
<
'A'
||
c
>
'Z'
)
&&
(
c
<
'0'
||
c
>
'9'
))
forever
{
if
(
!
(
unicode
&
(
0xFF
<<
8
))
&&
unicode
!=
DOT
&&
unicode
!=
UNDERSCORE
&&
//unicode != SINGLEQUOTE && unicode != DOUBLEQUOTE &&
(
unicode
<
'a'
||
unicode
>
'z'
)
&&
(
unicode
<
'A'
||
unicode
>
'Z'
)
&&
(
unicode
<
'0'
||
unicode
>
'9'
))
break
;
var
.
append
(
QChar
(
c
));
var
.
append
(
QChar
(
unicode
));
if
(
++
i
==
str_len
)
break
;
c
=
str_data
[
i
].
unicode
();
unicode
=
str_data
[
i
].
unicode
();
// at this point, i points to either the 'term' or 'next' character (which is in unicode)
}
if
(
var_type
==
VAR
&&
c
==
LPAREN
)
{
if
(
var_type
==
VAR
&&
unicode
==
LPAREN
)
{
var_type
=
FUNCTION
;
int
depth
=
0
;
while
(
1
)
{
forever
{
if
(
++
i
==
str_len
)
break
;
c
=
str_data
[
i
].
unicode
();
if
(
c
==
LPAREN
)
{
unicode
=
str_data
[
i
].
unicode
();
if
(
unicode
==
LPAREN
)
{
depth
++
;
}
else
if
(
c
==
RPAREN
)
{
}
else
if
(
unicode
==
RPAREN
)
{
if
(
!
depth
)
break
;
--
depth
;
}
args
.
append
(
QChar
(
c
));
args
.
append
(
QChar
(
unicode
));
}
if
(
i
<
str_len
-
1
)
c
=
str_data
[
++
i
].
unicode
();
if
(
++
i
<
str_len
)
unicode
=
str_data
[
i
].
unicode
();
else
c
=
0
;
unicode
=
0
;
// at this point i is pointing to the 'next' character (which is in unicode)
// this might actually be a term character since you can do $${func()}
}
if
(
term
)
{
if
(
c
!=
term
)
{
if
(
unicode
!=
term
)
{
q
->
logMessage
(
format
(
"Missing %1 terminator [found %2]"
)
.
arg
(
QChar
(
term
)).
arg
(
QChar
(
c
)));
if
(
ok
)
*
ok
=
false
;
.
arg
(
QChar
(
term
))
.
arg
(
unicode
?
QString
(
unicode
)
:
QString
::
fromLatin1
((
"end-of-line"
))));
// if (ok)
// *ok = false;
return
QStringList
();
}
c
=
0
;
}
else
if
(
i
>
str_len
-
1
)
{
c
=
0
;
}
else
{
// move the 'cursor' back to the last char of the thing we were looking at
--
i
;
}
// since i never points to the 'next' character, there is no reason for this to be set
unicode
=
0
;
QStringList
replacement
;
if
(
var_type
==
ENVIRON
)
{
replacement
<<
QString
::
fromLocal8Bit
(
qgetenv
(
var
.
toL
ocal8Bit
().
constData
()));
replacement
=
split_value_list
(
QString
::
fromLocal8Bit
(
qgetenv
(
var
.
toL
atin1
().
constData
()))
)
;
}
else
if
(
var_type
==
PROPERTY
)
{
replacement
<<
propertyValue
(
var
);
//if (prop)
// replacement = QStringList(prop->value(var));
}
else
if
(
var_type
==
FUNCTION
)
{
replacement
<<
evaluateExpandFunction
(
var
,
args
);
}
else
if
(
var_type
==
VAR
)
{
replacement
+
=
values
(
var
);
replacement
=
values
(
var
);
}
if
(
!
(
replaced
++
)
&&
start_var
)
current
=
str
.
left
(
start_var
);
if
(
!
replacement
.
isEmpty
())
{
/* If a list is beteen two strings make sure it expands in such a way
* that the string to the left is prepended to the first string and
* the string to the right is appended to the last string, example:
* LIST = a b c
* V3 = x/$$LIST/f.cpp
* message($$member(V3,0)) # Outputs "x/a"
* message($$member(V3,1)) # Outputs "b"
* message($$member(V3,2)) # Outputs "c/f.cpp"
*/
current
.
append
(
replacement
.
at
(
0
));
for
(
int
i
=
1
;
i
<
replacement
.
count
();
++
i
)
{
unquote
(
&
current
);
ret
.
append
(
current
);
current
=
replacement
.
at
(
i
);
if
(
quote
)
{
current
+=
replacement
.
join
(
QString
(
Option
::
field_sep
));
}
else
{
current
+=
replacement
.
takeFirst
();
if
(
!
replacement
.
isEmpty
())
{
if
(
!
current
.
isEmpty
())
ret
.
append
(
current
);
current
=
replacement
.
takeLast
();
if
(
!
replacement
.
isEmpty
())
ret
+=
replacement
;
}
}
}
}
else
{
...
...
@@ -1135,17 +1115,43 @@ QStringList ProFileEvaluator::Private::expandVariableReferences(const QString &s
current
.
append
(
QLatin1Char
(
'$'
));
}
}
if
(
replaced
&&
c
!=
0
)
current
.
append
(
QChar
(
c
));
if
(
quote
&&
unicode
==
quote
)
{
unicode
=
0
;
quote
=
0
;
}
else
if
(
unicode
==
BACKSLASH
)
{
bool
escape
=
false
;
const
char
*
symbols
=
"[]{}()$
\\
'
\"
"
;
for
(
const
char
*
s
=
symbols
;
*
s
;
++
s
)
{
if
(
str_data
[
i
+
1
].
unicode
()
==
(
ushort
)
*
s
)
{
i
++
;
escape
=
true
;
if
(
!
(
replaced
++
))
current
=
str
.
left
(
start_var
);
current
.
append
(
str
.
at
(
i
));
break
;
}
}
if
(
escape
||
!
replaced
)
unicode
=
0
;
}
else
if
(
!
quote
&&
(
unicode
==
SINGLEQUOTE
||
unicode
==
DOUBLEQUOTE
))
{
quote
=
unicode
;
unicode
=
0
;
if
(
!
(
replaced
++
)
&&
i
)
current
=
str
.
left
(
i
);
}
else
if
(
!
quote
&&
(
unicode
==
SPACE
||
unicode
==
TAB
))
{
unicode
=
0
;
if
(
!
current
.
isEmpty
())
{
ret
.
append
(
current
);
current
.
clear
();
}
}
if
(
replaced
&&
unicode
)
current
.
append
(
QChar
(
unicode
));
}
if
(
!
replaced
)
{
cur
re
n
t
=
str
;
unquote
(
&
current
);
if
(
!
replaced
)
ret
=
QStringList
(
str
)
;
else
if
(
!
current
.
isEmpty
())
ret
.
append
(
current
);
}
else
if
(
!
current
.
isEmpty
())
{
unquote
(
&
current
);
ret
.
append
(
current
);
}
return
ret
;
}
...
...
src/shared/proparser/proparserutils.h
View file @
027b52a2
...
...
@@ -116,17 +116,6 @@ QString Option::dirlist_sep;
QString
Option
::
dir_sep
;
QChar
Option
::
field_sep
;
static
void
unquote
(
QString
*
string
)
{
PRE
(
string
);
if
(
(
string
->
startsWith
(
QLatin1Char
(
'\"'
))
&&
string
->
endsWith
(
QLatin1Char
(
'\"'
)))
||
(
string
->
startsWith
(
QLatin1Char
(
'\''
))
&&
string
->
endsWith
(
QLatin1Char
(
'\''
)))
)
{
string
->
remove
(
0
,
1
);
string
->
remove
(
string
->
length
()
-
1
,
1
);
}
}
static
void
insertUnique
(
QHash
<
QString
,
QStringList
>
*
map
,
const
QString
&
key
,
const
QStringList
&
value
)
{
...
...
@@ -221,7 +210,8 @@ static QStringList split_arg_list(QString params)
quote
=
0
;
}
else
if
(
!
quote
&&
(
unicode
==
SINGLEQUOTE
||
unicode
==
DOUBLEQUOTE
))
{
quote
=
unicode
;
}
else
if
(
!
parens
&&
!
quote
&&
unicode
==
COMMA
)
{
}
if
(
!
parens
&&
!
quote
&&
unicode
==
COMMA
)
{
QString
mid
=
params
.
mid
(
last
,
x
-
last
).
trimmed
();
args
<<
mid
;
last
=
x
+
1
;
...
...
@@ -230,8 +220,6 @@ static QStringList split_arg_list(QString params)
++
last
;
}
}
for
(
int
i
=
0
;
i
<
args
.
count
();
i
++
)
unquote
(
&
args
[
i
]);
return
args
;
}
...
...
@@ -239,34 +227,35 @@ static QStringList split_value_list(const QString &vals, bool do_semicolon=false
{
QString
build
;
QStringList
ret
;
QStack
<
QC
har
>
quote
;
QStack
<
c
har
>
quote
;
const
QChar
LPAREN
=
QLatin1Char
(
'('
)
;
const
QChar
RPAREN
=
QLatin1Char
(
')'
)
;
const
QChar
SINGLEQUOTE
=
QLatin1Char
(
'\''
)
;
const
QChar
DOUBLEQUOTE
=
QLatin1Char
(
'"'
)
;
const
QChar
BACKSLASH
=
QLatin1Char
(
'\\'
)
;
const
QChar
SEMICOLON
=
QLatin1Char
(
';'
)
;
const
ushort
LPAREN
=
'('
;
const
ushort
RPAREN
=
')'
;
const
ushort
SINGLEQUOTE
=
'\''
;
const
ushort
DOUBLEQUOTE
=
'"'
;
const
ushort
BACKSLASH
=
'\\'
;
const
ushort
SEMICOLON
=
';'
;
ushort
unicode
;
const
QChar
*
vals_data
=
vals
.
data
();
const
int
vals_len
=
vals
.
length
();
for
(
int
x
=
0
,
parens
=
0
;
x
<
vals_len
;
x
++
)
{
QChar
c
=
vals_data
[
x
];
if
(
x
!=
vals_len
-
1
&&
c
==
BACKSLASH
&&
vals_data
[
x
+
1
].
unicode
()
==
'\''
||
vals_data
[
x
+
1
]
==
DOUBLEQUOTE
)
{
build
+=
vals_data
[
x
++
];
//
get that 'escape'
}
else
if
(
!
quote
.
isEmpty
()
&&
c
==
quote
.
top
())
{
unicode
=
vals_data
[
x
]
.
unicode
()
;
if
(
x
!=
(
int
)
vals_len
-
1
&&
unicode
==
BACKSLASH
&&
(
vals_data
[
x
+
1
].
unicode
()
==
SINGLEQUOTE
||
vals_data
[
x
+
1
]
.
unicode
()
==
DOUBLEQUOTE
)
)
{
build
+=
vals_data
[
x
++
];
//get that 'escape'
}
else
if
(
!
quote
.
isEmpty
()
&&
unicode
==
quote
.
top
())
{
quote
.
pop
();
}
else
if
(
c
==
SINGLEQUOTE
||
c
==
DOUBLEQUOTE
)
{
quote
.
push
(
c
);
}
else
if
(
c
==
RPAREN
)
{
}
else
if
(
unicode
==
SINGLEQUOTE
||
unicode
==
DOUBLEQUOTE
)
{
quote
.
push
(
unicode
);
}
else
if
(
unicode
==
RPAREN
)
{
--
parens
;
}
else
if
(
c
==
LPAREN
)
{
}
else
if
(
unicode
==
LPAREN
)
{
++
parens
;
}
if
(
!
parens
&&
quote
.
isEmpty
()
&&
((
do_semicolon
&&
c
==
SEMICOLON
)
||
vals_data
[
x
]
==
Option
::
field_sep
))
{
if
(
!
parens
&&
quote
.
isEmpty
()
&&
((
do_semicolon
&&
unicode
==
SEMICOLON
)
||
vals_data
[
x
]
==
Option
::
field_sep
))
{
ret
<<
build
;
build
.
clear
();
}
else
{
...
...
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