Improvements to the curses interface.

This commit is contained in:
Berk Geveci 2001-11-29 16:44:22 -05:00
parent e57a982136
commit 521d8d9410
11 changed files with 442 additions and 138 deletions

View File

@ -6,6 +6,7 @@ SOURCE_FILES( CURSES_SRCS
cmCursesFilePathWidget
cmCursesForm
cmCursesLabelWidget
cmCursesLongMessageForm
cmCursesMainForm
cmCursesPathWidget
cmCursesStringWidget

View File

@ -1,5 +1,6 @@
#include "../cmCacheManager.h"
#include "../cmSystemTools.h"
#include "../cmake.h"
#include <signal.h>
#include <sys/ioctl.h>
@ -9,11 +10,11 @@
#include <curses.h>
#include <form.h>
static cmCursesMainForm* myform=0;
cmCursesForm* cmCursesForm::CurrentForm=0;
void onsig(int sig)
{
if (myform)
if (cmCursesForm::CurrentForm)
{
endwin();
WINDOW* w= initscr(); /* Initialization */
@ -23,30 +24,44 @@ void onsig(int sig)
KEY_DOWN*/
refresh();
int x,y;
getmaxyx(w, y, x);
myform->SetWindow(w);
myform->Render(1,1,x,y);
myform->UpdateStatusBar();
getmaxyx(stdscr, y, x);
cmCursesForm::CurrentForm->Render(1,1,x,y);
cmCursesForm::CurrentForm->UpdateStatusBar();
}
signal(SIGWINCH, onsig);
}
void CMakeErrorHandler(const char* message, const char* title, bool& disable)
{
cmCursesForm::CurrentForm->AddError(message, title);
}
int main(int argc, char** argv)
{
if ( argc > 2 )
unsigned int i;
cmake msg;
std::vector<std::string> args;
for(i =0; i < argc; ++i)
{
std::cerr << "Usage: " << argv[0] << " source_directory."
<< std::endl;
return -1;
args.push_back(argv[i]);
}
int newCache = false;
if (!cmCacheManager::GetInstance()->LoadCache(cmSystemTools::GetCurrentWorkingDirectory().c_str()))
{
newCache = true;
}
for(i=1; i < args.size(); ++i)
{
std::string arg = args[i];
if(arg.find("-help",0) != std::string::npos ||
arg.find("--help",0) != std::string::npos ||
arg.find("/?",0) != std::string::npos ||
arg.find("-usage",0) != std::string::npos)
{
msg.Usage(args[0].c_str());
return -1;
}
}
cmSystemTools::DisableRunCommandOutput();
cmCacheManager::GetInstance()->LoadCache(cmSystemTools::GetCurrentWorkingDirectory().c_str());
WINDOW* w=initscr(); /* Initialization */
noecho(); /* Echo off */
@ -57,25 +72,40 @@ int main(int argc, char** argv)
signal(SIGWINCH, onsig);
int x,y;
getmaxyx(w, y, x);
std::string whereCMake = cmSystemTools::GetProgramPath(argv[0]);
whereCMake += "/cmake";
if ( argc == 2 )
getmaxyx(stdscr, y, x);
if ( x < cmCursesMainForm::MIN_WIDTH ||
y < cmCursesMainForm::MIN_HEIGHT )
{
endwin();
std::cerr << "Window is too small. A size of at least "
<< cmCursesMainForm::MIN_WIDTH << " x "
<< cmCursesMainForm::MIN_HEIGHT
<< " is required to run ccmake." << std::endl;
return 1;
}
cmCursesMainForm* myform;
myform = new cmCursesMainForm(args);
cmSystemTools::SetErrorCallback(CMakeErrorHandler);
cmCursesForm::CurrentForm = myform;
myform->InitializeUI();
myform->RunCMake(false);
myform = new cmCursesMainForm(argv[1], whereCMake.c_str(), newCache);
}
else
{
myform = new cmCursesMainForm("", whereCMake.c_str(), newCache);
}
myform->InitializeUI(w);
myform->Render(1, 1, x, y);
myform->HandleInput();
// Need to clean-up better
clear();
touchwin(stdscr);
endwin();
delete myform;
delete cmCursesForm::CurrentForm;
cmCursesForm::CurrentForm = 0;
return 0;
}

View File

@ -71,3 +71,15 @@ cmCursesCacheEntryComposite::~cmCursesCacheEntryComposite()
delete m_IsNewLabel;
delete m_Entry;
}
const char* cmCursesCacheEntryComposite::GetValue()
{
if (m_Label)
{
return m_Label->GetValue();
}
else
{
return 0;
}
}

View File

@ -12,6 +12,7 @@ public:
const cmCacheManager::CacheEntry& value,
bool isNew);
~cmCursesCacheEntryComposite();
const char* GetValue();
friend class cmCursesMainForm;

View File

@ -17,6 +17,17 @@ public:
// Display form.
virtual void Render(int left, int top, int width, int height) = 0;
// Description:
// This method should normally called only by the form.
// The only exception is during a resize.
virtual void UpdateStatusBar() = 0;
// During a CMake run, an error handle should add errors
// to be displayed afterwards.
virtual void AddError(const char* message, const char* title) {};
static cmCursesForm* CurrentForm;
protected:
cmCursesForm(const cmCursesForm& from);
void operator=(const cmCursesForm&);

View File

@ -9,6 +9,7 @@
#include "cmCursesFilePathWidget.h"
#include "cmCursesDummyWidget.h"
#include "cmCursesCacheEntryComposite.h"
#include "cmCursesLongMessageForm.h"
const int cmCursesMainForm::MIN_WIDTH = 65;
const int cmCursesMainForm::MIN_HEIGHT = 6;
@ -20,15 +21,16 @@ inline int ctrl(int z)
return (z&037);
}
cmCursesMainForm::cmCursesMainForm(const char* whereSource,
const char* whereCMake,
bool newCache) :
m_WhereSource(whereSource), m_WhereCMake(whereCMake)
cmCursesMainForm::cmCursesMainForm(std::vector<std::string> const& args) :
m_Args(args)
{
m_Fields = 0;
m_Window = 0;
m_Height = 0;
m_Entries = 0;
m_AdvancedMode = false;
m_NumberOfVisibleEntries = 0;
m_OkToGenerate = false;
m_HelpMessage.push_back(s_ConstHelpMessage);
}
cmCursesMainForm::~cmCursesMainForm()
@ -72,9 +74,8 @@ bool cmCursesMainForm::LookForCacheEntry(const char* key)
return false;
}
void cmCursesMainForm::InitializeUI(WINDOW* w)
void cmCursesMainForm::InitializeUI()
{
m_Window = w;
// Get the cache entries.
const cmCacheManager::CacheEntryMap &cache =
@ -126,6 +127,7 @@ void cmCursesMainForm::InitializeUI(WINDOW* w)
{
newEntries->push_back(new cmCursesCacheEntryComposite(key, value,
true));
m_OkToGenerate = false;
}
}
@ -160,6 +162,12 @@ void cmCursesMainForm::InitializeUI(WINDOW* w)
delete m_Entries;
m_Entries = newEntries;
this->RePost();
}
void cmCursesMainForm::RePost()
{
// Create the fields to be passed to the form.
if (m_Form)
{
@ -168,16 +176,45 @@ void cmCursesMainForm::InitializeUI(WINDOW* w)
m_Form = 0;
}
delete[] m_Fields;
int size = m_Entries->size();
m_Fields = new FIELD*[3*size+1];
for(int j=0; j < size; j++)
if (m_AdvancedMode)
{
m_Fields[3*j] = (*m_Entries)[j]->m_Label->m_Field;
m_Fields[3*j+1] = (*m_Entries)[j]->m_IsNewLabel->m_Field;
m_Fields[3*j+2] = (*m_Entries)[j]->m_Entry->m_Field;
m_NumberOfVisibleEntries = m_Entries->size();
}
else
{
m_NumberOfVisibleEntries = 0;
std::vector<cmCursesCacheEntryComposite*>::iterator it;
for (it = m_Entries->begin(); it != m_Entries->end(); ++it)
{
if (!m_AdvancedMode && cmCacheManager::GetInstance()->IsAdvanced(
(*it)->GetValue()))
{
continue;
}
m_NumberOfVisibleEntries++;
}
}
m_Fields = new FIELD*[3*m_NumberOfVisibleEntries+1];
int j=0;
std::vector<cmCursesCacheEntryComposite*>::iterator it;
for (it = m_Entries->begin(); it != m_Entries->end(); ++it)
{
if (!m_AdvancedMode && cmCacheManager::GetInstance()->IsAdvanced(
(*it)->GetValue()))
{
continue;
}
m_Fields[3*j] = (*it)->m_Label->m_Field;
m_Fields[3*j+1] = (*it)->m_IsNewLabel->m_Field;
m_Fields[3*j+2] = (*it)->m_Entry->m_Field;
j++;
}
// Has to be null terminated.
m_Fields[3*size] = 0;
m_Fields[3*m_NumberOfVisibleEntries] = 0;
}
void cmCursesMainForm::Render(int left, int top, int width, int height)
@ -205,41 +242,82 @@ void cmCursesMainForm::Render(int left, int top, int width, int height)
return;
}
height -= 5;
height -= 6;
m_Height = height;
int size = m_Entries->size();
bool isNewPage;
for(int i=0; i < size; i++)
if (m_AdvancedMode)
{
m_NumberOfVisibleEntries = m_Entries->size();
}
else
{
m_NumberOfVisibleEntries = 0;
std::vector<cmCursesCacheEntryComposite*>::iterator it;
for (it = m_Entries->begin(); it != m_Entries->end(); ++it)
{
if (!m_AdvancedMode && cmCacheManager::GetInstance()->IsAdvanced(
(*it)->GetValue()))
{
continue;
}
m_NumberOfVisibleEntries++;
}
}
bool isNewPage;
int i=0;
std::vector<cmCursesCacheEntryComposite*>::iterator it;
for (it = m_Entries->begin(); it != m_Entries->end(); ++it)
{
if (!m_AdvancedMode && cmCacheManager::GetInstance()->IsAdvanced(
(*it)->GetValue()))
{
continue;
}
int row = (i % height) + 1;
int page = (i / height) + 1;
isNewPage = ( page > 1 ) && ( row == 1 );
(*m_Entries)[i]->m_Label->Move(left, top+row-1, isNewPage);
(*m_Entries)[i]->m_IsNewLabel->Move(left+32, top+row-1, false);
(*m_Entries)[i]->m_Entry->Move(left+33, top+row-1, false);
(*it)->m_Label->Move(left, top+row-1, isNewPage);
(*it)->m_IsNewLabel->Move(left+32, top+row-1, false);
(*it)->m_Entry->Move(left+33, top+row-1, false);
i++;
}
m_Form = new_form(m_Fields);
post_form(m_Form);
this->UpdateStatusBar();
this->PrintKeys();
touchwin(m_Window);
touchwin(stdscr);
refresh();
}
void cmCursesMainForm::PrintKeys()
{
int x,y;
getmaxyx(m_Window, y, x);
getmaxyx(stdscr, y, x);
if ( x < cmCursesMainForm::MIN_WIDTH ||
y < cmCursesMainForm::MIN_HEIGHT )
{
return;
}
char firstLine[512], secondLine[512];
sprintf(firstLine, "C)onfigure G)enerate and Exit");
sprintf(secondLine, "Q)uit H)elp");
if (m_OkToGenerate)
{
sprintf(firstLine, "C)onfigure G)enerate and Exit H)elp");
}
else
{
sprintf(firstLine, "C)onfigure H)elp");
}
if (m_AdvancedMode)
{
sprintf(secondLine, "Q)uit Without Generating T)oggle Advanced Mode (On)");
}
else
{
sprintf(secondLine, "Q)uit Without Generating T)oggle Advanced Mode (Off)");
}
curses_move(y-2,0);
printw(firstLine);
@ -254,66 +332,104 @@ void cmCursesMainForm::PrintKeys()
void cmCursesMainForm::UpdateStatusBar()
{
int x,y;
getmaxyx(m_Window, y, x);
getmaxyx(stdscr, y, x);
if ( x < cmCursesMainForm::MIN_WIDTH ||
y < cmCursesMainForm::MIN_HEIGHT )
{
clear();
curses_move(0,0);
printw("Window is too small. A size of at least %dx%d is required.",
cmCursesMainForm::MIN_WIDTH, cmCursesMainForm::MIN_HEIGHT);
touchwin(m_Window);
wrefresh(m_Window);
touchwin(stdscr);
wrefresh(stdscr);
return;
}
FIELD* cur = current_field(m_Form);
int index = field_index(cur);
char* curField = field_buffer(m_Fields[index-2], 0);
cmCursesWidget* lbl = reinterpret_cast<cmCursesWidget*>(field_userptr(
m_Fields[index-2]));
const char* curField = lbl->GetValue();
// We want to display this on the right
char help[128];
const char* helpString;
cmCacheManager::CacheEntry *entry =
cmCacheManager::GetInstance()->GetCacheEntry(curField);
if (entry)
{
helpString = entry->m_HelpString.c_str();
if (strlen(helpString) > 127)
{
sprintf(help,"%127s", helpString);
}
else
{
sprintf(help,"%s", helpString);
}
}
else
{
sprintf(help," ");
}
char version[128];
sprintf(version,"(CMake Version %d.%d)", cmMakefile::GetMajorVersion(),
cmMakefile::GetMinorVersion());
char bar[cmCursesMainForm::MAX_WIDTH];
int i, curFieldLen = strlen(curField);
int versionLen = strlen(version);
int leftLen = cmCursesMainForm::IDEAL_WIDTH - versionLen;
if (curFieldLen >= leftLen)
int helpLen = strlen(help);
int width;
if (x < cmCursesMainForm::MAX_WIDTH )
{
strncpy(bar, curField, leftLen);
width = x;
}
else
{
width = cmCursesMainForm::MAX_WIDTH;
}
int leftLen = width - helpLen;
if (curFieldLen >= width)
{
strncpy(bar, curField, width);
}
else
{
strcpy(bar, curField);
for(i=curFieldLen; i < leftLen; ++i) { bar[i] = ' '; }
}
strcpy(bar+leftLen, version);
if ( x < cmCursesMainForm::MAX_WIDTH )
{
if (x > cmCursesMainForm::IDEAL_WIDTH )
bar[curFieldLen] = ':';
bar[curFieldLen+1] = ' ';
if (curFieldLen + helpLen + 2 >= width)
{
for(i=cmCursesMainForm::IDEAL_WIDTH; i < x; i++)
{
bar[i] = ' ';
strncpy(bar+curFieldLen+2, help, width
- curFieldLen - 2);
}
else
{
strcpy(bar+curFieldLen+2, help);
for(i=curFieldLen+helpLen+2; i < width; ++i)
{
bar[i] = ' ';
}
}
bar[x] = '\0';
}
else
{
for(i=cmCursesMainForm::IDEAL_WIDTH;
i < cmCursesMainForm::MAX_WIDTH-1; i++)
{
bar[i] = ' ';
}
bar[cmCursesMainForm::MAX_WIDTH-1] = '\0';
}
curses_move(y-3,0);
bar[width] = '\0';
char version[cmCursesMainForm::MAX_WIDTH];
char vertmp[128];
sprintf(vertmp,"CMake Version %d.%d", cmMakefile::GetMajorVersion(),
cmMakefile::GetMinorVersion());
int sideSpace = (width-strlen(vertmp));
for(i=0; i<sideSpace; i++) { version[i] = ' '; }
sprintf(version+sideSpace, "%s", vertmp);
version[width] = '\0';
curses_move(y-4,0);
attron(A_STANDOUT);
printw(bar);
attroff(A_STANDOUT);
curses_move(y-3,0);
printw(version);
pos_form_cursor(m_Form);
}
@ -321,8 +437,13 @@ void cmCursesMainForm::RunCMake(bool generateMakefiles)
{
int x,y;
getmaxyx(m_Window, y, x);
getmaxyx(stdscr, y, x);
clear();
curses_move(1,1);
printw("Running CMake, please wait.");
touchwin(stdscr);
refresh();
endwin();
// always save the current gui values to disk
this->FillCacheManagerFromUI();
@ -331,32 +452,66 @@ void cmCursesMainForm::RunCMake(bool generateMakefiles)
// create a cmake object
cmake make;
// create the arguments for the cmake object
std::vector<std::string> args;
args.push_back(m_WhereCMake);
if (m_WhereSource != "")
{
std::string arg;
arg = m_WhereSource;
args.push_back(arg);
}
std::string whereCMake = cmSystemTools::GetProgramPath(m_Args[0].c_str());
whereCMake += "/cmake";
m_Args[0] = whereCMake;
// Get rid of previous errors
m_Errors = std::vector<std::string>();
// run the generate process
if(make.Generate(args, generateMakefiles) != 0)
m_OkToGenerate = true;
if(make.Generate(m_Args, generateMakefiles) != 0 || !m_Errors.empty())
{
// TODO : error message here
m_OkToGenerate = false;
cmSystemTools::ResetErrorOccuredFlag();
int x,y;
getmaxyx(stdscr, y, x);
cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(m_Errors,
"Errors which during last pass.");
CurrentForm = msgs;
msgs->Render(1,1,x,y);
msgs->HandleInput();
CurrentForm = this;
this->Render(1,1,x,y);
}
m_Window = initscr(); /* Initialization */
initscr(); /* Initialization */
noecho(); /* Echo off */
cbreak(); /* nl- or cr not needed */
keypad(m_Window,TRUE); /* Use key symbols as
keypad(stdscr,TRUE); /* Use key symbols as
KEY_DOWN*/
this->InitializeUI(m_Window);
this->InitializeUI();
this->Render(1, 1, x, y);
}
void cmCursesMainForm::AddError(const char* message, const char* title)
{
m_Errors.push_back(message);
}
void cmCursesMainForm::RemoveEntry(const char* value)
{
if (!value)
{
return;
}
std::vector<cmCursesCacheEntryComposite*>::iterator it;
for (it = m_Entries->begin(); it != m_Entries->end(); ++it)
{
const char* val = (*it)->GetValue();
if ( val && !strcmp(value, val) )
{
m_Entries->erase(it);
break;
}
}
}
// copy from the list box to the cache manager
void cmCursesMainForm::FillCacheManagerFromUI()
{
@ -397,7 +552,7 @@ void cmCursesMainForm::HandleInput()
currentWidget = reinterpret_cast<cmCursesWidget*>(field_userptr(
currentField));
if (!currentWidget || !currentWidget->HandleInput(key, m_Form, m_Window))
if (!currentWidget || !currentWidget->HandleInput(key, m_Form, stdscr))
{
// quit
if ( key == 'q' )
@ -405,15 +560,19 @@ void cmCursesMainForm::HandleInput()
break;
}
// if not end of page, next field otherwise next page
// each entry consists of fields: label, isnew, value
// therefore, the label field for the prev. entry is index-5
// and the label field for the next entry is index+1
// (index always corresponds to the value field)
else if ( key == KEY_DOWN || key == ctrl('n') )
{
FIELD* cur = current_field(m_Form);
unsigned int index = field_index(cur);
if ( index == 3*m_Entries->size()-1 )
if ( index == 3*m_NumberOfVisibleEntries-1 )
{
continue;
}
if ( (index < 3*m_Entries->size()-1) && new_page(m_Fields[index+1]))
if (new_page(m_Fields[index+1]))
{
form_driver(m_Form, REQ_NEXT_PAGE);
}
@ -423,6 +582,10 @@ void cmCursesMainForm::HandleInput()
}
}
// if not beginning of page, previous field, otherwise previous page
// each entry consists of fields: label, isnew, value
// therefore, the label field for the prev. entry is index-5
// and the label field for the next entry is index+1
// (index always corresponds to the value field)
else if ( key == KEY_UP || key == ctrl('p') )
{
FIELD* cur = current_field(m_Form);
@ -456,11 +619,56 @@ void cmCursesMainForm::HandleInput()
{
this->RunCMake(false);
}
// display help
else if ( key == 'h' )
{
int x,y;
getmaxyx(stdscr, y, x);
cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(m_HelpMessage,
"Help.");
CurrentForm = msgs;
msgs->Render(1,1,x,y);
msgs->HandleInput();
CurrentForm = this;
this->Render(1,1,x,y);
}
// display last errors
else if ( key == 'l' )
{
int x,y;
getmaxyx(stdscr, y, x);
cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(m_Errors,
"Errors which during last pass.");
CurrentForm = msgs;
msgs->Render(1,1,x,y);
msgs->HandleInput();
CurrentForm = this;
this->Render(1,1,x,y);
}
// switch advanced on/off
else if ( key == 't' )
{
if (m_AdvancedMode)
{
m_AdvancedMode = false;
}
else
{
m_AdvancedMode = true;
}
int x,y;
getmaxyx(stdscr, y, x);
this->RePost();
this->Render(1, 1, x, y);
}
// generate and exit
else if ( key == 'g' )
{
this->RunCMake(true);
break;
if ( m_OkToGenerate )
{
this->RunCMake(true);
break;
}
}
// delete cache entry
else if ( key == 'd' )
@ -469,11 +677,16 @@ void cmCursesMainForm::HandleInput()
unsigned int index = field_index(cur);
// make the next or prev. current field after deletion
// each entry consists of fields: label, isnew, value
// therefore, the label field for the prev. entry is index-5
// and the label field for the next entry is index+1
// (index always corresponds to the value field)
FIELD* nextCur;
if ( index == 2 )
{
nextCur=0;
}
else if ( index == 3*m_Entries->size()-1 )
else if ( index == 3*m_NumberOfVisibleEntries-1 )
{
nextCur = m_Fields[index-5];
}
@ -483,36 +696,49 @@ void cmCursesMainForm::HandleInput()
}
// Get the label widget
// each entry consists of fields: label, isnew, value
// therefore, the label field for the is index-2
// (index always corresponds to the value field)
cmCursesWidget* lbl = reinterpret_cast<cmCursesWidget*>(field_userptr(
m_Fields[index-2]));
cmCacheManager::GetInstance()->RemoveCacheEntry(lbl->GetValue());
std::string nextVal (reinterpret_cast<cmCursesWidget*>(field_userptr(nextCur))->GetValue());
std::string nextVal;
if (nextCur)
{
nextVal = (reinterpret_cast<cmCursesWidget*>(field_userptr(nextCur))->GetValue());
}
int x,y;
getmaxyx(m_Window, y, x);
this->InitializeUI(m_Window);
getmaxyx(stdscr, y, x);
this->RemoveEntry(lbl->GetValue());
this->RePost();
this->Render(1, 1, x, y);
// make the next or prev. current field after deletion
nextCur = 0;
std::vector<cmCursesCacheEntryComposite*>::iterator it;
for (it = m_Entries->begin(); it != m_Entries->end(); ++it)
{
if (nextVal == (*it)->m_Key)
{
nextCur = (*it)->m_Entry->m_Field;
}
}
if (nextCur)
{
set_current_field(m_Form, nextCur);
// make the next or prev. current field after deletion
nextCur = 0;
std::vector<cmCursesCacheEntryComposite*>::iterator it;
for (it = m_Entries->begin(); it != m_Entries->end(); ++it)
{
if (nextVal == (*it)->m_Key)
{
nextCur = (*it)->m_Entry->m_Field;
}
}
if (nextCur)
{
set_current_field(m_Form, nextCur);
}
}
}
}
touchwin(m_Window);
wrefresh(m_Window);
touchwin(stdscr);
wrefresh(stdscr);
}
}
const char* cmCursesMainForm::s_ConstHelpMessage = "CMake is used to configure and generate build files for software projects. The basic steps for configuring a project are as follows:\n\n1. Select the source directory for the project. This should contain the CMakeLists.txt files for the project.\n\n2. Select the build directory for the project. This is the directory where the project will be built. It can be the same or a different directory than the source directory. For easy clean up, a separate build directory is recommended. CMake will create the directory if it does not exist.\n\n3. Once the source and binary directories are selected, it is time to press the Configure button. This will cause CMake to read all of the input files and discover all the variables used by the project. The first time a variable is displayed it will be in Red. Users should inspect red variables making sure the values are correct. For some projects the Configure process can be iterative, so continue to press the Configure button until there are no longer red entries.\n\n4. Once there are no longer red entries, you should click the OK button. This will write the build files to the build directory and exit CMake.";

View File

@ -10,13 +10,12 @@ class cmCursesCacheEntryComposite;
class cmCursesMainForm : public cmCursesForm
{
public:
cmCursesMainForm(const char* whereSource, const char* whereCMake,
bool newCache);
cmCursesMainForm(std::vector<string> const& args);
virtual ~cmCursesMainForm();
// Description:
// Set the widgets which represent the cache entries.
void InitializeUI(WINDOW* w);
void InitializeUI();
// Description:
// Handle user input.
@ -27,11 +26,6 @@ public:
// at top, left.
virtual void Render(int left, int top, int width, int height);
// Description:
// Change the window containing the form.
void SetWindow(WINDOW* w)
{ m_Window = w; }
// Description:
// Returns true if an entry with the given key is in the
// list of current composites.
@ -45,26 +39,44 @@ public:
// Description:
// This method should normally called only by the form.
// The only exception is during a resize.
void UpdateStatusBar();
virtual void UpdateStatusBar();
// Description:
// This method should normally called only by the form.
// The only exception is during a resize.
void PrintKeys();
// Description:
// During a CMake run, an error handle should add errors
// to be displayed afterwards.
virtual void AddError(const char* message, const char* title);
// Description:
// Used to run cmake.
void RunCMake(bool generateMakefiles);
protected:
cmCursesMainForm(const cmCursesMainForm& from);
void operator=(const cmCursesMainForm&);
void RunCMake(bool generateMakefiles);
void FillCacheManagerFromUI();
void RePost();
void RemoveEntry(const char* value);
std::vector<cmCursesCacheEntryComposite*>* m_Entries;
std::vector<std::string> m_Errors;
std::vector<std::string> m_Args;
std::vector<std::string> m_HelpMessage;
static const char* s_ConstHelpMessage;
FIELD** m_Fields;
WINDOW* m_Window;
std::string m_WhereSource;
std::string m_WhereCMake;
int m_Height;
int m_NumberOfVisibleEntries;
bool m_AdvancedMode;
bool m_OkToGenerate;
};

View File

@ -71,16 +71,21 @@ bool cmListFileCache::CacheFile(const char* path)
std::vector<std::string> arguments;
cmListFile inFile;
inFile.m_ModifiedTime = cmSystemTools::ModifiedTime(path);
bool parseError;
while ( fin )
{
cmListFileFunction inFunction;
if(cmSystemTools::ParseFunction(fin,
inFunction.m_Name,
inFunction.m_Arguments,
path))
path, parseError))
{
inFile.m_Functions.push_back(inFunction);
}
if (parseError)
{
inFile.m_ModifiedTime = 0;
}
}
m_ListFileCache[path] = inFile;
return true;

View File

@ -522,8 +522,10 @@ const char *cmSystemTools::ConvertToWindowsSlashesAndCleanUp(std::string& path)
bool cmSystemTools::ParseFunction(std::ifstream& fin,
std::string& name,
std::vector<std::string>& arguments,
const char* filename)
const char* filename,
bool& parseError)
{
parseError = false;
name = "";
arguments = std::vector<std::string>();
const int BUFFER_SIZE = 4096;
@ -586,6 +588,7 @@ bool cmSystemTools::ParseFunction(std::ifstream& fin,
}
else
{
parseError = true;
cmSystemTools::Error("Parse error in read function missing end )\nIn File: ",
filename, "\nCurrent line:", inbuffer);
return false;
@ -595,6 +598,7 @@ bool cmSystemTools::ParseFunction(std::ifstream& fin,
}
else
{
parseError = true;
cmSystemTools::Error("Parse error in read function\nIn file:",
filename, "\nCurrent line:", inbuffer);
return false;

View File

@ -133,7 +133,7 @@ public:
static bool ParseFunction(std::ifstream&,
std::string& name,
std::vector<std::string>& arguments,
const char* filename);
const char* filename, bool& parseError);
/**
* Extract white-space separated arguments from a string.

View File

@ -107,9 +107,11 @@ void ctest::ProcessDirectory(int &passed, int &failed)
cmRegularExpression var(this->m_RegExp.c_str());
cmRegularExpression dartStuff("([\t\n ]*<DartMeasurement.*/DartMeasurement[a-zA-Z]*>[\t ]*[\n]*)");
bool parseError;
while ( fin )
{
if(cmSystemTools::ParseFunction(fin, name, args, "DartTestfile.txt"))
if(cmSystemTools::ParseFunction(fin, name, args, "DartTestfile.txt",
parseError))
{
if (name == "SUBDIRS")
{