1 
2 /* List a node on a file */
3 
4 #include "Python.h"
5 #include "pycore_interp.h"        // PyInterpreterState.parser
6 #include "pycore_pystate.h"       // _PyInterpreterState_GET()
7 #include "token.h"
8 #include "node.h"
9 
10 /* Forward */
11 static void list1node(FILE *, node *);
12 static void listnode(FILE *, node *);
13 
14 void
PyNode_ListTree(node * n)15 PyNode_ListTree(node *n)
16 {
17     listnode(stdout, n);
18 }
19 
20 static void
listnode(FILE * fp,node * n)21 listnode(FILE *fp, node *n)
22 {
23     PyInterpreterState *interp = _PyInterpreterState_GET();
24 
25     interp->parser.listnode.level = 0;
26     interp->parser.listnode.atbol = 1;
27     list1node(fp, n);
28 }
29 
30 static void
list1node(FILE * fp,node * n)31 list1node(FILE *fp, node *n)
32 {
33     PyInterpreterState *interp;
34 
35     if (n == NULL)
36         return;
37     if (ISNONTERMINAL(TYPE(n))) {
38         int i;
39         for (i = 0; i < NCH(n); i++)
40             list1node(fp, CHILD(n, i));
41     }
42     else if (ISTERMINAL(TYPE(n))) {
43         interp = _PyInterpreterState_GET();
44         switch (TYPE(n)) {
45         case INDENT:
46             interp->parser.listnode.level++;
47             break;
48         case DEDENT:
49             interp->parser.listnode.level--;
50             break;
51         default:
52             if (interp->parser.listnode.atbol) {
53                 int i;
54                 for (i = 0; i < interp->parser.listnode.level; ++i)
55                     fprintf(fp, "\t");
56                 interp->parser.listnode.atbol = 0;
57             }
58             if (TYPE(n) == NEWLINE) {
59                 if (STR(n) != NULL)
60                     fprintf(fp, "%s", STR(n));
61                 fprintf(fp, "\n");
62                 interp->parser.listnode.atbol = 1;
63             }
64             else
65                 fprintf(fp, "%s ", STR(n));
66             break;
67         }
68     }
69     else
70         fprintf(fp, "? ");
71 }
72