int sampgdk_array_remove(struct sampgdk_array *a, int index, int count) { int move_count; assert(a != NULL); assert(index >= 0); assert(index < a->count); if (count <= 0 || count > a->count - index) { return -EINVAL; } move_count = a->count - index - count; if (move_count > 0) { memmove(get_element_ptr(a, index), get_element_ptr(a, index + count), move_count * a->elem_size); } a->count -= count; if (a->count <= a->size / 4) { return sampgdk_array_resize(a, a->size / 2); } return 0; }
void sampgdk_array_set(struct sampgdk_array *a, int index, void *elem) { assert(a != NULL); assert(elem != NULL); assert(index >= 0); assert(index < a->count); memcpy(get_element_ptr(a, index), elem, a->elem_size); }
int sampgdk_array_insert(struct sampgdk_array *a, int index, int count, void *elems) { int need_count; int move_count; assert(a != NULL); assert(elems != NULL); assert(index >= 0); assert(index < a->count); if (count <= 0) { return -EINVAL; } need_count = a->count + count - a->size; move_count = a->count - index; if (need_count > 0) { int error; if ((error = sampgdk_array_resize(a, a->size + need_count)) < 0) { return error; } } if (move_count > 0) { memmove(get_element_ptr(a, index + count), get_element_ptr(a, index), move_count * a->elem_size); } a->count += count; memcpy(get_element_ptr(a, index), elems, count * a->elem_size); return 0; }
/* * Parse parameter list. * Parse DECLARE statements until all parameters in param_list * have been found. Split declare statements into those used in * param_list and those not. Return pointers to head of both * DECL_MEMBER lists. */ void parse_param_list(PARAM_LIST *param_list, DECL **decl_list, DECL **extra_decl_list) { DECL *extra_decl, *extra_decl_ptr; DECL *list, *list_ptr; DECL_MEMBER *extra_list_ptr; DECL_MEMBER *el_ptr, *last_el_ptr, *next_el_ptr; DECL_MEMBER *extra_el_ptr; int token_class; TOKEN *decl_token; DECL_ID *var_ptr, *last_var_ptr, *next_var_ptr; DECL_ID *extra_last_var_ptr; PARAM_LIST *param_ptr, *last_param; *decl_list = NULL; *extra_decl_list = NULL; /* Pointer to next DECL_MEMBER in decl_ptr */ list_ptr = NULL; /* Pointer to next DECL in extra_decl_list */ extra_decl_ptr = NULL; while (param_list) { /* Get declaration */ get_token_ptr(&decl_token); token_class = get_token(decl_token); if ((token_class != RESERVED) || (decl_token->token_type != DECLARE)) { parse_error("DECLARE expected"); free((char *) decl_token); return; } /* Get declaration list */ get_decl_ptr(&list); get_decl_list(list); list->decl_token = decl_token; /* Points to start of extra declaration list */ extra_list_ptr = NULL; /* Pointer to previous el_ptr */ last_el_ptr = NULL; /* Check each element of the DECLARE statement */ el_ptr = list->decl_list; while (el_ptr) { /* Point to next member */ next_el_ptr = el_ptr->next_member; /* Pointer to next DECL_MEMBER in extra_decl_ptr */ extra_el_ptr = NULL; /* Points to last variable in variable list */ last_var_ptr = NULL; /* Contains not found variables in name_list */ extra_last_var_ptr = NULL; /* Check each variable in name list */ for (var_ptr = el_ptr->name_list; var_ptr; ) { /* Point to following var_ptr */ next_var_ptr = var_ptr->next_var; /* Is this variable in param list? */ last_param = NULL; for (param_ptr = param_list; param_ptr; param_ptr = param_ptr->next_param) { if (!strcmp(param_ptr->param.token_name, var_ptr->name->token_name)) break; else last_param = param_ptr; } if (param_ptr) { /* Variable found */ /* Remove from parameter list */ if (last_param) last_param->next_param = param_ptr->next_param; else param_list = param_ptr->next_param; free((char *) param_ptr); last_var_ptr = var_ptr; } else { /* * Variable not found - Add to extra variable list */ if (extra_el_ptr == NULL) { /* * Create new element and copy DECLARE info */ get_element_ptr(&extra_el_ptr); element_copy(el_ptr, extra_el_ptr); extra_last_var_ptr = NULL; /* * Link new extra element into extra_list_ptr */ if (extra_list_ptr) { extra_list_ptr->next_member = extra_el_ptr; } else { /* * Create new extra declaration */ get_decl_ptr(&extra_decl); /* Point to DECLARE token */ extra_decl->decl_token = list->decl_token; extra_decl->decl_list = extra_el_ptr; /* * Link new extra declaration into extra_decl_list */ if (extra_decl_ptr) extra_decl_ptr->next_decl = extra_decl; else *extra_decl_list = extra_decl; extra_decl_ptr = extra_decl; } extra_list_ptr = extra_el_ptr; } /* Add var_ptr to extra list */ if (extra_last_var_ptr) extra_last_var_ptr->next_var = var_ptr; else extra_list_ptr->name_list = var_ptr; extra_last_var_ptr = var_ptr; /* Remove from DECLARE list */ if (last_var_ptr) last_var_ptr->next_var = next_var_ptr; else el_ptr->name_list = next_var_ptr; var_ptr->next_var = NULL; } var_ptr = next_var_ptr; } /* * Check for empty name list */ if (el_ptr->name_list == NULL) { /* * Empty name list - unlink and discard element from declaration list */ if (last_el_ptr) last_el_ptr->next_member = next_el_ptr; else list->decl_list = next_el_ptr; el_ptr->next_member = NULL; free((char *) el_ptr); } else last_el_ptr = el_ptr; el_ptr = next_el_ptr; } /* Save found items in decl_list */ if (list->decl_list->name_list) { if (*decl_list) list_ptr->next_decl = list; else *decl_list = list; list_ptr = list; } else free((char *) list); } }
/* * Parse statement starting with an identifier. * Possibilities include: * Assignment * Procedure statement */ void parse_identifier(TOKEN *first_token) { TOKEN token, next_token; TOKEN param_token, attrib_token, type_token; int token_class, next_token_class; DECL *decl_list, *extra_decl_list; PARAM_LIST *param_list, *param_ptr; DECL_MEMBER *decl_ptr; DECL_ID *decl_id; BOOLEAN extern_proc, got_type, interrupt_proc; char *tmp_text_ptr; /* Check for label or procedure */ tmp_text_ptr = text_ptr; token_class = get_token(&token); if (token_class == LABEL) { /* Determine if label or procedure definition */ next_token_class = get_token(&next_token); if ((next_token_class == RESERVED) && (next_token.token_type == PROCEDURE)) { /* * Procedure - Check for parameter list */ param_list = NULL; token_class = get_token(¶m_token); if (token_class == LEFT_PAREN) { /* Yes - get parameter list */ get_param_list(¶m_list); /* Get token after parameter list */ token_class = get_token(&attrib_token); } else /* No param list - save as attribute */ token_copy(¶m_token, &attrib_token); out_white_space(first_token); extern_proc = FALSE; interrupt_proc = FALSE; got_type = (token_class == RESERVED) && (attrib_token.token_type >= BYTE) && (attrib_token.token_type <= SELECTOR); if (got_type) { /* * Process [ <type> ] */ token_copy(&attrib_token, &type_token); token_class = get_token(&attrib_token); } while (token_class == RESERVED) { if (attrib_token.token_type == INTERRUPT) { /* * Process [ <interrupt> ] */ interrupt_proc = TRUE; token_class = get_token(&attrib_token); if (token_class == NUMERIC) /* Interrupt number */ token_class = get_token(&attrib_token); } else /* * Process [ EXTERNAL | { [ PUBLIC ] [ REENTRANT ] } ] */ if (attrib_token.token_type == EXTERNAL) { out_str("extern"); out_must_white(&attrib_token); extern_proc = TRUE; token_class = get_token(&attrib_token); } else if ((attrib_token.token_type == PUBLIC) || (attrib_token.token_type == REENTRANT)) { do { if (attrib_token.token_type == PUBLIC) { /* Ignore for now */ token_class = get_token(&attrib_token); } else if (attrib_token.token_type == REENTRANT) { /* Ignore for now */ token_class = get_token(&attrib_token); } else break; } while (token_class == RESERVED); } else break; } if (token_class != END_OF_LINE) { parse_error("';' expected"); return; } if (interrupt_proc && !extern_proc) parse_warning("INTERRUPT procedure declared"); /* Create declaration for procedure */ get_element_ptr(&decl_ptr); get_var_ptr(&decl_ptr->name_list); /* Type = PROCEDURE */ get_token_ptr(&decl_ptr->type); token_copy(&next_token, decl_ptr->type); /* Name = procedure name */ get_token_ptr(&decl_ptr->name_list->name); token_copy(first_token, decl_ptr->name_list->name); /* Flag if parameter list */ if (param_list) decl_ptr->initialization = DATA; /* Add it to context */ add_to_context(decl_ptr); if (got_type) { /* Output procedure type */ out_token_name(&type_token); out_must_white(&type_token); } /* Output procedure name */ out_token_name(first_token); if (extern_proc) { out_str("()"); if (param_list) /* Parse parameter declarations */ parse_param_list(param_list, &decl_list, &extra_decl_list); out_char(';'); /* Eat closing 'END [<proc name>];' */ token_class = get_token(&token); if ((token_class != RESERVED) || (token.token_type != END)) { parse_error("END expected"); return; } out_white_space(&token); token_class = get_token(&token); if (token_class == IDENTIFIER) { token_class = get_token(&token); } if (token_class != END_OF_LINE) { parse_error("';' expected"); } return; } else if (param_list) { out_token(¶m_token); /* Output parameter list */ param_ptr = param_list; while (param_ptr) { out_token(¶m_ptr->param); param_ptr = param_ptr->next_param; if (param_ptr) out_char(','); } out_char(')'); /* Parse parameter declarations */ parse_param_list(param_list, &decl_list, &extra_decl_list); /* Output declarations */ if (decl_list) { out_decl(decl_list); /* Add declarations to context */ add_decl_to_context(decl_list); } out_str("\n{"); /* } for dumb vi */ if (extra_decl_list) { out_decl(extra_decl_list); /* Add declarations to context */ add_decl_to_context(extra_decl_list); } /* Discard declarations */ free_decl(decl_list); free_decl(extra_decl_list); } else /* No parameter list */ out_str("()\n{"); /* } for dumb vi */ /* Create new context */ new_context(PROCEDURE, first_token); /* Parse statements to END */ parse_to_end(); /* Pop procedure context */ pop_context(); } else { /* * Label - add label name */ out_token(first_token); /* Add colon */ out_token(&token); /* Is this a defined label or a module? */ if (find_symbol(first_token, &decl_ptr, &decl_id)) { if (decl_ptr->type->token_class == LABEL) { /* Label - new context */ new_context(MODULE, first_token); parse_statement(&next_token); pop_context(); } else { parse_error("Illegal label name"); return; } } else parse_statement(&next_token); } return; } /* Assignment statement */ text_ptr = tmp_text_ptr; token_copy(first_token, &token); token_class = parse_variable(&token, &decl_ptr, &decl_id); /* Check for multiple assignments */ while (token_class == COMMA) { /* Print ' =' instead of ',' */ out_str(" ="); out_white_space(&token); /* Get identifier part of next assignment variable */ token_class = get_token(&token); if (token_class != IDENTIFIER) { parse_error("Illegal assignment"); return; } /* Parse remainder of variable (if any) */ token_class = parse_variable(&token, &decl_ptr, &decl_id); } if (token_class == OPERATOR) { if (token.token_type != EQUAL) { parse_error("Illegal use of identifier"); return; } out_token(&token); /* Check for POINTER assignment */ if (decl_ptr->type->token_type == POINTER) { /* Yes - cast it */ out_str(" ("); out_str(TYPE_POINTER); out_str(" *) "); } if (parse_expression(&token) != END_OF_LINE) parse_error("';' expected"); else out_token(&token); return; } else if (token_class != LABEL) { parse_error("Illegal use of identifier"); return; } }
void *sampgdk_array_get(struct sampgdk_array *a, int index) { assert(a != NULL); assert(index >= 0); assert(index < a->count); return get_element_ptr(a, index); }