My Project
fehelp.cc
Go to the documentation of this file.
1/****************************************
2* Computer Algebra System SINGULAR *
3****************************************/
4/*
5* ABSTRACT: help system
6*/
7
8#include "kernel/mod2.h"
9#include "omalloc/omalloc.h"
10#include "misc/mylimits.h"
12#include "reporter/reporter.h"
14#include "reporter/si_signals.h"
15
16#include "ipid.h"
17#include "ipshell.h"
18#include "libparse.h"
19#include "feOpt.h"
20
21#include "tok.h"
22#include "fehelp.h"
23
24/*****************************************************************
25 *
26 * Declarations: Data structures
27 *
28 *****************************************************************/
29#define MAX_HE_ENTRY_LENGTH 160
30typedef struct
31{
35 long chksum;
36} heEntry_s;
38
39typedef void (*heBrowserHelpProc)(heEntry hentry, int br);
40typedef BOOLEAN (*heBrowserInitProc)(int warn, int br);
41
42typedef struct
43{
44 const char* browser;
47 const char* required;
48 const char* action;
51
52/*****************************************************************
53 *
54 * Declarations: Local functions
55 *
56 *****************************************************************/
57static char* strclean(char* str);
58static BOOLEAN heKey2Entry(char* filename, char* key, heEntry hentry);
59static int heReKey2Entry (char* filename, char* key, heEntry hentry);
60static BOOLEAN strmatch(char* s, char* re);
61static BOOLEAN heOnlineHelp(char* s);
62static void heBrowserHelp(heEntry hentry);
63static long heKeyChksum(char* key);
64
65// browser functions
66static BOOLEAN heGenInit(int,int); static void heGenHelp(heEntry hentry,int);
67 static void heBuiltinHelp(heEntry hentry,int);
68static BOOLEAN heDummyInit(int,int); static void heDummyHelp(heEntry hentry,int);
69static BOOLEAN heEmacsInit(int,int); static void heEmacsHelp(heEntry hentry,int);
70
73
74
75/*****************************************************************
76 *
77 * Definition: available help browsers
78 *
79 *****************************************************************/
80// order is important -- first possible help is chosen
81// moved to LIB/help.cnf
83
84/*****************************************************************
85 *
86 * Implementation: public function
87 *
88 *****************************************************************/
89void feHelp(char *str)
90{
91 str = strclean(str);
92 if (str == NULL) {heBrowserHelp(NULL); return;}
93
94 if (strlen(str) > MAX_HE_ENTRY_LENGTH - 2) // need room for extra **
95 str[MAX_HE_ENTRY_LENGTH - 3] = '\0';
96
97 BOOLEAN key_is_regexp = (strchr(str, '*') != NULL);
98
99
100 heEntry_s hentry;
101 memset(&hentry,0,sizeof(hentry));
102 char* idxfile = feResource('x' /*"IdxFile"*/);
103
104 // Try exact match of help string with key in index
105 if (!key_is_regexp && (idxfile != NULL) && heKey2Entry(idxfile, str, &hentry))
106 {
107 heBrowserHelp(&hentry);
108 return;
109 }
110
111 // Try to match approximately with key in index file
112 if (idxfile != NULL)
113 {
116
117 StringSetS("");
118 int found = heReKey2Entry(idxfile, str, &hentry);
119
120
121 if (found == 0)
122 {
123 // try proc help and library help
124 if (! key_is_regexp && heOnlineHelp(str)) return;
125
126 // Try to match with str*
127 char mkey[MAX_HE_ENTRY_LENGTH];
128 strcpy(mkey, str);
129 strcat(mkey, "*");
130 found = heReKey2Entry(idxfile, mkey, &hentry);
131 // Try to match with *str*
132 if (found == 0)
133 {
134 mkey[0] = '*';
135 strcpy(mkey + 1, str);
136 strcat(mkey, "*");
137 found = heReKey2Entry(idxfile, mkey, &hentry);
138 }
139
140 // Print warning and return if nothing found
141 if (found == 0)
142 {
143 Warn("No help for topic '%s' (not even for '*%s*')", str, str);
144 WarnS("Try '?;' for general help");
145 WarnS("or '?Index;' for all available help topics.");
146 return;
147 }
148 }
149
150 // do help if unique match was found
151 if (found == 1)
152 {
153 heBrowserHelp(&hentry);
154 return;
155 }
156 // Print warning about multiple matches and return
157 if (key_is_regexp)
158 Warn("No unique help for '%s'", str);
159 else
160 Warn("No help for topic '%s'", str);
161 WarnS("Try one of");
162 char *matches=StringEndS();
163 PrintS(matches);
164 omFree(matches);
165 PrintLn();
166 return;
167 }
168
169 // no idx file, let Browsers deal with it, if they can
170 strcpy(hentry.key, str);
171 *hentry.node = '\0';
172 *hentry.url = '\0';
173 hentry.chksum = 0;
174 heBrowserHelp(&hentry);
175}
176static void feBrowserFile()
177{
178 FILE *f=feFopen("help.cnf","r",NULL,TRUE);
179 int br=0;
180 if (f!=NULL)
181 {
182 char buf[512];
183 while (fgets( buf, sizeof(buf), f))
184 {
185 if ((buf[0]!='#') && (buf[0]>' ')) br++;
186 }
187 fseek(f,0,SEEK_SET);
188 // for the 4(!) default browsers
190 br = 0;
191 while (fgets( buf, sizeof(buf), f))
192 {
193 if ((buf[0]!='#') && (buf[0]>' '))
194 {
195 char *name=strtok(buf,"!");
196 char *req=strtok(NULL,"!");
197 char *cmd=strtok(NULL,"!");
198 if ((name!=NULL) && (req!=NULL) && (cmd!=NULL))
199 {
200 while ((cmd[0]!='\0') && (cmd[strlen(cmd)-1]<=' '))
201 cmd[strlen(cmd)-1]='\0';
202 //Print("name %d >>%s<<\n\treq:>>%s<<\n\tcmd:>>%s<<\n",br,name,req,cmd);
203 heHelpBrowsers[br].browser=(char *)omStrDup(name);
208 br++;
209 }
210 else
211 {
212 Print("syntax error in help.cnf, at line starting with %s\n",buf);
213 }
214 }
215 }
216 fclose(f);
217 }
218 else
219 {
220 // for the 4(!) default browsers
222 }
223 heHelpBrowsers[br].browser="builtin";
226 heHelpBrowsers[br].required="i";
227 //heHelpBrowsers[br].action=NULL;
228 br++;
229 heHelpBrowsers[br].browser="dummy";
232 //heHelpBrowsers[br].required=NULL;
233 //heHelpBrowsers[br].action=NULL;
234 br++;
235 heHelpBrowsers[br].browser="emacs";
238 //heHelpBrowsers[br].required=NULL;
239 //heHelpBrowsers[br].action=NULL;
240 //br++;
241 //heHelpBrowsers[br].browser=NULL;
242 //heHelpBrowsers[br].init_proc=NULL;
243 //heHelpBrowsers[br].help_proc=NULL;
244 //heHelpBrowsers[br].required=NULL;
245 //heHelpBrowsers[br].action=NULL;
246}
247
248const char* feHelpBrowser(char* which, int warn)
249{
250 int i = 0;
251
252 // if no argument, choose first available help browser
254 if (which == NULL || *which == '\0')
255 {
256 // return, if already set
259
260 // First, try emacs, if emacs-option is set
261 if (feOptValue(FE_OPT_EMACS) != NULL)
262 {
263 while (heHelpBrowsers[i].browser != NULL)
264 {
265 if (strcmp(heHelpBrowsers[i].browser, "emacs") == 0 &&
266 (heHelpBrowsers[i].init_proc(0,i)))
267 {
270 goto Finish;
271 }
272 i++;
273 }
274 i=0;
275 }
276 while (heHelpBrowsers[i].browser != NULL)
277 {
278 if (heHelpBrowsers[i].init_proc(0,i))
279 {
282 goto Finish;
283 }
284 i++;
285 }
286 // should never get here
287 dReportBug("should never get here");
288 }
289
290 // with argument, find matching help browser
291 while (heHelpBrowsers[i].browser != NULL &&
292 strcmp(heHelpBrowsers[i].browser, which) != 0)
293 {i++;}
294
295 if (heHelpBrowsers[i].browser == NULL)
296 {
297 if (warn) Warn("No help browser '%s' available.", which);
298 }
299 else
300 {
301 // see whether we can init it
302 if (heHelpBrowsers[i].init_proc(warn,i))
303 {
306 goto Finish;
307 }
308 }
309
310 // something went wrong
312 {
315 if (warn)
316 Warn("Setting help browser to '%s'.", heCurrentHelpBrowser->browser);
318 }
319 else
320 {
321 // or, leave as is
322 if (warn)
323 Warn("Help browser stays at '%s'.", heCurrentHelpBrowser->browser);
325 }
326
327 Finish:
328 // update value of Browser Option
329 if (feOptSpec[FE_OPT_BROWSER].value == NULL ||
330 strcmp((char*) feOptSpec[FE_OPT_BROWSER].value,
332 {
333 omfree(feOptSpec[FE_OPT_BROWSER].value);
334 feOptSpec[FE_OPT_BROWSER].value
336 }
338}
339
341{
342 int i;
343 StringAppendS("Available HelpBrowsers: ");
344
345 i = 0;
347 while (heHelpBrowsers[i].browser != NULL)
348 {
349 if (heHelpBrowsers[i].init_proc(warn,i))
350 StringAppend("%s, ", heHelpBrowsers[i].browser);
351 i++;
352 }
353 StringAppend("\nCurrent HelpBrowser: %s ", feHelpBrowser());
354}
355
356
357/*****************************************************************
358 *
359 * Implementation: local function
360 *
361 *****************************************************************/
362// Remove whitspaces from beginning and end, return NULL if only whitespaces
363static char* strclean(char* str)
364{
365 if (str == NULL) return NULL;
366 char *s=str;
367 while ((*s <= ' ') && (*s != '\0')) s++;
368 if (*s == '\0') return NULL;
369 char *ss=s;
370 while (*ss!='\0') ss++;
371 ss--;
372 while ((*ss <= ' ') && (*ss != '\0'))
373 {
374 *ss='\0';
375 ss--;
376 }
377 if (*ss == '\0') return NULL;
378 return s;
379}
380
381// Finds help entry for key:
382// returns filled-in hentry and TRUE, on success
383// FALSE, on failure
384// Assumes that lines of idx file have the following form
385// key\tnode\turl\tchksum\n (chksum ma be empty, then it is set to -1)
386// and that lines are sorted alpahbetically w.r.t. index entries
387static BOOLEAN heKey2Entry(char* filename, char* key, heEntry hentry)
388{
389 FILE* fd;
390 int c, k;
391 int kl, i;
392 *(hentry->key) = '\0';
393 *(hentry->url) = '\0';
394 *(hentry->node) = '\0';
395 hentry->chksum = 0;
396 if (filename == NULL || key == NULL) return FALSE;
397 fd = fopen(filename, "r");
398 if (fd == NULL) return FALSE;
399 kl = strlen(key);
400
401 k = key[0];
402 i = 0;
403 while ((c = getc(fd)) != EOF)
404 {
405 if (c < k)
406 {
407 /* Skip line */
408 while (getc(fd) != '\n') {};
409 if (i)
410 {
411 i=0;
412 k=key[0];
413 }
414 }
415 else if (c == k)
416 {
417 i++;
418 if (i == kl)
419 {
420 // \t must follow, otherwise only substring match
421 if (getc(fd) != '\t') goto Failure;
422
423 // Now we found an exact match
424 if (hentry->key != key) strcpy(hentry->key, key);
425 // get node
426 i = 0;
427 while ((c = getc(fd)) != '\t' && c != EOF)
428 {
429 hentry->node[i] = c;
430 i++;
431 }
432 if (c == EOF) goto Failure;
433 if (hentry->node[0]=='\0')
434 strcpy(hentry->node,hentry->key);
435
436 // get url
437 //hentry->node[i] = '\0';
438 i = 0;
439 while ((c = getc(fd)) != '\t' && c != EOF)
440 {
441 hentry->url[i] = c;
442 i++;
443 }
444 if (c == EOF) goto Failure;
445
446 // get chksum
447 hentry->url[i] = '\0';
448
449 if (si_fscanf(fd, "%ld\n", &(hentry->chksum)) != 1)
450 {
451 hentry->chksum = -1;
452 }
453 fclose(fd);
454 return TRUE;
455 }
456 else if (i > kl)
457 {
458 goto Failure;
459 }
460 else
461 {
462 k = key[i];
463 }
464 }
465 else
466 {
467 goto Failure;
468 }
469 }
470 Failure:
471 fclose(fd);
472 return FALSE;
473}
474
475// return TRUE if s matches re
476// FALSE, otherwise
477// does not distinguish lower and upper cases
478// inteprets * as wildcard
479static BOOLEAN strmatch(char* s, char* re)
480{
481 if (s == NULL || *s == '\0')
482 return (re == NULL || *re == '\0' || strcmp(re, "*") == 0);
483 if (re == NULL || *re == '\0') return FALSE;
484
485 int i;
486 char ls[MAX_HE_ENTRY_LENGTH + 1];
487 char rs[MAX_HE_ENTRY_LENGTH + 1];
488 char *l, *r, *ll, *rr;
489
490 // make everything to lower case
491 i=1;
492 ls[0] = '\0';
493 do
494 {
495 if (*s >= 'A' && *s <= 'Z') ls[i] = *s + ('a' - 'A');
496 else ls[i] = *s;
497 i++;
498 s++;
499 } while (*s != '\0');
500 ls[i] = '\0';
501 l = &(ls[1]);
502
503 i=1;
504 rs[0] = '\0';
505 do
506 {
507 if (*re >= 'A' && *re <= 'Z') rs[i]= *re + ('a' - 'A');
508 else rs[i] = *re;
509 i++;
510 re++;
511 } while (*re != '\0');
512 rs[i] = '\0';
513 r = &(rs[1]);
514
515 // chopp of exact matches from beginning and end
516 while (*r != '*' && *r != '\0' && *l != '\0')
517 {
518 if (*r != *l) return FALSE;
519 *r = '\0';
520 *s = '\0';
521 r++;
522 l++;
523 }
524 if (*r == '\0') return (*l == '\0');
525 if (*r == '*' && r[1] == '\0') return TRUE;
526 if (*l == '\0') return FALSE;
527
528 rr = &r[strlen(r) - 1];
529 ll = &l[strlen(l) - 1];
530 while (*rr != '*' && *rr != '\0' && *ll != '\0')
531 {
532 if (*rr != *ll) return FALSE;
533 *rr = '\0';
534 *ll = '\0';
535 rr--;
536 ll--;
537 }
538 if (*rr == '\0') return (*ll == '\0');
539 if (*rr == '*' && rr[-1] == '\0') return TRUE;
540 if (*ll == '\0') return FALSE;
541
542 // now *r starts with a * and ends with a *
543 r++;
544 *rr = '\0'; rr--;
545 while (*r != '\0')
546 {
547 rr = r + 1;
548 while (*rr != '*' && *rr != '\0') rr++;
549 if (*rr == '*')
550 {
551 *rr = '\0';
552 rr++;
553 }
554 l = strstr(l, r);
555 if (l == NULL) return FALSE;
556 r = rr;
557 }
558 return TRUE;
559}
560
561// similar to heKey2Entry, except that
562// key is taken as regexp (see above)
563// and number of matches is returned
564// if number of matches > 0, then hentry contains entry for first match
565// if number of matches > 1, matches are printed as komma-separated
566// into global string
567static int heReKey2Entry (char* filename, char* key, heEntry hentry)
568{
569 int i = 0;
570 FILE* fd;
571 char index_key[MAX_HE_ENTRY_LENGTH];
572
573 if (filename == NULL || key == NULL) return 0;
574 fd = fopen(filename, "r");
575 if (fd == NULL) return 0;
576 memset(index_key,0,MAX_HE_ENTRY_LENGTH);
577 while (si_fscanf(fd, "%[^\t]\t%*[^\n]\n", index_key) == 1)
578 {
579 if ((index_key[MAX_HE_ENTRY_LENGTH-1]!='\0'))
580 {
581 index_key[MAX_HE_ENTRY_LENGTH-1]='\0';
582 Werror("index file corrupt at line >>%s<<",index_key);
583 break;
584 }
585 else if (strmatch(index_key, key))
586 {
587 i++;
588 if (i == 1)
589 {
590 heKey2Entry(filename, index_key, hentry);
591 }
592 else if (i == 2)
593 {
594 StringAppend("?%s; ?%s;", hentry->key, index_key);
595 }
596 else
597 {
598 StringAppend(" ?%s;", index_key);
599 }
600 }
601 }
602 fclose(fd);
603 return i;
604}
605
606// test for h being a string and print it
607static void hePrintHelpStr(const idhdl hh,const char *id,const char *pa)
608{
609 if ((hh!=NULL) && (IDTYP(hh)==STRING_CMD))
610 {
611 PrintS(IDSTRING(hh));
612 PrintLn();
613 }
614 else
615 Print("`%s` not found in package %s\n",id,pa);
616}
617// try to find the help string as a loaded procedure or library
618// if found, display the help and return TRUE
619// otherwise, return FALSE
620static BOOLEAN heOnlineHelp(char* s)
621{
622 char *ss;
623 idhdl h;
624
625 if ((ss=strstr(s,"::"))!=NULL)
626 {
627 *ss='\0';
628 ss+=2;
629 h=ggetid(s);
630 if (h!=NULL)
631 {
632 Print("help for %s from package %s\n",ss,s);
633 char s_help[200];
634 strcpy(s_help,ss);
635 strcat(s_help,"_help");
636 idhdl hh=IDPACKAGE(h)->idroot->get(s_help,0);
637 hePrintHelpStr(hh,s_help,s);
638 return TRUE;
639 }
640 else Print("package %s not found\n",s);
641 return TRUE; /* do not search the manual */
642 }
643 h=IDROOT->get(s,myynest);
644 // try help for a procedure
645 if (h!=NULL)
646 {
647 if (IDTYP(h)==PROC_CMD)
648 {
649 char *lib=iiGetLibName(IDPROC(h));
650 if((lib!=NULL)&&(*lib!='\0'))
651 {
652 Print("// proc %s from lib %s\n",s,lib);
654 if (pi->language==LANG_SINGULAR)
655 {
657 if (s!=NULL)
658 {
659 PrintS(s);
660 omFree((ADDRESS)s);
661 }
662 return TRUE;
663 }
664 }
665 }
666 else if (IDTYP(h)==PACKAGE_CMD)
667 {
668 idhdl hh=IDPACKAGE(h)->idroot->get("info",0);
669 hePrintHelpStr(hh,"info",s);
670 return TRUE;
671 }
672 return FALSE;
673 }
674
675 // try help for a library
676 int ls = strlen(s);
677 char* str = NULL;
678 // check that it ends with "[.,_]lib"
679 if (strlen(s) >=4 && strcmp(&s[ls-3], "lib") == 0)
680 {
681 if (s[ls - 4] == '.') str = s;
682 else
683 {
684 str = omStrDup(s);
685 str[ls - 4] = '.';
686 }
687 }
688 else
689 {
690 return FALSE;
691 }
692
693 char libnamebuf[1024];
694 FILE *fp=NULL;
695 // first, search for library of that name
696 if ((str[1]!='\0') &&
698 ||
699 ((fp=feFopen(str,"rb", libnamebuf))!=NULL)))
700 {
701 EXTERN_VAR FILE *yylpin;
702 lib_style_types lib_style; // = OLD_LIBSTYLE;
703
704 yylpin = fp;
705 yylplex(str, libnamebuf, &lib_style, IDROOT, FALSE, GET_INFO);
706 reinit_yylp();
707 if(lib_style == OLD_LIBSTYLE)
708 {
709 char buf[256];
710 fseek(fp, 0, SEEK_SET);
711 Warn( "library %s has an old format. Please fix it for the next time",
712 str);
713 if (str != s) omFree(str);
715 while (fgets( buf, sizeof(buf), fp))
716 {
717 if (strncmp(buf,"//",2)==0)
718 {
719 if (found) return TRUE;
720 }
721 else if ((strncmp(buf,"proc ",5)==0)||(strncmp(buf,"LIB ",4)==0))
722 {
723 if (!found) WarnS("no help part in library found");
724 return TRUE;
725 }
726 else
727 {
728 found=TRUE;
729 PrintS(buf);
730 }
731 }
732 }
733 else
734 {
735 if (str != s) omFree(str);
736 fclose( yylpin );
740 }
741 return TRUE;
742 }
743
744 if (str != s) omFree(str);
745 return FALSE;
746}
747
748static long heKeyChksum(char* key)
749{
750 if (key == NULL || *key == '\0') return 0;
751 idhdl h=IDROOT->get(key,myynest);
752 if ((h!=NULL) && (IDTYP(h)==PROC_CMD))
753 {
754 procinfo *pi = IDPROC(h);
755 if (pi != NULL) return pi->data.s.help_chksum;
756 }
757 return 0;
758}
759
760/*****************************************************************
761 *
762 * Implementation : Help Browsers
763 *
764 *****************************************************************/
765
767
768static void heBrowserHelp(heEntry hentry)
769{
770 // check checksums of procs
771 int kchksum = (hentry != NULL && hentry->chksum > 0 ?
772 heKeyChksum(hentry->key) : 0);
773 if (kchksum && kchksum != hentry->chksum && heOnlineHelp(hentry->key))
774 return;
775
778 if (! feHelpCalled)
779 {
780 Warn("Displaying help in browser '%s'.", heCurrentHelpBrowser->browser);
781 //if (strcmp(heCurrentHelpBrowser->browser, "netscape") == 0 &&
782 // feResource('h', 0) == NULL)
783 //{
784 // Warn("Using URL '%s'.", feResource('u', 0));
785 //}
786 WarnS("Use 'system(\"--browser\", <browser>);' to change browser,");
787 StringSetS("where <browser> can be: ");
788 int i = 0;
789 i = 0;
790 while (heHelpBrowsers[i].browser != NULL)
791 {
792 if (heHelpBrowsers[i].init_proc(0,i))
793 StringAppend("\"%s\", ", heHelpBrowsers[i].browser);
794 i++;
795 }
796 char *browsers=StringEndS();
797 if (browsers[strlen(browsers)-2] == ',')
798 {
799 browsers[strlen(browsers)-2] = '.';
800 browsers[strlen(browsers)-1] = '\0';
801 }
802 WarnS(browsers);
803 omFree(browsers);
804 }
805
808}
809
810#define MAX_SYSCMD_LEN MAXPATHLEN*2
811static BOOLEAN heGenInit(int warn, int br)
812{
813 if (heHelpBrowsers[br].required==NULL) return TRUE;
814 const char *p=heHelpBrowsers[br].required;
815 while (*p>'\0')
816 {
817 switch (*p)
818 {
819 case '#': break;
820 case ' ': break;
821 case 'i': /* singular.info */
822 case 'x': /* singular.idx */
823 case 'h': /* html dir */
824 if (feResource(*p, warn) == NULL)
825 {
826 if (warn) Warn("resource `%c` not found",*p);
827 return FALSE;
828 }
829 break;
830 case 'D': /* DISPLAY */
831 if (getenv("DISPLAY") == NULL)
832 {
833 if (warn) WarnS("resource `D` not found");
834 return FALSE;
835 }
836 break;
837 case 'E': /* executable: E:xterm: */
838 case 'O': /* OS: O:ix86Mac-darwin/ppcMac-darwin: */
839 {
840 char name[128];
841 char exec[128];
842 char op=*p;
843 memset(name,0,128);
844 int i=0;
845 p++;
846 while (((*p==':')||(*p<=' ')) && (*p!='\0')) p++;
847 while((i<127) && (*p>' ') && (*p!=':'))
848 {
849 name[i]=*p; p++; i++;
850 }
851 if (i==0) return FALSE;
852
853 if ((op=='O') && (strcmp(name,S_UNAME)!=0))
854 return FALSE;
855 if ((op=='E') && (omFindExec(name,exec)==NULL))
856 {
857 if (warn) Warn("executable `%s` not found",name);
858 return FALSE;
859 }
860 }
861 break;
862 default: Warn("unknown char %c",*p);
863 break;
864 }
865 p++;
866 }
867 return TRUE;
868}
869
870static void heGenHelp(heEntry hentry, int br)
871{
872 char sys[MAX_SYSCMD_LEN];
873 const char *p=heHelpBrowsers[br].action;
874 if (p==NULL) {PrintS("no action ?\n"); return;}
875 memset(sys,0,MAX_SYSCMD_LEN);
876 int i=0;
877 while ((*p>'\0')&& (i<MAX_SYSCMD_LEN))
878 {
879 if ((*p)=='%')
880 {
881 p++;
882 switch (*p)
883 {
884 case 'f': /* local html:file */
885 case 'h': /* local html:URL */
886 case 'H': /* www html */
887 {
888 char temp[256];
889 char *htmldir = feResource('h' /*"HtmlDir"*/);
890 if ((*p=='h')&&(htmldir!=NULL))
891 strcat(sys,"file://localhost");
892 else if ((*p=='H')||(htmldir==NULL))
893 htmldir = feResource('u' /* %H -> "ManualUrl"*/);
894 /* always defined */
895 if (hentry != NULL && *(hentry->url) != '\0')
896 #ifdef HAVE_VSNPRINTF
897 {
898 if (*p=='H')
899 #ifdef SINGULAR_4_2
900 snprintf(temp,256,"%s/%d-%d/%s", htmldir,
901 SINGULAR_VERSION/1000,
902 (SINGULAR_VERSION % 1000)/100,
903 #else
904 snprintf(temp,256,"%s/%d-%d-%d/%s", htmldir,
905 SINGULAR_VERSION/1000,
906 (SINGULAR_VERSION % 1000)/100,
907 (SINGULAR_VERSION % 100)/10,
908 #endif
909 hentry->url);
910 else
911 snprintf(temp,256,"%s/%s", htmldir, hentry->url);
912 }
913 else
914 {
915 if (*p=='H')
916 snprintf(temp,256,"%s/%d-%d-%d/index.htm", htmldir,
917 SINGULAR_VERSION/1000,
918 (SINGULAR_VERSION % 1000)/100,
919 (SINGULAR_VERSION % 100)/10
920 );
921 else
922 snprintf(temp,256,"%s/index.htm", htmldir);
923 }
924 #else
925 {
926 if (*p=='H')
927 sprintf(temp,"%s/%d-%d-%d/%s", htmldir,
928 SINGULAR_VERSION/1000,
929 (SINGULAR_VERSION % 1000)/100,
930 (SINGULAR_VERSION % 100)/10,
931 hentry->url);
932 else
933 sprintf(temp,"%s/%d-%d-%d/%s", htmldir, hentry->url);
934 }
935 else
936 if (*p=='H')
937 sprintf(temp,"%s/%d-%d-%d/index.htm", htmldir,
938 SINGULAR_VERSION/1000,
939 (SINGULAR_VERSION % 1000)/100,
940 (SINGULAR_VERSION % 100)/10
941 );
942 else
943 sprintf(temp,"%s/index.htm", htmldir);
944 }
945 #endif
946 strcat(sys,temp);
947 if ((*p)=='f')
948 { // remove #SEC
949 char *pp=(char *)strchr(sys,'#');
950 if (pp!=NULL)
951 {
952 *pp='\0';
953 i=strlen(sys);
954 memset(pp,0,MAX_SYSCMD_LEN-i);
955 }
956 }
957 i=strlen(sys);
958 break;
959 }
960 case 'i': /* singular.info */
961 {
962 char *i_res=feResource('i');
963 if (i_res!=NULL) strcat(sys,i_res);
964 else
965 {
966 WarnS("singular.info not found");
967 return;
968 }
969 i=strlen(sys);
970 break;
971 }
972 case 'n': /* info node */
973 {
974 char temp[256];
975 if ((hentry!=NULL) && (*(hentry->node) != '\0'))
976 sprintf(temp,"%s",hentry->node);
977 //else if ((hentry!=NULL) && (hentry->key!=NULL))
978 // sprintf(temp,"Index '%s'",hentry->key);
979 else
980 sprintf(temp,"Top");
981 strcat(sys,temp);
982 i=strlen(sys);
983 break;
984 }
985 case 'v': /* version number*/
986 {
987 char temp[256];
988 sprintf(temp,"%d-%d-%d",SINGULAR_VERSION/1000,
989 (SINGULAR_VERSION % 1000)/100,
990 (SINGULAR_VERSION % 100)/10);
991 strcat(sys,temp);
992 i=strlen(sys);
993 break;
994 }
995 default: break;
996 }
997 p++;
998 }
999 else
1000 {
1001 sys[i]=*p;
1002 p++;i++;
1003 }
1004 }
1005 Print("running `%s`\n",sys);
1006 (void) system(sys);
1007}
1008
1009static BOOLEAN heDummyInit(int /*warn*/, int /*br*/)
1010{
1011 return TRUE;
1012}
1013static void heDummyHelp(heEntry /*hentry*/, int /*br*/)
1014{
1015 WerrorS("No functioning help browser available.");
1016}
1017
1018static BOOLEAN heEmacsInit(int /*warn*/, int /*br*/)
1019{
1020 return TRUE;
1021}
1022static void heEmacsHelp(heEntry hentry, int /*br*/)
1023{
1024 WarnS("Your help command could not be executed. Use");
1025 Warn("C-h C-s %s",
1026 (hentry != NULL && *(hentry->node) != '\0' ? hentry->node : "Top"));
1027 WarnS("to enter the Singular online help. For general");
1028 WarnS("information on Singular running under Emacs, type C-h m.");
1029}
1030static int singular_manual(char *str, BOOLEAN isIndexEntry);
1031static void heBuiltinHelp(heEntry hentry, int /*br*/)
1032{
1033 char* node = omStrDup(hentry != NULL && *(hentry->key) != '\0' ?
1034 hentry->key : "Top");
1035 singular_manual(node,(hentry != NULL) && *(hentry->url)!='\0');
1036 omFree(node);
1037}
1038
1039
1040/* ========================================================================== */
1041// old, stupid builtin_help
1042// This could be implemented much more clever, but I'm too lazy to do this now
1043//
1044#define HELP_OK 0
1045#define FIN_INDEX '\037'
1046#define HELP_NOT_OPEN 1
1047#define HELP_NOT_FOUND 2
1048#define BUF_LEN 256
1049#define IDX_LEN 256
1050
1051static inline char tolow(char p)
1052{
1053 if (('A'<=p)&&(p<='Z')) return p | 040;
1054 return p;
1055}
1056
1057/*************************************************/
1058static int show(unsigned long offset, char *close)
1059{ char buffer[BUF_LEN+1];
1060 int lines = 0;
1061 FILE * help;
1062
1063 if( (help = fopen(feResource('i'), "rb")) == NULL)
1064 return HELP_NOT_OPEN;
1065
1066 fseek(help, (long)(offset+1), (int)0);
1067 while( (!feof(help))
1068 && (*fgets(buffer, BUF_LEN, help) != EOF)
1069 && (buffer[0] != FIN_INDEX))
1070 {
1071 printf("%s", buffer);
1072 if(lines++==pagelength)
1073 {
1074 printf("\n Press <RETURN> to continue or x to exit help.\n");
1075 fflush(stdout);
1076 *close = (char)getchar();
1077 if(*close=='x')
1078 {
1079 getchar();
1080 break;
1081 }
1082 lines=0;
1083 }
1084 }
1085 if((*close!='x')&&(pagelength>0))
1086 {
1087 printf("\nEnd of part. Press <RETURN> to continue or x to exit help.\n");
1088 fflush(stdout);
1089 *close = (char)getchar();
1090 if(*close=='x')
1091 getchar();
1092 }
1093 fclose(help);
1094 return HELP_OK;
1095}
1096
1097/*************************************************/
1098static int singular_manual(char *str, BOOLEAN isIndexEntry)
1099{ FILE *index=NULL;
1100 unsigned long offset;
1101 char *p,close=' ';
1102 int done = 0;
1103 char buffer[BUF_LEN+1],
1104 Index[IDX_LEN+1],
1105 String[IDX_LEN+1];
1106 Print("HELP >>%s>>\n",str);
1107
1108 if( (index = fopen(feResource('i'), "rb")) == NULL)
1109 {
1110 return HELP_NOT_OPEN;
1111 }
1112
1113 if (!isIndexEntry)
1114 {
1115 for(p=str; *p; p++) *p = tolow(*p);/* */
1116 do
1117 {
1118 p--;
1119 }
1120 while ((p != str) && (*p<=' '));
1121 p++;
1122 *p='\0';
1123 (void)sprintf(String, " %s ", str);
1124 }
1125 else
1126 {
1127 (void)sprintf(String, " %s", str);
1128 }
1129
1130 while(!feof(index)
1131 && (fgets(buffer, BUF_LEN, index) != (char *)0)
1132 && (buffer[0] != FIN_INDEX));
1133
1134 while(!feof(index))
1135 {
1136 if (fgets(buffer, BUF_LEN, index)==NULL) break; /*fill buffer */
1137 if (si_sscanf(buffer, "Node:%[^\177]\177%ld\n", Index, &offset)!=2)
1138 continue;
1139 if (!isIndexEntry)
1140 {
1141 for(p=Index; *p; p++) *p = tolow(*p);/* */
1142 (void)strcat(Index, " ");
1143 if( strstr(Index, String)!=NULL)
1144 {
1145 done++; (void)show(offset, &close);
1146 }
1147 }
1148 else if( strcmp(Index, String)==0)
1149 {
1150 done++; (void)show(offset, &close);
1151 break;
1152 }
1153 Index[0]='\0';
1154 if(close=='x')
1155 break;
1156 }
1157 if (index != NULL) (void)fclose(index);
1158 if(done==0)
1159 {
1160 Warn("`%s` not found",String);
1161 return HELP_NOT_FOUND;
1162 }
1163 return HELP_OK;
1164}
1165/*************************************************/
int BOOLEAN
Definition: auxiliary.h:87
#define TRUE
Definition: auxiliary.h:100
#define FALSE
Definition: auxiliary.h:96
void * ADDRESS
Definition: auxiliary.h:119
CanonicalForm FACTORY_PUBLIC pp(const CanonicalForm &)
CanonicalForm pp ( const CanonicalForm & f )
Definition: cf_gcd.cc:676
int l
Definition: cfEzgcd.cc:100
int i
Definition: cfEzgcd.cc:132
int k
Definition: cfEzgcd.cc:99
int p
Definition: cfModGcd.cc:4078
CanonicalForm fp
Definition: cfModGcd.cc:4102
FILE * f
Definition: checklibs.c:9
int lines
Definition: checklibs.c:13
Definition: idrec.h:35
BOOLEAN pa(leftv res, leftv args)
Definition: cohomo.cc:4344
#define Warn
Definition: emacs.cc:77
#define WarnS
Definition: emacs.cc:78
#define StringAppend
Definition: emacs.cc:79
const CanonicalForm int s
Definition: facAbsFact.cc:51
bool found
Definition: facFactorize.cc:55
FILE * feFopen(const char *path, const char *mode, char *where, short useWerror, short path_only)
Definition: feFopen.cc:47
void WerrorS(const char *s)
Definition: feFopen.cc:24
static void * feOptValue(feOptIndex opt)
Definition: feOpt.h:40
EXTERN_VAR struct fe_option feOptSpec[]
Definition: feOpt.h:17
static char * feResource(feResourceConfig config, int warn)
Definition: feResource.cc:236
VAR int myynest
Definition: febase.cc:41
char * getenv()
void * value
Definition: fegetopt.h:93
void feHelp(char *str)
Definition: fehelp.cc:89
void system(sys)
static BOOLEAN heDummyInit(int, int)
Definition: fehelp.cc:1009
static void feBrowserFile()
Definition: fehelp.cc:176
static int show(unsigned long offset, char *close)
Definition: fehelp.cc:1058
Print("running `%s`\n", sys)
const char * action
Definition: fehelp.cc:48
char url[MAX_HE_ENTRY_LENGTH]
Definition: fehelp.cc:34
void feStringAppendBrowsers(int warn)
Definition: fehelp.cc:340
static void hePrintHelpStr(const idhdl hh, const char *id, const char *pa)
Definition: fehelp.cc:607
static BOOLEAN heGenInit(int, int)
Definition: fehelp.cc:811
static BOOLEAN heEmacsInit(int, int)
Definition: fehelp.cc:1018
STATIC_VAR heBrowser_s * heHelpBrowsers
Definition: fehelp.cc:82
static char * strclean(char *str)
Definition: fehelp.cc:363
heBrowserInitProc init_proc
Definition: fehelp.cc:45
static void heBrowserHelp(heEntry hentry)
Definition: fehelp.cc:768
BOOLEAN(* heBrowserInitProc)(int warn, int br)
Definition: fehelp.cc:40
static int heReKey2Entry(char *filename, char *key, heEntry hentry)
Definition: fehelp.cc:567
#define HELP_OK
Definition: fehelp.cc:1044
const char * required
Definition: fehelp.cc:47
#define MAX_SYSCMD_LEN
Definition: fehelp.cc:810
char node[MAX_HE_ENTRY_LENGTH]
Definition: fehelp.cc:33
heBrowserHelpProc help_proc
Definition: fehelp.cc:46
static void heDummyHelp(heEntry hentry, int)
Definition: fehelp.cc:1013
STATIC_VAR heBrowser heCurrentHelpBrowser
Definition: fehelp.cc:71
#define BUF_LEN
Definition: fehelp.cc:1048
STATIC_VAR BOOLEAN feHelpCalled
Definition: fehelp.cc:766
#define MAX_HE_ENTRY_LENGTH
Definition: fehelp.cc:29
#define IDX_LEN
Definition: fehelp.cc:1049
heBrowser_s * heBrowser
Definition: fehelp.cc:50
char key[MAX_HE_ENTRY_LENGTH]
Definition: fehelp.cc:32
static int singular_manual(char *str, BOOLEAN isIndexEntry)
Definition: fehelp.cc:1098
#define FIN_INDEX
Definition: fehelp.cc:1045
static void heEmacsHelp(heEntry hentry, int)
Definition: fehelp.cc:1022
static void heBuiltinHelp(heEntry hentry, int)
Definition: fehelp.cc:1031
static BOOLEAN heKey2Entry(char *filename, char *key, heEntry hentry)
Definition: fehelp.cc:387
heEntry_s * heEntry
Definition: fehelp.cc:37
long chksum
Definition: fehelp.cc:35
static long heKeyChksum(char *key)
Definition: fehelp.cc:748
const char * browser
Definition: fehelp.cc:44
#define HELP_NOT_FOUND
Definition: fehelp.cc:1047
#define HELP_NOT_OPEN
Definition: fehelp.cc:1046
const char * feHelpBrowser(char *which, int warn)
Definition: fehelp.cc:248
STATIC_VAR int heCurrentHelpBrowserIndex
Definition: fehelp.cc:72
static void heGenHelp(heEntry hentry, int)
Definition: fehelp.cc:870
static BOOLEAN strmatch(char *s, char *re)
Definition: fehelp.cc:479
static char tolow(char p)
Definition: fehelp.cc:1051
void(* heBrowserHelpProc)(heEntry hentry, int br)
Definition: fehelp.cc:39
static BOOLEAN heOnlineHelp(char *s)
Definition: fehelp.cc:620
#define STATIC_VAR
Definition: globaldefs.h:7
#define EXTERN_VAR
Definition: globaldefs.h:6
@ PROC_CMD
Definition: grammar.cc:280
idhdl ggetid(const char *n)
Definition: ipid.cc:572
#define IDSTRING(a)
Definition: ipid.h:136
#define IDPROC(a)
Definition: ipid.h:140
#define IDROOT
Definition: ipid.h:19
#define IDPACKAGE(a)
Definition: ipid.h:139
#define IDTYP(a)
Definition: ipid.h:119
BOOLEAN iiLocateLib(const char *lib, char *where)
Definition: iplib.cc:870
char * iiGetLibProcBuffer(procinfo *pi, int part)
Definition: iplib.cc:197
static char * iiGetLibName(const procinfov pi)
find the library of an proc
Definition: ipshell.h:66
STATIC_VAR int offset
Definition: janet.cc:29
STATIC_VAR Poly * h
Definition: janet.cc:971
#define pi
Definition: libparse.cc:1145
#define help
Definition: libparse.cc:1230
#define url
Definition: libparse.cc:1260
void reinit_yylp()
Definition: libparse.cc:3376
VAR char * text_buffer
Definition: libparse.cc:1099
VAR char libnamebuf[1024]
Definition: libparse.cc:1098
lib_style_types
Definition: libparse.h:9
@ OLD_LIBSTYLE
Definition: libparse.h:9
@ GET_INFO
Definition: libparse.h:10
int yylplex(const char *libname, const char *libfile, lib_style_types *lib_style, idhdl pl, BOOLEAN autoexport=FALSE, lp_modes=LOAD_LIB)
#define SEEK_SET
Definition: mod2.h:113
#define assume(x)
Definition: mod2.h:387
#define SINGULAR_VERSION
Definition: mod2.h:85
char * str(leftv arg)
Definition: shared.cc:704
#define omStrDup(s)
Definition: omAllocDecl.h:263
#define omfree(addr)
Definition: omAllocDecl.h:237
#define omFree(addr)
Definition: omAllocDecl.h:261
#define omAlloc0(size)
Definition: omAllocDecl.h:211
char * omFindExec(const char *name, char *exec)
Definition: omFindExec.c:314
#define NULL
Definition: omList.c:12
static int index(p_Length length, p_Ord ord)
Definition: p_Procs_Impl.h:592
void StringSetS(const char *st)
Definition: reporter.cc:128
void StringAppendS(const char *st)
Definition: reporter.cc:107
void PrintS(const char *s)
Definition: reporter.cc:284
char * StringEndS()
Definition: reporter.cc:151
void PrintLn()
Definition: reporter.cc:310
void Werror(const char *fmt,...)
Definition: reporter.cc:189
EXTERN_VAR int pagelength
Definition: reporter.h:17
#define dReportBug(s)
Definition: reporter.h:113
int status int void * buf
Definition: si_signals.h:59
int status int fd
Definition: si_signals.h:59
@ LANG_SINGULAR
Definition: subexpr.h:22
@ PACKAGE_CMD
Definition: tok.h:149
@ STRING_CMD
Definition: tok.h:185
char name(const Variable &v)
Definition: variable.h:95