⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 user.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* User Menu implementation
   Copyright (C) 1994 Miguel de Icaza, Janne Kukonlehto

   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.  */

#include <config.h>
#include <stdio.h>
#ifdef OS2_NT
#    include <io.h>
#endif
#include "tty.h"
#include <stdlib.h>	/* For free() */
#include "fs.h"
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include "mad.h"
#include "util.h"
#include "global.h"
#include "dialog.h"
#include "color.h"
#include "dir.h"
#include "panel.h"
#include "main.h"
#include "user.h"
#include "layout.h"
#include "../vfs/vfs.h"

/* For the simple listbox manager */
#include "dlg.h"
#include "widget.h"
#include "wtools.h"

#include "view.h" /* for default_* externs */

/* "$Id: user.c 15091 2005-05-07 21:24:31Z sedwards $" */

#define MAX_ENTRIES 40
#define MAX_ENTRY_LEN 60

static char *data;
static char *entries [MAX_ENTRIES];
static int max_cols;
static int menu_lines;
static int debug_flag = 0;
static int debug_error = 0;
extern char *search_string (char *, char *);

/* Formats defined:
   %%  The % character
   %f  The current file (if non-local vfs, file will be copied locally and
       %f will be full path to it).
   %p  The current file
   %d  The current working directory
   %s  "Selected files"; the tagged files if any, otherwise the current file
   %t  Tagged files
   %u  Tagged files (and they are untagged on return from expand_format)
   %view Runs the commands and pipes standard output to the view command
       if %view is directly followed by '{', a list of keywords
       ascii, hex, nroff, unformated and

   If the format letter is in uppercase, it refers to the other panel.

   With a number followed the % character you can turn quoting on (default)
   and off. For example:
       %f    quote expanded macro
       %1f   ditto
       %0f   don't quote expanded macro

   expand_format returns a memory block that must be free()d.
*/

/* Returns how many characters we should advance if %view was found */
int check_format_view (char *p)
{
    char *q = p;
    if (!strncmp (p, "view", 4)){
    	q += 4;
    	if (*q == '{'){
    	    for (q++;*q && *q != '}';q++){
    	    	if (!strncmp (q, "ascii", 5)){
    	    	    default_hex_mode = 0;
    	    	    q += 4;
    	    	} else if (!strncmp (q, "hex", 3)){
    	    	    default_hex_mode = 1;
    	    	    q += 2;
    	    	} else if (!strncmp (q, "nroff", 5)){
    	    	    default_nroff_flag = 1;
    	    	    q += 4;
    	    	} else if (!strncmp (q, "unformated", 10)){
    	    	    default_nroff_flag = 0;
    	    	    q += 9;
    	    	}
    	    }
    	    if (*q == '}')
    	    	q++;
    	}
    	return q - p;
    } else
    	return 0;
}

int check_format_cd (char *p)
{
    if (!strncmp (p, "cd", 2))
    	return 3;
    else
    	return 0;
}

/* Check if p has a "^var\{var-name\}" */
/* Returns the number of skipped characters (zero on not found) */
/* V will be set to the expanded variable name */
int check_format_var (char *p, char **v)
{
    char *q = p;
    char *var_name;
    char *value;
    char *dots;

    *v = 0;
    dots = 0;
    if (!strncmp (p, "var{", 4)){
	for (q += 4; *q && *q != '}'; q++){
	    if (*q == ':')
		dots = q+1;
	    ;
	}
	if (!*q)
	    return 0;

	if (!dots || dots == q+5){
	    message (1,
		     " Format error on file Extensions File ",
		     !dots ? " The %%var macro does not have a default "
		     :       " The %%var macros does not have a variable " );
	    return 0;
	}

	/* Copy the variable name */
	var_name = xmalloc (dots - p, "check_format_var");
	strncpy (var_name, p+4, dots-2 - (p+3));
	var_name [dots-2 - (p+3)] = 0;

	value = getenv (var_name);
	if (value){
	    *v = strdup (value);
	    return q-p;
	}
	free (var_name);
	var_name = xmalloc (q - dots + 1, "check_format_var_2");
	strncpy (var_name, dots, q - dots + 1);
	var_name [q-dots] = 0;
	*v = var_name;
	return q-p;
    }
    return 0;
}

/* strip file's extension */
char *strip_ext(char *ss)
{
    register char *s = ss;
    char *e = NULL;
    while(*s) {
        if(*s == '.') e = s;
        if(*s == PATH_SEP && e) e=NULL; /* '.' in *directory* name */
        s++;
    }
    if(e) *e = 0;
    return ss;
}

char *expand_format (char c, int quote)
{
    WPanel *panel;
    char *(*quote_func)(const char *, int);

    if (quote)
	quote_func = name_quote;
    else
	quote_func = fake_name_quote;

    if (c == '%')
	return strdup ("%");

    if (islower (c))
	panel = cpanel;
    else {
	if (get_other_type () == view_listing){
	    panel = other_panel;
	} else
	    return strdup ("");
    }
    if (!panel)
	panel = cpanel;

    c = tolower (c);

    switch (c){
    case 'f':
    case 'p': return (*quote_func) (panel->dir.list [panel->selected].fname, 0);
    case 'b':
	return strip_ext((*quote_func) (panel->dir.list [panel->selected].fname, 0));
    case 'd': return (*quote_func) (panel->cwd, 0);
    case 's':
	if (!panel->marked)
	    return (*quote_func) (panel->dir.list [panel->selected].fname, 0);

	/* Fall through */

    case 't':
    case 'u':
    {
	int length = 2, i;
	char *block, *tmp;

	for (i = 0; i < panel->count; i++)
	    if (panel->dir.list [i].f.marked)
		length += strlen (panel->dir.list [i].fname) + 1;

	block = xmalloc (length*2+1, "expand_format");
	*block = 0;
	for (i = 0; i < panel->count; i++)
	    if (panel->dir.list [i].f.marked){
		strcat (block, tmp = (*quote_func) (panel->dir.list [i].fname, 0));
		free (tmp);
		strcat (block, " ");
		if (c == 'u')
		    do_file_mark (panel, i, 0);
	    }
	return block;
    } /* sub case block */
    } /* switch */
    return strdup ("");
}

/* Checks for shell patterns defination */
char *check_patterns (char *p)
{
    const char *def_name = "shell_patterns=";
    int value;

    if (strncmp (p, def_name, sizeof (def_name)) == 0){
	p += strlen (def_name);
	value = *p++ - '0';
	if (value == 0 || value == 1)
	    easy_patterns = value;
	else
	    message (1, MSG_ERROR, _(" Invalid shell pattern defination \"%c\". "), value + '0');
    }
    while (*p == '\n' || *p == '\t' || *p == ' ') p++;
    return p;
}

/* Copies a whitespace separated argument from p to arg. Returns the
   point after argument. */
static char *extract_arg (char *p, char *arg)
{
    while (*p && (*p == ' ' || *p == '\t' || *p == '\n'))
	p++;
    while (*p && *p != ' ' && *p != '\t' && *p != '\n')
	*arg++ = *p++;
    *arg = 0;
    if (!*p || *p == '\n')
	p --;
    return p;
}

/* Tests whether the selected file in the panel is of any of the types
   specified in argument. */
static int test_type (WPanel *panel, char *arg)
{
    int result = 0; /* False by default */
    int st_mode = panel->dir.list [panel->selected].buf.st_mode;

    for (;*arg != 0; arg++){
	switch (*arg){
	case 'n':	/* Not a directory */
	    result |= !S_ISDIR (st_mode);
	    break;
	case 'r':	/* Regular file */
	    result |= S_ISREG (st_mode);
	    break;
	case 'd':	/* Directory */
	    result |= S_ISDIR (st_mode);
	    break;
	case 'l':	/* Link */
	    result |= S_ISLNK (st_mode);
	    break;
	case 'c':	/* Character special */
	    result |= S_ISCHR (st_mode);
	    break;
	case 'b':	/* Block special */
	    result |= S_ISBLK (st_mode);
	    break;
	case 'f':	/* Fifo (named pipe) */
	    result |= S_ISFIFO (st_mode);
	    break;
	case 's':	/* Socket */
	    result |= S_ISSOCK (st_mode);
	    break;
	case 'x':	/* Executable */
	    result |= (st_mode & 0111) ? 1 : 0;
	    break;
	case 't':
	    result |= panel->marked ? 1 : 0;
	    break;
	default:
	    debug_error = 1;
	    break;
	}
    }
    return result;
}

/* Calculates the truth value of the next condition starting from
   p. Returns the point after condition. */
static char *test_condition (char *p, int *condition)
{
    WPanel *panel;
    char arg [256];

    /* Handle one condition */
    for (;*p != '\n' && *p != '&' && *p != '|'; p++){
	if (*p == ' ' || *p == '\t')
	    continue;
	if (*p >= 'a')
	    panel = cpanel;
	else {
	    if (get_other_type () == view_listing)
		panel = other_panel;
	    else
		panel = NULL;
	}
	*p |= 0x20;

	switch (*p++){
	case '!':
	    p = test_condition (p, condition);
	    *condition = ! *condition;
	    p--;
	    break;
	case 'f':
	    p = extract_arg (p, arg);
	    *condition = panel && regexp_match (arg, panel->dir.list [panel->selected].fname, match_file);
	    break;
	case 'd':
	    p = extract_arg (p, arg);
	    *condition = panel && regexp_match (arg, panel->cwd, match_file);
	    break;
	case 't':
	    p = extract_arg (p, arg);
	    *condition = panel && test_type (panel, arg);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -