00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #define _GNU_SOURCE
00026 #include <stdlib.h>
00027 #include <stdio.h>
00028 #include <inttypes.h>
00029 #include <stdint.h>
00030 #include <math.h>
00031 #include <limits.h>
00032 #include <errno.h>
00033 #include <unistd.h>
00034 #include <string.h>
00035 #include <stdarg.h>
00036 #include <arpa/inet.h>
00037 #include <yyast/node.h>
00038 #include <yyast/utils.h>
00039 #include <yyast/config.h>
00040 #include <yyast/count.h>
00041
00042 ya_t YA_NODE_DEFAULT = {
00043 .type = YA_NODE_TYPE_NULL,
00044 .position = {.line = UINT32_MAX, .column = UINT32_MAX, .file = UINT32_MAX},
00045 .size = sizeof (ya_node_t),
00046 .node = NULL
00047 };
00048
00049 ya_t ya_generic_nodev(const char * restrict name, ya_type_t type, va_list ap)
00050 {
00051 va_list ap2;
00052 ya_t *item;
00053 size_t item_size = 0;
00054 ya_t self = YA_NODE_DEFAULT;
00055 off_t self_offset = 0;
00056
00057 va_copy(ap2, ap);
00058
00059
00060 self.type = type;
00061 for (item = va_arg(ap, ya_t *); item != NULL; item = va_arg(ap, ya_t *)) {
00062 if (self.position.file == UINT32_MAX && item->position.file != UINT32_MAX) {
00063
00064 self.position.file = item->position.file;
00065 self.position.line = item->position.line;
00066 self.position.column = item->position.column;
00067
00068 } else if (self.position.file == item->position.file) {
00069
00070 if (item->position.line < self.position.line) {
00071 self.position.line = item->position.line;
00072 self.position.column = item->position.column;
00073
00074 } else if ((item->position.line == self.position.line) && (item->position.column < self.position.column)) {
00075 self.position.column = item->position.column;
00076 }
00077 }
00078
00079 switch (item->type) {
00080 case YA_NODE_TYPE_COUNT:
00081 fprintf(stderr, "Found YA_NODE_TYPE_COUNT token, which is only allowed for line counting\n");
00082 abort();
00083
00084 case YA_NODE_TYPE_LIST:
00085
00086 self.size+= item->size - sizeof (ya_node_t);
00087 break;
00088
00089 default:
00090
00091 self.size+= item->size;
00092 }
00093 }
00094
00095
00096 self.node = calloc(1, self.size);
00097 self.node->name = htonll(ya_create_name(name));
00098 self.node->type = self.type;
00099 self.node->size = htonll(self.size);
00100 self.node->position.file = htonl(self.position.file);
00101 self.node->position.line = htonl(self.position.line);
00102 self.node->position.column = htonl(self.position.column);
00103
00104
00105 for (item = va_arg(ap2, ya_t *); item != NULL; item = va_arg(ap2, ya_t *)) {
00106 switch (item->type) {
00107 case YA_NODE_TYPE_COUNT:
00108 fprintf(stderr, "Found YA_NODE_TYPE_COUNT token, which is only allowed for line counting\n");
00109 abort();
00110
00111 case YA_NODE_TYPE_LIST:
00112
00113 item_size = item->size - sizeof (ya_node_t);
00114 memcpy(&(self.node->data[self_offset]), item->node->data, item_size);
00115 self_offset+= item_size;
00116 break;
00117
00118 default:
00119
00120 item_size = item->size;
00121 memcpy(&(self.node->data[self_offset]), item->node, item_size);
00122 self_offset+= item_size;
00123 }
00124
00125
00126 free(item->node);
00127 }
00128
00129 va_end(ap2);
00130
00131
00132 if (self.position.file == UINT32_MAX) {
00133 self.position = ya_previous_position;
00134 }
00135
00136 return self;
00137 }
00138
00139 ya_t ya_generic_node(const char * restrict name, ya_type_t type, ...)
00140 {
00141 ya_t r;
00142 va_list ap;
00143
00144 va_start(ap, type);
00145 r = ya_generic_nodev(name, type, ap);
00146 va_end(ap);
00147
00148 return r;
00149 }
00150
00151 ya_t ya_branch(const char * restrict name, ...)
00152 {
00153 ya_t r;
00154 va_list ap;
00155
00156 va_start(ap, name);
00157 r = ya_generic_nodev(name, YA_NODE_TYPE_BRANCH, ap);
00158 va_end(ap);
00159
00160 return r;
00161 }
00162
00163 ya_t ya_list(const char * restrict name, ...)
00164 {
00165 ya_t r;
00166 va_list ap;
00167
00168 va_start(ap, name);
00169 r = ya_generic_nodev(name, YA_NODE_TYPE_LIST, ap);
00170 va_end(ap);
00171
00172 return r;
00173 }
00174
00175 void ya_node_save(FILE *output_file, ya_t *node)
00176 {
00177 fwrite(node->node, node->size, 1, output_file);
00178 }
00179