patterncppMinor
C++ line-editing micro-library
Viewed 0 times
editinglibrarymicroline
Problem
Working on a project, I've taken to adapting the linenoise line editing library for my own use, among other things, rewriting it using C++. The idea is to separate my changes and updates into a new library, and publish it on GitHub, as one does. But before I release my changes into the wild, I'd like to ensure that it is, you know, good.
What I would like is general notes on correctness and practices.
(History not being implemented is a known issue.)
linenoise.h
`/* linenoise.h -- guerrilla line editing library against the idea that a
* line editing lib needs to be 20,000 lines of C code.
*
* See linenoise.cpp for more information.
*
* ------------------------------------------------------------------------
*
* Copyright (c) 2014-2014, Williham Totland
* Copyright (c) 2010-2014, Salvatore Sanfilippo
* Copyright (c) 2010-2013, Pieter Noordhuis
*
* All rights reserved.
*
* BSD 2-term, abbreviated for clarity.
*/
#import
#import
#import
#import
namespace linenoise {
typedef struct termios termiosSettings;
class terminal {
friend class editor;
std::unordered_set unsupportedTerminals;
int inputFileDescriptor, outputFileDescriptor;
termiosSettings original, rawMode;
bool initializeRawMode ();
size_t cursorPosition ();
size_t columns ();
void clearScreen ();
public:
terminal(const std::unordered_set &uT, int ifd, int ofd) : unsupportedTerminals(uT), inputFileDescriptor(ifd), outputFileDescriptor(ofd) {
initializeRawMode();
}
bool supported () const;
bool enableRawMode (int);
void disableRawMode (int);
static void beep ();
};
class editor {
enum class keyAction;
class cursor {
friend class editor;
const editor &editor;
size_t position;
public:
cursor(const class editor &e) : editor(e), position(0) { }
void home (), left (), right (), end ();
};
cursor cursor;
class history : public std::deque {
frie
What I would like is general notes on correctness and practices.
(History not being implemented is a known issue.)
linenoise.h
`/* linenoise.h -- guerrilla line editing library against the idea that a
* line editing lib needs to be 20,000 lines of C code.
*
* See linenoise.cpp for more information.
*
* ------------------------------------------------------------------------
*
* Copyright (c) 2014-2014, Williham Totland
* Copyright (c) 2010-2014, Salvatore Sanfilippo
* Copyright (c) 2010-2013, Pieter Noordhuis
*
* All rights reserved.
*
* BSD 2-term, abbreviated for clarity.
*/
#import
#import
#import
#import
namespace linenoise {
typedef struct termios termiosSettings;
class terminal {
friend class editor;
std::unordered_set unsupportedTerminals;
int inputFileDescriptor, outputFileDescriptor;
termiosSettings original, rawMode;
bool initializeRawMode ();
size_t cursorPosition ();
size_t columns ();
void clearScreen ();
public:
terminal(const std::unordered_set &uT, int ifd, int ofd) : unsupportedTerminals(uT), inputFileDescriptor(ifd), outputFileDescriptor(ofd) {
initializeRawMode();
}
bool supported () const;
bool enableRawMode (int);
void disableRawMode (int);
static void beep ();
};
class editor {
enum class keyAction;
class cursor {
friend class editor;
const editor &editor;
size_t position;
public:
cursor(const class editor &e) : editor(e), position(0) { }
void home (), left (), right (), end ();
};
cursor cursor;
class history : public std::deque {
frie
Solution
I don't have the time to do a completely thorough review at the moment, but here are some things that I noticed that may help you improve your code.
Don't use
Although it is supported by some compilers, code which is intended to be reused should avoid non-standard extensions. In this case, it's also not really needed because all of the files except for
Don't reuse the same name for conflicting things
In the existing code, we have these lines of code:
I see a few problems with that. First, the word
Eliminate unused variables
Both the parameters
Initialize variables before acting on them
In the
Avoid C-style casts
If you're writing in C++, use C++ style casts rather than C-style casts. They're safer and more explicit to the reader of your code.
Use C-style includes
Instead of including
Don't use
#importAlthough it is supported by some compilers, code which is intended to be reused should avoid non-standard extensions. In this case, it's also not really needed because all of the files except for
linenoise.h already contain an include guard, and it's a simple matter to add one to linenoise.h. In a similar vein, it would probably make sense to omit the #pragmas as well. They are inherently compiler-specific. If you feel you must use them, wrap them in guards to hide them from compilers that don't support them. (Yes, compilers will ignore #pragmas they don't support but this often generates a warning.)Don't reuse the same name for conflicting things
In the existing code, we have these lines of code:
class editor {
enum class keyAction;
class cursor {
friend class editor;
const editor &editor;I see a few problems with that. First, the word
class isn't really need in the friend declaration. It's implicit because editor completely defines a type. However, the more serious problem is with the last line because it changes what editor means. On the line above, it referred to a class type. Now it's a const reference to a class of editor type. While compilers may or may not complain about this, users certainly will. One simple way to avoid this would be to use a common convention such as using Editor to name the class and editor to signify an instance of that class.Eliminate unused variables
Both the parameters
stdin_fd and stdout_fd are unused within the edit() routine. Also, the nread variable is set but never used. Initialize variables before acting on them
In the
edit function, the variable c is part of the switch statment, but it hasn't been initialized to any particular value the first time through.Avoid C-style casts
If you're writing in C++, use C++ style casts rather than C-style casts. They're safer and more explicit to the reader of your code.
Use C-style includes
Instead of including
stdio.h you should instead use #include . The difference is in namespaces as you can read about in this question.Code Snippets
class editor {
enum class keyAction;
class cursor {
friend class editor;
const editor &editor;Context
StackExchange Code Review Q#74263, answer score: 5
Revisions (0)
No revisions yet.