/* // Full copyright information is available in the file ../doc/CREDITS */ #include "defs.h" #include "cdc_pcode.h" COLDC_FUNC(bufgraft) { cData * args; register cBuf * new, * b1, * b2; Int pos; if (!func_init_3(&args, BUFFER, INTEGER, BUFFER)) return; pos = INT2 - 1; b1 = BUF1; b2 = BUF3; if (pos > buffer_len(b1) || pos < 0) THROW((range_id, "Position %D is outside of the range of the string.", &args[1])) anticipate_assignment(); if (pos == 0) { args[0].u.buffer = buffer_append(b2, b1); pop(2); } else if (pos == buffer_len(b1)) { args[0].u.buffer = buffer_append(b1, b2); pop(2); } else { new = buffer_new(b1->len + b2->len); MEMCPY(new->s, b1->s, pos); MEMCPY(new->s + pos, b2->s, b2->len); MEMCPY(new->s + pos + b2->len, b1->s + pos, b1->len - pos + 1); new->len = b1->len + b2->len; pop(3); push_buffer(new); buffer_discard(new); } } COLDC_FUNC(buflen) { cData * args; Int len; if (!func_init_1(&args, BUFFER)) return; len = buffer_len(_BUF(ARG1)); pop(1); push_int(len); } COLDC_FUNC(buf_replace) { cData * args; Int pos; if (!func_init_3(&args, BUFFER, INTEGER, INTEGER)) return; pos = _INT(ARG2) - 1; if (pos < 0) THROW((range_id, "Position (%d) is less than one.", pos + 1)) else if (pos >= buffer_len(_BUF(ARG1))) THROW((range_id, "Position (%d) is greater than buffer length (%d).", pos + 1, buffer_len(_BUF(ARG1)))) _BUF(ARG1) = buffer_replace(_BUF(ARG1), pos, _INT(ARG3)); pop(2); } COLDC_FUNC(subbuf) { cData *args; Int start, len, nargs, blen; if (!func_init_2_or_3(&args, &nargs, BUFFER, INTEGER, INTEGER)) return; blen = args[0].u.buffer->len; start = args[1].u.val - 1; len = (nargs == 3) ? args[2].u.val : blen - start; if (start < 0) THROW((range_id, "Start (%d) is less than one.", start + 1)) else if (len < 0) THROW((range_id, "Length (%d) is less than zero.", len)) else if (start + len > blen) THROW((range_id, "The subrange extends to %d, past the end of the buffer (%d).", start + len, blen)) anticipate_assignment(); args[0].u.buffer = buffer_subrange(args[0].u.buffer, start, len); pop(nargs - 1); } COLDC_FUNC(buf_to_str) { cData *args; cStr * str; if (!func_init_1(&args, BUFFER)) return; str = buf_to_string(args[0].u.buffer); pop(1); push_string(str); string_discard(str); } COLDC_FUNC(buf_to_strings) { cData *args; Int num_args; cList *list; cBuf *sep; if (!func_init_1_or_2(&args, &num_args, BUFFER, BUFFER)) return; sep = (num_args == 2) ? args[1].u.buffer : NULL; list = buf_to_strings(args[0].u.buffer, sep); pop(num_args); push_list(list); list_discard(list); } COLDC_FUNC(str_to_buf) { cData *args; cBuf *buf; if (!func_init_1(&args, STRING)) return; buf = buffer_from_string(args[0].u.str); pop(1); push_buffer(buf); buffer_discard(buf); } COLDC_FUNC(strings_to_buf) { cData *args, *d; Int num_args, i; cBuf *buf, *sep; cList *list; if (!func_init_1_or_2(&args, &num_args, LIST, BUFFER)) return; list = args[0].u.list; sep = (num_args == 2) ? args[1].u.buffer : NULL; for (d = list_first(list), i=0; d; d = list_next(list, d),i++) { if (d->type != STRING) THROW((type_id, "List element %d (%D) not a string.", i + 1, d)) } buf = buffer_from_strings(list, sep); pop(num_args); push_buffer(buf); buffer_discard(buf); } COLDC_FUNC(bufidx) { int origin; int r; uChar c; int clen; uChar * cp; INIT_2_OR_3_ARGS(BUFFER, ANY_TYPE, INTEGER); if (argc == 3) origin = INT3; else origin = 1; if (args[1].type == INTEGER) { c = (uChar) args[1].u.val; cp = &c; clen = 1; } else if (args[1].type == BUFFER) { cp = BUF2->s; clen = BUF2->len; } else THROW((type_id, "Second argument must be a buffer or integer.")) if ((r = buffer_index(BUF1, cp, clen, origin)) == F_FAILURE) THROW((range_id, "Origin is beyond the range of the buffer.")) pop(argc); push_int(r); }