File indexing completed on 2024-04-28 04:35:56

0001 /* This file is part of KDevelop
0002  *
0003  * Copyright (C) 2010-2015 Miquel Sabaté Solà <mikisabate@gmail.com>
0004  *
0005  * This program is free software: you can redistribute it and/or modify
0006  * it under the terms of the GNU General Public License as published by
0007  * the Free Software Foundation, either version 3 of the License, or
0008  * (at your option) any later version.
0009  *
0010  * This program is distributed in the hope that it will be useful,
0011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013  * GNU General Public License for more details.
0014  *
0015  * You should have received a copy of the GNU General Public License
0016  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0017  */
0018 
0019 
0020 #ifdef BUILD_TESTS
0021 #include <stdio.h>
0022 #endif
0023 #include <stdlib.h>
0024 
0025 #include "node.h"
0026 
0027 
0028 /*
0029  * alloc functions.
0030  */
0031 
0032 struct Node * alloc_node(int kind, struct Node *l, struct Node *r)
0033 {
0034     struct Node *n = (struct Node *) malloc(sizeof(struct Node));
0035 
0036     if (!n)
0037         exit(0);
0038     n->kind = kind;
0039     n->flags = 0;
0040     n->name = NULL;
0041     n->context = NULL;
0042     n->comment = NULL;
0043     n->next = NULL;
0044     n->last = NULL;
0045     n->cond = NULL;
0046     n->ensure = NULL;
0047     n->l = l;
0048     n->r = r;
0049     n->pos.offset = 0;
0050     n->pos.start_line = n->pos.end_line = -1;
0051     n->pos.start_col = n->pos.end_col = -1;
0052     return n;
0053 }
0054 
0055 struct Node * alloc_cond(int kind, struct Node *cond, struct Node *l, struct Node *r)
0056 {
0057     struct Node *n = alloc_node(kind, l, r);
0058     n->cond = cond;
0059     return n;
0060 }
0061 
0062 struct Node * alloc_ensure(int kind, struct Node *l, struct Node *r,
0063                            struct Node *els, struct Node *ensure)
0064 {
0065     struct Node *n = alloc_cond(kind, els, l, r);
0066     n->ensure = ensure;
0067     return n;
0068 }
0069 
0070 
0071 /*
0072  * List manipulation functions
0073  */
0074 
0075 struct Node * create_list(struct Node *head, struct Node *tail)
0076 {
0077     head->next = tail;
0078     head->last = tail->last;
0079     return head;
0080 }
0081 
0082 struct Node * update_list(struct Node *head, struct Node *tail)
0083 {
0084     if (!tail)
0085         return head;
0086     (head->last == NULL) ? (head->next = tail) : (head->last->next = tail);
0087     tail->next = NULL;
0088     head->last = tail;
0089     return head;
0090 }
0091 
0092 struct Node * concat_list(struct Node *head, struct Node *tail)
0093 {
0094     if (!tail)
0095         return head;
0096     (head->last == NULL) ? (head->next = tail) : (head->last->next = tail);
0097     head->last = (tail->last) ? tail->last : tail;
0098     return head;
0099 }
0100 
0101 /*
0102  * Auxiliar functions
0103  */
0104 
0105 #ifdef BUILD_TESTS
0106 
0107 void raw_print(struct Node *n)
0108 {
0109     printf("%i", n->kind);
0110     if (n->name != NULL)
0111         printf("(%s)", n->name);
0112     if (n->pos.start_line != -1 && n->pos.start_col != -1 &&
0113         n->pos.end_line != -1 && n->pos.end_col != -1) {
0114         printf("[%i,%i:%i,%i] ", n->pos.start_line, n->pos.start_col,
0115                                     n->pos.end_line, n->pos.end_col);
0116     } else
0117         printf(" ");
0118 }
0119 
0120 void print_list(struct Node *n)
0121 {
0122     struct Node * p;
0123 
0124     printf("\nNext statements: ");
0125     for (p = n; p != NULL; p = p->next)
0126         raw_print(p);
0127     printf("\nRoot: ");
0128 }
0129 
0130 void print_node(struct Node *n)
0131 {
0132     if (n != NULL) {
0133         print_node(n->l);
0134         raw_print(n);
0135         print_node(n->r);
0136         if (n->next != NULL)
0137             print_list(n->next);
0138     }
0139 }
0140 
0141 void print_errors(struct error_t *e)
0142 {
0143     struct error_t *aux;
0144 
0145     for (aux = e; aux; aux = aux->next)
0146         printf("Line: %i, Column: %i; %s\n", aux->line, aux->column, aux->msg);
0147 }
0148 
0149 #endif
0150 
0151 void free_ast(struct Node *n)
0152 {
0153     if (!n)
0154         return;
0155 
0156     free_ast(n->next);
0157     free_ast(n->l);
0158     free_ast(n->r);
0159     free_ast(n->cond);
0160     free_ast(n->ensure);
0161     if (n->name)
0162         free(n->name);
0163     if (n->comment) {
0164         free(n->comment);
0165         n->comment = NULL;
0166     }
0167     free(n);
0168 }
0169 
0170 void free_errors(struct ast_t *ra)
0171 {
0172     struct error_t *aux;
0173 
0174     for (aux = ra->errors; aux; aux = aux->next)
0175         free(aux->msg);
0176 }
0177 
0178 /*
0179  * Interface to the parser
0180  */
0181 
0182 void rb_free(struct ast_t *ra)
0183 {
0184     free_ast(ra->tree);
0185     free_errors(ra);
0186     free(ra);
0187 }
0188 
0189 struct Node * rb_name_node(struct Node *n)
0190 {
0191     struct Node *name;
0192     const char isMethod = (n->kind == token_function);
0193 
0194     if (isMethod)
0195         name = (n->cond->r != NULL) ? n->cond->r : n->cond;
0196     else
0197         name = (n->r->last != NULL) ? n->r->last : n->r;
0198     return name;
0199 }