MEL error unterminated string, script for textures to change their strings - scripting

Recently i got into MEL programming to help out a few friends in maya. They wanted to have their files refferenced on a server, so i needed to change the reff strings. Now i have compiled a solution to do this, and used another example as a guide, but when i run the script it says
// Error: int $nt=tokenize $TexturePath "\" $buff;
//
// Error: Line 12.43: Unterminated string. //
What gives?
p.s. full code below for anyone who wants to use it
string $SceneTextures[] = `ls -tex`;
string $plus="";//Place a file type here to be saved in that subfolder
for ($i = 0; $i< (`size $SceneTextures`); $i++)
{
$Test = catchQuiet(`getAttr ($SceneTextures[$i] + ".fileTextureName")`);
if ($Test == 0)
{
string $TexturePath = `getAttr ($SceneTextures[$i] + ".fileTextureName")`;
string $buff[];
int $nt=`tokenize $TexturePath "\\" $buff`;
string $newPath=("${ARC_SURF}\\" + plus + "\\" + $buff[$nt-3] + "\\" + $buff[$nt-2] + "\\" + $buff[$nt-1]);
setAttr -type "string" ($SceneTextures[$i] + ".fileTextureName") $NewPath;
catchQuiet (AEfileTextureReloadCmd ($SceneTextures[$i] + ".fileTextureName"));
//print $TexturePath;
}//end if
}//end for i
EDIT: Fixed the code as it should be, now it only throws // Error: line 14: Invalid negative index used to reference array "$buff".
But i think that probably only 1 texture screws stuff up, will check and report back

I'm no expert in MEL, but in many languages \ is used to escape control-sequences, so I would guess you want "\\" instead of "\", in the many places it appears.

Related

StreamWriter cannot call a method on a null-valued expression

First time user, looking for help with a script that's been driving me crazy.
Basically, I need to create a set number of files of an exact size (512KB, 2MB, 1GB) to test a SAN. These files need to be filled with random text so that the SAN doesn't catch the nuls and does actually allocate the blocks - that's also the reason I couldn't just use fsutils.
Now, I've been messing with the new-bigrandomfile by Verboon and tweaking it to my needs.
However I'm getting the error:
You cannot call a method on a null-valued expression.
At L:\random5.ps1:34 char:9
+ $stream.Write($longstring)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
This is the bit of code I've come up with so far; I'll add a loop at the end to copy the file I just created N times so to fill up the lun.
Set-Strictmode -Version 2.0
#temp file
$file = "c:\temp\temp.rnd"
#charset size
$charset = 64
#Block Size
$blocksize = 512
#page size
$Pagesize = 512KB
#Number of blocks in a page
$blocknum = $Pagesize / $blocksize
#Resulting/desired test file size
$filesize = 1GB
#number of pages in a file
$pagenum = $filesize / $Pagesize
# create the stream writer
$stream = System.IO.StreamWriter $file
# get a 64 element Char[]; I added the - and _ to have 64 chars
[char[]]$chars = 'azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN0123456789-_'
1..$Pagenum | ForEach-Object {
# get a page's worth of blocks
1..$blocknum| ForEach-Object {
# randomize all chars and...
$rndChars = $chars | Get-Random -Count $chars.Count
# ...join them in a string
$string = -join $rndChars
# repeat random string N times to get a full block string length
$longstring = $string * ($blocksize / $charset)
# write 1 block to file
$stream.Write($longstring)
# release resources by clearing string variables
Clear-Variable string, longstring
}
}
$stream.Close()
$stream.Dispose()
# release resources through garbage collection
[GC]::Collect()
$file.Close()
I've tried a gazillion variants like:
$stream = [System.IO.StreamWriter] $file
$stream = System.IO.StreamWriter $file
$stream = NewObject System.IO.StreamWriter $file
Of course, being a total noob at powershell, I've tried using quotes, brackets, provided the full path instead of the variable, etc. All (or most) seem to be valid syntax variants, according to a ton of examples I found online, but the output is still the same.
In case you have any improvement to suggest or alternative way to perform this task I'm all ears.
Edited the script above: just a couple of " for $file made the error disappear, - thanks LinuxDisciple; however, the file gets created but stays at 0 bytes and the script stuck in a loop.
Fix your instantiation of StreamWriter to any of these correct variants:
$stream = [System.IO.StreamWriter]::new($file)
$stream = [IO.StreamWriter]::new($file) # the default namespace may be omitted
$stream = New-Object System.IO.StreamWriter $file
You can specify encoding:
$stream = [IO.StreamWriter]::new(
$file,
$false, # don't append
[Text.Encoding]::ASCII
)
See StreamWriter on MSDN for available constructors and parameters.
PowerShell ISE offers autocomplete with tooltips:
type [streamw and press Ctrl-Space to autocomplete the full .NET class name
type ]:: to see the available methods and properties
type new and press Ctrl-Space to see the constructor overrides
whenever needed, put the caret at the method name and press Ctrl-Space for the tooltip
I know nothing about powershell but a few things:
Are you sure $longstring has a value before you call stream.Write()? It sounds like it's null and that's why the error. If you can somehow output the value of $longstring to the console, it would help you make sure that it has a value.
Also, troubleshoot the code with a simplified version of your code, so that you can pinpoint what's going on, for example
$file = c:\temp\temp.rnd
$stream = System.IO.StreamWriter $file
$longstring = 'whatever'
$stream.Write($longstring)

How can I signal parsing errors with LPeg?

I'm writing an LPeg-based parser. How can I make it so a parsing error returns nil, errmsg?
I know I can use error(), but as far as I know that creates a normal error, not nil, errmsg.
The code is pretty long, but the relevant part is this:
local eof = lpeg.P(-1)
local nl = (lpeg.P "\r")^-1 * lpeg.P "\n" + lpeg.P "\\n" + eof -- \r for winblows compat
local nlnoeof = (lpeg.P "\r")^-1 * lpeg.P "\n" + lpeg.P "\\n"
local ws = lpeg.S(" \t")
local inlineComment = lpeg.P("`") * (1 - (lpeg.S("`") + nl * nl)) ^ 0 * lpeg.P("`")
local wsc = ws + inlineComment -- comments count as whitespace
local backslashEscaped
= lpeg.P("\\ ") / " " -- escaped spaces
+ lpeg.P("\\\\") / "\\" -- escaped escape character
+ lpeg.P("\\#") / "#"
+ lpeg.P("\\>") / ">"
+ lpeg.P("\\`") / "`"
+ lpeg.P("\\n") -- \\n newlines count as backslash escaped
+ lpeg.P("\\") * lpeg.P(function(_, i)
error("Unknown backslash escape at position " .. i) -- this error() is what I wanna get rid of.
end)
local Line = lpeg.C((wsc + (backslashEscaped + 1 - nl))^0) / function(x) return x end * nl * lpeg.Cp()
I want Line:match(...) to return nil, errmsg when there's an invalid escape.
LPeg itself doesn't provide specific functions to help you with error reporting. A quick fix to your problem would be to make a protected call (pcall) to match like this:
local function parse(text)
local ok, result = pcall(function () return Line:match(text) end)
if ok then
return result
else
-- `result` will contain the error thrown. If it is a string
-- Lua will add additional information to it (filename and line number).
-- If you do not want this, throw a table instead like `{ msg = "error" }`
-- and access the message using `result.msg`
return nil, result
end
end
However, this will also catch any other error, which you probably don't want. A better solution would be to use LPegLabel instead. LPegLabel is an extension of LPeg that adds support for labeled failures. Just replace require"lpeg" with require"lpeglabel" and then use lpeg.T(L) to throw labels where L is an integer from 1-255 (0 is used for regular PEG failures).
local unknown_escape = 1
local backslashEscaped = ... + lpeg.P("\\") * lpeg.T(unknown_escape)
Now Line:match(...) will return nil, label, suffix if there is a label thrown (suffix is the remaining unprocessed input, which you can use to compute for the error position via its length). With this, you can print out the appropriate error message based on the label. For more complex grammars, you would probably want a more systematic way of mapping the error labels and messages. Please check the documentation found in the readme of the LPegLabel repository to see examples of how one may do so.
LPegLabel also allows you to catch the labels in the grammar by the way (via labeled choice); this is useful for implementing things like error recovery. For more information on labeled failures and examples, please check the documentation.

ASSERT failure in QList<T>::at: "index out of range" in Qt 5

I want to generate *.png files from my directory randomly in qt using qrand() function.
to do that I have created a QStringList object so that I can store all files I have in my
directory.thinking that I have some list of files in my QStringList object when I run my application it crush.
I have also warning in my issue pane:> warning: unknown escape sequence: '\D' [enabled by default]
applicationPath = "C:\\Users\\Tekme\Documents\\QtProject\\4Toddler";
^
the reason I add the above warning issues is that, I am on window machine so I am thinking the problem can be path problem
the code is
QString MainWindow::randomIcon()
{
QStringList iconFileList;
QString searchPath = applicationPath + "\\icons";//applicationPath =
QDir directory = QDir(searchPath);
QStringList filters;
filters << "*.png";
directory.setNameFilters(filters);
iconFileList = directory.entryList(QDir::AllEntries);//i have 6 *.png files
int randomIndex = qrand() % iconFileList.count();
return iconFileList.at(randomIndex);//my application crash here
}
Even when I try to replace iconFileList.at(randomIndex) by iconFileList.at(2) it crush.
I am sure I have more than 2 files in my directory
The answer is in the error:
applicationPath = "C:\\Users\\Tekme\Documents\\QtProject\\4Toddler";
Should be
applicationPath = "C:\\Users\\Tekme\\Documents\\QtProject\\4Toddler";
You are missing an extra slash

Save Image-Path into SQL, Webmatrix

I want to create a group-function to my Website. In every group there should be a group-image, which people can upload. So I must save the path into my SQL-DB. My Code:
newFileName = Guid.NewGuid().ToString() + "_" + Path.GetFileName(photo.FileName);
imagePath = #"images\" + newFileName;
imageThumbPath = #"images\thumbs\" + newFileName;
var setPath = (#"~\" + imageThumbPath);
var intoGroupImg = ("UPDATE groups SET img= " + #setPath+ " WHERE id= "+#grID);
db.Execute(intoGroupImg);
I always get the error-message: Token line number = 1,Token line offset = 26,Token in error = images. I don't know why.
I've got a solution:
var intoGroupImg = ("UPDATE groups SET img = #0 WHERE id= " +#grID);
db.Execute(intoGroupImg, imageThumbPath);
First off, please, please use parameterized queries. It is your smoking gun versus SQL injection. Even if you're not adding user-input, it is a good habit to get into.
Anyway, I'm not sure what some of your # symbols are in there for, but I am used to using C#.net with WebMatrix, but I think that is what you're using also. Try this:
var newFileName = Guid.NewGuid().ToString() + "_" + Path.GetFileName(photo.FileName);
var imagePath = "images/" + newFileName;
var imageThumbPath = "images/thumbs/" + newFileName;
var setPath = "~/" + imageThumbPath;
var intoGroupImg = "UPDATE groups SET img = #0 WHERE id = #1";
db.Execute(intoGroupImg, setPath, grID);
This is how I would imagine it to look in C# with parameterized queries.
Given the line offset I believe the error is from #setPath but I'm not sure. Try going to the database tab in WebMatrix and manually doing a query with what you expect the value of #setPath to be.
Also, I noticed you used "backslashes" instead of "forward slashes" in the concatenated string in your example. Is this intentional? Is that what the # symbol is doing? Keeping you from having to escape each backslash with \\? Either way, the forward slash / in its place should do fine, no?
Anyway, hope I helped, at least some.

How to convert file name with path to short file name (DOS style) in Adobe AIR?

How to convert file name with path to short file name (DOS style) in Adobe AIR?
For example convert next path
"C:\Program Files\Common Files\Adobe AIR\Versions\1.0\Resources\Adobe AIR Updater.exe"
to
"C:\PROGRA~1\COMMON~1\ADOBEA~1\VERSIONS\1.0\RESOUR~1\ADOBEA~1.EXE"
Is there any algorithm?
Assuming your text portion is a string variable, you can split it by using "\" as delimiter. Then, you will have an array which you can use to check if each block is longer than 8 characters. While looping the array you can chop the last characters of each long block and put ~1. Since you're in the loop, you can progressively add to a temporary variable all these changes which will give you the final edited result at the end.
The only part that's a bit tricky is to pay attention to .exe part at the end.
So, if I were you, I'd start reading on String.split(), String.substring(), for loop, arrays
Here's my handy method that does this below:
public static string GetShortPathName(string path)
{
string[] arrPath = path.Split(System.IO.Path.DirectorySeparatorChar);
path = arrPath[0]; // drive
// skip first, ( drive ) and last program name
for (int i = 1; i < arrPath.Length - 1; i++)
{
string dosDirName = arrPath[i];
if (dosDirName.Count() > 8)
{
dosDirName = dosDirName.Substring(0, 6) + "~1";
}
path += System.IO.Path.DirectorySeparatorChar + dosDirName;
}
// include program name if any
path += System.IO.Path.DirectorySeparatorChar + arrPath[arrPath.Length - 1];
return path;
}