github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/demos/calc/calcread.c (about)

     1  /* Readline support for calc program.
     2  
     3  Copyright 2000, 2001 Free Software Foundation, Inc.
     4  
     5  This file is part of the GNU MP Library.
     6  
     7  This program is free software; you can redistribute it and/or modify it under
     8  the terms of the GNU General Public License as published by the Free Software
     9  Foundation; either version 3 of the License, or (at your option) any later
    10  version.
    11  
    12  This program is distributed in the hope that it will be useful, but WITHOUT ANY
    13  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
    14  PARTICULAR PURPOSE.  See the GNU General Public License for more details.
    15  
    16  You should have received a copy of the GNU General Public License along with
    17  this program.  If not, see https://www.gnu.org/licenses/.  */
    18  
    19  #include "calc-common.h"
    20  
    21  #if WITH_READLINE
    22  #include <stdio.h>   /* for FILE for old versions of readline/readline.h */
    23  #include <stdlib.h>  /* for free */
    24  #include <string.h>  /* for strdup */
    25  #include <unistd.h>  /* for isatty */
    26  #include <readline/readline.h>
    27  #include <readline/history.h>
    28  
    29  #include "gmp.h"
    30  
    31  
    32  /* change this to "#define TRACE(x) x" for a few diagnostics */
    33  #define TRACE(x)
    34  
    35  
    36  #define MIN(x,y) ((x) < (y) ? (x) : (y))
    37  
    38  char *
    39  calc_completion_entry (const char *text, int state)
    40  {
    41    static int  index, len;
    42    char  *name;
    43  
    44    if (!state)
    45      {
    46        index = 0;
    47        len = strlen (text);
    48      }
    49    TRACE (printf ("calc_completion_entry %s %d, index=%d len=%d\n",
    50  		 text, state, index, len));
    51    while ((name = calc_keywords[index].name) != NULL)
    52      {
    53        index++;
    54        if (memcmp (name, text, len) == 0)
    55  	return (strdup (name));
    56      }
    57    return NULL;
    58  }
    59  
    60  void
    61  calc_init_readline (void)
    62  {
    63    /* By default use readline when the input is a tty.  It's a bit contrary
    64       to the GNU interface conventions to make the behaviour depend on where
    65       the input is coming from, but this is pretty convenient.  */
    66    if (calc_option_readline == -1)
    67      {
    68        calc_option_readline = isatty (fileno (stdin));
    69        TRACE (printf ("calc_option_readline %d\n", calc_option_readline));
    70      }
    71  
    72    if (calc_option_readline)
    73      {
    74        printf ("GNU MP demo calculator program, gmp version %s\n", gmp_version);
    75        printf ("Type \"help\" for help.\n");
    76        rl_readline_name = "gmp-calc";
    77        rl_completion_entry_function = calc_completion_entry;
    78      }
    79  }
    80  
    81  
    82  /* This function is supposed to return YY_NULL to indicate EOF, but that
    83     constant is only in calclex.c and we don't want to clutter calclex.l with
    84     this readline stuff, so instead just hard code 0 for YY_NULL.  That's
    85     it's defined value on unix anyway.  */
    86  
    87  int
    88  calc_input (char *buf, size_t max_size)
    89  {
    90    if (calc_option_readline)
    91      {
    92        static char    *line = NULL;
    93        static size_t  line_size = 0;
    94        static size_t  upto = 0;
    95        size_t         copy_size;
    96  
    97        if (upto >= line_size)
    98  	{
    99  	  if (line != NULL)
   100  	    free (line);
   101  
   102  	  line = readline (calc_more_input ? "more> " : "> ");
   103  	  calc_more_input = 1;
   104  	  if (line == NULL)
   105  	    return 0;
   106  	  TRACE (printf ("readline: %s\n", line));
   107  
   108  	  if (line[0] != '\0')
   109  	    add_history (line);
   110  
   111  	  line_size = strlen (line);
   112  	  line[line_size] = '\n';
   113  	  line_size++;
   114  	  upto = 0;
   115  	}
   116  
   117        copy_size = MIN (line_size-upto, max_size);
   118        memcpy (buf, line+upto, copy_size);
   119        upto += copy_size;
   120        return copy_size;
   121      }
   122    else
   123      {
   124        /* not readline */
   125        return fread (buf, 1, max_size, stdin);
   126      }
   127  }
   128  
   129  
   130  /* This redefined input() might let a traditional lex use the readline
   131     support here.  Apparently POSIX doesn't specify whether an override like
   132     this will work, so maybe it'll work or maybe it won't.  This function is
   133     also not particularly efficient, but don't worry about that, since flex
   134     is the preferred parser.  */
   135  
   136  int
   137  input (void)
   138  {
   139    char  c;
   140    if (calc_input (&c, 1) != 1)
   141      return EOF;
   142    else
   143      return (int) c;
   144  }
   145  
   146  #endif /* WITH_READLINE */