📄 array.c
字号:
* Allocate and return a new array element with index INDEX and value * VALUE. */ARRAY_ELEMENT *array_create_element(indx, value)arrayind_t indx;char *value;{ ARRAY_ELEMENT *r; r = (ARRAY_ELEMENT *)xmalloc(sizeof(ARRAY_ELEMENT)); r->ind = indx; r->value = value ? savestring(value) : (char *)NULL; r->next = r->prev = (ARRAY_ELEMENT *) NULL; return(r);}#ifdef INCLUDE_UNUSEDARRAY_ELEMENT *array_copy_element(ae)ARRAY_ELEMENT *ae;{ return(ae ? array_create_element(element_index(ae), element_value(ae)) : (ARRAY_ELEMENT *) NULL);}#endifvoidarray_dispose_element(ae)ARRAY_ELEMENT *ae;{ if (ae) { FREE(ae->value); free(ae); }}/* * Add a new element with index I and value V to array A (a[i] = v). */intarray_insert(a, i, v)ARRAY *a;arrayind_t i;char *v;{ register ARRAY_ELEMENT *new, *ae; if (a == 0) return(-1); new = array_create_element(i, v); if (i > array_max_index(a)) { /* * Hook onto the end. This also works for an empty array. * Fast path for the common case of allocating arrays * sequentially. */ ADD_BEFORE(a->head, new); a->max_index = i; a->num_elements++; SET_LASTREF(a, new); return(0); } /* * Otherwise we search for the spot to insert it. */ for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) { if (element_index(ae) == i) { /* * Replacing an existing element. */ array_dispose_element(new); free(element_value(ae)); ae->value = v ? savestring(v) : (char *)NULL; SET_LASTREF(a, ae); return(0); } else if (element_index(ae) > i) { ADD_BEFORE(ae, new); a->num_elements++; SET_LASTREF(a, new); return(0); } } INVALIDATE_LASTREF(a); return (-1); /* problem */}/* * Delete the element with index I from array A and return it so the * caller can dispose of it. */ARRAY_ELEMENT *array_remove(a, i)ARRAY *a;arrayind_t i;{ register ARRAY_ELEMENT *ae; if (a == 0 || array_empty(a)) return((ARRAY_ELEMENT *) NULL); for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) if (element_index(ae) == i) { ae->next->prev = ae->prev; ae->prev->next = ae->next; a->num_elements--; if (i == array_max_index(a)) a->max_index = element_index(ae->prev); INVALIDATE_LASTREF(a); return(ae); } return((ARRAY_ELEMENT *) NULL);}/* * Return the value of a[i]. */char *array_reference(a, i)ARRAY *a;arrayind_t i;{ register ARRAY_ELEMENT *ae; if (a == 0 || array_empty(a)) return((char *) NULL); if (i > array_max_index(a)) return((char *)NULL); /* Keep roving pointer into array to optimize sequential access */ if (lastref && IS_LASTREF(a)) ae = (i >= element_index(lastref)) ? lastref : element_forw(a->head); else ae = element_forw(a->head); for ( ; ae != a->head; ae = element_forw(ae)) if (element_index(ae) == i) { SET_LASTREF(a, ae); return(element_value(ae)); } UNSET_LASTREF(); return((char *) NULL);}/* Convenience routines for the shell to translate to and from the form used by the rest of the code. */WORD_LIST *array_to_word_list(a)ARRAY *a;{ WORD_LIST *list; ARRAY_ELEMENT *ae; if (a == 0 || array_empty(a)) return((WORD_LIST *)NULL); list = (WORD_LIST *)NULL; for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) list = make_word_list (make_bare_word(element_value(ae)), list); return (REVERSE_LIST(list, WORD_LIST *));}ARRAY *array_from_word_list (list)WORD_LIST *list;{ ARRAY *a; if (list == 0) return((ARRAY *)NULL); a = array_create(); return (array_assign_list (a, list));}WORD_LIST *array_keys_to_word_list(a)ARRAY *a;{ WORD_LIST *list; ARRAY_ELEMENT *ae; char *t; if (a == 0 || array_empty(a)) return((WORD_LIST *)NULL); list = (WORD_LIST *)NULL; for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) { t = itos(element_index(ae)); list = make_word_list (make_bare_word(t), list); free(t); } return (REVERSE_LIST(list, WORD_LIST *));}ARRAY *array_assign_list (array, list)ARRAY *array;WORD_LIST *list;{ register WORD_LIST *l; register arrayind_t i; for (l = list, i = 0; l; l = l->next, i++) array_insert(array, i, l->word->word); return array;}char **array_to_argv (a)ARRAY *a;{ char **ret, *t; int i; ARRAY_ELEMENT *ae; if (a == 0 || array_empty(a)) return ((char **)NULL); ret = strvec_create (array_num_elements (a) + 1); i = 0; for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) { t = element_value (ae); ret[i++] = t ? savestring (t) : (char *)NULL; } ret[i] = (char *)NULL; return (ret);} /* * Return a string that is the concatenation of the elements in A from START * to END, separated by SEP. */static char *array_to_string_internal (start, end, sep, quoted)ARRAY_ELEMENT *start, *end;char *sep;int quoted;{ char *result, *t; ARRAY_ELEMENT *ae; int slen, rsize, rlen, reg; if (start == end) /* XXX - should not happen */ return ((char *)NULL); slen = strlen(sep); result = NULL; for (rsize = rlen = 0, ae = start; ae != end; ae = element_forw(ae)) { if (rsize == 0) result = (char *)xmalloc (rsize = 64); if (element_value(ae)) { t = quoted ? quote_string(element_value(ae)) : element_value(ae); reg = strlen(t); RESIZE_MALLOCED_BUFFER (result, rlen, (reg + slen + 2), rsize, rsize); strcpy(result + rlen, t); rlen += reg; if (quoted && t) free(t); /* * Add a separator only after non-null elements. */ if (element_forw(ae) != end) { strcpy(result + rlen, sep); rlen += slen; } } } if (result) result[rlen] = '\0'; /* XXX */ return(result);}char *array_to_assign (a, quoted)ARRAY *a;int quoted;{ char *result, *valstr, *is; char indstr[INT_STRLEN_BOUND(intmax_t) + 1]; ARRAY_ELEMENT *ae; int rsize, rlen, elen; if (a == 0 || array_empty (a)) return((char *)NULL); result = (char *)xmalloc (rsize = 128); result[0] = '('; rlen = 1; for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) { is = inttostr (element_index(ae), indstr, sizeof(indstr)); valstr = element_value (ae) ? sh_double_quote (element_value(ae)) : (char *)NULL; elen = STRLEN (is) + 8 + STRLEN (valstr); RESIZE_MALLOCED_BUFFER (result, rlen, (elen + 1), rsize, rsize); result[rlen++] = '['; strcpy (result + rlen, is); rlen += STRLEN (is); result[rlen++] = ']'; result[rlen++] = '='; if (valstr) { strcpy (result + rlen, valstr); rlen += STRLEN (valstr); } if (element_forw(ae) != a->head) result[rlen++] = ' '; FREE (valstr); } RESIZE_MALLOCED_BUFFER (result, rlen, 1, rsize, 8); result[rlen++] = ')'; result[rlen] = '\0'; if (quoted) { /* This is not as efficient as it could be... */ valstr = sh_single_quote (result); free (result); result = valstr; } return(result);}char *array_to_string (a, sep, quoted)ARRAY *a;char *sep;int quoted;{ if (a == 0) return((char *)NULL); if (array_empty(a)) return(savestring("")); return (array_to_string_internal (element_forw(a->head), a->head, sep, quoted));}#if defined (INCLUDE_UNUSED) || defined (TEST_ARRAY)/* * Return an array consisting of elements in S, separated by SEP */ARRAY *array_from_string(s, sep)char *s, *sep;{ ARRAY *a; WORD_LIST *w; if (s == 0) return((ARRAY *)NULL); w = list_string (s, sep, 0); if (w == 0) return((ARRAY *)NULL); a = array_from_word_list (w); return (a);}#endif#if defined (TEST_ARRAY)/* * To make a running version, compile -DTEST_ARRAY and link with: * xmalloc.o syntax.o lib/malloc/libmalloc.a lib/sh/libsh.a */int interrupt_immediately = 0;intsignal_is_trapped(s)int s;{ return 0;}voidfatal_error(const char *s, ...){ fprintf(stderr, "array_test: fatal memory error\n"); abort();}voidprogramming_error(const char *s, ...){ fprintf(stderr, "array_test: fatal programming error\n"); abort();}WORD_DESC *make_bare_word (s)const char *s;{ WORD_DESC *w; w = (WORD_DESC *)xmalloc(sizeof(WORD_DESC)); w->word = s ? savestring(s) : savestring (""); w->flags = 0; return w;}WORD_LIST *make_word_list(x, l)WORD_DESC *x;WORD_LIST *l;{ WORD_LIST *w; w = (WORD_LIST *)xmalloc(sizeof(WORD_LIST)); w->word = x; w->next = l; return w;}WORD_LIST *list_string(s, t, i)char *s, *t;int i;{ char *r, *a; WORD_LIST *wl; if (s == 0) return (WORD_LIST *)NULL; r = savestring(s); wl = (WORD_LIST *)NULL; a = strtok(r, t); while (a) { wl = make_word_list (make_bare_word(a), wl); a = strtok((char *)NULL, t); } return (REVERSE_LIST (wl, WORD_LIST *));}GENERIC_LIST *list_reverse (list)GENERIC_LIST *list;{ register GENERIC_LIST *next, *prev; for (prev = 0; list; ) { next = list->next; list->next = prev; prev = list; list = next; } return prev;}char *pat_subst(s, t, u, i)char *s, *t, *u;int i;{ return ((char *)NULL);}char *quote_string(s)char *s;{ return savestring(s);}print_element(ae)ARRAY_ELEMENT *ae;{ char lbuf[INT_STRLEN_BOUND (intmax_t) + 1]; printf("array[%s] = %s\n", inttostr (element_index(ae), lbuf, sizeof (lbuf)), element_value(ae));}print_array(a)ARRAY *a;{ printf("\n"); array_walk(a, print_element, (void *)NULL);}main(){ ARRAY *a, *new_a, *copy_of_a; ARRAY_ELEMENT *ae, *aew; char *s; a = array_create(); array_insert(a, 1, "one"); array_insert(a, 7, "seven"); array_insert(a, 4, "four"); array_insert(a, 1029, "one thousand twenty-nine"); array_insert(a, 12, "twelve"); array_insert(a, 42, "forty-two"); print_array(a); s = array_to_string (a, " ", 0); printf("s = %s\n", s); copy_of_a = array_from_string(s, " "); printf("copy_of_a:"); print_array(copy_of_a); array_dispose(copy_of_a); printf("\n"); free(s); ae = array_remove(a, 4); array_dispose_element(ae); ae = array_remove(a, 1029); array_dispose_element(ae); array_insert(a, 16, "sixteen"); print_array(a); s = array_to_string (a, " ", 0); printf("s = %s\n", s); copy_of_a = array_from_string(s, " "); printf("copy_of_a:"); print_array(copy_of_a); array_dispose(copy_of_a); printf("\n"); free(s); array_insert(a, 2, "two"); array_insert(a, 1029, "new one thousand twenty-nine"); array_insert(a, 0, "zero"); array_insert(a, 134, ""); print_array(a); s = array_to_string (a, ":", 0); printf("s = %s\n", s); copy_of_a = array_from_string(s, ":"); printf("copy_of_a:"); print_array(copy_of_a); array_dispose(copy_of_a); printf("\n"); free(s); new_a = array_copy(a); print_array(new_a); s = array_to_string (new_a, ":", 0); printf("s = %s\n", s); copy_of_a = array_from_string(s, ":"); free(s); printf("copy_of_a:"); print_array(copy_of_a); array_shift(copy_of_a, 2, AS_DISPOSE); printf("copy_of_a shifted by two:"); print_array(copy_of_a); ae = array_shift(copy_of_a, 2, 0); printf("copy_of_a shifted by two:"); print_array(copy_of_a); for ( ; ae; ) { aew = element_forw(ae); array_dispose_element(ae); ae = aew; } array_rshift(copy_of_a, 1, (char *)0); printf("copy_of_a rshift by 1:"); print_array(copy_of_a); array_rshift(copy_of_a, 2, "new element zero"); printf("copy_of_a rshift again by 2 with new element zero:"); print_array(copy_of_a); s = array_to_assign(copy_of_a, 0); printf("copy_of_a=%s\n", s); free(s); ae = array_shift(copy_of_a, array_num_elements(copy_of_a), 0); for ( ; ae; ) { aew = element_forw(ae); array_dispose_element(ae); ae = aew; } array_dispose(copy_of_a); printf("\n"); array_dispose(a); array_dispose(new_a);}#endif /* TEST_ARRAY */#endif /* ARRAY_VARS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -