Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Tobias Hunger
qt-creator
Commits
027b52a2
Commit
027b52a2
authored
Mar 11, 2009
by
Oswald Buddenhagen
Browse files
sync variable expansion and list splitting with qmake
parent
5bc97eb1
Changes
2
Hide whitespace changes
Inline
Side-by-side
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
Supports
Markdown
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