/* %Z%%M% %I% %E% */ /* * Copyright (c) 1992, 1993, 1995 by Wayne C. Gramlich. * All rights reserved. * * Permission to use, copy, modify, distribute, and sell this software * for any purpose is hereby granted without fee provided that the above * copyright notice and this permission are retained. The author makes * no representations about the suitability of this software for any purpose. * It is provided "as is" without express or implied warranty. */ /* This file will parse a routine_info signature string: */ #ifndef HEAP_EXPORTS_H #include "heap_exports.h" #endif #ifndef ROUTINE_INFO_DEFS_H #include "routine_info_defs.h" #endif #ifndef UNIX_ASSERT_H #include "unix_assert.h" #endif #ifndef UNIX_CTYPE_H #include "unix_ctype.h" #endif #ifndef UNIX_STDLIB_H #include "unix_stdlib.h" #endif #ifndef UNIX_UNISTD_H #include "unix_unistd.h" #endif #ifndef VECTOR_DEFS_H #include "vector_defs.h" #endif static Str symbol_get(Str, Heap); static Str type_ref_get(Str, Heap); /* * routine__info__parse(info, heap) * This routine will parse and return a routine__info__type object * allocated from "heap" using "info". */ routine__info__type routine__info__parse( Str info, Heap heap) { Vec(Str) argument_names; Vec(Str) argument_type_refs; int index; int line_number; Vec(int) line_numbers; Str name; Vec(Str) return_type_refs; routine__info__type routine_info; Str routine_name; Str type_name; Str type_ref; Vec(Str) variable_names; Vec(Str) variable_type_refs; Vec(Str) yield_type_refs; routine_name = symbol_get(info, heap); info += strlen(routine_name); if (info[0] == '@') { info++; type_name = symbol_get(info, heap); info += strlen(type_name); } else { type_name = "global__"; } /* Set up all of the fields; */ argument_names = vec_create(Str, heap); argument_type_refs = vec_create(Str, heap); line_numbers = vec_create(int, heap); return_type_refs = vec_create(Str, heap); variable_names = vec_create(Str, heap); variable_type_refs = vec_create(Str, heap); yield_type_refs = vec_create(Str, heap); /* Extract the rest of the information: */ do { switch (info[0]) { case '(': /* Arguments */ info++; while (info[0] != ')') { name = symbol_get(info, heap); vec_append(Str, argument_names, name); info += strlen(name) + 1; type_ref = type_ref_get(info, heap); info += strlen(type_ref); vec_append(Str, argument_type_refs, type_ref); if (info[0] == ',') { info++; } } info++; break; case '=': /* Returns */ index = 0; info++; info++; do { info++; index++; type_ref = type_ref_get(info, heap); vec_append(Str, return_type_refs, type_ref); info += strlen(type_ref); name = strprintf(heap, "return__value__%d", index); } while (info[0] == ','); info++; break; case '-': /* Yields */ info++; index = 0; do { info++; index++; type_ref = type_ref_get(info, heap); vec_append(Str, yield_type_refs, type_ref); info += strlen(type_ref); name = strprintf(heap, "yield__value__%d", index); } while (info[0] == ','); break; case '{': /* Variables: */ info++; while (info[0] != '}') { name = symbol_get(info, heap); vec_append(Str, variable_names, name); info += strlen(name) + 1; type_ref = type_ref_get(info, heap); info += strlen(type_ref); vec_append(Str, variable_type_refs, type_ref); if (info[0] == ',') { info++; } } info++; break; case '[': info++; do { line_number = atoi(info); vec_append(int, line_numbers, line_number); while (isdigit(info[0])) { info++; } } while (*info++ != ']'); break; case '\0': /* All done: */ break; default: assert_fail(); } } while (info[0] != '\0'); routine_info = heap_allocate(heap, routine__info__type); routine_info->argument_names = argument_names; routine_info->argument_type_refs = argument_type_refs; routine_info->breakpoints = (char *)0; routine_info->instantiations = (instantiation___object *)0; routine_info->line_numbers = line_numbers; routine_info->name = routine_name; routine_info->return_type_refs = return_type_refs; routine_info->type_name = type_name; routine_info->variable_names = variable_names; routine_info->variable_type_refs = variable_type_refs; routine_info->yield_type_refs = yield_type_refs; return routine_info; } /* * symbol_get(info, heap) * This routine will return the symbol at the front of "info" allocated * from "heap". */ static Str symbol_get( Str info, Heap heap) { char chr; Str pointer; Str result; int size; pointer = info; do { chr = *pointer++; } while (isalpha(chr) || (chr == '_') || isdigit(chr)); size = pointer - info; result = (Str)heap_alloc(heap, size); size--; (void)strncpy(result, info, size); result[size] = '\0'; return result; } /* * routine__info__type_ref_get(info, heap) * This routine will get the next type reference from "info" using * "heap". */ static Str type_ref_get( Str info, Heap heap) { int bracket_count; char chr; Str pointer; Str result; int size; bracket_count = 0; pointer = info; do { chr = *pointer++; if (chr == '[') { bracket_count++; do { chr = *pointer++; switch (chr) { case '[': bracket_count++; break; case ']': bracket_count--; break; } } while (bracket_count != 0); chr = *pointer++; } } while (isalpha(chr) || (chr == '_') || isdigit(chr)); size = pointer - info; result = (Str)heap_alloc(heap, size); size--; (void)strncpy(result, info, size); result[size] ='\0'; return result; }