Escape Spaces in QT - qt

I want to use the QString.split(' ') method to split a input command into the command
QStringList commandList = command.split(' ');
however command has a UNIX path at the end of it. i.e. it looks something like
QString command = new QString("caommand -a -b /path/to\ specific/file");
the path command is specified by the user at runtime(the user escapes any spaces in the path). For some reason command.split(' '); does not escape the spaces.
I am new to QT, how does it escape spaces?
Thanks for any help

You can use QDir::toNativeSeparators() to convert it to unix style. And split received result by spaces, though you have got to figure out where are the spaces between commands and where are the possible spaces in filename
For example:
QString myUnixPath = QDir::toNativeSeparators("/home/path with spaces/");
will return unix style path, while
QString qtPath = QDir::fromNativeSeparators("/path/with\ spaces/");
will return /path with spaces/

Related

combining strings to one string in r

I'm trying to combine some stings to one. In the end this string should be generated:
//*[#id="coll276"]
So my inner part of the string is an vector: tag <- 'coll276'
I already used the paste() method like this:
paste('//*[#id="',tag,'"]', sep = "")
But my result looks like following: //*[#id=\"coll276\"]
I don't why R is putting some \ into my string, but how can I fix this problem?
Thanks a lot!
tldr: Don't worry about them, they're not really there. It's just something added by print
Those \ are escape characters that tell R to ignore the special properties of the characters that follow them. Look at the output of your paste function:
paste('//*[#id="',tag,'"]', sep = "")
[1] "//*[#id=\"coll276\"]"
You'll see that the output, since it is a string, is enclosed in double quotes "". Normally, the double quotes inside your string would break the string up into two strings with bare code in the middle:
"//*[#id\" coll276 "]"
To prevent this, R "escapes" the quotes in your string so they don't do this. This is just a visual effect. If you write your string to a file, you'll see that those escaping \ aren't actually there:
write(paste('//*[#id="',tag,'"]', sep = ""), 'out.txt')
This is what is in the file:
//*[#id="coll276"]
You can use cat to print the exact value of the string to the console (Thanks #LukeC):
cat(paste('//*[#id="',tag,'"]', sep = ""))
//*[#id="coll276"]
Or use single quotes (if possible):
paste('//*[#id=\'',tag,'\']', sep = "")
[1] "//*[#id='coll276']"

Test Regex with new line string \n via PHPUnit

I created a php library that parse content via regex. One of this regex is '#\n-{3,}#' to parse --- only with an break, a new line, before.
I have also tests written in PHPUnit for all methods and always I get a failure for tests with the new line regex. I test always with assertSame()
I tried to set as input the follow strings:
$input = PHP_EOL . '---';
$input = '<br>---';
$input = '
---'; // with break in code
As expected I set:
'<hr/>'
However always it fail and get an error. If I send this variables to the assert check it will fail and parse not the new line. Only without the \n inside the Regex, like '#-{3,}#', it works fine without error for the tests.
Also if I use as input for the test a new line with a string before, it works also, like
$input = "test\n---";
But I would like also to test without string, only start with a new line.
The parse for front end works fine, it replace via this regex from my markdown file if the content is include a break and followed by the 3 -.
How is it possible to set as input for the assertSame() function in PHPUnit a new line before the string?
The problem is you are using single quotes in your pattern.
In PHP \n means "new line" in a string only if double quotes are used.
$input = PHP_EOL . '---';
preg_match("#\n-{3,}#", $input); // this will match
See https://3v4l.org/EpEGf

Unix: Using filename from another file

A basic Unix question.
I have a script which counts the number of records in a delta file.
awk '{
n++
} END {
if(n >= 1000) print "${completeFile}"; else print "${deltaFile}";
}' <${deltaFile} >${fileToUse}
Then, depending on the IF condition, I want to process the appropriate file:
cut -c2-11 < ${fileToUse}
But how do I use the contents of the file as the filename itself?
And if there are any tweaks to be made, feel free.
Thanks in advance
Cheers
Simon
To use as a filename the contents of a file which is itself identified by a variable (as asked)
cut -c2-11 <"$( cat $filetouse )"
// or in zsh just
cut -c2-11 <"$( < $filetouse )"
unless the filename in the file ends with one or more newline character(s), which people rarely do because it's quite awkward and inconvenient, then something like:
read -rdX var <$filetouse; cut -c2-11 < "${var%?}"
// where X is a character that doesn't occur in the filename
// maybe something like $'\x1f'
Tweaks: your awk prints the variable reference ${completeFile} or ${deltaFile} (because they're within the single-quoted awk script) not the value of either variable. If you actually want the value, as I'd expect from your description, you should pass the shell vars to awk vars like this
awk -vf="$completeFile" -vd="$deltaFile" '{n++} END{if(n>=1000)print f; else print d}' <"$deltaFile"`
# the " around $var can be omitted if the value contains no whitespace and no glob chars
# people _often_ but not always choose filenames that satisfy this
# and they must not contain backslash in any case
or export the shell vars as env vars (if they aren't already) and access them like
awk '{n++} END{if(n>=1000) print ENVIRON["completeFile"]; else print ENVIRON["deltaFile"]}' <"$deltaFile"
Also you don't need your own counter, awk already counts input records
awk -vf=... -vd=... 'END{if(NR>=1000)print f;else print d}' <...
or more briefly
awk -vf=... -vd=... 'END{print (NR>=1000?f:d)}' <...
or using a file argument instead of redirection so the name is available to the script
awk -vf="$completeFile" 'END{print (NR>=1000?f:FILENAME)}' "$deltaFile" # no <
and barring trailing newlines as above you don't need an intermediate file at all, just
cut -c2-11 <"$( awk -vf="$completeFile" -'END{print (NR>=1000?f:FILENAME)}' "$deltaFile")"
Or you don't really need awk, wc can do the counting and any POSIX or classic shell can do the comparison
if [ $(wc -l <"$deltaFile") -ge 1000 ]; then c="$completeFile"; else c="$deltaFile"; fi
cut -c2-11 <"$c"

trouble passing parameters to console application

I have trouble with correctly launching cloc 1.62 from windows command line using qprocess. Here is what i have:
A QStringList with all the languages cloc recognizes;
QStringList languages;
languages<<"\"ABAP\""<<"\"ActionScript\""<<"\"Ada\""<<"\"ADSO/IDSM\""<<"\"AMPLE\""<<"\"Ant\""<<"\"Apex Trigger\"";
Then i create a qstring consisting of all of the list's elements separated by comma, exept for one, which is stored in a lang variable;
QString langsinuse;
for (int i=0;i<languages.length();i++)
{
if (languages.at(i) != lang)
{
if (langsinuse.isEmpty())
{
langsinuse=langsinuse+languages.at(i);
}
else
{
langsinuse=langsinuse+','+languages.at(i);
}
}
}
then i build an arguments stringlist and launch the process:
QStringList arguments;
QProcess cloc;
QString params="cloc-1.62.exe --xml --by-file --report-file="+
list1.at(1).trimmed()+'/'+name+'/'+"report.xml"+" --exclude-lang="+langsinuse+" "+distr;
arguments<<"/k"<<params;
cloc.startDetached("cmd.exe",arguments,"cloc/");
But somehow the spaces in the languages names are not considered escaped and every word separated by space considered a different parameter for cloc, even though both words are in double quotes (for example "\"Apex Trigger\"") and clock produces a bunch of errors.
(50 errors:
Unable to read: Trigger","Arduino
Unable to read: Sketch","ASP","ASP.Net","Assembly","AutoHotkey","awk","Bourne)
It's the error that happens when you don't put a language's name that contains spaces in double quotes, int the --exclude-lang= option (for example --exclude-lang=Apex Trigger will cause an error, --exclude-lang="Apex Trigger" won't)
However if i just save the whole command i build in qt and save it in some batch file it runs just fine.
Am i missing something in escaping the double quotes correctly?
Ok i just had to pass arguments separately and not as a single string.
arguments<<"/k"<<"cloc-1.62.exe" <<"--xml"<<"--by-file"<<"--report-file="+
list1.at(1).trimmed()+'/'+name+'/'+"report.xml"<<"--exclude-lang="+langsinuse<<distr;

QRegExp: individual quantifiers can't be non-greedy, but what good alternatives then?

I'm trying to write code that appends ending _my_ending to the filename, and does not change file extension.
Examples of what I need to get:
"test.bmp" -> "test_my_ending.bmp"
"test.foo.bar.bmp" -> "test.foo.bar_my_ending.bmp"
"test" -> "test_my_ending"
I have some experience in PCRE, and that's trivial task using it. Because of the lack of experience in Qt, initially I wrote the following code:
QString new_string = old_string.replace(
QRegExp("^(.+?)(\\.[^.]+)?$"),
"\\1_my_ending\\2"
);
This code does not work (no match at all), and then I found in the docs that
Non-greedy matching cannot be applied to individual quantifiers, but can be applied to all the quantifiers in the pattern
As you see, in my regexp I tried to reduce greediness of the first quantifier + by adding ? after it. This isn't supported in QRegExp.
This is really disappointing for me, and so, I have to write the following ugly but working code:
//-- write regexp that matches only filenames with extension
QRegExp r = QRegExp("^(.+)(\\.[^.]+)$");
r.setMinimal(true);
QString new_string;
if (old_string.contains(r)){
//-- filename contains extension, so, insert ending just before it
new_string = old_string.replace(r, "\\1_my_ending\\2");
} else {
//-- filename does not contain extension, so, just append ending
new_string = old_string + time_add;
}
But is there some better solution? I like Qt, but some things that I see in it seem to be discouraging.
How about using QFileInfo? This is shorter than your 'ugly' code:
QFileInfo fi(old_string);
QString new_string = fi.completeBaseName() + "_my_ending"
+ (fi.suffix().isEmpty() ? "" : ".") + fi.suffix();

Resources