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 }