Skip to content

Commit

Permalink
Code maintenance for Exception classes and usage
Browse files Browse the repository at this point in the history
  • Loading branch information
PlayWithIt committed Nov 11, 2022
1 parent 6ab4ce3 commit a18a03f
Show file tree
Hide file tree
Showing 24 changed files with 709 additions and 150 deletions.
25 changes: 19 additions & 6 deletions src/utils/Compatability.h → src/stubserver/Compatibility.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Compatability.h
*
* Copyright (C) 2015 Holger Grosenick
* Copyright (C) 2015-2022 Holger Grosenick
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand All @@ -17,18 +17,31 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef UTILS_COMPATABILITY_H_
#define UTILS_COMPATABILITY_H_
#ifndef UTILS_COMPATIBILITY_H_
#define UTILS_COMPATIBILITY_H_

/**
* Some basic defines to handle differences between Windows (Visual Studio 2013) and Linux.
*/

#ifdef _WIN32
#define NOEXCEPT
//--- Windows ---
#include <stdint.h>

// Compatibility implemented in DateTime.cpp
extern "C" {
int gettimeofday(struct timeval* tp, struct timezone* tzp);
}

#define SSCANF sscanf_s
#define strncasecmp _strnicmp
#define strcasecmp _stricmp

#else
#define NOEXCEPT noexcept
//--- Linux ---

#define SSCANF sscanf

#endif

#endif /* UTILS_COMPATABILITY_H_ */
#endif /* UTILS_COMPATIBILITY_H_ */
46 changes: 17 additions & 29 deletions src/stubserver/SimulatedDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -872,8 +872,6 @@ SimulatedDevice::SimulatedDevice(BrickStack *_brickStack, const char *_uidStr, c
, isV2(false)
, traceLv(0)
{
char msg[200];

std::string key(uidStr + ".properties");
const char *str = props.get(key);
if (str && *str)
Expand All @@ -896,9 +894,8 @@ SimulatedDevice::SimulatedDevice(BrickStack *_brickStack, const char *_uidStr, c
deviceTypeId = gAllDeviceIdentifiers[i].deviceIdentifier;
}
if (deviceTypeId == 0) {
sprintf(msg, "Unkown device type '%s' for uid %s", str, _uidStr);
cleanup(); // cleanup removes the properties -> 'str' would be empty
throw Exception(msg);
throw Exception("Unkown device type '%s' for uid %s", str, _uidStr);
}
deviceTypeName = str;
label = getProperty("label");
Expand Down Expand Up @@ -936,8 +933,7 @@ SimulatedDevice::SimulatedDevice(BrickStack *_brickStack, const char *_uidStr, c
}
else {
cleanup();
sprintf(msg, "Invalid position char '%c' for uid %s", p, _uidStr);
throw Exception(msg);
throw Exception("Invalid position char '%c' for uid %s", p, _uidStr);
}

// Main brick which is not connected to another brick has parent id '0'
Expand Down Expand Up @@ -966,12 +962,10 @@ SimulatedDevice::SimulatedDevice(BrickStack *_brickStack, const char *_uidStr, c

// parts are already checked above ...
if (false == isBrick && (position < 'A' || position > 'H')) {
sprintf(msg, "ERROR: invalid position char '%c' (%d) for BRICKLET %s (must be A..D)", position, position, uidStr.c_str());
throw utils::Exception(msg);
throw Exception("ERROR: invalid position char '%c' (%d) for BRICKLET %s (must be A..D)", position, position, uidStr.c_str());
}
if (true == isBrick && (position < '0' || position > '9') && position != 'I') {
sprintf(msg, "ERROR: invalid position char '%c' (%d) for BRICK %s (must be 0..9,I)", position, position, uidStr.c_str());
throw utils::Exception(msg);
throw Exception("ERROR: invalid position char '%c' (%d) for BRICK %s (must be 0..9,I)", position, position, uidStr.c_str());
}
}
catch (const std::exception &e) {
Expand Down Expand Up @@ -1020,22 +1014,20 @@ void SimulatedDevice::clearVisualizationClient() const {
const char *SimulatedDevice::getProperty(const std::string &key, int minLength)
{
const char *res = properties->get(uidStr + "." + key);
if (res == NULL || *res == 0)
if (!res || *res == 0)
res = properties->get(key);
if (res == NULL) {
if (!res) {
if (minLength <= 0)
return "";
}
if (res == NULL || static_cast<int>(strlen(res)) < minLength)
if (!res || static_cast<int>(strlen(res)) < minLength)
{
char msg[128];
if (!res)
sprintf(msg, "Property '%s' for uid %s does not exist, check properties",
key.c_str(), uidStr.c_str());
else
sprintf(msg, "Property '%s' for uid %s must have length %u, but has %d",
key.c_str(), uidStr.c_str(), minLength, res ? static_cast<int>(strlen(res)) : 0);
throw Exception(msg);
throw Exception("Property '%s' for uid %s does not exist, check properties",
key.c_str(), uidStr.c_str());

throw Exception("Property '%s' for uid %s must have length %u, but has %d",
key.c_str(), uidStr.c_str(), minLength, res ? static_cast<int>(strlen(res)) : 0);
}
return res;
}
Expand Down Expand Up @@ -1094,7 +1086,6 @@ void SimulatedDevice::checkCallbacks()
*/
void SimulatedDevice::connect(SimulatedDevice* child)
{
char msg[128];
bool positions[128];
unsigned index;

Expand All @@ -1103,8 +1094,7 @@ void SimulatedDevice::connect(SimulatedDevice* child)
for (auto it : children)
{
if (it->uid == child->uid) {
sprintf(msg, "Device with uid %s already connected!", it->getUidStr().c_str());
throw std::logic_error(msg);
throw Exception("Device with uid %s already connected!", it->getUidStr().c_str());
}
index = it->position;
positions[index] = true;
Expand All @@ -1125,14 +1115,12 @@ void SimulatedDevice::connect(SimulatedDevice* child)
}

if (index > maxIndex) {
sprintf(msg, "Device with uid %s uses position '%c' which is an invalid value, max port value is '%c'!",
child->getUidStr().c_str(), index, maxIndex);
throw std::logic_error(msg);
throw Exception("Device with uid %s uses position '%c' which is an invalid value, max port value is '%c'!",
child->getUidStr().c_str(), index, maxIndex);
}
if (positions[index]) {
sprintf(msg, "Device with uid %s uses position '%c' which is already connected!",
child->getUidStr().c_str(), index);
throw std::logic_error(msg);
throw Exception("Device with uid %s uses position '%c' which is already connected!",
child->getUidStr().c_str(), index);
}
children.push_back(child);
}
Expand Down
28 changes: 28 additions & 0 deletions src/stubserver/VisualizationClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,34 @@ class SensorState : public VisibleDeviceState
SensorState();
SensorState(int _min, int _max);

/**
* Returns the value of led1.
*/
uint8_t getLed1() const {
return led1;
}

/**
* Returns the value of led2.
*/
uint8_t getLed2() const {
return led2;
}

/**
* Returns the value of led3.
*/
uint8_t getLed3() const {
return led3;
}

/**
* Returns the value of led1.
*/
uint8_t getLed4() const {
return led4;
}

/**
* Returns the current "sensor" value.
*/
Expand Down
10 changes: 9 additions & 1 deletion src/utils/AsyncTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,15 @@ AsyncTask::~AsyncTask() {
*/
void AsyncTask::callRunMethod()
{
run();
try {
run();
}
catch (const std::exception &e) {
Log::error("callRunMethod()", e);
}
catch (...) {
Log::error("Unspecific exception in callRunMethod() !");
}
setActive(false);
}

Expand Down
36 changes: 27 additions & 9 deletions src/utils/ChildProcess.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* ChildProcess.cpp
*
* Copyright (C) 2013-2021 Holger Grosenick
* Copyright (C) 2013-2022 Holger Grosenick
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -78,7 +78,7 @@ struct Redirect
if (pipeHandles[0] >= 0 || pipeHandles[1] >= 0)
throw std::logic_error("Child stream already open, cannot change any more!");
if (pipe(pipeHandles) < 0)
throw utils::RuntimeError("pipe() failed");
throw utils::IOException("pipe", "");
type = Redirect::PIPE;
}

Expand Down Expand Up @@ -309,7 +309,7 @@ void ChildProcess::setWorkDir(const char *_workDir)
void ChildProcess::splitCmdLine(const char *cmdLine, std::vector<std::string> &out)
{
if (!cmdLine || *cmdLine == 0 ) // invalid argument
throw Exception("Invalid argument: 'cmdLine' is NULL or empty");
throw std::invalid_argument("'cmdLine' is NULL or empty");

out.clear(); // remove all previous entries
const char *c = cmdLine;
Expand Down Expand Up @@ -352,10 +352,33 @@ void ChildProcess::splitCmdLine(const char *cmdLine, std::vector<std::string> &o
else
++c; // set to next valid char

// printf("ADD: %s\n", arg);
out.push_back(std::string(arg));
} while (!done);
}

/**
* Start the child process and waits until it finishes in the given time period.
* If 'ms' is zero then we wait forever until the process finishes.
* <P>
* Internally this is the sequence of
* - start()
* - waitFor()
* - getRc()
* <P>
* Returns:
* -1 : if ms is larger than zero and the process did not finish yet
* negative values: process terminated with signal / exception
* other : normal return code of the process
*/
int ChildProcess::run(unsigned ms)
{
start();
if (waitFor(ms))
return getRc();
return -1;
}

/**
* Now really start the child process.
*/
Expand Down Expand Up @@ -492,11 +515,7 @@ void ChildProcess::tryToStart()
else {
// PID < 0: start of process failed ...
active = false;

int err = errno;
char buffer[2048];
sprintf(buffer, "Start of '%s' failed", programAndArgs[0].c_str());
throw utils::RuntimeError(buffer, err);
throw utils::IOException("execv", programAndArgs[0].c_str());
}
}

Expand Down Expand Up @@ -540,7 +559,6 @@ void ChildProcess::validateRedirect()
{
if (active)
throw Exception("Child process already active, cannot change redirect any more!");

}

/**
Expand Down
31 changes: 30 additions & 1 deletion src/utils/ChildProcess.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* ChildProcess.h
*
* Copyright (C) 2013 Holger Grosenick
* Copyright (C) 2013-2022 Holger Grosenick
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -36,6 +36,15 @@ struct Redirect;
/**
* This class is used for starting other processes asynchronously.
* The status of the process can be asked via the class methods.
* <p>
* Usual way to start a ChildProcess is the call sequence:<br>
* - start()
* - optionally use redirect methods like "stdout()"
* - waitFor()
* - getRc
*
* OR just
* - run()
*/
class ChildProcess {

Expand Down Expand Up @@ -64,12 +73,32 @@ class ChildProcess {
setWorkDir(workDir.c_str());
}

/**
* Start the child process and waits until it finishes in the given time period.
* If 'ms' is zero then we wait forever until the process finishes.
* <p>
* When run() is used, redirecting stdout / stderr is not possible !
* <P>
* Internally this is the sequence of
* - start()
* - waitFor()
* - getRc()
* <P>
* Returns:
* -1 : if ms is larger than zero and the process did not finish yet
* negative values: process terminated with signal / exception
* other : normal return code of the process
*/
int run(unsigned ms = 0);

/**
* Start the child process asynchronously and return. If starting the process fails, an
* exception is thrown.
* <P>
* If a child has finished, the start() method maybe called again. Be aware that existing
* redirects get invalidated when the child terminates.
* <P>
* After start() you have to use waitFor() to check if the process has finished.
*/
void start();

Expand Down
4 changes: 4 additions & 0 deletions src/utils/Compatibility.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
*/

#ifdef _WIN32
//--- Windows ---
#include <stdint.h>

// Compatibility implemented in DateTime.cpp
Expand All @@ -33,8 +34,11 @@ int gettimeofday(struct timeval* tp, struct timezone* tzp);
}

#define SSCANF sscanf_s
#define strncasecmp _strnicmp
#define strcasecmp _stricmp

#else
//--- Linux ---

#define SSCANF sscanf

Expand Down
Loading

0 comments on commit a18a03f

Please sign in to comment.