find.c

来自「具有IDE功能的编辑器」· C语言 代码 · 共 480 行

C
480
字号
/* find.c - find files as a front end to find ... -exec grep ...   Copyright (C) 1996-2000 Paul Sheer   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., 59 Temple Place, Suite 330, Boston, MA   02111-1307, USA. */#include <config.h>#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <sys/types.h>#if HAVE_SYS_WAIT_H#include <sys/wait.h>#endif#include <X11/Xlib.h>#include <X11/Xutil.h>#include <X11/Xatom.h>#include "lkeysym.h"#include "stringtools.h"#include "coolwidget.h"#include "edit.h"#include "editcmddef.h"#include "loadfile.h"#include "editoptions.h"#include "cmdlineopt.h"#include "shell.h"#if HAVE_DIRENT_H#include <dirent.h>#define NAMLEN(dirent) strlen((dirent)->d_name)#else#define dirent direct#define NAMLEN(dirent) (dirent)->d_namlen#if HAVE_SYS_NDIR_H#include <sys/ndir.h>#endif#if HAVE_SYS_DIR_H#include <sys/dir.h>#endif#if HAVE_NDIR_H#include <ndir.h>#endif#endif#include "find.h"#include "mad.h"#define MID_X 20#define MID_Y 20int execute_background_display_output (char *title, char *s, char *name);Window find_mapped_window (Window w);int CInputsWithOptions (Window parent, int x, int y, char *heading, \	    char **inputs[], char *input_labels[], char *input_names[], \    char *input_tool_hint[], int *check_values[], char *check_labels[], \			char *check_tool_hints[], int options, int width){    char *f = 0;    Window win;    XEvent xev;    CEvent cev;    CState s;    int xh, yh, h, ys;    int k, labels_in_column, cancel = 0;    CBackupState (&s);    CDisable ("*");    if (options & INPUTS_WITH_OPTIONS_FREE_STRINGS)	for (k = 0; inputs[k]; k++)	    if (!*inputs[k])		*inputs[k] = (char *) strdup ("");    if (!parent) {	x = MID_X;	y = MID_Y;    }    parent = find_mapped_window (parent);    win = CDrawHeadedDialog ("_IWO", parent, x, y, heading);    CIdent ("_IWO")->position = WINDOW_ALWAYS_RAISED;    CGetHintPos (&xh, 0);    for (k = 0; inputs[k] && input_labels[k] && input_names[k]; k++) {	char *hot, id[32] = "_IWO.t.x", *l, *last;	l = (char *) strdup (_ (input_labels[k]));	hot = strchr (l, '&');	if (!hot)	    hot = "";	else {	    strcpy (hot, hot + 1);	}	id[7] = 'A' + k;	CGetHintPos (0, &yh);	(CDrawText (id, win, xh, yh, _ (l)))->hotkey = *hot;	free (l);	CGetHintPos (0, &yh);	last = CLastInput (input_names[k]);	if (!*last || input_names[k][0] == '~')	    last = *inputs[k];	if ((options & (INPUTS_WITH_OPTIONS_BROWSE_LOAD << k)) || (options & (INPUTS_WITH_OPTIONS_BROWSE_SAVE << k)) || (options & (INPUTS_WITH_OPTIONS_BROWSE_DIR << k))) {	    int xt;	    char bi[33];	    (CDrawTextInput (input_names[k], win, xh, yh, FONT_MEAN_WIDTH * width - WIDGET_SPACING - 8 - CImageTextWidth (_ (" Browse... "), 11), AUTO_HEIGHT, 256, last))->hotkey = *hot;	    CGetHintPos (&xt, 0);	    if (options & (INPUTS_WITH_OPTIONS_BROWSE_LOAD << k))		sprintf (bi, "%s.bl", input_names[k]);	    else if (options & (INPUTS_WITH_OPTIONS_BROWSE_SAVE << k))		sprintf (bi, "%s.bs", input_names[k]);	    else		sprintf (bi, "%s.bd", input_names[k]);	    CDrawButton (bi, win, xt, yh, AUTO_SIZE, _ (" Browse... "));	} else {	    (CDrawTextInput (input_names[k], win, xh, yh, FONT_MEAN_WIDTH * width, AUTO_HEIGHT, 256, last))->hotkey = *hot;	}	if (input_tool_hint) {	    CSetToolHint (id, _ (input_tool_hint[k]));	    CSetToolHint (input_names[k], _ (input_tool_hint[k]));	}    }    for (k = 0; check_values[k] && check_labels[k]; k++);    labels_in_column = (k + 1) / 2;    CGetHintPos (0, &ys);/* The following are check boxes */    get_hint_limits (&x, &y);    h = 0;    for (k = 0; check_values[k] && check_labels[k]; k++) {	char id[32] = "_IWO.c.x";	id[7] = 'A' + k;	CGetHintPos (0, &yh);	if (k == labels_in_column)	    yh = ys;	CDrawSwitch (id, win, xh + ((k >= labels_in_column) ? x / 2 : 0), yh, *check_values[k], _ (check_labels[k]), 0);	if (check_tool_hints) {	    CSetToolHint (id, _ (check_tool_hints[k]));	    strcat (id, ".label");	    CSetToolHint (id, _ (check_tool_hints[k]));	    id[8] = '\0';	}    }    get_hint_limits (&x, &yh);    CDrawPixmapButton ("_IWO.ok", win, x / 3 - TICK_BUTTON_WIDTH / 2, yh, PIXMAP_BUTTON_TICK);    CSetToolHint ("_IWO.ok", _ ("Execute, Enter"));    CDrawPixmapButton ("_IWO.cancel", win, 2 * x / 3 - TICK_BUTTON_WIDTH / 2, yh, PIXMAP_BUTTON_CROSS);    CSetToolHint ("_IWO.cancel", _ ("Abort this dialog, Esc"));    CSetSizeHintPos ("_IWO");    CMapDialog ("_IWO");    if (CIdent (input_names[0]))	CFocus (CIdent (input_names[0]));    for (;;) {	CNextEvent (&xev, &cev);	if (!CIdent ("_IWO")) {	    cancel = 1;	    break;	}	if (!strcmp (cev.ident, "_IWO.cancel") || cev.command == CK_Cancel) {	    cancel = 1;	    break;	}	if (!strcmp (cev.ident, "_IWO.ok") || cev.command == CK_Enter) {	    for (k = 0; inputs[k] && input_labels[k] && input_names[k]; k++) {		if (options & INPUTS_WITH_OPTIONS_FREE_STRINGS) {		    if (*inputs[k])			free (*inputs[k]);		    *inputs[k] = (char *) strdup (CIdent (input_names[k])->text);		    if (!(*inputs[k])[0]) {			free (*inputs[k]);			*inputs[k] = 0;		    }		} else		    *inputs[k] = (char *) strdup (CIdent (input_names[k])->text);	    }	    for (k = 0; check_values[k] && check_labels[k]; k++) {		char id[32] = "_IWO.c.x";		id[7] = 'A' + k;		*check_values[k] = CIdent (id)->keypressed;	    }	    break;	}	if (!strcmp (cev.ident + strlen (cev.ident) - 3, ".bl")) {	/* FIXME: possible segfault with short ident name */	    f = CGetLoadFile (parent, 20, 20, current_dir, "", _ (" Browse l"));	    goto there;	}	if (!strcmp (cev.ident + strlen (cev.ident) - 3, ".bs")) {	/* FIXME: possible segfault with short ident name */	    f = CGetSaveFile (parent, 20, 20, current_dir, "", _ (" Browse "));	    goto there;	}	if (!strcmp (cev.ident + strlen (cev.ident) - 3, ".bd")) {	/* FIXME: possible segfault with short ident name */	    f = CGetDirectory (parent, 20, 20, current_dir, "", _ (" Browse "));	  there:	    if (f)		if (*f) {		    CWidget *ttw;		    char tt[33];		    strcpy (tt, cev.ident);		    tt[strlen (tt) - 3] = '\0';		    ttw = CIdent (tt);		    if (ttw->text)			free (ttw->text);		    ttw->text = f;		    ttw->cursor = strlen (f);		    CExpose (tt);		    CFocus (ttw);		}	}    }    CDestroyWidget ("_IWO");    CRestoreState (&s);    if (options & INPUTS_WITH_OPTIONS_FREE_STRINGS)	for (k = 0; inputs[k]; k++)	    if (*inputs[k])		if (cancel || !(*inputs[k])[0]) {		    free (*inputs[k]);		    *inputs[k] = 0;		}    return cancel;}void find_file (void){    char s[4096] = "#!/bin/sh\n";    char *inputs[10] =    {	gettext_noop ("."),	gettext_noop ("*"),	gettext_noop (""),	0    };    char *input_labels[10] =    {	gettext_noop ("&Starting directory"),	gettext_noop ("Filenames matching &glob expression"),	gettext_noop ("&Containing"),	0    };    char *check_labels[10] =    {	gettext_noop ("Containing reg. exp."),	gettext_noop ("Containing case insens."),	gettext_noop ("Search follows symlinks"),	gettext_noop ("Search is case insens."),	0    };    char *check_tool_hints[10] =    {    gettext_noop ("Enter regular expression pattern to find within file"),    gettext_noop ("Match case insensitively when searching within files"),	gettext_noop ("Dive into symlinks to directories"),	gettext_noop ("Filenames are matched case insensitively"),	0    };    char *input_names[10] =    {	gettext_noop ("find-start_dir"),	gettext_noop ("find-glob_express"),	gettext_noop ("find-containing"),	0    };    char *input_tool_hint[10] =    {	gettext_noop ("Starting directory for the recursive search"),	gettext_noop ("Find files that match glob expressions such as *.[ch] or *.doc"),	gettext_noop ("Check if file contains this sequence\n(don't forget that you can match whole words eg. \\<the\\>)"),	0    };    static int checks_values[10] =    {	0, 0, 0, 0, 0    };    int *checks_values_result[10];    char **inputs_result[10];    int r;    inputs_result[0] = &inputs[0];    inputs_result[1] = &inputs[1];    inputs_result[2] = &inputs[2];    inputs_result[3] = &inputs[3];    inputs_result[4] = 0;    checks_values_result[0] = &checks_values[0];    checks_values_result[1] = &checks_values[1];    checks_values_result[2] = &checks_values[2];    checks_values_result[3] = &checks_values[3];    checks_values_result[4] = 0;    r = CInputsWithOptions (0, 0, 0, _ ("Find File"), inputs_result, input_labels, input_names, input_tool_hint, checks_values_result, check_labels, check_tool_hints, INPUTS_WITH_OPTIONS_BROWSE_DIR_1, 60);    if (r)	return;    strcat (s, "find ");    strcat (s, inputs[0]);    if (checks_values[2])	strcat (s, " -follow");    strcat (s, " -type f ");    if (inputs[1][0]) {	if (checks_values[3]) {	    strcat (s, "-iname '");	    strcat (s, inputs[1]);	} else {	    strcat (s, "-name '");	    strcat (s, inputs[1]);	}	strcat (s, "' ");    } else {	strcat (s, "-name '*' ");	/* needed for non-GNU find commands */    }    if (inputs[2][0]) {	strcat (s, "-exec ");	if (checks_values[0]) {	    strcat (s, "grep -s -n ");	} else {	    strcat (s, "fgrep -s -n ");	}	if (checks_values[1])	    strcat (s, "-i ");	if (inputs[2][0] == '-')	    strcat (s, "-e ");	strcat (s, "'");	strcat (s, inputs[2]);	strcat (s, "' 'Not any such file here at all' {} \\; ");    }    strcat (s, "\necho Done\n");    if (inputs[0])	free (inputs[0]);    if (inputs[1])	free (inputs[1]);    if (inputs[2])	free (inputs[2]);    execute_background_display_output (_ (" Find File "), s, "FindfIlEmAgiC");}void ctags (void){    char s[4096] = "#!/bin/sh\n";    char types[20] = "";    char *inputs[20] =    {	gettext_noop ("."),	gettext_noop ("*"),	gettext_noop (""),	0    };    char *input_labels[20] =    {	gettext_noop ("&Starting directory"),	gettext_noop ("Filenames matching &glob expression"),	gettext_noop ("&Extra arguments"),	0    };    char *check_labels[20] =    {	gettext_noop ("Recursive search"),	gettext_noop ("Classes"),	gettext_noop ("Macro definitions"),	gettext_noop ("Enumerators"),	gettext_noop ("Dunction definitions"),	gettext_noop ("Enumeration names"),	gettext_noop ("class and struct members"),	gettext_noop ("Namespaces"),	gettext_noop ("Function prototypes"),	gettext_noop ("Structure name"),	gettext_noop ("Typedefs"),	gettext_noop ("Union names"),	gettext_noop ("Variable definitions"),	gettext_noop ("Extern and forward defs"),	0    };    char *check_tool_hints[20] =    {      gettext_noop ("Dive into subdirectories to look for source files"),	gettext_noop ("Find classes"),	gettext_noop ("Find definitions (and #undef names)"),	gettext_noop ("Find enumerators"),	gettext_noop ("Find definitions"),	gettext_noop ("Find numeration names"),	gettext_noop ("Find class, struct or union members"),	gettext_noop ("Find namespaces"),	gettext_noop ("Find function prototypes and declarations"),	gettext_noop ("Find structure names"),	gettext_noop ("Find typedefs"),	gettext_noop ("Find union names"),	gettext_noop ("Find variable definitions"),	gettext_noop ("Find extern and forward variable declarations"),	0    };    char *input_names[20] =    {	gettext_noop ("ctags-start_dir"),	gettext_noop ("ctags-glob_express"),	gettext_noop ("ctags-extra"),	0    };    char *input_tool_hint[20] =    {	gettext_noop ("Starting directory for recursive search"),	gettext_noop ("Find files that match glob expressions\nsuch as *.[ch] or *.cc (default - autodetect)"),	gettext_noop ("Extra arguments to pass to ctags - see ctags(1)"),	0    };    static int checks_values[20] =    {	1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0    };    int *checks_values_result[20];    char **inputs_result[20];    int i, k, r;    inputs_result[0] = &inputs[0];    inputs_result[1] = &inputs[1];    inputs_result[2] = &inputs[2];    inputs_result[3] = &inputs[3];    inputs_result[4] = 0;    checks_values_result[0] = &checks_values[0];    checks_values_result[1] = &checks_values[1];    checks_values_result[2] = &checks_values[2];    checks_values_result[3] = &checks_values[3];    checks_values_result[4] = &checks_values[4];    checks_values_result[5] = &checks_values[5];    checks_values_result[6] = &checks_values[6];    checks_values_result[7] = &checks_values[7];    checks_values_result[8] = &checks_values[8];    checks_values_result[9] = &checks_values[9];    checks_values_result[10] = &checks_values[10];    checks_values_result[11] = &checks_values[11];    checks_values_result[12] = &checks_values[12];    checks_values_result[13] = &checks_values[13];    checks_values_result[14] = 0;    r = CInputsWithOptions (0, 0, 0, _ ("Ctags Index"), inputs_result, input_labels, input_names, input_tool_hint, checks_values_result, check_labels, check_tool_hints, INPUTS_WITH_OPTIONS_BROWSE_DIR_1, 60);    if (r)	return;    for (k = 0, i = 0; i < 13; i++) {	types[k] = ("cdefgmnpstuvx")[i];	if (checks_values[i + 1])	    k++;    }    types[k] = '\0';    if (!strlen (types)) {	CMessageDialog (0, 20, 20, 0, _ ("Ctags Index"), _ ("You must specify at least one type to search for."));	return;    } else if (checks_values[0]) {	sprintf (s, "find %s -name '%s' | ctags %s --c-types=%s -x -f - -L - | awk '{ print $1 \" \" $2 \" \" $4 \":\" $3  }'\necho Done\n", \		 inputs[0], inputs[1] ? (*inputs[1] ? inputs[1] : "*") : "*", inputs[2], types);    } else {	sprintf (s, "ctags %s --c-types=%s -x -f - %s/%s | awk '{ print $1 \" \" $2 \" \" $4 \":\" $3  }'\necho Done\n", \		 inputs[2], types, inputs[0], inputs[1] ? (*inputs[1] ? inputs[1] : "*") : "*");    }    if (inputs[0])	free (inputs[0]);    if (inputs[1])	free (inputs[1]);    if (inputs[2])	free (inputs[2]);    execute_background_display_output (_ (" Ctags Output "), s, "FindTagSmAgiC");}

⌨️ 快捷键说明

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