static int allocate_arg_space (SLcmd_Cmd_Table_Type *table, int argc, unsigned int *space_ptr) { unsigned int space = *space_ptr; char *p; if (argc + 1 < (int) space) return 0; if (space > 128) { if (space > 1024) space += 1024; else space += 128; } else space += 32; if (NULL == (p = SLrealloc ((char *)table->string_args, space * sizeof (char *)))) return -1; table->string_args = (char **)p; table->string_args [argc] = NULL; if (NULL == (p = SLrealloc ((char *)table->int_args, space * sizeof (int)))) return -1; table->int_args = (int *)p; if (NULL == (p = SLrealloc ((char *)table->double_args, space * sizeof (double)))) return -1; table->double_args = (double *)p; if (NULL == (p = SLrealloc ((char *)table->arg_type, space * sizeof (unsigned char)))) return -1; table->arg_type = (unsigned char *)p; *space_ptr = space; return 0; }
static int allocate_arg_space (SLcmd_Cmd_Table_Type *table, SLstrlen_Type argc, SLstrlen_Type *space_ptr) { SLstrlen_Type space = *space_ptr; char *p; if (argc + 1 < space) return 0; if (space > 128) { if (space > 1024) space += 1024; else space += 128; } else space += 32; if (NULL == (p = (char *)SLrealloc ((char *)table->string_args, space * sizeof (char *)))) return -1; table->string_args = (SLFUTURE_CONST char **)p; table->string_args [argc] = NULL; if (NULL == (p = (char *)SLrealloc ((char *)table->int_args, space * sizeof (int)))) return -1; table->int_args = (int *)p; if (NULL == (p = (char *)SLrealloc ((char *)table->double_args, space * sizeof (double)))) return -1; table->double_args = (double *)p; if (NULL == (p = (char *)SLrealloc ((char *)table->arg_type, space * sizeof (SLtype)))) return -1; table->arg_type = (SLtype *)p; *space_ptr = space; return 0; }
static int push_values_array (Values_Array_Type *av, int allow_empty_array) { SLang_Array_Type *at; char **new_values; if (av->num == 0) { if (allow_empty_array == 0) return SLang_push_null (); SLfree ((char *) av->values); av->values = NULL; } else { if (NULL == (new_values = (char **)SLrealloc ((char *)av->values, av->num*sizeof(char *)))) return -1; av->values = new_values; } av->num_allocated = av->num; at = SLang_create_array (SLANG_STRING_TYPE, 0, av->values, &av->num, 1); if (at == NULL) return -1; av->num_allocated = 0; av->num = 0; av->values = NULL; return SLang_push_array (at, 1); }
static SLang_Array_Type *string_list_to_array (_pSLString_List_Type *p, int delete_list) { unsigned int num; SLindex_Type inum; SLang_Array_Type *at; char **buf; buf = p->buf; num = p->num; if (delete_list == 0) return _pSLstrings_to_array (buf, num); inum = (SLindex_Type) num; if (num == 0) num++; /* so realloc succeeds */ /* Since the list is to be deleted, we can steal the buffer */ if ((num != p->max_num) && (NULL == (buf = (char **)SLrealloc ((char *) buf, sizeof (char *) * num)))) { _pSLstring_list_delete (p); return NULL; } p->max_num = num; p->buf = buf; if (NULL == (at = SLang_create_array (SLANG_STRING_TYPE, 0, (VOID_STAR) buf, &inum, 1))) { _pSLstring_list_delete (p); return NULL; } p->buf = NULL; _pSLstring_list_delete (p); return at; }
static int check_space (SLrline_Type *This_RLI, unsigned int dn) { unsigned char *new_buf; unsigned int new_len; new_len = 1 + This_RLI->len + dn; if (new_len <= This_RLI->buf_len) return 0; if (NULL == (new_buf = (unsigned char *) SLrealloc ((char *)This_RLI->buf, new_len))) return -1; This_RLI->buf_len = new_len; This_RLI->buf = new_buf; return 0; }
static int store_value (Values_Array_Type *va, char *value) { SLindex_Type num_allocated; num_allocated = va->num_allocated; if (num_allocated == va->num) { char **values; num_allocated += 256; values = (char **)SLrealloc ((char *)va->values, num_allocated*sizeof(char *)); if (values == NULL) return -1; va->values = values; } if (NULL == (va->values[va->num] = SLang_create_slstring (value))) return -1; va->num++; return 0; }
int _pSLstring_list_append (_pSLString_List_Type *p, char *s) { if (s == NULL) return -1; if (p->max_num == p->num) { char **b; unsigned int max_num = p->num + p->delta_num; b = (char **)SLrealloc ((char *)p->buf, max_num * sizeof (char *)); if (b == NULL) return -1; p->buf = b; p->max_num = max_num; } p->buf[p->num] = s; p->num++; return 0; }
/* Usage: nn = read (f, &buf, n); */ static void posix_read (SLFile_FD_Type *f, SLang_Ref_Type *ref, unsigned int *nbytes) { unsigned int len; char *b; SLang_BString_Type *bstr; b = NULL; len = *nbytes; if ((NULL == (b = SLmalloc (len + 1))) || (-1 == do_read (f, b, &len))) goto return_error; if (len != *nbytes) { char *b1 = SLrealloc (b, len + 1); if (b1 == NULL) goto return_error; b = b1; } bstr = SLbstring_create_malloced ((unsigned char *) b, len, 0); if (bstr != NULL) { if (-1 == SLang_assign_to_ref (ref, SLANG_BSTRING_TYPE, (VOID_STAR)&bstr)) { SLbstring_free (bstr); return; } SLbstring_free (bstr); (void) SLang_push_uinteger (len); return; } return_error: if (b != NULL) SLfree ((char *)b); (void) SLang_assign_to_ref (ref, SLANG_NULL_TYPE, NULL); (void) SLang_push_integer (-1); }
/* I malloc one extra so that I can always add a null character to last line */ char *vgets(VFILE *vp, unsigned int *num) /*{{{*/ { register char *bp, *bp1; register char *bmax, *bpmax; char *neew; int fd = vp->fd; unsigned int n, max, fmode = vp->mode; int doread = 0; n = vp->size; *num = 0; if (NULL == vp->buf) { #if defined (__MSDOS_16BIT__) if (!n) n = 512; #else if (!n) n = 64 * 1024; #endif if (NULL == (neew = SLmalloc(n + 1))) return NULL; vp->bp = vp->buf = neew; vp->bmax = neew + n; doread = 1; } bp = vp->bp; if ((vp->eof != NULL) && (bp >= vp->eof)) return (NULL); bp1 = vp->buf; bmax = vp->bmax; while (1) { if (doread) { max = (int) (vp->bmax - bp); while (max > 0) { int nread; nread = read(fd, bp, max); if (nread == 0) break; if (nread == -1) { if (SLKeyBoard_Quit || (SLang_get_error () == SL_USER_BREAK)) break; #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__BORLANDC__)) # ifdef EPIPE if (errno == EPIPE) break; # endif #endif #ifndef IBMPC_SYSTEM # ifdef EINTR if (errno == EINTR) { if (-1 == jed_handle_interrupt ()) break; continue; } # endif # ifdef EAGAIN if (errno == EAGAIN) { if (-1 == jed_handle_interrupt ()) break; sleep (1); continue; } # endif #endif return NULL; } max -= nread; bp += nread; } if (max) vp->eof = bp; if (bp == bp1) { return(NULL); } bp = bp1; } else bp1 = bp; /* extract a line */ if (vp->eof != NULL) bmax = vp->eof; n = (unsigned int) (bmax - bp); #if defined(__MSDOS__) if (n) { bpmax = bp; #if defined(__BORLANDC__) && !defined(__WIN32__) asm { mov bx, di mov al, 10 mov cx, n les di, bpmax cld repne scasb inc cx sub n, cx mov di, bx } bp += n; #else if (NULL == (bpmax = SLMEMCHR(bp, '\n', n))) bp += n; else bp = bpmax; #endif /* __WIN32__ */ if (*bp != '\n') bp++; } if (bp < bmax) { vp->bp = ++bp; *num = (unsigned int) (bp - bp1); /* if it is text, replace the carriage return by a newline and adjust the number read by 1 */ bp -= 2; if ((fmode == VFILE_TEXT) && (*num > 1) && (*bp == '\r')) { *bp = '\n'; *num -= 1; vp->cr_flag = 1; } return bp1; } #else if (NULL != (bpmax = SLMEMCHR(bp, '\n', n))) { bpmax++; vp->bp = bpmax; *num = (unsigned int) (bpmax - bp1); if ((fmode == VFILE_TEXT) && (*num > 1)) { bpmax -= 2; if (*bpmax == '\r') { vp->cr_flag = 1; *bpmax = '\n'; (*num)--; } } return bp1; } bp = bp + n; #endif /* __MSDOS__ */ if (vp->eof != NULL) { *num = (unsigned int) (bp - bp1); vp->bp = bp; #if defined(IBMPC_SYSTEM) /* kill ^Z at EOF if present */ if ((fmode == VFILE_TEXT) && (*num) && (26 == *(bp - 1))) { *num -= 1; if (!*num) bp1 = NULL; } #endif return(bp1); } doread = 1; bp = bp1; bp1 = vp->buf; if (bp != bp1) { /* shift to beginning */ while (bp < bmax) *bp1++ = *bp++; bp = bp1; bp1 = vp->buf; } else { bp = bmax; vp->bmax += 2 * (int) (vp->bmax - vp->buf); neew = SLrealloc (vp->buf, 1 + (unsigned int) (vp->bmax - vp->buf)); if (neew == NULL) return NULL; bp = neew + (int) (bmax - vp->buf); bmax = vp->bmax = neew + (int) (vp->bmax - vp->buf); bp1 = vp->buf = neew; } } }
static void _iconv(ICONV_Type *it, SLang_BString_Type *bstr) { char *buf = NULL; size_t rc; char ICONV_CONST *instr; char *outstr; size_t inn, outn, bufn; size_t fail = (size_t)-1; SLstrlen_Type bstrlen; if (NULL == (instr = (char ICONV_CONST *)SLbstring_get_pointer(bstr, &bstrlen))) return; inn = (size_t) bstrlen; bufn = outn = 2*inn + 2; if (NULL == (buf = (char *)SLmalloc(bufn))) return; outstr = buf; while (1) { errno = 0; rc = iconv(it->cd, &instr, &inn, &outstr, &outn); if (rc != (size_t)-1) break; /* ok! */ if (fail == inn) { SLang_verror (SL_Unknown_Error, "Unknown error in iconv"); goto error; } fail = inn; switch (errno) { case EILSEQ: SLang_verror (SL_InvalidUTF8_Error, "Invalid multibyte sequence or unable to convert to the target encoding"); goto error; case EINVAL: SLang_verror (SL_InvalidUTF8_Error, "Incomplete multibyte sequence"); goto error; case 0: /* drop */ /* grrrr * At least on windows, libiconv returns with errno = 0 * (or unmodified?) when there's no more roon on outstr * if so, fallback */ case E2BIG: { char *p; long outdelta; outdelta = outstr - buf; outn += bufn; bufn += bufn; p = (char *)SLrealloc(buf, bufn); if (p == NULL) goto error; buf = p; outstr = buf + outdelta; } break; default: SLang_verror (SL_Unknown_Error, "Unknown iconv error"); goto error; } } bstr = SLbstring_create((unsigned char *) buf, outstr - buf); if (bstr != NULL) (void) SLang_push_bstring(bstr); SLbstring_free (bstr); /* drop */ error: SLfree(buf); }
static int get_doc_string (char *file, char *topic) { FILE *fp; char line[1024]; unsigned int topic_len, str_len; char *str; char ch; if (NULL == (fp = fopen (file, "r"))) return -1; topic_len = strlen (topic); ch = *topic; while (1) { if (NULL == fgets (line, sizeof(line), fp)) { fclose (fp); return -1; } if ((ch == *line) && (0 == strncmp (line, topic, topic_len)) && ((line[topic_len] == '\n') || (line [topic_len] == 0) || (line[topic_len] == ' ') || (line[topic_len] == '\t'))) break; } if (NULL == (str = SLmake_string (line))) { fclose (fp); return -1; } str_len = strlen (str); while (NULL != fgets (line, sizeof (line), fp)) { unsigned int len; char *new_str; ch = *line; if (ch == '#') continue; if (ch == '-') break; len = strlen (line); if (NULL == (new_str = SLrealloc (str, str_len + len + 1))) { SLfree (str); str = NULL; break; } str = new_str; strcpy (str + str_len, line); str_len += len; } fclose (fp); (void) SLang_push_malloced_string (str); return 0; }
static int decode_csv_row (CSV_Type *csv, int flags) { char *line; size_t line_ofs; char *value; size_t value_size, value_ofs; char delimchar, quotechar; int return_status; Values_Array_Type av; int do_read, in_quote; int blank_line_seen; int is_quoted; if (NULL == csv->read_callback) { SLang_verror (SL_InvalidParm_Error, "CSV decoder object has no read callback function"); return -1; } if (-1 == init_values_array_type (&av)) return -1; delimchar = csv->delimchar; quotechar = csv->quotechar; value_ofs = line_ofs = 0; value_size = 0; value = NULL; line = NULL; do_read = 1; in_quote = 0; return_status = -1; blank_line_seen = 0; is_quoted = 0; while (1) { int status; char ch; if (value_ofs == value_size) { char *new_value; if (value_size < 64) value_size += 32; else if (value_size < 8192) value_size *= 2; else value_size += 8192; new_value = SLrealloc (value, value_size); if (new_value == NULL) goto return_error; value = new_value; } NEXT_CHAR(ch) if ((ch == quotechar) && quotechar) { if (in_quote) { NEXT_CHAR(ch) if (ch == quotechar) { value[value_ofs++] = ch; continue; } if ((ch != ',') && (ch != 0) && (ch != '\n')) { SLang_verror (SL_Data_Error, "Expecting a delimiter after an end-quote character"); goto return_error; } in_quote = 0; /* drop */ } else if (value_ofs != 0) { SLang_verror (SL_Data_Error, "Misplaced quote character inside a csv field"); goto return_error; } else { in_quote = 1; is_quoted = 1; continue; } } if (ch == delimchar) { if (in_quote) { value[value_ofs++] = ch; continue; } value[value_ofs] = 0; if (-1 == store_value (&av, value)) goto return_error; value_ofs = 0; continue; } if ((ch == 0) || (ch == '\n')) { if (in_quote) { if (ch == '\n') { value[value_ofs++] = ch; do_read = 1; continue; } SLang_verror (SL_Data_Error, "No closing quote seen parsing CSV data"); goto return_error; } if ((ch == '\n') || (av.num != 0) || (value_ofs > 0)) { if ((is_quoted == 0) && (ch == '\n') && (av.num == 0) && (value_ofs == 0)) { /* blank line */ int blank_line_behavior = (flags & BLANK_ROW_BEHAVIOR); if (blank_line_behavior == CSV_SKIP_BLANK_ROWS) { do_read = 1; continue; } if (blank_line_behavior == CSV_STOP_ON_BLANK_ROWS) { blank_line_seen = 1; break; } } value[value_ofs] = 0; if (-1 == store_value (&av, value)) goto return_error; } break; /* done */ } value[value_ofs++] = ch; }
/* This function returns a malloced string */ SLuchar_Type *SLuchar_apply_char_map (SLwchar_Map_Type *map, SLuchar_Type *str) { SLuchar_Type *str_max; SLuchar_Type *output, *output_max, *outptr; int use_chmap; size_t len; SLwchar_Type *chmap; if ((map == NULL) || (str == NULL)) return NULL; use_chmap = 1; if (_pSLinterp_UTF8_Mode == 0) str_max = str + strlen ((char *)str); else { str_max = str; while (*str_max) { if (*str_max & 0x80) use_chmap = 0; str_max++; } } len = str_max - str; chmap = map->chmap; if (use_chmap) { unsigned int i; output = (SLuchar_Type *)SLmalloc (len+1); if (output == NULL) return NULL; for (i = 0; i < len; i++) output[i] = chmap[str[i]]; output[len] = 0; return output; } /* Hard way */ len += SLUTF8_MAX_MBLEN; if (NULL == (output = (SLuchar_Type *)SLmalloc (len + 1))) return NULL; output_max = output + len; outptr = output; while (str < str_max) { SLwchar_Type w_out, w_in; unsigned int encoded_len; w_in = (SLwchar_Type) *str; if (w_in < 0x80) str++; else if (NULL == (str = _pSLinterp_decode_wchar (str, str_max, &w_in))) goto return_error; if (w_in < 0x100) { w_out = chmap[w_in]; if ((w_out < 0x80) && (outptr < output_max)) { *outptr++ = (SLuchar_Type) w_out; continue; } } else { if (-1 == SLwchar_apply_char_map (map, &w_in, &w_out, 1)) goto return_error; } if (outptr + SLUTF8_MAX_MBLEN >= output_max) { SLuchar_Type *tmp; len += 32 * SLUTF8_MAX_MBLEN; if (NULL == (tmp = (SLuchar_Type *)SLrealloc ((char *)output, len))) goto return_error; outptr = tmp + (outptr - output); output = tmp; output_max = output + len; } if (NULL == (outptr = _pSLinterp_encode_wchar (w_out, outptr, &encoded_len))) goto return_error; } *outptr = 0; return output; return_error: SLfree ((char *) output); return NULL; }
static SLuchar_Type *xform_utf8 (SLuchar_Type *u, SLuchar_Type *umax, SLwchar_Type (*fun)(SLwchar_Type)) { SLuchar_Type *buf, *p; unsigned int malloced_len, len; if (umax < u) return NULL; len = 0; p = buf = NULL; malloced_len = 0; while (1) { SLwchar_Type w; SLuchar_Type *u1; unsigned int nconsumed; if (malloced_len <= len + SLUTF8_MAX_MBLEN) { SLuchar_Type *newbuf; malloced_len += 1 + (umax - u) + SLUTF8_MAX_MBLEN; newbuf = (SLuchar_Type *)SLrealloc ((char *)buf, malloced_len); if (newbuf == NULL) { SLfree ((char *)buf); return NULL; } buf = newbuf; p = buf + len; } if (u >= umax) { *p = 0; p = (SLuchar_Type *) SLang_create_nslstring ((char *)buf, len); SLfree ((char *)buf); return p; } if (NULL == (u1 = SLutf8_decode (u, umax, &w, &nconsumed))) { /* Invalid sequence */ memcpy ((char *) p, u, nconsumed); p += nconsumed; len += nconsumed; u1 = u + nconsumed; } else { SLuchar_Type *p1; p1 = SLutf8_encode ((*fun)(w), p, malloced_len); if (p1 == NULL) { SLfree ((char *)buf); _pSLang_verror (SL_INTERNAL_ERROR, "SLutf8_encode returned NULL"); return NULL; } len += p1 - p; p = p1; } u = u1; } }