Edinburgh Speech Tools  2.1-release
slib_doc.cc
Go to the documentation of this file.
1 /*
2  * COPYRIGHT (c) 1988-1994 BY *
3  * PARADIGM ASSOCIATES INCORPORATED, CAMBRIDGE, MASSACHUSETTS. *
4  * See the source file SLIB.C for more information. *
5 
6  * Reorganization of files (Mar 1999) by Alan W Black <awb@cstr.ed.ac.uk>
7 
8  * Documentation support
9 
10 */
11 #include <cstdio>
12 #include "EST_cutils.h"
13 #include "siod.h"
14 #include "siodp.h"
15 #include "siodeditline.h"
16 
17 using std::cerr;
18 using std::endl;
19 
20 void setdoc(LISP name,LISP doc)
21 {
22  /* Set documentation string for name */
23  LISP lpair = assq(name,siod_docstrings);
24  if (lpair == NIL)
26  else
27  {
28  cerr << "SIOD: duplicate builtin function: " <<
29  get_c_string(name) << endl;
30  cerr << "SIOD: probably an error" << endl;
31  CDR(lpair) = doc;
32  }
33 }
34 
35 static LISP siod_doc(LISP args,LISP penv)
36 {
37  /* Return documentation string for sym */
38  (void)penv;
39  LISP lpair,val,tmp,code;
40  LISP var_docstrings;
41 
42  if (TYPE(car(args)) != tc_symbol)
43  return rintern("No documentation available for non-symbol.");
44  tmp = envlookup(car(args),penv);
45  if NNULLP(tmp)
46  val = car(tmp);
47  else
48  val = VCELL(car(args));
49  if EQ(val,unbound_marker)
50  return rintern("Symbol is unbound.");
51  else
52  {
53  var_docstrings = symbol_value(rintern("var-docstrings"),penv);
54  lpair = assq(car(args),var_docstrings);
55  if (lpair)
56  return cdr(lpair);
57  else
58  rintern("No documentation available for symbol.");
59  }
60  switch (TYPE(val))
61  {
62  case tc_subr_0:
63  case tc_subr_1:
64  case tc_subr_2:
65  case tc_subr_3:
66  case tc_subr_4:
67  case tc_lsubr:
68  case tc_fsubr:
69  case tc_msubr:
70  lpair = assq(car(args),siod_docstrings);
71  if (lpair != NIL)
72  return cdr(lpair);
73  else
74  return rintern("No documentation available for builtin function.");
75  break;
76  case tc_closure:
77  code = val->storage_as.closure.code;
78  if ((TYPE(cdr(code)) == tc_cons) &&
79  (TYPE(car(cdr(cdr(code)))) == tc_string))
80  return car(cdr(cdr(code)));
81  else
82  return rintern("No documentation available for user-defined function.");
83  default:
84  return rintern("No documentation available for symbol.");
85  }
86 
87 }
88 
89 static LISP siod_all_function_docstrings(void)
90 {
91  // Returns all an assoc list of ALL functions that have any form
92  // of documentation strings, internal functions or user defined.
93  LISP docs = siod_docstrings;
94 
95  // But we need user defined function with docstrings too.
96  // The docustring must start with a ( to be included
97  LISP l = oblistvar;
98  LISP code,val;
99 
100  // Search the oblist for functions
101  for(;CONSP(l);l=CDR(l))
102  {
103  if (VCELL(car(l)) == NIL) continue;
104  switch(TYPE(VCELL(CAR(l))))
105  {
106  case tc_closure:
107  val = VCELL(CAR(l));
108  code = val->storage_as.closure.code;
109  if ((CONSP(code)) &&
110  (CONSP(cdr(code))) &&
111  (CONSP(cdr(cdr(code)))) &&
112  (TYPE(car(cdr(cdr(code)))) == tc_string))
113  docs = cons(cons(car(l),car(cdr(cdr(code)))),docs);
114  default:
115  continue;
116  }
117  }
118 
119  return docs;
120 }
121 
122 static int sort_compare_docstrings(const void *x, const void *y)
123 {
124  LISP a=*(LISP *)x;
125  LISP b=*(LISP *)y;
126 
128 }
129 
130 static void siod_print_docstring(const char *symname,
131  const char *docstring, FILE *fp)
132 {
133  // Print to fp a texinfo list item for this description
134  // Take the first line of the docstring as the label, and also remove
135  // any indentation in the remainder of the lines
136  int i,state;
137  (void)symname;
138  EST_String ds = docstring;
139  const char *dsc;
140 
141  if (ds.contains(make_regex("\\[see .*\\]$")))
142  { // Contains a cross reference so replace it with texi xref command
143  EST_String rest, ref;
144  rest = ds.before(make_regex("\\[see [^\n]*\\]$"));
145  ref = ds.after(rest);
146  ref = ref.after("[see ");
147  ref = ref.before("]");
148  ds = rest + EST_String("[\\@pxref\\{") + ref + EST_String("\\}]");
149  }
150 
151  dsc = ds;
152 
153  fprintf(fp,"@item ");
154  for (state=0,i=0; dsc[i] != '\0'; i++)
155  {
156  if (((dsc[i] == '@') ||
157  (dsc[i] == '{') ||
158  (dsc[i] == '}')) &&
159  ((i == 0) ||
160  (dsc[i-1] != '\\')))
161  putc('@',fp);
162  if ((dsc[i] == '\\') &&
163  ((dsc[i+1] == '@') ||
164  (dsc[i+1] == '{') ||
165  (dsc[i+1] == '}')))
166  continue;
167  else if (state == 0)
168  {
169  putc(dsc[i],fp);
170  if (dsc[i] == '\n')
171  state = 1;
172  }
173  else if (state == 1)
174  if (dsc[i] != ' ')
175  {
176  putc(dsc[i],fp);
177  state = 0;
178  }
179  }
180  fprintf(fp,"\n");
181 }
182 
183 static LISP siod_sort_and_dump_docstrings(LISP type,LISP filefp)
184 {
185  // sort docstrings then dump them to filefp as a texinfo list
186  LISP *array,l,docstrings;
187  int num_strings;
188  int i;
189 
190  if (streq(get_c_string(type),"function"))
191  docstrings = siod_all_function_docstrings();
192  else if (streq(get_c_string(type),"features"))
193  docstrings = symbol_value(rintern("ff_docstrings"),NIL);
194  else
195  docstrings = symbol_value(rintern("var-docstrings"),NIL);
196 
197  num_strings = siod_llength(docstrings);
198  array = walloc(LISP,num_strings);
199  for (l=docstrings,i=0; i < num_strings; i++,l=cdr(l))
200  array[i] = car(l);
201  qsort(array,num_strings,sizeof(LISP),sort_compare_docstrings);
202 
203  for (i=0; i < num_strings; i++)
204  siod_print_docstring(get_c_string(car(array[i])),
205  get_c_string(cdr(array[i])),
206  get_c_file(filefp,stdout));
207 
208  wfree(array);
209 
210  return NIL;
211 
212 }
213 
214 const char *siod_docstring(const char *symbol)
215 {
216  LISP doc;
217 
218  doc = siod_doc(cons(rintern(symbol),NIL),NIL);
219 
220  return get_c_string(doc);
221 }
222 
223 const char *siod_manual_sym(const char *symbol)
224 {
225  // For siodline
226  LISP info;
227 
228  info = leval(cons(rintern("manual-sym"),
229  cons(quote(rintern(symbol)),NIL)),NIL);
230 
231  return get_c_string(info);
232 }
233 
234 void siod_saydocstring(const char *symbol)
235 {
236  // This isn't guaranteed to work but might be ok sometimes
237 
238  leval(cons(rintern("tts_text"),
239  cons(cons(rintern("doc"),cons(rintern(symbol),NIL)),
240  cons(NIL,NIL))),NIL);
241 
242 }
243 
244 void init_subrs_doc(void)
245 {
246  init_fsubr("doc",siod_doc,
247  "(doc SYMBOL)\n\
248  Return documentation for SYMBOL.");
249  init_subr_2("sort-and-dump-docstrings",siod_sort_and_dump_docstrings,
250  "(sort-and-dump-docstrings DOCSTRINGS FILEFP)\n\
251  DOCSTRINGS is an assoc list of name and document string var-docstrings\n\
252  or func-docstrings. This very individual function sorts the list and \n\
253  prints out the documentation strings as texinfo list members to FILEFP.");
254 
255 }
LISP envlookup(LISP var, LISP env)
Definition: slib.cc:1353
#define tc_fsubr
Definition: siod_defs.h:112
#define walloc(TYPE, SIZE)
Definition: EST_walloc.h:52
void qsort(EST_TList< T > &a)
int contains(const char *s, ssize_t pos=-1) const
Does it contain this substring?
Definition: EST_String.h:365
#define tc_symbol
Definition: siod_defs.h:106
LISP siod_docstrings
Definition: slib.cc:151
const char * siod_manual_sym(const char *symbol)
Definition: slib_doc.cc:223
#define NIL
Definition: siod_defs.h:92
int siod_llength(LISP list)
Definition: siod.cc:202
void init_subr_2(const char *name, LISP(*fcn)(LISP, LISP), const char *doc)
Definition: slib.cc:900
#define EQ(x, y)
Definition: siod_defs.h:93
LISP unbound_marker
Definition: slib.cc:140
#define streq(X, Y)
Definition: EST_cutils.h:57
void init_fsubr(const char *name, LISP(*fcn)(LISP, LISP), const char *doc)
Definition: slib.cc:908
#define TYPE(x)
Definition: siod_defs.h:98
#define VCELL(x)
Definition: siod_defs.h:79
FILE * get_c_file(LISP p, FILE *deflt)
Definition: slib_file.cc:349
const char * get_c_string(LISP x)
Definition: slib.cc:638
#define tc_lsubr
Definition: siod_defs.h:111
EST_Regex & make_regex(const char *r)
Definition: siod.cc:361
#define tc_msubr
Definition: siod_defs.h:113
LISP cons(LISP x, LISP y)
Definition: slib_list.cc:97
#define tc_cons
Definition: siod_defs.h:104
#define tc_subr_0
Definition: siod_defs.h:107
void setdoc(LISP name, LISP doc)
Definition: slib_doc.cc:20
#define tc_subr_3
Definition: siod_defs.h:110
#define tc_closure
Definition: siod_defs.h:114
LISP symbol_value(LISP x, LISP env)
Definition: slib_core.cc:229
#define CAR(x)
Definition: siod_defs.h:76
char * name
Definition: siodp.h:43
#define tc_string
Definition: siod_defs.h:116
LISP rintern(const char *name)
Definition: slib.cc:734
#define tc_subr_2
Definition: siod_defs.h:109
LISP quote(LISP item)
Definition: siod.cc:252
LISP oblistvar
Definition: slib.cc:131
int EST_strcasecmp(const char *s1, const char *s2, const unsigned char *charmap)
LISP leval(LISP x, LISP env)
Definition: slib.cc:1378
#define tc_subr_4
Definition: siod_defs.h:122
LISP assq(LISP x, LISP alist)
Definition: slib_list.cc:45
#define tc_subr_1
Definition: siod_defs.h:108
LISP car(LISP x)
Definition: slib_list.cc:115
EST_String after(int pos, int len=1) const
Part after pos+len.
Definition: EST_String.h:308
void init_subrs_doc(void)
Definition: slib_doc.cc:244
EST_String before(int pos, int len=0) const
Part before position.
Definition: EST_String.h:276
LISP fp
Definition: kkcompile.cc:63
EST_String
void wfree(void *p)
Definition: walloc.c:131
const char * siod_docstring(const char *symbol)
Definition: slib_doc.cc:214
#define CONSP(x)
Definition: siod_defs.h:153
LISP cdr(LISP x)
Definition: slib_list.cc:124
#define CDR(x)
Definition: siod_defs.h:77
#define NNULLP(x)
Definition: siod_defs.h:96
void siod_saydocstring(const char *symbol)
Definition: slib_doc.cc:234