LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
12
返回列表 发新帖
楼主: vanii

static FILE *stream = stdin; 错在哪??

[复制链接]
 楼主| 发表于 2004-1-24 01:17:56 | 显示全部楼层
here you are.


/*
    This file is part of the FElt finite element analysis package.
    Copyright (C) 1993-2000 Jason I. Gobat and Darren C. Atkinson

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/************************************************************************
* File:        interactive.c                                                *
*                                                                        *
* Description:        This file contains the public and private function        *
*                definitions for the interactive interface.                *
************************************************************************/

# include <stdio.h>
# include <ctype.h>
# include <malloc.h>
# include <string.h>
# include "error.h"
# include "lexer.h"
# include "allocate.h"
# include "our-stdlib.h"
# include "interactive.h"


static char *start_up_message = "\
This is burlap, copyright 1995 by Jason I. Gobat and Darren C. Atkinson.\n\
This is free software, and you are welcome to redistribute it under certain\n\
conditions, but there is absolutely no warranty.  Type help (\"copyright\")\n\
for details.  Use the -q option to suppress this message.\n\n\
";

# define MaxAliases 64

static struct alias {
    char *alias_name;
    char *real_name;
    int   expanded;
} aliases [MaxAliases];

static int num_aliases;

static int   compare_aliases PROTO ((void *, void *));
static void  sort_aliases    PROTO ((void));
static int   parse_alias     PROTO ((char *));
static char *expand_alias    PROTO ((char *));


# define NumDefaults (sizeof (default_aliases) / sizeof (*default_aliases))

static struct {
    char *alias_name;
    char *real_name;
} default_aliases [ ] = {
# ifdef READLINE
    {"exit",        "exit (!*)"},
    {"h",        "history (20)"},
    {"help",        "help (\"!$\")"},
    {"ls",        "system (\"ls !*\")"},
    {"quit",        "exit (!*)"},
# else
    {"exit",        "exit (%s)"},
    {"h",        "history (20)"},
    {"help",        "help (\"%s\")"},
    {"ls",        "system (\"ls %s\")"},
    {"quit",        "exit (%s)"},
# endif
};

FILE stdin;
# ifndef READLINE
static FILE *stream = stdin;
//static FILE *stream = -1;
# endif


# ifndef PROMPT
# define PROMPT "[%u] "
# define CONTINUATION " %u>"
# endif


# ifdef READLINE
# include <readline/history.h>
# include <readline/readline.h>
# include "functab.h"
# include "consttab.h"

//if (stream == -1)  stream = stdin;

static char *completion_generator PROTO ((char *, int));

static char *keywords [ ] = {
    "break", "do", "else", "end", "for", "function", "global",
    "if", "in", "next", "return", "shared", "then", "while",
    "or", "and", "div", "mod", "not", NULL
};

/************************************************************************
* Function:        completion_generator                                        *
*                                                                        *
* Description:        Completion generator for readline().  If we are inside        *
*                a string literal, as determined by counting the number        *
*                of quotes, then filenames are completed.  Otherwise,        *
*                intrinsic functions and keywords are completed.                *
************************************************************************/

static char *completion_generator (text, state)
    char *text;
    int   state;
{
    char      *ptr;
    static int index;
    static int length;
    static int constants;
    static int functions;
    static int filenames;


    if (!state) {
        index = -1;
        functions = 1;
        constants = 1;
        filenames = 0;
        length = strlen (text);

        for (ptr = rl_line_buffer; *ptr; ptr ++)
            if (*ptr == '"' && (ptr == rl_line_buffer || *(ptr - 1) != '\\'))
                filenames = !filenames;
    }

    if (filenames)
        return filename_completion_function (text, state);

    if (functions) {
        while (++ index < NumIntrinsics)
            if (!strncmp (text, functab [index].name, length))
                return Strdup (functab [index].name);

        functions = 0;
        index = -1;
    }

    if (constants) {
        if (text [0] == '&')
            while (++ index < NumConstants)
                if (!strncmp (text, consttab [index].name, length))
                    return Strdup (consttab [index].name);

        constants = 0;
        index = -1;
    }

    while (keywords [++ index])
        if (!strncmp (text, keywords [index], length))
            return Strdup (keywords [index]);

    return NULL;
}
# endif /* READLINE */


/************************************************************************
* Function:        compare_aliases                                                *
*                                                                        *
* Description:        Compares two aliases.                                        *
************************************************************************/

static int compare_aliases (p1, p2)
    void *p1;
    void *p2;
{
    struct alias *a1;
    struct alias *a2;


    a1 = (struct alias *) p1;
    a2 = (struct alias *) p2;

    return strcmp (a1 -> alias_name, a2 -> alias_name);
}


/************************************************************************
* Function:        sort_aliases                                                *
*                                                                        *
* Description:        Sorts the alias list in place.                                *
************************************************************************/

static void sort_aliases ( )
{
    qsort (aliases, num_aliases, sizeof (*aliases), compare_aliases);
}


/************************************************************************
* Function:        parse_alias                                                *
*                                                                        *
* Description:        Parses an input line and checks if it is an alias or        *
*                unalias command.  Note that the parsing is not very        *
*                sophisticated and no history expansion is done on the        *
*                input line.                                                *
************************************************************************/

static int parse_alias (line)
    char *line;
{
    int  i;
    char alias [1024];
    char real  [1024];


    /* Parse the alias command. */

    if (!strncmp (line, "alias", 5))
        if (!line [5] || isspace (line [5])) {
            switch (sscanf (line, "%*s%s%*[ \t]%[^\n]", alias, real)) {


            /* List all aliases. */

            case -1:
                for (i = 0; i < num_aliases; i ++) {
                    printf ("%s\t", aliases .alias_name);
                    printf ("%s\n", aliases .real_name);
                }
                break;


            /* List an alias. */

            case 1:
                for (i = 0; i < num_aliases; i ++)
                    if (!strcmp (aliases .alias_name, alias)) {
                        printf ("%s\n", aliases .real_name);
                        break;
                    }
                break;



            /* Add or overwrite an alias. */

            case 2:
                for (i = 0; i < num_aliases; i ++)
                    if (!strcmp (aliases .alias_name, alias)) {
                        free (aliases .real_name);
                        aliases .real_name = Strdup (real);
                        break;
                    }


                if (i == num_aliases) {
                    if (num_aliases < MaxAliases) {
                        num_aliases ++;
                        aliases .alias_name = Strdup (alias);
                        aliases .real_name = Strdup (real);
                        sort_aliases ( );
                    } else
                        rterror ("too many aliases");
                }
                break;
            }

            line_num ++;
            return 1;
        }



    /* Parse the unalias command. */

    if (!strncmp (line, "unalias", 7))
        if (!line [7] || isspace (line [7])) {
            if (sscanf (line, "%*s%s", alias) == 1)
                for (i = 0; i < num_aliases; i ++)
                    if (!strcmp (aliases .alias_name, alias)) {
                        free (aliases .alias_name);
                        free (aliases .real_name);
                        aliases = aliases [-- num_aliases];
                        sort_aliases ( );
                    }

            line_num ++;
            return 1;
        }


    /* Not a special command. */

    return 0;
}


/************************************************************************
* Function:        expand_alias                                                *
*                                                                        *
* Description:        Expands an alias in the specified text string.  If the        *
*                readline library is used then history expansion                *
*                characters work as in csh.                                *
************************************************************************/

static char *expand_alias (text)
    char *text;
{
    int   i;
    int   length;
    int   result;
    char *alias;
    char *expanded;

# ifndef READLINE
    static char temp   [2048];
    static char buffer [2048];
# endif


    for (i = 0; i < num_aliases; i ++)
        aliases .expanded = 0;

    for (i = 0; i < num_aliases; i ++) {
        alias = aliases .alias_name;
        length = strlen (alias);

        if (!strncmp (text, alias, length) && !aliases .expanded)
            if (!text [length] || isspace (text [length])) {
                aliases .expanded = 1;

# ifdef READLINE
                result = history_expand (aliases .real_name, &expanded);
                if (result < 0 || result == 2) {
                    rterror ("%s", expanded);
                    free (expanded);
                    break;
                } else {
                    free (text);
                    text = expanded;
                    i = 0;
                    continue;
                }

# else /* READLINE */

                if (text [strlen (text) - 1] == '\n')
                    text [strlen (text) - 1] = 0;

                sprintf (temp, aliases .real_name, text + length + 1);
                strcpy (buffer, temp);
                text = buffer;
                expanded = NULL;
                result = 0;
                i = 0;
                continue;

# endif /* READLINE */
            }
    }

    return text;
}


/************************************************************************
* Function:        init_interactive                                        *
*                                                                        *
* Description:        Initializes the state for interactive mode.                *
************************************************************************/

void init_interactive (argv0, s_file, q_flag, a_flag)
    char *argv0;
    char *s_file;
    int   q_flag;
    int   a_flag;
{
    int i;


# ifdef READLINE

    char *ptr;

    ptr = (ptr = strrchr (argv0, '/')) ? ptr + 1 : argv0;

    using_history ( );
    rl_readline_name = ptr;
    rl_completion_entry_function = (Function *) completion_generator;
    rl_special_prefixes = "&";

# endif /* READLINE */


    if (!q_flag)
        printf ("%s", start_up_message);

    if (!a_flag) {
        num_aliases = NumDefaults;
        for (i = 0; i < NumDefaults; i ++) {
            aliases .alias_name = Strdup (default_aliases .alias_name);
            aliases .real_name = Strdup (default_aliases .real_name);
        }
    }


    if (s_file) {
# ifdef READLINE
        if ((rl_instream = fopen (s_file, "r"))) {
            rl_outstream = fopen ("/dev/null", "w");
            bfinclude (NULL);
            fclose (rl_instream);
            fclose (rl_outstream);
        }
        rl_instream = stdin;
        rl_outstream = stdout;
# else
        if ((stream = fopen (s_file, "r"))) {
            bfinclude (NULL);
            fclose (stream);
        }
        stream = stdin;
# endif
    }
}


/************************************************************************
* Function:        readchar                                                *
*                                                                        *
* Description:        Reads and returns the next character from the standard        *
*                input stream using either getchar() or readline().        *
************************************************************************/

int readchar ( )
{
# ifdef READLINE
    int   result;
    char *expansion;
    char  buffer [2048];
    HIST_ENTRY *entry;

    static char *ptr;
    static char *line;
    static char  prompt [32];
    static int   last_line;


    if (ptr && *ptr)
        return *ptr ++;

    if (line) {
        free (line);
        line = ptr = NULL;
        last_line = line_num;
        return '\n';
    }

    sprintf (prompt, last_line == line_num ? CONTINUATION : PROMPT, line_num);

    while ((line = readline (prompt))) {
        if (*line) {
            if (parse_alias (line)) {
                add_history (line);
                sprintf (prompt, last_line == line_num ? CONTINUATION : PROMPT, line_num);
                continue;
            }

            if ((result = history_expand (line, &expansion)))
                printf ("%s\n", expansion);

            if (result < 0 || result == 2) {
                free (expansion);
                free (line);
                line = NULL;
            } else {
                free (line);

                if (last_line == line_num) {
                    entry = remove_history (where_history ( ) - 1);
                    sprintf (buffer, "%s %s", entry -> line, expansion);
                    add_history (buffer);
                    free (entry -> line);
                    free (entry);

                } else {
                    add_history (expansion);
                    expansion = expand_alias (expansion);
                }

                ptr = line = expansion;
                return *ptr ++;
            }
        }
    }

# else /* READLINE */

    static char *ptr;
    static char *expansion;
    static char  line [2048];
    static int   last_line;


    if (ptr && *ptr && *ptr != '\n')
        return *ptr ++;

    if (ptr) {
        ptr = NULL;
        last_line = line_num;
        return '\n';
    }

    ptr = NULL;

    if (stream == stdin)
        printf (last_line == line_num ? CONTINUATION : PROMPT, line_num);

    while (fgets (line, sizeof (line), stream)) {
        if (parse_alias (line)) {
            if (stream == stdin)
                printf (last_line == line_num ? CONTINUATION : PROMPT, line_num);
            continue;
        }

        expansion = expand_alias (line);

        if (*expansion && *expansion != '\n') {
            ptr = expansion;
            return *ptr ++;
        }

        if (stream == stdin)
            printf (last_line == line_num ? CONTINUATION : PROMPT, line_num);
    }
# endif /* READLINE */

    return 0;
}


/************************************************************************
* Function:        print_history                                                *
*                                                                        *
* Description:        Prints the last elements of the history list.                *
************************************************************************/

int print_history (n)
    int n;
{
# ifdef READLINE
    int                 i;
    int                 j;
    HIST_ENTRY **list;


    if ((list = history_list ( ))) {
        i = n ? history_length - n : 0;
        for (i = i < 0 ? 0 : i, j = 0; list ; i ++, j ++)
            printf ("%3d  %s\n", i + history_base, list -> line);

        return j;
    }

# endif /* READLINE */

    return 0;
}
发表于 2004-1-24 17:52:00 | 显示全部楼层
把81行的FILE stdin去掉,我刚也看了,stdin在stdio.h中被定义了
 楼主| 发表于 2004-1-25 09:21:39 | 显示全部楼层
solution:

stdin is not a constant !

In ANSI C, it's forbidden to declare a variable with non constant(for exemple : `` int a = b; '' : only constants `` int a = 3; ''.

To resolve your problem, let's do :

        static FILE *stream = -1;
        ...
        if(stream == -1) stream = stdin;
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表