From 3431cc222502b1c960819612038c1f9e54475f30 Mon Sep 17 00:00:00 2001 From: Moritz Martinius Date: Fri, 13 Oct 2023 00:02:44 +0200 Subject: [PATCH] Some refactorings to incoporate CLI parsing --- .vscode/launch.json | 2 +- README.md | 4 +-- meson.build | 3 ++- src/P700Printer.cpp | 9 +++---- src/P700Printer.hpp | 14 +++++----- src/PtouchPrint.cpp | 40 ++++++++++++++++++++++++----- src/PtouchPrint.hpp | 20 ++++++++++++--- src/constants.hpp | 26 +++++++++++++++++++ src/libusbwrap/UsbDeviceFactory.cpp | 3 ++- src/main.cpp | 20 ++++++--------- 10 files changed, 101 insertions(+), 40 deletions(-) create mode 100644 src/constants.hpp diff --git a/.vscode/launch.json b/.vscode/launch.json index 33a2921..9f29407 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,7 +9,7 @@ "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/builddir/ptprnt", - "args": [], + "args": ["--verbose"], "stopAtEntry": false, "cwd": "${fileDirname}", "environment": [], diff --git a/README.md b/README.md index b0bfc7c..90221ed 100644 --- a/README.md +++ b/README.md @@ -14,12 +14,12 @@ This project requires: Install dependencies on Arch Linux ``` bash -pacman -S libusb spdlog pango cairo meson gcovr +pacman -S libusb spdlog pango cairo meson gcovr cli11 ``` Install dependencies on Debian/Ubuntu ``` bash -apt-get install libusb-1.0-0-dev libspdlog-dev libpango1.0-dev libcairo2-dev meson gcovr +apt-get install libusb-1.0-0-dev libspdlog-dev libpango1.0-dev libcairo2-dev meson gcovr libcli11-dev ``` ## Build diff --git a/meson.build b/meson.build index 2323591..96cf2c7 100644 --- a/meson.build +++ b/meson.build @@ -7,6 +7,7 @@ project('ptprnt', 'cpp', usb_dep = dependency('libusb-1.0') log_dep = dependency('spdlog') pangocairo_dep = dependency('pangocairo') +cli11_dep = dependency('CLI11') incdir = include_directories('src') @@ -48,7 +49,7 @@ ptprnt_exe = executable( 'ptprnt', 'src/main.cpp', install: true, - dependencies : [usb_dep, log_dep, ptprnt_dep], + dependencies : [usb_dep, log_dep, ptprnt_dep, cli11_dep], cpp_args : ['-DPROJ_VERSION="'+meson.project_version()+'"'], ) diff --git a/src/P700Printer.cpp b/src/P700Printer.cpp index 7944375..98ed2ed 100644 --- a/src/P700Printer.cpp +++ b/src/P700Printer.cpp @@ -72,13 +72,10 @@ const PrinterStatus P700Printer::getPrinterStatus() { int tx = 0; int tries = 0; std::vector recvBuf(32); - do { + while (tries++ < MAX_TRIES_GET_STATUS) { std::this_thread::sleep_for(100ms); - mUsbHndl->bulkTransfer(0x81, recvBuf, &tx, 0); - if (tries++ > 10) { - break; - } - } while (tx == 0); + mUsbHndl->bulkTransfer(commands["printerinfo"][0], recvBuf, &tx, 0); + } return PrinterStatus{.tapeWidthMm = recvBuf[10]}; } diff --git a/src/P700Printer.hpp b/src/P700Printer.hpp index b7d74d2..a21fc55 100644 --- a/src/P700Printer.hpp +++ b/src/P700Printer.hpp @@ -31,6 +31,8 @@ namespace ptprnt::printer { +constexpr uint8_t MAX_TRIES_GET_STATUS = 10; + class P700Printer : public ::ptprnt::IPrinterDriver { public: P700Printer() = default; @@ -61,11 +63,11 @@ class P700Printer : public ::ptprnt::IPrinterDriver { std::shared_ptr mUsbHndl{nullptr}; - PrinterInfo mInfo{.driverName = "P700", - .name = "Brother P-touch P700", - .version = "v1.0", - .vid = 0x04f9, - .pid = 0x2061}; + static constexpr PrinterInfo mInfo{.driverName = "P700", + .name = "Brother P-touch P700", + .version = "v1.0", + .vid = 0x04f9, + .pid = 0x2061}; std::map> commands{ {"rasterstart", {0x1b, 0x69, 0x61, @@ -75,7 +77,7 @@ class P700Printer : public ::ptprnt::IPrinterDriver { {"lf", {0x5a}}, {"ff", {0x0c}}, {"eject", {0x1a}}, - }; + {"printerinfo", {0x81}}}; }; } // namespace ptprnt::printer \ No newline at end of file diff --git a/src/PtouchPrint.cpp b/src/PtouchPrint.cpp index 0fd7162..feecc42 100644 --- a/src/PtouchPrint.cpp +++ b/src/PtouchPrint.cpp @@ -19,30 +19,45 @@ #include "PtouchPrint.hpp" +#include +#include #include #include "P700Printer.hpp" #include "graphics/Bitmap.hpp" #include "libusbwrap/UsbDeviceFactory.hpp" -PtouchPrint::PtouchPrint() {} +PtouchPrint::PtouchPrint(const char* versionString) : mVersionString{versionString} {} -PtouchPrint::~PtouchPrint() {} +int PtouchPrint::init(int argc, char** argv) { + setupCliParser(); + if (mVerboseFlag) { + setupLogger(spdlog::level::debug); + } else { + setupLogger(spdlog::level::critical); + } + + try { + mApp.parse(argc, argv); + } catch (const CLI::ParseError& e) { + return mApp.exit(e); + } -void PtouchPrint::init() { mUsbDeviceFactory.init(); mCompatiblePrinters = {std::make_shared()}; + return 0; } -void PtouchPrint::run() { +int PtouchPrint::run() { + auto numFoundPrinters = getCompatiblePrinters(); if (numFoundPrinters == 0) { spdlog::error( "No compatible printers found, please make sure if they are turned on and connected"); - return; + return -1; } else if (numFoundPrinters > 1) { spdlog::warn("Found more than one compatible printer. Currently not supported."); - return; + return -1; } auto printer = mCompatiblePrinters[0]; @@ -50,7 +65,7 @@ void PtouchPrint::run() { if (devices.size() != 1) { spdlog::warn( "Found more than one device of the same printer on bus. Currently not supported"); - return; + return -1; } printer->attachUsbDevice(devices[0]); auto status = printer->getPrinterStatus(); @@ -58,6 +73,8 @@ void PtouchPrint::run() { auto bm = ptprnt::graphics::Bitmap(512, 128); printer->printBitmap(bm); //printer->printText("wurst", 1); + + return 0; } unsigned int PtouchPrint::getCompatiblePrinters() { @@ -81,3 +98,12 @@ unsigned int PtouchPrint::getCompatiblePrinters() { mCompatiblePrinters.clear(); return mDetectedPrinters.size(); } + +void PtouchPrint::setupLogger(spdlog::level::level_enum lvl) { + spdlog::set_level(lvl); + spdlog::debug("Starting ptprnt {}", mVersionString); +} + +void PtouchPrint::setupCliParser() { + mApp.add_option("-v,--verbose", mVerboseFlag, "Enable verbose output"); +} \ No newline at end of file diff --git a/src/PtouchPrint.hpp b/src/PtouchPrint.hpp index f8b5533..9643c84 100644 --- a/src/PtouchPrint.hpp +++ b/src/PtouchPrint.hpp @@ -19,23 +19,35 @@ #pragma once +#include +#include +#include + +#include "constants.hpp" #include "interface/IPrinterDriver.hpp" #include "libusbwrap/UsbDeviceFactory.hpp" class PtouchPrint { public: - PtouchPrint(); - ~PtouchPrint(); + PtouchPrint(const char* versionString); + ~PtouchPrint() = default; - void init(); - void run(); + int init(int argc, char** argv); + int run(); private: // methods + void setupLogger(spdlog::level::level_enum lvl); + void setupCliParser(); unsigned int getCompatiblePrinters(); // member variables + CLI::App mApp{ptprnt::APP_DESC}; libusbwrap::UsbDeviceFactory mUsbDeviceFactory; std::vector> mCompatiblePrinters; std::vector> mDetectedPrinters; + std::string mVersionString = ""; + + // CLI flags + bool mVerboseFlag = false; }; \ No newline at end of file diff --git a/src/constants.hpp b/src/constants.hpp new file mode 100644 index 0000000..027b488 --- /dev/null +++ b/src/constants.hpp @@ -0,0 +1,26 @@ +/* + ptrnt - print labels on linux + Copyright (C) 2023 Moritz Martinius + + 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 + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + */ + +#pragma once + +namespace ptprnt { +constexpr const char* const APP_NAME = "ptprnt"; +constexpr const char* const APP_DESC = + "ptprnt - a userspace driver for Brother P-touch label printer"; +} // namespace ptprnt \ No newline at end of file diff --git a/src/libusbwrap/UsbDeviceFactory.cpp b/src/libusbwrap/UsbDeviceFactory.cpp index 53a8695..dfc8c8a 100644 --- a/src/libusbwrap/UsbDeviceFactory.cpp +++ b/src/libusbwrap/UsbDeviceFactory.cpp @@ -32,7 +32,8 @@ namespace libusbwrap { UsbDeviceFactory::UsbDeviceFactory() {} UsbDeviceFactory::~UsbDeviceFactory() { - libusb_free_device_list(mLibusbDeviceList, 1); + // ToDo: SEGV here + libusb_free_device_list(mLibusbDeviceList, 0); } std::vector> UsbDeviceFactory::findAllDevices() { diff --git a/src/main.cpp b/src/main.cpp index 525fe8a..3a57c4d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,21 +17,17 @@ */ +#include +#include #include #include "PtouchPrint.hpp" -void setupLogger() { - spdlog::set_level(spdlog::level::debug); - spdlog::info("Starting ptprnt {}", PROJ_VERSION); -} - int main(int argc, char** argv) { - setupLogger(); - - PtouchPrint ptouchprnt; - ptouchprnt.init(); - ptouchprnt.run(); - - return 0; + PtouchPrint ptouchprnt(PROJ_VERSION); + int ret = ptouchprnt.init(argc, argv); + if (ret != 0) { + return ret; + } + return ptouchprnt.run(); }