#include "globals.h"
#include "vendor.h"
#define SEARCHARGS 10
static FILE * DoManualSearch(ManpageGlobals *man_globals, char * string);
static int BEntrySearch(char * string, char ** first, int number);
void
MakeSearchWidget(ManpageGlobals * man_globals, Widget parent)
{
Widget dialog, command, text, cancel;
Arg arglist[2];
Cardinal num_args = 0;
XtSetArg(arglist[0], XtNtransientFor, parent);
man_globals->search_widget = XtCreatePopupShell(SEARCHNAME,
transientShellWidgetClass,
parent,
arglist, 1);
if (resources.clear_search_string) {
XtSetArg(arglist[0], XtNvalue, ""); num_args++;
}
dialog = XtCreateManagedWidget(DIALOG, dialogWidgetClass,
man_globals->search_widget,
arglist, num_args);
if ( (text = XtNameToWidget(dialog, "value")) == (Widget) NULL)
PopupWarning(NULL, "Could not find text widget in MakeSearchWidget.");
else
XtSetKeyboardFocus(dialog, text);
XawDialogAddButton(dialog, MANUALSEARCH, NULL, NULL);
XawDialogAddButton(dialog, APROPOSSEARCH, NULL, NULL);
XawDialogAddButton(dialog, CANCEL, NULL, NULL);
if ( ((command = XtNameToWidget(dialog, MANUALSEARCH)) == (Widget) NULL) ||
((cancel = XtNameToWidget(dialog, CANCEL)) == (Widget) NULL) )
PopupWarning(NULL,
"Could not find manual search widget in MakeSearchWidget.");
else {
static char * half_size[] = {
MANUALSEARCH, APROPOSSEARCH, NULL
};
static char * full_size[] = {
"label", "value", CANCEL, NULL
};
num_args = 0;
XtSetArg(arglist[num_args], XtNfromVert, command); num_args++;
XtSetArg(arglist[num_args], XtNfromHoriz, NULL); num_args++;
XtSetValues(cancel, arglist, num_args);
FormUpWidgets(dialog, full_size, half_size);
}
}
static char *
SearchString(
ManpageGlobals * man_globals)
{
Widget dialog;
dialog = XtNameToWidget(man_globals->search_widget, DIALOG);
if (dialog != NULL)
return(XawDialogGetValueString(dialog));
PopupWarning(man_globals,
"Could not get the search string, no search will be preformed.");
return(NULL);
}
#define LOOKLINES 6
FILE *
DoSearch(ManpageGlobals * man_globals, int type)
{
char cmdbuf[BUFSIZ],*mantmp, *manpath;
char tmp[BUFSIZ],path[BUFSIZ];
char string_buf[BUFSIZ], cmp_str[BUFSIZ], error_buf[BUFSIZ];
char * search_string = SearchString(man_globals);
FILE * file;
#ifdef HAS_MKSTEMP
int fd;
#endif
int count;
Boolean flag;
if (search_string == NULL) return(NULL);
if ( streq(search_string,"") ) {
PopupWarning(man_globals, "Search string is empty.");
return(NULL);
}
if (strlen(search_string) >= BUFSIZ) {
PopupWarning(man_globals, "Search string too long.");
return(NULL);
}
if (search_string[0] == ' ') {
PopupWarning(man_globals, "First character cannot be a space.");
return(NULL);
}
if (type == APROPOS) {
char label[BUFSIZ];
strcpy(tmp, MANTEMP);
#ifdef HAS_MKSTEMP
fd = mkstemp(tmp);
if (fd < 0) {
PopupWarning(man_globals, "Cant create temp file");
return NULL;
}
#else
(void)mktemp(tmp);
#endif
mantmp = tmp;
manpath=getenv("MANPATH");
if (manpath == NULL || streq(manpath,"") ) {
#ifdef MANCONF
if (!ReadManConfig(path))
#endif
{
strcpy(path,SYSMANPATH);
#ifdef LOCALMANPATH
strcat(path,":");
strcat(path,LOCALMANPATH);
#endif
}
} else {
strcpy(path,manpath);
}
snprintf(label, sizeof(label),
"Results of apropos search on: %s", search_string);
#ifdef NO_MANPATH_SUPPORT
snprintf(cmdbuf, sizeof(cmdbuf), APROPOS_FORMAT, search_string, mantmp);
#else
snprintf(cmdbuf, sizeof(cmdbuf), APROPOS_FORMAT, path, search_string, mantmp);
#endif
if(system(cmdbuf) != 0) {
snprintf(error_buf, sizeof(error_buf), "Something went wrong trying to run %s\n",cmdbuf);
PopupWarning(man_globals, error_buf);
}
#ifdef HAS_MKSTEMP
if ((file = fdopen(fd, "r")) == NULL)
#else
if((file = fopen(mantmp,"r")) == NULL)
#endif
PrintError("lost temp file? out of temp space?");
unlink(mantmp);
snprintf(string_buf, sizeof(string_buf), "%s: nothing appropriate", search_string);
count = 0;
flag = FALSE;
while ( (fgets(cmp_str, BUFSIZ, file) != NULL) && (count < LOOKLINES) ) {
if ( cmp_str[strlen(cmp_str) - 1] == '\n')
cmp_str[strlen(cmp_str) - 1] = '\0';
if (streq(cmp_str, string_buf)) {
flag = TRUE;
break;
}
count++;
}
if (flag) {
fclose(file);
file = NULL;
ChangeLabel(man_globals->label,string_buf);
return(NULL);
}
snprintf(man_globals->manpage_title, sizeof(man_globals->manpage_title),
"%s", label);
ChangeLabel(man_globals->label,label);
fseek(file, 0L, SEEK_SET);
}
else {
file = DoManualSearch(man_globals, search_string);
if (file == NULL) {
snprintf(string_buf, sizeof(string_buf), "No manual entry for %s.", search_string);
ChangeLabel(man_globals->label, string_buf);
if (man_globals->label == NULL)
PopupWarning(man_globals, string_buf);
return(NULL);
}
}
if (resources.clear_search_string) {
Arg arglist[1];
Widget dialog;
dialog = XtNameToWidget(man_globals->search_widget, DIALOG);
if (dialog == NULL)
PopupWarning(man_globals, "Could not clear the search string.");
XtSetArg(arglist[0], XtNvalue, "");
XtSetValues(dialog, arglist, (Cardinal) 1);
}
return(file);
}
#define NO_ENTRY -100
static FILE *
DoManualSearch(ManpageGlobals *man_globals, char * string)
{
int e_num = NO_ENTRY;
int i;
i = man_globals->current_directory;
e_num = BEntrySearch(string, manual[i].entries, manual[i].nentries);
if (e_num == NO_ENTRY) {
i = 0;
while ( TRUE ) {
if (i == man_globals->current_directory)
if (++i >= sections) return(NULL);
e_num = BEntrySearch(string, manual[i].entries, manual[i].nentries);
if (e_num != NO_ENTRY) break;
if (++i >= sections) return(NULL);
}
if ( man_globals->manpagewidgets.box != NULL)
XawListUnhighlight(
man_globals->manpagewidgets.box[man_globals->current_directory]);
}
else {
if ( man_globals->manpagewidgets.box != NULL)
XawListHighlight(man_globals->manpagewidgets.box[i], e_num);
}
return(FindManualFile(man_globals, i, e_num));
}
static int
BEntrySearch(
char * string,
char ** first,
int number)
{
int check, cmp, len_cmp, global_number;
char *head, *tail;
global_number = 0;
while (TRUE) {
if (number == 0) {
return(NO_ENTRY);
}
check = number/2;
head = rindex(first[ global_number + check ], '/');
if (head == NULL)
PrintError("index failure in BEntrySearch");
head++;
tail = rindex(head, '.');
if (tail == NULL)
tail = head + strlen(head);
cmp = strncmp(string, head, (tail - head));
len_cmp = strlen(string) - (int) (tail - head);
if ( cmp == 0 && len_cmp == 0) {
return(global_number + check);
}
else if ( cmp < 0 || ((cmp == 0) && (len_cmp < 0)) )
number = check;
else {
global_number += (check + 1);
number -= ( check + 1 );
}
}
}