/*
* The LineBreaker class takes a c++ string and splits it on spaces to provide
* an array of pointers to char that is just what the classic Unix execv()
* function desperately wants as an array of arguments. A NULL is placed
* after the data as required by execv().
*/
#pragma once
#ifndef _linebreaker2_h_
#define _linebreaker2_h_
#include <vector>
#include <memory>
#include <string>
#include <cstring>
using namespace std;
class LineBreaker2 {
public:
LineBreaker2() { m_ptrs.push_back(nullptr); }
/*
* Create all the object so that it contains the words in the line
* (as separated by blanks).
*/
LineBreaker2(string line): m_data(new char[line.length() + 1]) {
strcpy(m_data.get(), line.c_str());
fill();
}
/*
* Return an array of plain C pointers, ending with a NULL pointer,
* which represents all the words in the line. This is what execv()
* wants for its second parameter.
*/
char **c_arr() { return m_ptrs.data(); }
/*
* Returns the number of strings, excluding the terminator
*/
int size() { return m_ptrs.size() - 1; }
/*
* Subscript. Returns the plain c string at that subscript.
*/
char *operator[](int s) { return m_ptrs[s]; }
/*
* Return the last string, or null if there are none.
*/
char *back() { return size() > 0 ? *(m_ptrs.end()-2) : nullptr; }
/*
* Remove and return the last string, if any, otherwise return null.
*/
char *pop_back();
private:
void fill();
unique_ptr<char[]> m_data;
vector<char *> m_ptrs;
};
#endif