//------------------------------------------------------------------------------
// DelftOnline -- Interactive Client Program
// Command Parser
//
// Irv.Elshoff@Deltares.NL
// 24 may 12
//
//------------------------------------------------------------------------------
//---- LGPL --------------------------------------------------------------------
//
// Copyright (C) Stichting Deltares, 2011-2013.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation version 2.1.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see .
//
// contact: delft3d.support@deltares.nl
// Stichting Deltares
// P.O. Box 177
// 2600 MH Delft, The Netherlands
//
// All indications and logos of, and references to, "Delft3D" and "Deltares"
// are registered trademarks of Stichting Deltares, and remain the property of
// Stichting Deltares. All rights reserved.
//
//------------------------------------------------------------------------------
// $Id:$
// $HeadURL:$
%{
#include "dolcli.h"
#define YYDEBUG 1
void
yyerror (
const char * str
);
void
EmitList (
const char * title,
DOL::Client::List * list,
int maxlen
) {
printf (" %s:\n\t", title);
int len = 0;
for (int i = 0 ; i < list->count ; i++) {
printf (" %s", list->name[i]);
if ((len += strlen (list->name[i]) + 1) >= maxlen) {
printf ("\n\t");
len = 0;
}
}
putchar ('\n');
}
void
RenderArrayShape (
DOL::Client::ArrayShape * ash
) {
printf ("ArrayShape: \"%s\" has %d dimension%s: [", ash->pathname, ash->dimensionality, (ash->dimensionality > 1) ? "s" : "");
long size = 1;
for (unsigned int i = 0 ; i < ash->dimensionality; i++) {
printf (" %d", ash->dimensions[i]);
size *= ash->dimensions[i];
}
printf (" ] = %ld element%s\n", size, (size > 1) ? "s" : "");
}
void
ShowDirectory (
const char * name
) {
DOL::Client::Directory * dir = Global->dol->GetDirectory (name);
if (dir == NULL)
printf ("Directory \"%s\" not found\n", name);
else {
printf ("Directory \"%s\":\n", dir->pathname);
const int maxlen = 60;
if (dir->subdirs.count > 0)
EmitList ("Directories", &dir->subdirs, maxlen);
if (dir->arrays.count > 0)
EmitList ("ArrayShapes", &dir->arrays, maxlen);
if (dir->elements.count > 0)
EmitList ("DataElements", &dir->elements, maxlen);
if (dir->functions.count > 0)
EmitList ("Functions", &dir->functions, maxlen);
delete dir;
}
}
//------------------------------------------------------------------------------
%}
%union {
uint32_t val;
void * ptr;
}
%type keyword
%type string
%token TOK_ASH
%token TOK_CALL
%token TOK_CD
%token TOK_DESC
%token TOK_DIR
%token TOK_ELT
%token TOK_ENDOFINPUT
%token TOK_EOL
%token TOK_FUNC
%token TOK_GET
%token TOK_HELP
%token TOK_INTEGER
%token TOK_LS
%token TOK_PUT
%token TOK_QUIT
%token TOK_SLEEP
%token TOK_START
%token TOK_STATUS
%token TOK_STEP
%token TOK_STOP
%token TOK_STRING
%token TOK_TERMINATE
%token TOK_THR
%start commands
%%
commands :
TOK_ENDOFINPUT { return 0; } |
command TOK_ENDOFINPUT { return 0; } |
command commands TOK_ENDOFINPUT { return 0; }
;
command:
TOK_EOL |
ash_command TOK_EOL |
call_command TOK_EOL |
cd_command TOK_EOL |
desc_command TOK_EOL |
dir_command TOK_EOL |
elt_command TOK_EOL |
func_command TOK_EOL |
get_command TOK_EOL |
help_command TOK_EOL |
ls_command TOK_EOL |
put_command TOK_EOL |
quit_command TOK_EOL |
sleep_command TOK_EOL |
start_command TOK_EOL |
status_command TOK_EOL |
step_command TOK_EOL |
stop_command TOK_EOL |
terminate_command TOK_EOL |
thr_command TOK_EOL |
error TOK_ENDOFINPUT {
yyclearin;
yyerrok;
return 0;
}
;
ash_command:
TOK_ASH string {
char * name = (char *) $2;
DOL::Client::ArrayShape * ash = Global->dol->GetArrayShape (name);
if (ash == NULL)
printf ("ArrayShape \"%s\" not found\n", name);
else {
RenderArrayShape (ash);
delete ash;
}
}
;
call_command:
TOK_CALL string TOK_INTEGER {
}
;
cd_command:
TOK_CD string {
char * name = (char *) $2;
char * dir = Global->dol->ChangeDirectory (name);
if (dir == NULL)
printf ("Directory \"%s\" not found\n", (name));
else {
printf ("Now in \"%s\"\n", dir);
free (dir);
}
} |
TOK_CD {
char * dir = Global->dol->PWD ();
printf ("Now in \"%s\"\n", dir);
free (dir);
}
;
desc_command:
TOK_DESC {
char * description = Global->dol->GetDescription ();
if (description == NULL)
printf ("No description\n");
else {
printf ("%s\n", description);
free (description);
}
}
;
dir_command:
TOK_DIR {
ShowDirectory (".");
} |
TOK_DIR string {
ShowDirectory ((char *) $2);
}
;
elt_command:
TOK_ELT string {
char * name = (char *) $2;
DOL::Client::DataElement * elt = Global->dol->GetDataElement (name);
if (elt == NULL)
printf ("DataElement \"%s\" not found\n", name);
else {
printf ("DataElement \"%s\" is %s ", elt->pathname, DOL::BaseTypeString (elt->basetype));
if (elt->arrayshape) {
printf ("array\n ");
RenderArrayShape (elt->arrayshape);
}
else
printf ("scalar\n");
if (elt->description != NULL) printf (" Description: %s\n", elt->description);
if (elt->definedon != NULL) printf (" Defined on: %s\n", elt->definedon);
if (elt->units != NULL) printf (" Units: %s\n", elt->units);
delete elt;
}
}
;
func_command:
TOK_FUNC string {
char * name = (char *) $2;
DOL::Client::Function * func = Global->dol->GetFunction (name);
if (func == NULL)
printf ("Function \"%s\" not found\n", name);
else {
printf ("Function \"%s\" has context %p\n", func->pathname, func->context);
if (func->description != NULL) printf ("\tDescription: %s\n", func->description);
delete func;
}
}
;
get_command:
TOK_GET string {
printf ("1arg\n\"%s\"\n", (char *) $2);
GetElement ((char *) $2, NULL);
} |
TOK_GET string string {
printf ("2arg\n\"%s\"\n\"%s\"\n", (char *) $2, (char *) $3);
GetElement ((char *) $2, (char *) $3);
}
;
help_command:
TOK_HELP {
printf ("Client commands: (abbreviation follows /)\n");
printf (" ash Print array shape info\n");
printf (" call Call a function with the specified integer argument\n");
printf (" cd [] Change (or print) current directory\n");
printf (" desc Print DOL server description\n");
printf (" dir Print directory info\n");
printf (" elt Print data element info\n");
printf (" func Print function info\n");
printf (" get [] Get data element contents (and possible write to file)\n");
printf (" help/? Print this command summary\n");
printf (" ls [] List current or specified directory\n");
printf (" put Write a scalar data element\n");
printf (" quit/q Terminate client\n");
printf (" sleep Pause client for specified number of seconds\n");
printf (" sleep Pause client for random number of milliseconds between and \n");
printf (" start/g Tell server to resume (go)\n");
printf (" status Print server status\n");
printf (" step/n [] Resume server for next milestone units; default 1\n");
printf (" stop/b Pause (brake) server indefinitely\n");
printf (" terminate/ZZ Terminate client and server\n");
printf (" thr Print server threads\n");
}
;
ls_command:
TOK_LS {
ListDirectory (".");
} |
TOK_LS string {
ListDirectory ((char *) $2);
}
;
put_command:
TOK_PUT string {
}
;
quit_command:
TOK_QUIT {
Global->input.quit = true;
return 0; // cause yyparse to return, exiting the command loop
}
;
sleep_command:
TOK_SLEEP TOK_INTEGER {
usleep (1000 * $2);
} |
TOK_SLEEP TOK_INTEGER TOK_INTEGER {
double r = drand48 ();
int duration = (int) round ($2 + r * ($3 -$2));
printf ("Sleeping for %d ms\n", duration);
usleep (1000 * duration);
}
;
start_command:
TOK_START {
bool success = Global->dol->Start ();
printf ("Start %s\n", success ? "succeeds" : "fails");
}
;
status_command:
TOK_STATUS {
DOL::Status * status = Global->dol->ServerStatus ();
if (status == NULL)
printf ("Cannot get status\n");
else {
printf ("AllowControl: %s\n", status->allowControl ? "true" : "false");
printf ("Running: %s\n", status->running ? "true" : "false");
printf ("Milestone: %d\n", status->milestone);
printf ("Generation: %d\n", status->generation);
printf ("Distance: %d\n", status->distance);
delete status;
}
}
;
step_command:
TOK_STEP {
DOL::Milestone milestone = Global->dol->Step (1);
if (milestone > 0)
printf ("Stopped at milestone %d\n", milestone);
else
printf ("Step fails\n");
} |
TOK_STEP TOK_INTEGER {
DOL::Milestone milestone = Global->dol->Step ($2);
if (milestone > 0)
printf ("Stopped at milestone %d\n", milestone);
else
printf ("Step fails\n");
}
;
stop_command:
TOK_STOP {
DOL::Milestone milestone = Global->dol->Stop ();
if ((int) milestone > 0)
printf ("Stopped at milestone %d\n", milestone);
else {
DOL::Status * status = Global->dol->ServerStatus ();
if (status != NULL && status->running == false)
printf ("Already stopped\n");
else
printf ("Stop fails; status fails\n");
}
}
;
terminate_command:
TOK_TERMINATE {
bool success = Global->dol->Terminate ();
if (success) {
Global->input.quit = true;
return 0; // cause yyparse to return, exiting the command loop
}
printf ("Terminate fails\n");
}
;
thr_command:
TOK_THR {
printf ("Threads: ");
int n = Global->dol->GetThreadCount ();
printf ("[%d] ", n);
for (int i = 0 ; i < n ; i++) {
char * name = Global->dol->GetThreadName (i);
printf (" %s", name);
free (name);
}
putchar ('\n');
}
;
//------------------------------------------------------------------------------
string:
TOK_STRING |
keyword
;
keyword:
TOK_ASH |
TOK_CALL |
TOK_CD |
TOK_DESC |
TOK_DIR |
TOK_ELT |
TOK_FUNC |
TOK_GET |
TOK_HELP |
TOK_LS |
TOK_PUT |
TOK_QUIT |
TOK_SLEEP |
TOK_START |
TOK_STATUS |
TOK_STEP |
TOK_STOP |
TOK_TERMINATE |
TOK_THR
;
%%
//------------------------------------------------------------------------------
// YACC-required functions
void
yyerror (
const char * str
) {
printf ("%s on line %d\n", str, Global->input.linenum);
}