39 |
#ifdef HAVE_UNISTD_H |
#ifdef HAVE_UNISTD_H |
40 |
#include <unistd.h> |
#include <unistd.h> |
41 |
#endif |
#endif |
42 |
|
#ifdef HAVE_LIMITS_H |
43 |
|
#include <limits.h> |
44 |
|
#endif |
45 |
#include "getopt.h" |
#include "getopt.h" |
46 |
|
|
47 |
#include "global.h" |
#include "global.h" |
60 |
void grep(const char *); |
void grep(const char *); |
61 |
void pathlist(const char *, const char *); |
void pathlist(const char *, const char *); |
62 |
void parsefile(int, char **, const char *, const char *, const char *, int); |
void parsefile(int, char **, const char *, const char *, const char *, int); |
63 |
|
static int exec_parser(const char *, const char *, const char *, const char *, FILE *); |
64 |
void printtag(FILE *, const char *); |
void printtag(FILE *, const char *); |
65 |
int search(const char *, const char *, const char *, int); |
int search(const char *, const char *, const char *, int); |
66 |
int includepath(const char *, const char *); |
int includepath(const char *, const char *); |
96 |
int debug; |
int debug; |
97 |
const char *extra_options; |
const char *extra_options; |
98 |
|
|
99 |
|
extern char **environ; |
100 |
|
|
101 |
static void |
static void |
102 |
usage(void) |
usage(void) |
103 |
{ |
{ |
907 |
int db; |
int db; |
908 |
{ |
{ |
909 |
char buf[MAXPATHLEN+1], *path; |
char buf[MAXPATHLEN+1], *path; |
910 |
const char *p; |
FILE *op; |
|
FILE *ip, *op; |
|
911 |
const char *parser, *av; |
const char *parser, *av; |
912 |
int count; |
int count; |
913 |
STRBUF *sb = strbuf_open(0); |
STRBUF *sb = strbuf_open(0); |
914 |
STRBUF *com = strbuf_open(0); |
STRBUF *path_list = strbuf_open(MAXPATHLEN); |
915 |
STRBUF *ib = strbuf_open(MAXBUFLEN); |
int path_list_max; |
916 |
|
int force_processing_one_file; |
917 |
|
char **e; |
918 |
|
|
919 |
/* |
/* |
920 |
* teach parser where is dbpath. |
* teach parser where is dbpath. |
928 |
die("cannot get parser for %s.", dbname(db)); |
die("cannot get parser for %s.", dbname(db)); |
929 |
parser = strbuf_value(sb); |
parser = strbuf_value(sb); |
930 |
|
|
931 |
|
/* |
932 |
|
* determine the maximum length of the list of paths. |
933 |
|
*/ |
934 |
|
#if !defined(ARG_MAX) && defined(_SC_ARG_MAX) |
935 |
|
#define ARG_MAX sysconf(_SC_ARG_MAX) |
936 |
|
#endif |
937 |
|
#ifdef ARG_MAX |
938 |
|
path_list_max = ARG_MAX; |
939 |
|
path_list_max -= 2048; |
940 |
|
if (path_list_max > 20 * 1024) |
941 |
|
path_list_max = 20 * 1024; |
942 |
|
for (e = environ; *e != NULL; e++) |
943 |
|
path_list_max -= strlen(*e) + 1; |
944 |
|
path_list_max -= strlen(parser); |
945 |
|
path_list_max -= 40; |
946 |
|
force_processing_one_file = (path_list_max <= 0); |
947 |
|
#else |
948 |
|
path_list_max = 0; |
949 |
|
force_processing_one_file = 1; |
950 |
|
#endif |
951 |
|
|
952 |
if (!(op = openfilter())) |
if (!(op = openfilter())) |
953 |
die("cannot open output filter."); |
die("cannot open output filter."); |
954 |
if (gpath_open(dbpath, 0, 0) < 0) |
if (gpath_open(dbpath, 0, 0) < 0) |
986 |
fprintf(stderr, "'%s' not found in GPATH.\n", path); |
fprintf(stderr, "'%s' not found in GPATH.\n", path); |
987 |
continue; |
continue; |
988 |
} |
} |
989 |
if (chdir(root) < 0) |
|
990 |
die("cannot move to '%s' directory.", root); |
if (force_processing_one_file) { |
991 |
/* |
count += exec_parser(parser, path, cwd, root, op); |
992 |
* make command line. |
continue; |
|
*/ |
|
|
strbuf_reset(com); |
|
|
makecommand(parser, path, com); |
|
|
if (debug) |
|
|
fprintf(stderr, "executing %s\n", strbuf_value(com)); |
|
|
if (!(ip = popen(strbuf_value(com), "r"))) |
|
|
die("cannot execute '%s'.", strbuf_value(com)); |
|
|
while ((p = strbuf_fgets(ib, ip, STRBUF_NOCRLF)) != NULL) { |
|
|
count++; |
|
|
printtag(op, p); |
|
993 |
} |
} |
994 |
if (pclose(ip) < 0) |
|
995 |
die("terminated abnormally."); |
if (strbuf_getlen(path_list) + 1 + strlen(path) > path_list_max) { |
996 |
if (chdir(cwd) < 0) |
count += exec_parser(parser, strbuf_value(path_list), |
997 |
die("cannot move to '%s' directory.", cwd); |
cwd, root, op); |
998 |
|
strbuf_reset(path_list); |
999 |
|
} |
1000 |
|
|
1001 |
|
if (strbuf_getlen(path_list)) |
1002 |
|
strbuf_putc(path_list, ' '); |
1003 |
|
strbuf_puts(path_list, path); |
1004 |
|
} |
1005 |
|
if (strbuf_getlen(path_list)) { |
1006 |
|
count += exec_parser(parser, strbuf_value(path_list), |
1007 |
|
cwd, root, op); |
1008 |
} |
} |
1009 |
gpath_close(); |
gpath_close(); |
1010 |
closefilter(op); |
closefilter(op); |
1011 |
strbuf_close(sb); |
strbuf_close(sb); |
1012 |
strbuf_close(com); |
strbuf_close(path_list); |
|
strbuf_close(ib); |
|
1013 |
if (vflag) { |
if (vflag) { |
1014 |
if (count == 0) |
if (count == 0) |
1015 |
fprintf(stderr, "object not found"); |
fprintf(stderr, "object not found"); |
1021 |
} |
} |
1022 |
} |
} |
1023 |
/* |
/* |
1024 |
|
* exec_parser: execute parser |
1025 |
|
* |
1026 |
|
* i) parser template of command line |
1027 |
|
* i) path_list space separated list of path |
1028 |
|
* i) cwd current directory |
1029 |
|
* i) root root directory of source tree |
1030 |
|
* i) op filter to output |
1031 |
|
* r) number of objects found |
1032 |
|
*/ |
1033 |
|
static int |
1034 |
|
exec_parser(parser, path_list, cwd, root, op) |
1035 |
|
const char *parser; |
1036 |
|
const char *path_list; |
1037 |
|
const char *cwd; |
1038 |
|
const char *root; |
1039 |
|
FILE *op; |
1040 |
|
{ |
1041 |
|
const char *p; |
1042 |
|
FILE *ip; |
1043 |
|
int count; |
1044 |
|
STRBUF *com = strbuf_open(0); |
1045 |
|
STRBUF *ib = strbuf_open(MAXBUFLEN); |
1046 |
|
|
1047 |
|
if (chdir(root) < 0) |
1048 |
|
die("cannot move to '%s' directory.", root); |
1049 |
|
/* |
1050 |
|
* make command line. |
1051 |
|
*/ |
1052 |
|
makecommand(parser, path_list, com); |
1053 |
|
if (debug) |
1054 |
|
fprintf(stderr, "executing %s\n", strbuf_value(com)); |
1055 |
|
if (!(ip = popen(strbuf_value(com), "r"))) |
1056 |
|
die("cannot execute '%s'.", strbuf_value(com)); |
1057 |
|
|
1058 |
|
count = 0; |
1059 |
|
while ((p = strbuf_fgets(ib, ip, STRBUF_NOCRLF)) != NULL) { |
1060 |
|
count++; |
1061 |
|
printtag(op, p); |
1062 |
|
} |
1063 |
|
|
1064 |
|
if (pclose(ip) < 0) |
1065 |
|
die("terminated abnormally."); |
1066 |
|
if (chdir(cwd) < 0) |
1067 |
|
die("cannot move to '%s' directory.", cwd); |
1068 |
|
|
1069 |
|
strbuf_close(com); |
1070 |
|
strbuf_close(ib); |
1071 |
|
|
1072 |
|
return count; |
1073 |
|
} |
1074 |
|
/* |
1075 |
* search: search specified function |
* search: search specified function |
1076 |
* |
* |
1077 |
* i) pattern search pattern |
* i) pattern search pattern |