Forked from
mlz / Frida
1048 commits behind the upstream repository.
-
Wuttke, Joachim authoredWuttke, Joachim authored
coord.cpp 4.09 KiB
//**************************************************************************************************
//* FRIDA: fast reliable interactive data analysis
//* (C) Joachim Wuttke 1990-, v2(C++) 2001-
//* http://apps.jcns.fz-juelich.de/frida
//**************************************************************************************************
//! \file coord.cpp
//! \brief Coordinates CCoord, numeric parameters CParam.
#include <cstring>
#include <iostream>
#include <../readplus/macro.hpp>
using namespace std;
#include "coord.hpp"
//**************************************************************************************************
//* class CCoord
//**************************************************************************************************
//! Constructor parsing "name (unit)", where unit may be empty.
CCoord::CCoord( const string in )
{
int i, j, np, n;
n = in.size();
if (in[n-1]!=')')
throw "input must terminate with ')'";
for(j=n-2, np=1; j!=(int)-1; j--) {
if (in[j]==')')
np++;
else if (in[j]=='(') {
np--;
if (np==0) break;
}
}
if (np!=0)
throw "input must contain balanced parentheses";
for (i=j; i>0 && strchr(" \t",in[i-1]); i--) ;
if (i==0)
throw "input must contain a non-empty coordinate name";
name = in.substr(0,i);
unit = in.substr(j+1, n-j-2);
}
//! Interactive setting with help functionality.
void CCoord::ask_and_set( const string& quest )
{
string prompt = quest;
if( name!="" )
prompt += " [" + str_std() + "]";
prompt += " ? ";
for( ;; ) {
string resp = NMacro::readln( prompt );
if ( resp == "\\q" ) {
throw "user escape to main menu";
} else if ( resp == "" ) {
if ( name!="" )
return; // keep current value
cout << "no default available\n";
} else if ( resp == "?" ) {
cout << "required input type: coordinate name and unit\n";
cout << "input must be in the form: name (unit)\n";
if( name!="" )
cout << "just press ENTER to let current value unchanged ["
<< str_std() << "]\n";
} else {
int i, j, np, n;
n = resp.size();
if (resp[n-1]!=')') {
cout << "input must terminate with ')'\n";
continue;
}
for(j=n-2, np=1; j!=(int)-1; j--) {
if (resp[j]==')')
np++;
else if (resp[j]=='(') {
np--;
if (np==0) break;
}
}
if (np!=0){
cout << "input must contain balanced parentheses\n";
continue;
}
for (i=j; i>0 && strchr(" \t",resp[i-1]); i--) ;
if (i==0){
cout << "input must contain a non-empty coordinate name\n";
continue;
}
name = resp.substr(0,i);
unit = resp.substr(j+1, n-j-2);
return;
}
}
}
//! Standard string.
string CCoord::str_std() const
{
return name + " (" + unit + ")";
}
//! Compact string for use in tables.
string CCoord::str_compact( int maxlen ) const
{
string ret = name + "(" + unit + ")";
if ( maxlen==0 || ret.length() <= maxlen )
return ret;
ret = name;
if ( ret.length() <= maxlen )
return ret;
if( maxlen>3 )
return name.substr(0,maxlen-2) + "..";
return name.substr(0,maxlen);
}
//! String for use in PostScript output.
string CCoord::str_ps() const // two blanks instead of one, and no unit ""
{
return name + ( unit!="" ? (" (" + unit + ")") : "");
}
//**************************************************************************************************
//* outside CCoord
//**************************************************************************************************
ostream& operator<< (ostream &s, CCoord C)
{
return s << C.str_std();
}