Nstrophy/src/dstring.c

248 lines
5.4 KiB
C
Raw Normal View History

2023-11-03 16:25:02 +00:00
/*
Copyright 2017-2023 Ian Jauslin
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "dstring.h"
#include <stdarg.h>
#include <stdlib.h>
// init
int dstring_init (dstring* str, unsigned int memory){
str->string=calloc(memory,sizeof(char));
str->memory=memory;
str->length=0;
return(0);
}
int dstring_free (dstring str){
free(str.string);
return(0);
}
// resize memory
int dstring_resize (dstring* str, unsigned int newsize){
unsigned int i;
dstring new_str;
dstring_init (&new_str, newsize);
for(i=0;i<str->length;i++){
new_str.string[i]=str->string[i];
}
new_str.length=str->length;
free(str->string);
*str=new_str;
return(0);
}
// add a character
int dstring_append (char val, dstring* output){
if(output->length >= output->memory){
dstring_resize (output,2*output->memory+1);
}
output->string[output->length]=val;
output->length++;
return(0);
}
// copy
int dstring_cpy (dstring input, dstring* output){
dstring_init (output, input.length);
dstring_cpy_noinit (input, output);
return(0);
}
// do not init output str
int dstring_cpy_noinit (dstring input, dstring* output){
unsigned int i;
if(output->memory<input.length){
fprintf(stderr,"error: cannot copy a dstring of length %u to a dstring with memory %u\n",input.length,output->memory);
return(-1);
}
for(i=0;i<input.length;i++){
output->string[i]=input.string[i];
}
output->length=input.length;
return(0);
}
// concatenate
int dstring_concat (dstring input, dstring* output){
unsigned int i;
for(i=0;i<input.length;i++){
dstring_append (input.string[i], output);
}
return(0);
}
// sub-str
int dstring_substr (dstring str, unsigned int begin, unsigned int end, dstring* substr){
unsigned int i;
if(begin>end || end>=str.length){
fprintf(stderr,"error: cannot take substring [%u,%u] of dstring of lengdth %u\n",begin,end,str.length);
return(-1);
}
dstring_init (substr,end-begin);
for(i=begin;i<=end;i++){
dstring_append (str.string[i], substr);
}
return(0);
}
// find
int dstring_find (char val, dstring str){
unsigned int i;
for(i=0;i<str.length;i++){
if(str.string[i]==val){
return(i);
}
}
return(-1);
}
// compare strings
int dstring_cmp (dstring str1, dstring str2){
unsigned int i;
// compare lengths
if(str1.length<str2.length){
return(-1);
}
if(str1.length>str2.length){
return(1);
}
// compare terms
for(i=0;i<str1.length;i++){
if(str1.string[i]<str2.string[i]){
return(-1);
}
if(str1.string[i]<str2.string[i]){
return(1);
}
}
// if equal
return(0);
}
// print str
int dstring_print (dstring str, FILE* file){
unsigned int i;
for(i=0;i<str.length;i++){
fprintf(file, "%s",str.string);
}
return(0);
}
// append a char*
int dstring_append_str(char* str, dstring* output){
char* ptr;
for (ptr=str;*ptr!='\0';ptr++){
dstring_append(*ptr, output);
}
return(0);
}
// convert to char*
int dstring_to_str(dstring input, char** output){
unsigned int i;
(*output)=calloc(input.length+1,sizeof(char));
for(i=0;i<input.length;i++){
(*output)[i]=input.string[i];
}
if((*output)[input.length-1]!='\0'){
(*output)[input.length]='\0';
}
return(0);
}
// noinit (changes the size of input if needed)
char* dstring_to_str_noinit(dstring* input){
if(input->string[input->length-1]!='\0'){
if(input->length==input->memory){
dstring_resize(input,input->length+1);
}
// add final '\0'
input->string[input->length]='\0';
}
return(input->string);
}
// convert from char*
int str_to_dstring(char* str, dstring* output){
char* ptr;
unsigned int str_len=0;
for(ptr=str;*ptr!='\0';ptr++){
str_len++;
}
dstring_init(output, str_len);
2023-11-03 20:04:53 +00:00
str_to_dstring_noinit(str, output);
return(0);
}
int str_to_dstring_noinit(char* str, dstring* output){
// reset length
output->length=0;
dstring_append_str(str, output);
2023-11-03 16:25:02 +00:00
return(0);
}
// compare a dstring and a char*
int dstring_cmp_str(dstring dstring, char* str){
unsigned int j;
for(j=0;j<dstring.length && str[j]!='\0';j++){
if(dstring.string[j]!=str[j]){
return(0);
}
}
if(j==dstring.length && str[j]=='\0'){
return(1);
}
return(0);
}
// format strings
int dstring_snprintf(dstring* output, char* fmt, ...){
size_t size=100;
unsigned int extra_size;
char* out_str=calloc(size,sizeof(char));
char* ptr;
va_list vaptr;
// initialize argument list starting after fmt
va_start(vaptr, fmt);
// print format
extra_size=vsnprintf(out_str, size, fmt, vaptr);
va_end(vaptr);
// if too large
if(extra_size>size){
// resize
free(out_str);
// +1 for '\0'
size=extra_size+1;
out_str=calloc(size,sizeof(char));
// read format again
va_start(vaptr, fmt);
vsnprintf(out_str,size,fmt,vaptr);
va_end(vaptr);
}
// write to char array
for(ptr=out_str;*ptr!='\0';ptr++){
dstring_append(*ptr, output);
}
free(out_str);
return(0);
}