How to use directory operations in C++Builder? - directory

I am stuck in creating a directory with C++Builder. If you check this here and here, I find examples for my case, but when I try to use them, none of them work for me! For example, the following code for creating a directory, where the edSourcePath->Text value has been defined.
Unfortunately the documentation is not complete.
try
{
/* Create directory to specified path */
TDirectory::CreateDirectory(edSourcePath->Text);
}
catch (...)
{
/* Catch the possible exceptions */
MessageDlg("Incorrect path", mtError, TMsgDlgButtons() << mbOK, NULL);
return;
}
The error message says TDirectory is not a class or namespace.
Another question is, how can I pass the source path and directory name by CreateDirectory(edSourcePath->Text)?

What you are seeing is a compile-time error, not a runtime error. The compiler cannot find the definition of the TDirectory class. You need to #include the header file that TDirectory is defined in, eg:
#include <System.IOUtils.hpp> // <-- add this!
try
{
/* Create directory to specified path */
TDirectory::CreateDirectory(edSourcePath->Text);
// or, if either DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE or
// NO_USING_NAMESPACE_SYSTEM_IOUTILS is defined, you need
// to use the fully qualified name instead:
//
// System::Ioutils::TDirectory::CreateDirectory(edSourcePath->Text);
}
catch (const Exception &e)
{
/* Catch the possible exceptions */
MessageDlg("Incorrect path.\n" + e.Message, mtError, TMsgDlgButtons() << mbOK, NULL);
return;
}
Note, however, that TDirectory::CreateDirectory() throws an exception ONLY if the input String is not a valid formatted path. It DOES NOT throw an exception if the actual directory creation fails. In fact, there is no way to detect that condition with TDirectory::CreateDirectory() itself, you would have to check with TDirectory::Exists() afterwards:
#include <System.IOUtils.hpp>
try
{
/* Create directory to specified path */
String path = edSourcePath->Text;
TDirectory::CreateDirectory(path);
if (!TDirectory::Exists(path))
throw Exception("Error creating directory");
}
catch (const Exception &e)
{
/* Catch the possible exceptions */
MessageDlg(e.Message, mtError, TMsgDlgButtons() << mbOK, NULL);
return;
}
Otherwise, TDirectory::CreateDirectory() is just a validating wrapper for System::Sysutils::ForceDirectories(), which has a bool return value. So, you could just call that function directly instead:
#include <System.SysUtils.hpp>
/* Create directory to specified path */
if (!ForceDirectories(edSourcePath->Text)) // or: System::Sysutils::ForceDirectories(...), if needed
{
MessageDlg("Error creating directory", mtError, TMsgDlgButtons() << mbOK, NULL);
return;
}

Related

How to check for Exception property with PHPunit

I have the following exception:
<?php
namespace App\Exception;
class LimitReachedException extends \Exception
{
private ?\DateTime $resumeAt;
...getter/setter..
}
My PHPUnit check for this exception like this:
$this->expectException(LimitReachedException::class);
How can I check that a certain value is stored in the $resumeAt property as well?
Even though PHPUnit has a expectExceptionObject method that allows passing an exception instance, that is just a shortcut to expectExceptionMessage, expectException and expectExceptionCode.
One way to achieve your assertion as of now (current version of PHPUnit being 9.5.27) is to instead of using PHPUnit's methods of expecting that exception is to catch it yourself and then assert the different properties:
function testException () {
$expectedException = null;
try {
$foo->doSomething();
} catch (LimitReachedException $e) {
$expectedException = $e;
}
// Put your assertions outside of the `catch` block, otherwise
// your test won't fail when the exception isn't thrown
// (it will turn risky instead because there are no assertions)
$this->assertInstanceOf(LimitReachedException::class, $expectedException);
$this->assertSame('myExceptionProperty', $expectedException->getProperty());
}

PHPUnit: How to force program exit on specific error

How can I force PHPUnit to stop running completely and exit when a specific condition (an error of my own choosing) is met? Effectively, what I need is something like the below, except that in reality PHPUnit traps the exit() and continues running instead of exiting.
// PHPUnit does not alter existing but empty env vars, so test for it.
if (strlen(getenv('APP_HOME')) < 1) {
$this->fail('APP_HOME set but empty.');
exit(1); // <-- Does not work.
}
Note: I want to continue running normally for other errors and failures, hence setting stopOnError="true" or stopOnFailure="true" in my XML file is not what I need.
I think you can achieve this by doing a few overrides and adding some custom behaviour to a base test case class.
EDIT:
As found by the OP after running the below code, calling exit(1); rather than $result->stop() will cause correct termination of the test at that point.
Try the following:
class MyBaseTestCase extends \PHPUnit_Framework_TestCase
{
// Test this flag at every test run, and stop if this has been set true.
protected $stopFlag = false;
// Override parent to gain access to the $result so we can call stop()
public function run(\PHPUnit_Framework_TestResult $result = null)
{
$result = parent::run($result);
if ($this->stopFlag === true)
{
//$result->stop(); // Stop the test for this special case
exit(1); // UPDATED: This works to terminate the process at this point
}
return $result; // return as normal
}
}
Then in a test case class:
class MyTestCase extends MyBaseTestCase
{
public function testThisStopsPhpunit()
{
if (strlen(getenv('APP_HOME')) < 1) {
$this->fail('APP_HOME set but empty.');
$this->stopFlag = true; // Stop further processing if this occurs
}
}
}

Dispatch not hooked to windows memory

Sometimes I get an error (exception):
java.lang.IllegalStateException: Dispatch not hooked to windows memory
What does it mean? How to prevent it?
This is a sample code that results in this error:
import com.jacob.activeX.*;
import com.jacob.com.*;
public class Hooked {
public static void main(String[] args) {
ActiveXComponent e = new ActiveXComponent("Excel.Application");
ActiveXComponent sh = new ActiveXComponent(
e.getProperty("ActiveSheet").toDispatch());
System.out.println(sh.getPropertyAsString("Name"));
}
}
That means that Dispatch = nothing using vba syntax, it's empty. The same dispatch that you receive with new Dispatch(). Unfortunately Jacob 1.17 does not provide any method to explicitly check whether the Dispatch is empty or not. So I see 3 possible solutions:
1) Use Variant.isNull() after receiving the Variant from COM call, before converting it to Dispatch. So it requires 1 additional line:
Variant vsh = e.getProperty("ActiveSheet");
if (vsh.isNull()) {
System.out.println("Null dispatch received.");
}
ActiveXComponent sh = new ActiveXComponent(vsh.toDispatch());
2) Catch IllegalStateException when using suspected Dispatch for the first time.
3) Write a custom isNull(Dispatch d) function
public static boolean isNull(Dispatch d)
{
try {
Dispatch.call(d, "");
}
catch (IllegalStateException ise) {
return true;
}
catch (ComFailException cfe) {
// that's ok, we didn't expect this call to succeed
}
return false;
}
In the specific example in the question the call was just a mistake, because Excel has no ActiveSheet if no workbook is open or created.

Detecting missing resources in QT Stylesheets

I am using QCSS stylesheets in QT to skin several buttons with images from the QT resource system:
QFrame#DialogButtonTitle_SaveAsNew
{
background-image: url(images:DialogButtonTitle_SaveAsNew.png);
}
This works great, but I would really like to write a warning to our logs if the image file referenced from the CSS could not be found (and the button is thus naked). Any way to catch such errors?
I believe you can do it like this:
Read about the QAbstractFileEngine and QAbstractFileEngineHandler classes.
Extend Qt's own implementation, QFSFileEngine. I believe it also handles the ":" namespace.
Reimplement the QAbstractFileEngine::open() method.
Register your engine using a custom QAbstractFileEngineHandler. The create() method should check the file name to see if it is being read from a resource file.
Haven't tested, but I think it should work. Code:
bool MyEngine::open(QIODevice::OpenMode mode)
{
bool r = QFSFileEngine::open(mode);
if (!r) {
qWarning() << "Failed to open" << fileName();
}
return r;
}
QAbstractFileEngine *MyEngineHandler::create(const QString &fileName) const
{
return fileName.startsWith("images:") ? new MyEngine(fileName) : 0;
}
Edit.
This will not work. The resource file system, “:”, is handled by a private file engine called QResourceFileEngine, not by QFSFileEngine.
Based on #andref answer, I came up with this, which works for me (TM):
class LoggingEngineHandler : public QAbstractFileEngineHandler
{
public:
LoggingEngineHandler()
: QAbstractFileEngineHandler()
, m_lookUpInProgress(false)
, m_lookUpPaths(QRegExp("^(images|meshes|app|sounds):"))
{
// empty
}
QAbstractFileEngine* create(const QString &fileName) const override
{
if (!fileName.contains(m_lookUpPaths))
return 0;
if (m_lookUpInProgress)
return 0;
m_lookUpInProgress = true;
QFileInfo info = QFileInfo(fileName);
m_lookUpInProgress = false;
if (!info.exists())
{
assert(!Utilities::isRunByUser("designer"));
LOG_WARN("Required resource file does not exist: %1%", QUtil_s(fileName));
}
return 0;
}
protected:
mutable bool m_lookUpInProgress;
QRegExp m_lookUpPaths;
};
It's possible that Qt will call one of their message functions when something like this happens (although I don't know for sure). If it does, you could install a message handler function and append some or all of the messages to your log file. There is some information about doing so in the documentation for qInstallMsgHandler.

Visual Studio ignore try catch - debug only

I think error handling is a good idea. :) When debugging it can get in the way - especially with nice user friendly messages. In VB6 I could just check a box for the compiler to ignore my error handling. I found the dialog that allows me to do something similar in VS, but it's about 10,000 check boxes instead of one - which is too many to change every time I want a production compilation.
Is there a way to set VS up so when I am in debugging mode I get one set of conditions and when I am in production I get another? ...or is there just another method to handling errors and debugging more efficiently?
Thanks
Try the Debug Menu and look at Exceptions. You can set it to automatically break when an exception is thrown.
In code, I'd probably just do something like:
#if !DEBUG
try {
#endif
DoSomething();
#if !DEBUG
} catch (Exception ex) {
LogEx(ex);
throw new FriendlyException(ex);
}
#endif
Or. more generally and with less #if:
#if DEBUG
public const bool DEBUG = true;
#else
public const bool DEBUG = false;
#endif
try {
DoSomething();
} catch (Exception ex) {
if (DEBUG) throw;
LogEx(ex);
throw new FriendlyException(ex);
}
Or, general purpose (like the Exception Handling library from P&P):
bool HandleException(Exception ex) {
return !DEBUG;
}
But, if your real problem is just the Visual Studio GUI - just use a macro.
You can add this attribute to your methods:
[Conditional("DEBUG")]
You can also use #if #endif statements if you wish.

Resources