]> gcc.gnu.org Git - gcc.git/blob - gcc/f/intdoc.c
cse.c (rtx_cost): Add default case in enumeration switch.
[gcc.git] / gcc / f / intdoc.c
1 /* intdoc.c
2 Copyright (C) 1997 Free Software Foundation, Inc.
3 Contributed by James Craig Burley (burley@gnu.ai.mit.edu).
4
5 This file is part of GNU Fortran.
6
7 GNU Fortran is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU Fortran is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Fortran; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
21
22 /* From f/proj.h, which uses #error -- not all C compilers
23 support that, and we want _this_ program to be compilable
24 by pretty much any C compiler. */
25
26 #include "assert.j" /* Use gcc's assert.h. */
27 #include <stdio.h>
28 #include <stddef.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #define FFEINTRIN_DOC 1
32 #include "intrin.h"
33
34 typedef enum
35 {
36 #if !defined(false) || !defined(true)
37 false = 0, true = 1,
38 #endif
39 #if !defined(FALSE) || !defined(TRUE)
40 FALSE = 0, TRUE = 1,
41 #endif
42 Doggone_Trailing_Comma_Dont_Work = 1
43 } bool;
44
45 #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
46
47 char *family_name (ffeintrinFamily family);
48 static void dumpif (ffeintrinFamily fam);
49 static void dumpendif (void);
50 static void dumpclearif (void);
51 static void dumpem (void);
52 static void dumpgen (int menu, char *name, char *name_uc,
53 ffeintrinGen gen);
54 static void dumpspec (int menu, char *name, char *name_uc,
55 ffeintrinSpec spec);
56 static void dumpimp (int menu, char *name, char *name_uc, size_t genno, ffeintrinFamily family,
57 ffeintrinImp imp, ffeintrinSpec spec);
58 static char *argument_info_ptr (ffeintrinImp imp, int argno);
59 static char *argument_info_string (ffeintrinImp imp, int argno);
60 static char *argument_name_ptr (ffeintrinImp imp, int argno);
61 static char *argument_name_string (ffeintrinImp imp, int argno);
62 #if 0
63 static char *elaborate_if_complex (ffeintrinImp imp, int argno);
64 static char *elaborate_if_maybe_complex (ffeintrinImp imp, int argno);
65 static char *elaborate_if_real (ffeintrinImp imp, int argno);
66 #endif
67 static void print_type_string (char *c);
68
69 int
70 main (int argc, char **argv)
71 {
72 if (argc != 1)
73 {
74 fprintf (stderr, "\
75 Usage: intdoc > intdoc.texi\n\
76 Collects and dumps documentation on g77 intrinsics\n\
77 to the file named intdoc.texi.\n");
78 exit (1);
79 }
80
81 dumpem ();
82 return 0;
83 }
84
85 struct _ffeintrin_name_
86 {
87 char *name_uc;
88 char *name_lc;
89 char *name_ic;
90 ffeintrinGen generic;
91 ffeintrinSpec specific;
92 };
93
94 struct _ffeintrin_gen_
95 {
96 char *name; /* Name as seen in program. */
97 ffeintrinSpec specs[2];
98 };
99
100 struct _ffeintrin_spec_
101 {
102 char *name; /* Uppercase name as seen in source code,
103 lowercase if no source name, "none" if no
104 name at all (NONE case). */
105 bool is_actualarg; /* Ok to pass as actual arg if -pedantic. */
106 ffeintrinFamily family;
107 ffeintrinImp implementation;
108 };
109
110 struct _ffeintrin_imp_
111 {
112 char *name; /* Name of implementation. */
113 #if 0 /* FFECOM_targetCURRENT == FFECOM_targetGCC */
114 ffecomGfrt gfrt; /* gfrt index in library. */
115 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
116 char *control;
117 };
118
119 static struct _ffeintrin_name_ names[] = {
120 #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC) \
121 { UPPER, LOWER, MIXED, FFEINTRIN_ ## GEN, FFEINTRIN_ ## SPEC },
122 #define DEFGEN(CODE,NAME,SPEC1,SPEC2)
123 #define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP)
124 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
125 #include "intrin.def"
126 #undef DEFNAME
127 #undef DEFGEN
128 #undef DEFSPEC
129 #undef DEFIMP
130 };
131
132 static struct _ffeintrin_gen_ gens[] = {
133 #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC)
134 #define DEFGEN(CODE,NAME,SPEC1,SPEC2) \
135 { NAME, { SPEC1, SPEC2, }, },
136 #define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP)
137 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
138 #include "intrin.def"
139 #undef DEFNAME
140 #undef DEFGEN
141 #undef DEFSPEC
142 #undef DEFIMP
143 };
144
145 static struct _ffeintrin_imp_ imps[] = {
146 #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC)
147 #define DEFGEN(CODE,NAME,SPEC1,SPEC2)
148 #define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP)
149 #if 0 /* FFECOM_targetCURRENT == FFECOM_targetGCC */
150 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) \
151 { NAME, FFECOM_gfrt ## GFRT, CONTROL },
152 #elif 1 /* FFECOM_targetCURRENT == FFECOM_targetFFE */
153 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) \
154 { NAME, CONTROL },
155 #else
156 #error
157 #endif
158 #include "intrin.def"
159 #undef DEFNAME
160 #undef DEFGEN
161 #undef DEFSPEC
162 #undef DEFIMP
163 };
164
165 static struct _ffeintrin_spec_ specs[] = {
166 #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC)
167 #define DEFGEN(CODE,NAME,SPEC1,SPEC2)
168 #define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) \
169 { NAME, CALLABLE, FAMILY, IMP, },
170 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
171 #include "intrin.def"
172 #undef DEFGEN
173 #undef DEFSPEC
174 #undef DEFIMP
175 };
176
177 struct cc_pair { ffeintrinImp imp; char *text; };
178
179 static char *descriptions[FFEINTRIN_imp] = { 0 };
180 static struct cc_pair cc_descriptions[] = {
181 #define DEFDOC(IMP,SUMMARY,DESCRIPTION) { FFEINTRIN_imp ## IMP, DESCRIPTION },
182 #include "intdoc.h0"
183 #undef DEFDOC
184 };
185
186 static char *summaries[FFEINTRIN_imp] = { 0 };
187 static struct cc_pair cc_summaries[] = {
188 #define DEFDOC(IMP,SUMMARY,DESCRIPTION) { FFEINTRIN_imp ## IMP, SUMMARY },
189 #include "intdoc.h0"
190 #undef DEFDOC
191 };
192
193 char *
194 family_name (ffeintrinFamily family)
195 {
196 switch (family)
197 {
198 case FFEINTRIN_familyF77:
199 return "familyF77";
200
201 case FFEINTRIN_familyASC:
202 return "familyASC";
203
204 case FFEINTRIN_familyMIL:
205 return "familyMIL";
206
207 case FFEINTRIN_familyGNU:
208 return "familyGNU";
209
210 case FFEINTRIN_familyF90:
211 return "familyF90";
212
213 case FFEINTRIN_familyVXT:
214 return "familyVXT";
215
216 case FFEINTRIN_familyFVZ:
217 return "familyFVZ";
218
219 case FFEINTRIN_familyF2C:
220 return "familyF2C";
221
222 case FFEINTRIN_familyF2U:
223 return "familyF2U";
224
225 case FFEINTRIN_familyBADU77:
226 return "familyBADU77";
227
228 default:
229 assert ("bad family" == NULL);
230 return "??";
231 }
232 }
233
234 static int in_ifset = 0;
235 static ffeintrinFamily latest_family = FFEINTRIN_familyNONE;
236
237 static void
238 dumpif (ffeintrinFamily fam)
239 {
240 assert (fam != FFEINTRIN_familyNONE);
241 if ((in_ifset != 2)
242 || (fam != latest_family))
243 {
244 if (in_ifset == 2)
245 printf ("@end ifset\n");
246 latest_family = fam;
247 printf ("@ifset %s\n", family_name (fam));
248 }
249 in_ifset = 1;
250 }
251
252 static void
253 dumpendif ()
254 {
255 in_ifset = 2;
256 }
257
258 static void
259 dumpclearif ()
260 {
261 if ((in_ifset == 2)
262 || (latest_family != FFEINTRIN_familyNONE))
263 printf ("@end ifset\n");
264 latest_family = FFEINTRIN_familyNONE;
265 in_ifset = 0;
266 }
267
268 static void
269 dumpem ()
270 {
271 int i;
272
273 for (i = 0; ((size_t) i) < ARRAY_SIZE (cc_descriptions); ++i)
274 {
275 assert (descriptions[cc_descriptions[i].imp] == NULL);
276 descriptions[cc_descriptions[i].imp] = cc_descriptions[i].text;
277 }
278
279 for (i = 0; ((size_t) i) < ARRAY_SIZE (cc_summaries); ++i)
280 {
281 assert (summaries[cc_summaries[i].imp] == NULL);
282 summaries[cc_summaries[i].imp] = cc_summaries[i].text;
283 }
284
285 printf ("@c This file is automatically derived from intdoc.c, intdoc.in,\n");
286 printf ("@c ansify.c, intrin.def, and intrin.h. Edit those files instead.\n");
287 printf ("@menu\n");
288 for (i = 0; ((size_t) i) < ARRAY_SIZE (names); ++i)
289 {
290 if (names[i].generic != FFEINTRIN_genNONE)
291 dumpgen (1, names[i].name_ic, names[i].name_uc,
292 names[i].generic);
293 if (names[i].specific != FFEINTRIN_specNONE)
294 dumpspec (1, names[i].name_ic, names[i].name_uc,
295 names[i].specific);
296 }
297 dumpclearif ();
298
299 printf ("@end menu\n\n");
300
301 for (i = 0; ((size_t) i) < ARRAY_SIZE (names); ++i)
302 {
303 if (names[i].generic != FFEINTRIN_genNONE)
304 dumpgen (0, names[i].name_ic, names[i].name_uc,
305 names[i].generic);
306 if (names[i].specific != FFEINTRIN_specNONE)
307 dumpspec (0, names[i].name_ic, names[i].name_uc,
308 names[i].specific);
309 }
310 dumpclearif ();
311 }
312
313 static void
314 dumpgen (int menu, char *name, char *name_uc, ffeintrinGen gen)
315 {
316 size_t i;
317 int total = 0;
318
319 if (!menu)
320 {
321 for (i = 0; i < ARRAY_SIZE (gens[gen].specs); ++i)
322 {
323 if (gens[gen].specs[i] != FFEINTRIN_specNONE)
324 ++total;
325 }
326 }
327
328 for (i = 0; i < ARRAY_SIZE (gens[gen].specs); ++i)
329 {
330 ffeintrinSpec spec;
331 size_t j;
332
333 if ((spec = gens[gen].specs[i]) == FFEINTRIN_specNONE)
334 continue;
335
336 dumpif (specs[spec].family);
337 dumpimp (menu, name, name_uc, i, specs[spec].family, specs[spec].implementation,
338 spec);
339 if (!menu && (total > 0))
340 {
341 if (total == 1)
342 {
343 printf ("\
344 For information on another intrinsic with the same name:\n");
345 }
346 else
347 {
348 printf ("\
349 For information on other intrinsics with the same name:\n");
350 }
351 for (j = 0; j < ARRAY_SIZE (gens[gen].specs); ++j)
352 {
353 if (j == i)
354 continue;
355 if ((spec = gens[gen].specs[j]) == FFEINTRIN_specNONE)
356 continue;
357 printf ("@xref{%s Intrinsic (%s)}.\n",
358 name, specs[spec].name);
359 }
360 printf ("\n");
361 }
362 dumpendif ();
363 }
364 }
365
366 static void
367 dumpspec (int menu, char *name, char *name_uc, ffeintrinSpec spec)
368 {
369 dumpif (specs[spec].family);
370 dumpimp (menu, name, name_uc, 0, specs[spec].family, specs[spec].implementation,
371 FFEINTRIN_specNONE);
372 dumpendif ();
373 }
374
375 static void
376 dumpimp (int menu, char *name, char *name_uc, size_t genno, ffeintrinFamily family, ffeintrinImp imp,
377 ffeintrinSpec spec)
378 {
379 char *c;
380 bool subr;
381 char *argc;
382 char *argi;
383 int colon;
384 int argno;
385
386 assert ((imp != FFEINTRIN_impNONE) || !genno);
387
388 if (menu)
389 {
390 printf ("* %s Intrinsic",
391 name);
392 if (spec != FFEINTRIN_specNONE)
393 printf (" (%s)", specs[spec].name); /* See XYZZY1 below */
394 printf ("::");
395 #define INDENT_SUMMARY 24
396 if ((imp == FFEINTRIN_impNONE)
397 || (summaries[imp] != NULL))
398 {
399 int spaces = INDENT_SUMMARY - 14 - strlen (name);
400 char *c;
401
402 if (spec != FFEINTRIN_specNONE)
403 spaces -= (3 + strlen (specs[spec].name)); /* See XYZZY1 above */
404 if (spaces < 1)
405 spaces = 1;
406 while (spaces--)
407 fputc (' ', stdout);
408
409 if (imp == FFEINTRIN_impNONE)
410 {
411 printf ("(Reserved for future use.)\n");
412 return;
413 }
414
415 for (c = summaries[imp]; c[0] != '\0'; ++c)
416 {
417 if ((c[0] == '@')
418 && (c[1] >= '0')
419 && (c[1] <= '9'))
420 {
421 int argno = c[1] - '0';
422
423 c += 2;
424 while ((c[0] >= '0')
425 && (c[0] <= '9'))
426 {
427 argno = 10 * argno + (c[0] - '0');
428 ++c;
429 }
430 assert (c[0] == '@');
431 if (argno == 0)
432 printf ("%s", name);
433 else if (argno == 99)
434 { /* Yeah, this is a major kludge. */
435 printf ("\n");
436 spaces = INDENT_SUMMARY + 1;
437 while (spaces--)
438 fputc (' ', stdout);
439 }
440 else
441 printf ("%s", argument_name_string (imp, argno - 1));
442 }
443 else
444 fputc (c[0], stdout);
445 }
446 }
447 printf ("\n");
448 return;
449 }
450
451 printf ("@node %s Intrinsic", name);
452 if (spec != FFEINTRIN_specNONE)
453 printf (" (%s)", specs[spec].name);
454 printf ("\n@subsubsection %s Intrinsic", name);
455 if (spec != FFEINTRIN_specNONE)
456 printf (" (%s)", specs[spec].name);
457 printf ("\n@cindex %s intrinsic\n@cindex intrinsics, %s\n",
458 name, name);
459
460 if (imp == FFEINTRIN_impNONE)
461 {
462 printf ("\n\
463 This intrinsic is not yet implemented.\n\
464 The name is, however, reserved as an intrinsic.\n\
465 Use @samp{EXTERNAL %s} to use this name for an\n\
466 external procedure.\n\
467 \n\
468 ",
469 name);
470 return;
471 }
472
473 c = imps[imp].control;
474 subr = (c[0] == '-');
475 colon = (c[2] == ':') ? 2 : 3;
476
477 printf ("\n\
478 @noindent\n\
479 @example\n\
480 %s%s(",
481 (subr ? "CALL " : ""), name);
482
483 fflush (stdout);
484
485 for (argno = 0; ; ++argno)
486 {
487 argc = argument_name_ptr (imp, argno);
488 if (argc == NULL)
489 break;
490 if (argno > 0)
491 printf (", ");
492 printf ("@var{%s}", argc);
493 argi = argument_info_string (imp, argno);
494 if ((argi[0] == '*')
495 || (argi[0] == 'n')
496 || (argi[0] == '+')
497 || (argi[0] == 'p'))
498 printf ("-1, @var{%s}-2, @dots{}, @var{%s}-n",
499 argc, argc);
500 }
501
502 printf (")\n\
503 @end example\n\
504 \n\
505 ");
506
507 if (!subr)
508 {
509 int other_arg;
510 char *arg_string;
511 char *arg_info;
512
513 if ((c[colon + 1] >= '0')
514 && (c[colon + 1] <= '9'))
515 {
516 other_arg = c[colon + 1] - '0';
517 arg_string = argument_name_string (imp, other_arg);
518 arg_info = argument_info_string (imp, other_arg);
519 }
520 else
521 {
522 other_arg = -1;
523 arg_string = NULL;
524 arg_info = NULL;
525 }
526
527 printf ("\
528 @noindent\n\
529 %s: ", name);
530 print_type_string (c);
531 printf (" function");
532
533 if ((c[0] == 'R')
534 && (c[1] == 'C'))
535 {
536 assert (other_arg >= 0);
537
538 if ((arg_info[0] == '?') || (arg_info[0] == '!') || (arg_info[0] == '+')
539 || (arg_info[0] == '*') || (arg_info[0] == 'n') || (arg_info[0] == 'p'))
540 ++arg_info;
541 if ((arg_info[0] == 'F') || (arg_info[0] == 'N'))
542 printf (".\n\
543 The exact type is @samp{REAL(KIND=1)} when argument @var{%s} is\n\
544 any type other than @code{COMPLEX}, or when it is @code{COMPLEX(KIND=1)}.\n\
545 When @var{%s} is any @code{COMPLEX} type other than @code{COMPLEX(KIND=1)},\n\
546 this intrinsic is valid only when used as the argument to\n\
547 @code{REAL()}, as explained below.\n\n",
548 arg_string,
549 arg_string);
550 else
551 printf (".\n\
552 This intrinsic is valid when argument @var{%s} is\n\
553 @code{COMPLEX(KIND=1)}.\n\
554 When @var{%s} is any other @code{COMPLEX} type,\n\
555 this intrinsic is valid only when used as the argument to\n\
556 @code{REAL()}, as explained below.\n\n",
557 arg_string,
558 arg_string);
559 }
560 #if 0
561 else if ((c[0] == 'I')
562 && (c[1] == 'p'))
563 printf (", the exact type being wide enough to hold a pointer\n\
564 on the target system (typically @code{INTEGER(KIND=1)} or @code{INTEGER(KIND=4)}).\n\n");
565 #endif
566 else if ((c[1] == '=')
567 && (c[colon + 1] >= '0')
568 && (c[colon + 1] <= '9'))
569 {
570 assert (other_arg >= 0);
571
572 if ((arg_info[0] == '?') || (arg_info[0] == '!') || (arg_info[0] == '+')
573 || (arg_info[0] == '*') || (arg_info[0] == 'n') || (arg_info[0] == 'p'))
574 ++arg_info;
575
576 if (((c[0] == arg_info[0])
577 && ((c[0] == 'A') || (c[0] == 'C') || (c[0] == 'I')
578 || (c[0] == 'L') || (c[0] == 'R')))
579 || ((c[0] == 'R')
580 && (arg_info[0] == 'C'))
581 || ((c[0] == 'C')
582 && (arg_info[0] == 'R')))
583 printf (", the @samp{KIND=} value of the type being that of argument @var{%s}.\n\n",
584 arg_string);
585 else if ((c[0] == 'S')
586 && ((arg_info[0] == 'C')
587 || (arg_info[0] == 'F')
588 || (arg_info[0] == 'N')))
589 printf (".\n\
590 The exact type depends on that of argument @var{%s}---if @var{%s} is\n\
591 @code{COMPLEX}, this function's type is @code{REAL}\n\
592 with the same @samp{KIND=} value as the type of @var{%s}.\n\
593 Otherwise, this function's type is the same as that of @var{%s}.\n\n",
594 arg_string, arg_string, arg_string, arg_string);
595 else
596 printf (", the exact type being that of argument @var{%s}.\n\n",
597 arg_string);
598 }
599 else if ((c[1] == '=')
600 && (c[colon + 1] == '*'))
601 printf (", the exact type being the result of cross-promoting the\n\
602 types of all the arguments.\n\n");
603 else if (c[1] == '=')
604 assert ("?0:?:" == NULL);
605 else
606 printf (".\n\n");
607 }
608
609 for (argno = 0, argc = &c[colon + 3]; *argc != '\0'; ++argno)
610 {
611 char optionality = '\0';
612 char extra = '\0';
613 char basic;
614 char kind;
615 int length;
616 int elements;
617
618 printf ("\
619 @noindent\n\
620 @var{");
621 for (; ; ++argc)
622 {
623 if (argc[0] == '=')
624 break;
625 printf ("%c", *argc);
626 }
627 printf ("}: ");
628
629 ++argc;
630 if ((*argc == '?')
631 || (*argc == '!')
632 || (*argc == '*')
633 || (*argc == '+')
634 || (*argc == 'n')
635 || (*argc == 'p'))
636 optionality = *(argc++);
637 basic = *(argc++);
638 kind = *(argc++);
639 if (*argc == '[')
640 {
641 length = *++argc - '0';
642 if (*++argc != ']')
643 length = 10 * length + (*(argc++) - '0');
644 ++argc;
645 }
646 else
647 length = -1;
648 if (*argc == '(')
649 {
650 elements = *++argc - '0';
651 if (*++argc != ')')
652 elements = 10 * elements + (*(argc++) - '0');
653 ++argc;
654 }
655 else if (*argc == '&')
656 {
657 elements = -1;
658 ++argc;
659 }
660 else
661 elements = 0;
662 if ((*argc == '&')
663 || (*argc == 'i')
664 || (*argc == 'w')
665 || (*argc == 'x'))
666 extra = *(argc++);
667 if (*argc == ',')
668 ++argc;
669
670 switch (basic)
671 {
672 case '-':
673 switch (kind)
674 {
675 case '*':
676 printf ("Any type");
677 break;
678
679 default:
680 assert ("kind arg" == NULL);
681 break;
682 }
683 break;
684
685 case 'A':
686 assert ((kind == '1') || (kind == '*'));
687 printf ("@code{CHARACTER");
688 if (length != -1)
689 printf ("*%d", length);
690 printf ("}");
691 break;
692
693 case 'C':
694 switch (kind)
695 {
696 case '*':
697 printf ("@code{COMPLEX}");
698 break;
699
700 case '1': case '2': case '3': case '4': case '5':
701 case '6': case '7': case '8': case '9':
702 printf ("@code{COMPLEX(KIND=%d)}", (kind - '0'));
703 break;
704
705 case 'A':
706 printf ("Same @samp{KIND=} value as for @var{%s}",
707 argument_name_string (imp, 0));
708 break;
709
710 default:
711 assert ("Ca" == NULL);
712 break;
713 }
714 break;
715
716 case 'I':
717 switch (kind)
718 {
719 case '*':
720 printf ("@code{INTEGER}");
721 break;
722
723 case '1': case '2': case '3': case '4': case '5':
724 case '6': case '7': case '8': case '9':
725 printf ("@code{INTEGER(KIND=%d)}", (kind - '0'));
726 break;
727
728 case 'A':
729 printf ("@code{INTEGER} with same @samp{KIND=} value as for @var{%s}",
730 argument_name_string (imp, 0));
731 break;
732
733 case 'p':
734 printf ("@code{INTEGER} wide enough to hold a pointer");
735 break;
736
737 default:
738 assert ("Ia" == NULL);
739 break;
740 }
741 break;
742
743 case 'L':
744 switch (kind)
745 {
746 case '*':
747 printf ("@code{LOGICAL}");
748 break;
749
750 case '1': case '2': case '3': case '4': case '5':
751 case '6': case '7': case '8': case '9':
752 printf ("@code{LOGICAL(KIND=%d)}", (kind - '0'));
753 break;
754
755 case 'A':
756 printf ("@code{LOGICAL} with same @samp{KIND=} value as for @var{%s}",
757 argument_name_string (imp, 0));
758 break;
759
760 default:
761 assert ("La" == NULL);
762 break;
763 }
764 break;
765
766 case 'R':
767 switch (kind)
768 {
769 case '*':
770 printf ("@code{REAL}");
771 break;
772
773 case '1': case '2': case '3': case '4': case '5':
774 case '6': case '7': case '8': case '9':
775 printf ("@code{REAL(KIND=%d)}", (kind - '0'));
776 break;
777
778 case 'A':
779 printf ("@code{REAL} with same @samp{KIND=} value as for @var{%s}",
780 argument_name_string (imp, 0));
781 break;
782
783 default:
784 assert ("Ra" == NULL);
785 break;
786 }
787 break;
788
789 case 'B':
790 switch (kind)
791 {
792 case '*':
793 printf ("@code{INTEGER} or @code{LOGICAL}");
794 break;
795
796 case '1': case '2': case '3': case '4': case '5':
797 case '6': case '7': case '8': case '9':
798 printf ("@code{INTEGER(KIND=%d)} or @code{LOGICAL(KIND=%d)}",
799 (kind - '0'), (kind - '0'));
800 break;
801
802 case 'A':
803 printf ("Same type and @samp{KIND=} value as for @var{%s}",
804 argument_name_string (imp, 0));
805 break;
806
807 default:
808 assert ("Ba" == NULL);
809 break;
810 }
811 break;
812
813 case 'F':
814 switch (kind)
815 {
816 case '*':
817 printf ("@code{REAL} or @code{COMPLEX}");
818 break;
819
820 case '1': case '2': case '3': case '4': case '5':
821 case '6': case '7': case '8': case '9':
822 printf ("@code{REAL(KIND=%d)} or @code{COMPLEX(KIND=%d)}",
823 (kind - '0'), (kind - '0'));
824 break;
825
826 case 'A':
827 printf ("Same type as @var{%s}",
828 argument_name_string (imp, 0));
829 break;
830
831 default:
832 assert ("Fa" == NULL);
833 break;
834 }
835 break;
836
837 case 'N':
838 switch (kind)
839 {
840 case '*':
841 printf ("@code{INTEGER}, @code{REAL}, or @code{COMPLEX}");
842 break;
843
844 case '1': case '2': case '3': case '4': case '5':
845 case '6': case '7': case '8': case '9':
846 printf ("@code{INTEGER(KIND=%d)}, @code{REAL(KIND=%d)}, or @code{COMPLEX(KIND=%d)}",
847 (kind - '0'), (kind - '0'), (kind - '0'));
848 break;
849
850 default:
851 assert ("N1" == NULL);
852 break;
853 }
854 break;
855
856 case 'S':
857 switch (kind)
858 {
859 case '*':
860 printf ("@code{INTEGER} or @code{REAL}");
861 break;
862
863 case '1': case '2': case '3': case '4': case '5':
864 case '6': case '7': case '8': case '9':
865 printf ("@code{INTEGER(KIND=%d)} or @code{REAL(KIND=%d)}",
866 (kind - '0'), (kind - '0'));
867 break;
868
869 case 'A':
870 printf ("@code{INTEGER} or @code{REAL} with same @samp{KIND=} value as for @var{%s}",
871 argument_name_string (imp, 0));
872 break;
873
874 default:
875 assert ("Sa" == NULL);
876 break;
877 }
878 break;
879
880 case 'g':
881 printf ("@samp{*@var{label}}, where @var{label} is the label\n\
882 of an executable statement");
883 break;
884
885 case 's':
886 printf ("Signal handler (@code{INTEGER FUNCTION} or @code{SUBROUTINE})\n\
887 or dummy/global @code{INTEGER(KIND=1)} scalar");
888 break;
889
890 default:
891 assert ("arg type?" == NULL);
892 break;
893 }
894
895 switch (optionality)
896 {
897 case '\0':
898 break;
899
900 case '!':
901 printf ("; OPTIONAL (must be omitted if @var{%s} is @code{COMPLEX})",
902 argument_name_string (imp, argno-1));
903 break;
904
905 case '?':
906 printf ("; OPTIONAL");
907 break;
908
909 case '*':
910 printf ("; OPTIONAL");
911 break;
912
913 case 'n':
914 case '+':
915 break;
916
917 case 'p':
918 printf ("; at least two such arguments must be provided");
919 break;
920
921 default:
922 assert ("optionality!" == NULL);
923 break;
924 }
925
926 switch (elements)
927 {
928 case -1:
929 break;
930
931 case 0:
932 if ((basic != 'g')
933 && (basic != 's'))
934 printf ("; scalar");
935 break;
936
937 default:
938 assert (extra != '\0');
939 printf ("; DIMENSION(%d)", elements);
940 break;
941 }
942
943 switch (extra)
944 {
945 case '\0':
946 if ((basic != 'g')
947 && (basic != 's'))
948 printf ("; INTENT(IN)");
949 break;
950
951 case 'i':
952 break;
953
954 case '&':
955 printf ("; cannot be a constant or expression");
956 break;
957
958 case 'w':
959 printf ("; INTENT(OUT)");
960 break;
961
962 case 'x':
963 printf ("; INTENT(INOUT)");
964 break;
965 }
966
967 printf (".\n\n");
968 }
969
970 printf ("\
971 @noindent\n\
972 Intrinsic groups: ");
973 switch (family)
974 {
975 case FFEINTRIN_familyF77:
976 printf ("(standard FORTRAN 77).");
977 break;
978
979 case FFEINTRIN_familyGNU:
980 printf ("@code{gnu}.");
981 break;
982
983 case FFEINTRIN_familyASC:
984 printf ("@code{f2c}, @code{f90}.");
985 break;
986
987 case FFEINTRIN_familyMIL:
988 printf ("@code{mil}, @code{f90}, @code{vxt}.");
989 break;
990
991 case FFEINTRIN_familyF90:
992 printf ("@code{f90}.");
993 break;
994
995 case FFEINTRIN_familyVXT:
996 printf ("@code{vxt}.");
997 break;
998
999 case FFEINTRIN_familyFVZ:
1000 printf ("@code{f2c}, @code{vxt}.");
1001 break;
1002
1003 case FFEINTRIN_familyF2C:
1004 printf ("@code{f2c}.");
1005 break;
1006
1007 case FFEINTRIN_familyF2U:
1008 printf ("@code{unix}.");
1009 break;
1010
1011 case FFEINTRIN_familyBADU77:
1012 printf ("@code{badu77}.");
1013 break;
1014
1015 default:
1016 assert ("bad family" == NULL);
1017 printf ("@code{???}.");
1018 break;
1019 }
1020 printf ("\n\n");
1021
1022 if (descriptions[imp] != NULL)
1023 {
1024 char *c = descriptions[imp];
1025
1026 printf ("\
1027 @noindent\n\
1028 Description:\n\
1029 \n");
1030
1031 while (c[0] != '\0')
1032 {
1033 if ((c[0] == '@')
1034 && (c[1] >= '0')
1035 && (c[1] <= '9'))
1036 {
1037 int argno = c[1] - '0';
1038
1039 c += 2;
1040 while ((c[0] >= '0')
1041 && (c[0] <= '9'))
1042 {
1043 argno = 10 * argno + (c[0] - '0');
1044 ++c;
1045 }
1046 assert (c[0] == '@');
1047 if (argno == 0)
1048 printf ("%s", name_uc);
1049 else
1050 printf ("%s", argument_name_string (imp, argno - 1));
1051 }
1052 else
1053 fputc (c[0], stdout);
1054 ++c;
1055 }
1056
1057 printf ("\n");
1058 }
1059 }
1060
1061 static char *
1062 argument_info_ptr (ffeintrinImp imp, int argno)
1063 {
1064 char *c = imps[imp].control;
1065 static char arginfos[8][32];
1066 static int argx = 0;
1067 int i;
1068
1069 if (c[2] == ':')
1070 c += 5;
1071 else
1072 c += 6;
1073
1074 while (argno--)
1075 {
1076 while ((c[0] != ',') && (c[0] != '\0'))
1077 ++c;
1078 if (c[0] != ',')
1079 break;
1080 ++c;
1081 }
1082
1083 if (c[0] == '\0')
1084 return NULL;
1085
1086 for (; (c[0] != '=') && (c[0] != '\0'); ++c)
1087 ;
1088
1089 assert (c[0] == '=');
1090
1091 for (i = 0, ++c; (c[0] != ',') && (c[0] != '\0'); ++c, ++i)
1092 arginfos[argx][i] = c[0];
1093
1094 arginfos[argx][i] = '\0';
1095
1096 c = &arginfos[argx][0];
1097 ++argx;
1098 if (((size_t) argx) >= ARRAY_SIZE (arginfos))
1099 argx = 0;
1100
1101 return c;
1102 }
1103
1104 static char *
1105 argument_info_string (ffeintrinImp imp, int argno)
1106 {
1107 char *p;
1108
1109 p = argument_info_ptr (imp, argno);
1110 assert (p != NULL);
1111 return p;
1112 }
1113
1114 static char *
1115 argument_name_ptr (ffeintrinImp imp, int argno)
1116 {
1117 char *c = imps[imp].control;
1118 static char argnames[8][32];
1119 static int argx = 0;
1120 int i;
1121
1122 if (c[2] == ':')
1123 c += 5;
1124 else
1125 c += 6;
1126
1127 while (argno--)
1128 {
1129 while ((c[0] != ',') && (c[0] != '\0'))
1130 ++c;
1131 if (c[0] != ',')
1132 break;
1133 ++c;
1134 }
1135
1136 if (c[0] == '\0')
1137 return NULL;
1138
1139 for (i = 0; (c[0] != '=') && (c[0] != '\0'); ++c, ++i)
1140 argnames[argx][i] = c[0];
1141
1142 assert (c[0] == '=');
1143 argnames[argx][i] = '\0';
1144
1145 c = &argnames[argx][0];
1146 ++argx;
1147 if (((size_t) argx) >= ARRAY_SIZE (argnames))
1148 argx = 0;
1149
1150 return c;
1151 }
1152
1153 static char *
1154 argument_name_string (ffeintrinImp imp, int argno)
1155 {
1156 char *p;
1157
1158 p = argument_name_ptr (imp, argno);
1159 assert (p != NULL);
1160 return p;
1161 }
1162
1163 static void
1164 print_type_string (char *c)
1165 {
1166 char basic = c[0];
1167 char kind = c[1];
1168
1169 switch (basic)
1170 {
1171 case 'A':
1172 assert ((kind == '1') || (kind == '='));
1173 if (c[2] == ':')
1174 printf ("@code{CHARACTER*1}");
1175 else
1176 {
1177 assert (c[2] == '*');
1178 printf ("@code{CHARACTER*(*)}");
1179 }
1180 break;
1181
1182 case 'C':
1183 switch (kind)
1184 {
1185 case '=':
1186 printf ("@code{COMPLEX}");
1187 break;
1188
1189 case '1': case '2': case '3': case '4': case '5':
1190 case '6': case '7': case '8': case '9':
1191 printf ("@code{COMPLEX(KIND=%d)}", (kind - '0'));
1192 break;
1193
1194 default:
1195 assert ("Ca" == NULL);
1196 break;
1197 }
1198 break;
1199
1200 case 'I':
1201 switch (kind)
1202 {
1203 case '=':
1204 printf ("@code{INTEGER}");
1205 break;
1206
1207 case '1': case '2': case '3': case '4': case '5':
1208 case '6': case '7': case '8': case '9':
1209 printf ("@code{INTEGER(KIND=%d)}", (kind - '0'));
1210 break;
1211
1212 case 'p':
1213 printf ("@code{INTEGER(KIND=0)}");
1214 break;
1215
1216 default:
1217 assert ("Ia" == NULL);
1218 break;
1219 }
1220 break;
1221
1222 case 'L':
1223 switch (kind)
1224 {
1225 case '=':
1226 printf ("@code{LOGICAL}");
1227 break;
1228
1229 case '1': case '2': case '3': case '4': case '5':
1230 case '6': case '7': case '8': case '9':
1231 printf ("@code{LOGICAL(KIND=%d)}", (kind - '0'));
1232 break;
1233
1234 default:
1235 assert ("La" == NULL);
1236 break;
1237 }
1238 break;
1239
1240 case 'R':
1241 switch (kind)
1242 {
1243 case '=':
1244 printf ("@code{REAL}");
1245 break;
1246
1247 case '1': case '2': case '3': case '4': case '5':
1248 case '6': case '7': case '8': case '9':
1249 printf ("@code{REAL(KIND=%d)}", (kind - '0'));
1250 break;
1251
1252 case 'C':
1253 printf ("@code{REAL}");
1254 break;
1255
1256 default:
1257 assert ("Ra" == NULL);
1258 break;
1259 }
1260 break;
1261
1262 case 'B':
1263 switch (kind)
1264 {
1265 case '=':
1266 printf ("@code{INTEGER} or @code{LOGICAL}");
1267 break;
1268
1269 case '1': case '2': case '3': case '4': case '5':
1270 case '6': case '7': case '8': case '9':
1271 printf ("@code{INTEGER(KIND=%d)} or @code{LOGICAL(KIND=%d)}",
1272 (kind - '0'), (kind - '0'));
1273 break;
1274
1275 default:
1276 assert ("Ba" == NULL);
1277 break;
1278 }
1279 break;
1280
1281 case 'F':
1282 switch (kind)
1283 {
1284 case '=':
1285 printf ("@code{REAL} or @code{COMPLEX}");
1286 break;
1287
1288 case '1': case '2': case '3': case '4': case '5':
1289 case '6': case '7': case '8': case '9':
1290 printf ("@code{REAL(KIND=%d)} or @code{COMPLEX(KIND=%d)}",
1291 (kind - '0'), (kind - '0'));
1292 break;
1293
1294 default:
1295 assert ("Fa" == NULL);
1296 break;
1297 }
1298 break;
1299
1300 case 'N':
1301 switch (kind)
1302 {
1303 case '=':
1304 printf ("@code{INTEGER}, @code{REAL}, or @code{COMPLEX}");
1305 break;
1306
1307 case '1': case '2': case '3': case '4': case '5':
1308 case '6': case '7': case '8': case '9':
1309 printf ("@code{INTEGER(KIND=%d)}, @code{REAL(KIND=%d)}, or @code{COMPLEX(KIND=%d)}",
1310 (kind - '0'), (kind - '0'), (kind - '0'));
1311 break;
1312
1313 default:
1314 assert ("N1" == NULL);
1315 break;
1316 }
1317 break;
1318
1319 case 'S':
1320 switch (kind)
1321 {
1322 case '=':
1323 printf ("@code{INTEGER} or @code{REAL}");
1324 break;
1325
1326 case '1': case '2': case '3': case '4': case '5':
1327 case '6': case '7': case '8': case '9':
1328 printf ("@code{INTEGER(KIND=%d)} or @code{REAL(KIND=%d)}",
1329 (kind - '0'), (kind - '0'));
1330 break;
1331
1332 default:
1333 assert ("Sa" == NULL);
1334 break;
1335 }
1336 break;
1337
1338 default:
1339 assert ("arg type?" == NULL);
1340 break;
1341 }
1342 }
This page took 0.096938 seconds and 5 git commands to generate.