|
Packit |
d394d9 |
/* Copyright (C) 2002 Bjoern Beutel. */
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Description. =============================================================*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* This is a GTK program that displays Malaga values. */
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Includes. ================================================================*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
#define _POSIX_SOURCE
|
|
Packit |
d394d9 |
#include <stdio.h>
|
|
Packit |
d394d9 |
#include <stdlib.h>
|
|
Packit |
d394d9 |
#include <stdarg.h>
|
|
Packit |
d394d9 |
#include <setjmp.h>
|
|
Packit |
d394d9 |
#include <string.h>
|
|
Packit |
d394d9 |
#include <math.h>
|
|
Packit |
d394d9 |
#include <gtk/gtk.h>
|
|
Packit |
d394d9 |
#include <glib.h>
|
|
Packit |
d394d9 |
#include "basic.h"
|
|
Packit |
d394d9 |
#include "input.h"
|
|
Packit |
d394d9 |
#include "scanner.h"
|
|
Packit |
d394d9 |
#include "files.h"
|
|
Packit |
d394d9 |
#include "canvas.h"
|
|
Packit |
d394d9 |
#include "allomorphs.h"
|
|
Packit |
d394d9 |
#include "expressions.h"
|
|
Packit |
d394d9 |
#include "result.h"
|
|
Packit |
d394d9 |
#include "tree.h"
|
|
Packit |
d394d9 |
#include "variables.h"
|
|
Packit |
d394d9 |
#ifdef POSIX
|
|
Packit |
d394d9 |
#include <unistd.h>
|
|
Packit |
d394d9 |
#endif
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Variables. ===============================================================*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
#ifdef WIN32
|
|
Packit |
d394d9 |
static bool_t input_consumed; /* Set by consumer, reset by pipe thread. */
|
|
Packit |
d394d9 |
static GCond *input_consumed_cond; /* Signals that "input_consumed" is set. */
|
|
Packit |
d394d9 |
static GMutex *input_consumed_mutex;
|
|
Packit |
d394d9 |
#endif
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Functions. ===============================================================*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
parse_font_size( string_t input, int_t *font_size )
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
int_t size;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
size = parse_cardinal( &input );
|
|
Packit |
d394d9 |
parse_end( &input );
|
|
Packit |
d394d9 |
if (size != 8 && size != 10 && size != 12 && size != 14 && size != 18
|
|
Packit |
d394d9 |
&& size != 24)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
complain( "Illegal font size, valid sizes are 8, 10, 12, 14, 18, 24." );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
*font_size = size;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static int_t
|
|
Packit |
d394d9 |
my_parse_int( string_t *input_p )
|
|
Packit |
d394d9 |
/* Parse an integer number in *INPUT_P, adjust *INPUT_P.
|
|
Packit |
d394d9 |
* Parsing stops when the first non-digit is encountered. */
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
int_t number;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
if (**input_p < '0' || **input_p > '9')
|
|
Packit |
d394d9 |
complain( "Number expected." );
|
|
Packit |
d394d9 |
number = 0;
|
|
Packit |
d394d9 |
while (**input_p >= '0' && **input_p <= '9')
|
|
Packit |
d394d9 |
number = 10 * number + (*(*input_p)++ - '0');
|
|
Packit |
d394d9 |
return number;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
parse_geometry( string_t input, rectangle_t *geometry )
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
static char_t malformed[] = "Malformed geometry.";
|
|
Packit |
d394d9 |
string_t arg, arg_p;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
arg_p = arg = parse_word( &input );
|
|
Packit |
d394d9 |
parse_end( &input );
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
if ((*arg_p < '0' || *arg_p > '9') && *arg_p != '+')
|
|
Packit |
d394d9 |
complain( malformed );
|
|
Packit |
d394d9 |
if (*arg_p >= '0' && *arg_p <= '9')
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
/* Parse size. */
|
|
Packit |
d394d9 |
geometry->width = my_parse_int( &arg_p );
|
|
Packit |
d394d9 |
if (*arg_p != 'x')
|
|
Packit |
d394d9 |
complain( malformed );
|
|
Packit |
d394d9 |
arg_p++;
|
|
Packit |
d394d9 |
geometry->height = my_parse_int( &arg_p );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
if (*arg_p == '+')
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
/* Parse position. */
|
|
Packit |
d394d9 |
arg_p++;
|
|
Packit |
d394d9 |
geometry->x = my_parse_int( &arg_p );
|
|
Packit |
d394d9 |
if (*arg_p != '+')
|
|
Packit |
d394d9 |
complain( malformed );
|
|
Packit |
d394d9 |
arg_p++;
|
|
Packit |
d394d9 |
geometry->y = my_parse_int( &arg_p );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
if (*arg_p != EOS)
|
|
Packit |
d394d9 |
complain( malformed );
|
|
Packit |
d394d9 |
free_mem( &arg );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
read_profile( string_t file_name )
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
FILE *stream;
|
|
Packit |
d394d9 |
string_t line_p, argument, value;
|
|
Packit |
d394d9 |
char_t *line;
|
|
Packit |
d394d9 |
volatile int_t line_count;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Initialise positions to be ignored. */
|
|
Packit |
d394d9 |
allomorphs_geometry.x = allomorphs_geometry.y = -1;
|
|
Packit |
d394d9 |
expressions_geometry.x = expressions_geometry.y = -1;
|
|
Packit |
d394d9 |
path_geometry.x = path_geometry.y = -1;
|
|
Packit |
d394d9 |
result_geometry.x = result_geometry.y = -1;
|
|
Packit |
d394d9 |
tree_geometry.x = tree_geometry.y = -1;
|
|
Packit |
d394d9 |
variables_geometry.x = variables_geometry.y = -1;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
stream = open_stream( file_name, "r" );
|
|
Packit |
d394d9 |
line_count = 0;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
while (TRUE)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
line = read_line( stream );
|
|
Packit |
d394d9 |
if (line == NULL)
|
|
Packit |
d394d9 |
break;
|
|
Packit |
d394d9 |
line_count++;
|
|
Packit |
d394d9 |
cut_comment( line );
|
|
Packit |
d394d9 |
line_p = line;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
if (*line_p != EOS)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
argument = NULL;
|
|
Packit |
d394d9 |
TRY
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
argument = parse_word( &line_p );
|
|
Packit |
d394d9 |
if (strcmp_no_case( argument, "allomorphs_geometry:" ) == 0)
|
|
Packit |
d394d9 |
parse_geometry( line_p, &allomorphs_geometry );
|
|
Packit |
d394d9 |
else if (strcmp_no_case( argument, "expressions_geometry:" ) == 0)
|
|
Packit |
d394d9 |
parse_geometry( line_p, &expressions_geometry );
|
|
Packit |
d394d9 |
else if (strcmp_no_case( argument, "path_geometry:" ) == 0)
|
|
Packit |
d394d9 |
parse_geometry( line_p, &path_geometry );
|
|
Packit |
d394d9 |
else if (strcmp_no_case( argument, "result_geometry:" ) == 0)
|
|
Packit |
d394d9 |
parse_geometry( line_p, &result_geometry );
|
|
Packit |
d394d9 |
else if (strcmp_no_case( argument, "tree_geometry:" ) == 0)
|
|
Packit |
d394d9 |
parse_geometry( line_p, &tree_geometry );
|
|
Packit |
d394d9 |
else if (strcmp_no_case( argument, "variables_geometry:" ) == 0)
|
|
Packit |
d394d9 |
parse_geometry( line_p, &variables_geometry );
|
|
Packit |
d394d9 |
else if (strcmp_no_case( argument, "font_size:" ) == 0)
|
|
Packit |
d394d9 |
parse_font_size( line_p, &font_size );
|
|
Packit |
d394d9 |
else if (strcmp_no_case( argument, "font:" ) == 0)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
if (font_family != NULL)
|
|
Packit |
d394d9 |
complain( "Font family already defined." );
|
|
Packit |
d394d9 |
font_family = parse_word( &line_p );
|
|
Packit |
d394d9 |
parse_end( &line_p );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
else if (strcmp_no_case( argument, "show_indexes:" ) == 0)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
show_state_indexes = parse_yes_no( &line_p );
|
|
Packit |
d394d9 |
parse_end( &line_p );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
else if (strcmp_no_case( argument, "hanging_style:" ) == 0)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
hanging_style = parse_yes_no( &line_p );
|
|
Packit |
d394d9 |
parse_end( &line_p );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
else if (strcmp_no_case( argument, "inline_path:" ) == 0)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
inline_path = parse_yes_no( &line_p );
|
|
Packit |
d394d9 |
parse_end( &line_p );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
else if (strcmp_no_case( argument, "show_tree:" ) == 0)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
value = parse_word( &line_p );
|
|
Packit |
d394d9 |
if (strcmp_no_case( value, "full" ) == 0)
|
|
Packit |
d394d9 |
tree_mode = FULL_TREE;
|
|
Packit |
d394d9 |
else if (strcmp_no_case( value, "no_dead_ends" ) == 0)
|
|
Packit |
d394d9 |
tree_mode = NO_DEAD_ENDS;
|
|
Packit |
d394d9 |
else if (strcmp_no_case( value, "result_paths" ) == 0)
|
|
Packit |
d394d9 |
tree_mode = RESULT_PATHS;
|
|
Packit |
d394d9 |
else
|
|
Packit |
d394d9 |
complain( "\"full\", \"no_dead_ends\" or \"result_paths\" "
|
|
Packit |
d394d9 |
"expected." );
|
|
Packit |
d394d9 |
free_mem( &value );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
IF_ERROR
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
print_text( error_text, " (\"%s\", line %d)\n",
|
|
Packit |
d394d9 |
name_in_path( file_name ), line_count );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
FINALLY
|
|
Packit |
d394d9 |
free_mem( &argument );
|
|
Packit |
d394d9 |
END_TRY;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
free_mem( &line );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
close_stream( &stream, file_name );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
read_input( string_t input_type )
|
|
Packit |
d394d9 |
/* Read and show INPUT_TYPE from STDIN. */
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
if (strcmp_no_case( input_type, "allomorph" ) == 0)
|
|
Packit |
d394d9 |
read_allomorphs();
|
|
Packit |
d394d9 |
else if (strcmp_no_case( input_type, "expressions" ) == 0)
|
|
Packit |
d394d9 |
read_expressions();
|
|
Packit |
d394d9 |
else if (strcmp_no_case( input_type, "result" ) == 0)
|
|
Packit |
d394d9 |
read_result();
|
|
Packit |
d394d9 |
else if (strcmp_no_case( input_type, "tree" ) == 0)
|
|
Packit |
d394d9 |
read_tree();
|
|
Packit |
d394d9 |
else if (strcmp_no_case( input_type, "variables" ) == 0)
|
|
Packit |
d394d9 |
read_variables();
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
#ifdef POSIX
|
|
Packit |
d394d9 |
static void
|
|
Packit |
d394d9 |
read_on_condition( gpointer data, gint source, GdkInputCondition condition )
|
|
Packit |
d394d9 |
/* This is called by GDK whenever there is something to read.
|
|
Packit |
d394d9 |
* It reads input from malaga and displays the appropriate canvas. */
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
string_t input_type;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
input_type = read_line( stdin );
|
|
Packit |
d394d9 |
if (input_type == NULL)
|
|
Packit |
d394d9 |
gtk_exit(0);
|
|
Packit |
d394d9 |
read_input( input_type );
|
|
Packit |
d394d9 |
free_mem( &input_type );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
#endif
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
#ifdef WIN32
|
|
Packit |
d394d9 |
static bool_t
|
|
Packit |
d394d9 |
read_input_notify( string_t input_type )
|
|
Packit |
d394d9 |
/* Read INPUT_TYPE from stdin, display it, and notify waiting thread. */
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
if (input_type == NULL)
|
|
Packit |
d394d9 |
gtk_exit(0);
|
|
Packit |
d394d9 |
read_input( input_type );
|
|
Packit |
d394d9 |
g_mutex_lock( input_consumed_mutex );
|
|
Packit |
d394d9 |
input_consumed = TRUE;
|
|
Packit |
d394d9 |
g_cond_signal( input_consumed_cond );
|
|
Packit |
d394d9 |
g_mutex_unlock( input_consumed_mutex );
|
|
Packit |
d394d9 |
return FALSE;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
#endif
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
#ifdef WIN32
|
|
Packit |
d394d9 |
static void *
|
|
Packit |
d394d9 |
input_thread( void *dummy )
|
|
Packit |
d394d9 |
/* Read one line from STDIN, inform main thread when new input has arrived. */
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
string_t input_type;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
while (TRUE)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
input_type = read_line( stdin );
|
|
Packit |
d394d9 |
g_idle_add( (GSourceFunc) read_input_notify, input_type );
|
|
Packit |
d394d9 |
g_mutex_lock( input_consumed_mutex );
|
|
Packit |
d394d9 |
while (! input_consumed)
|
|
Packit |
d394d9 |
g_cond_wait( input_consumed_cond, input_consumed_mutex );
|
|
Packit |
d394d9 |
input_consumed = FALSE;
|
|
Packit |
d394d9 |
g_mutex_unlock( input_consumed_mutex );
|
|
Packit |
d394d9 |
free_mem( &input_type );
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
return NULL;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
#endif
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/*---------------------------------------------------------------------------*/
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
int
|
|
Packit |
d394d9 |
main( int argc, char *argv[] )
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
string_t malagarc_path, input_type;
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
init_basic( "malshow" );
|
|
Packit |
d394d9 |
init_input();
|
|
Packit |
d394d9 |
init_scanner();
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
if (argc == 2)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
if (strcmp_no_case( argv[1], "--version" ) == 0
|
|
Packit |
d394d9 |
|| strcmp_no_case( argv[1], "-version" ) == 0
|
|
Packit |
d394d9 |
|| strcmp_no_case( argv[1], "-v" ) == 0)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
program_message();
|
|
Packit |
d394d9 |
exit(0);
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
else if (strcmp_no_case( argv[1], "--help" ) == 0
|
|
Packit |
d394d9 |
|| strcmp_no_case( argv[1], "-help" ) == 0
|
|
Packit |
d394d9 |
|| strcmp_no_case( argv[1], "-h" ) == 0)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
printf( "Display results of a Malaga process in a graphical format.\n\n"
|
|
Packit |
d394d9 |
"Usage:\n"
|
|
Packit |
d394d9 |
"malshow -- Display results from malaga.\n"
|
|
Packit |
d394d9 |
"malshow -v[ersion] -- Print the version number.\n"
|
|
Packit |
d394d9 |
"malshow -h[elp] -- Print this help.\n\n"
|
|
Packit |
d394d9 |
"This program is usually started by malaga or mallex.\n" );
|
|
Packit |
d394d9 |
exit(0);
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
gtk_init( &argc, &argv );
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Read Malaga profile. */
|
|
Packit |
d394d9 |
malagarc_path = NULL;
|
|
Packit |
d394d9 |
#ifdef POSIX
|
|
Packit |
d394d9 |
TRY
|
|
Packit |
d394d9 |
malagarc_path = absolute_path( "~/.malagarc", NULL );
|
|
Packit |
d394d9 |
IF_ERROR
|
|
Packit |
d394d9 |
RESUME;
|
|
Packit |
d394d9 |
END_TRY;
|
|
Packit |
d394d9 |
#endif
|
|
Packit |
d394d9 |
#ifdef WIN32
|
|
Packit |
d394d9 |
TRY
|
|
Packit |
d394d9 |
malagarc_path = absolute_path( "~\\malaga.ini", NULL );
|
|
Packit |
d394d9 |
IF_ERROR
|
|
Packit |
d394d9 |
RESUME;
|
|
Packit |
d394d9 |
END_TRY;
|
|
Packit |
d394d9 |
#endif
|
|
Packit |
d394d9 |
if (malagarc_path != NULL && file_exists( malagarc_path ))
|
|
Packit |
d394d9 |
read_profile( malagarc_path );
|
|
Packit |
d394d9 |
free_mem( &malagarc_path );
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Determine font name. */
|
|
Packit |
d394d9 |
if (font_family == NULL)
|
|
Packit |
d394d9 |
{
|
|
Packit |
d394d9 |
#ifdef POSIX
|
|
Packit |
d394d9 |
font_family = new_string( "Sans", NULL );
|
|
Packit |
d394d9 |
#endif
|
|
Packit |
d394d9 |
#ifdef WIN32
|
|
Packit |
d394d9 |
font_family = new_string( "Arial", NULL );
|
|
Packit |
d394d9 |
#endif
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Read first input. */
|
|
Packit |
d394d9 |
input_type = read_line( stdin );
|
|
Packit |
d394d9 |
read_input( input_type );
|
|
Packit |
d394d9 |
free_mem( &input_type );
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* Prepare to read again whenever there is new input. */
|
|
Packit |
d394d9 |
#ifdef POSIX
|
|
Packit |
d394d9 |
gdk_input_add( STDIN_FILENO, GDK_INPUT_READ, read_on_condition, NULL );
|
|
Packit |
d394d9 |
#endif
|
|
Packit |
d394d9 |
#ifdef WIN32
|
|
Packit |
d394d9 |
g_thread_init( NULL );
|
|
Packit |
d394d9 |
input_consumed_cond = g_cond_new();
|
|
Packit |
d394d9 |
input_consumed_mutex = g_mutex_new();
|
|
Packit |
d394d9 |
g_thread_create( input_thread, NULL, FALSE, NULL );
|
|
Packit |
d394d9 |
#endif
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
gtk_main();
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
free_mem( &font_family );
|
|
Packit |
d394d9 |
terminate_scanner();
|
|
Packit |
d394d9 |
terminate_input();
|
|
Packit |
d394d9 |
terminate_basic();
|
|
Packit |
d394d9 |
return 0;
|
|
Packit |
d394d9 |
}
|
|
Packit |
d394d9 |
|
|
Packit |
d394d9 |
/* End of file. =============================================================*/
|