Skip to content
Snippets Groups Projects
Commit 52573589 authored by Jonathan Schöbel's avatar Jonathan Schöbel
Browse files

Text: added stupid replacement function

The copy_and_replace function replaces a single character with a string,
while copying. This may be replaced by an elaborate function as
manipulating a text normally means that manipulating is deferred until
needed, which this function contradicts to.
parent e917f236
No related branches found
No related tags found
No related merge requests found
Checking pipeline status
......@@ -28,7 +28,7 @@ long_line_behaviour=1
long_line_column=72
[files]
current_page=25
current_page=45
FILE_NAME_0=139;None;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2FREADME;0;8
FILE_NAME_1=134;None;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2F.gitignore;0;8
FILE_NAME_2=1737;Sh;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fconfigure.ac;0;8
......@@ -51,10 +51,10 @@ FILE_NAME_18=19;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprg
FILE_NAME_19=19;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fattr.h;0;8
FILE_NAME_20=26;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fattr_static.c;0;8
FILE_NAME_21=24;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fattr_data.h;0;8
FILE_NAME_22=2765;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ftext.c;0;8
FILE_NAME_23=19;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ftext.h;0;8
FILE_NAME_22=2929;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ftext.c;0;8
FILE_NAME_23=2065;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ftext.h;0;8
FILE_NAME_24=1036;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ftext_data.h;0;8
FILE_NAME_25=4650;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ftext_segment.c;0;8
FILE_NAME_25=8479;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ftext_segment.c;0;8
FILE_NAME_26=1083;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ftext_segment.h;0;8
FILE_NAME_27=900;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ftext_segment_mark.c;0;8
FILE_NAME_28=1867;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ftext_mark_static.c;0;8
......@@ -74,7 +74,7 @@ FILE_NAME_41=8232;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fp
FILE_NAME_42=33;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_node_fragment.c;0;8
FILE_NAME_43=4771;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_text_fragment.c;0;8
FILE_NAME_44=24;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_attr.c;0;8
FILE_NAME_45=3584;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_text.c;0;8
FILE_NAME_45=4221;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_text.c;0;8
FILE_NAME_46=994;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_text_mark.c;0;8
FILE_NAME_47=29;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_validator.c;0;8
FILE_NAME_48=536;None;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftodo.txt;0;8
......
......@@ -144,6 +144,37 @@ SH_Text_copy (const struct SH_Text * text,
return copy;
}
/*@null@*/
/*@only@*/
struct SH_Text *
SH_Text_copy_and_replace (const struct SH_Text * text,
char old, char * new,
/*@null@*/ /*@out@*/ struct SH_Status * status)
/*@globals fileSystem@*/
/*@modifies fileSystem@*/
/*@modifies status@*/
{
struct SH_Text * copy;
copy = malloc (sizeof (struct SH_Text));
if (NULL == copy)
{
set_status (status, E_ALLOC, 3, "malloc failed");
return NULL;
}
copy->data = copy_and_replace_text_segment (text->data,
old, new, status);
if (NULL == copy->data)
{
free (copy);
return NULL;
}
set_success (status);
return copy;
}
size_t
SH_Text_get_length (const struct SH_Text * text,
/*@null@*/ /*@out@*/ struct SH_Status * status)
......
......@@ -68,6 +68,17 @@ SH_Text_copy (const SH_Text * text,
/*@modifies fileSystem@*/
/*@modifies status@*/;
/*@null@*/
/*@only@*/
SH_Text *
SH_Text_copy_and_replace (const SH_Text * text,
char old, char * new,
/*@null@*/ /*@out@*/ struct SH_Status * status)
/*@globals fileSystem@*/
/*@modifies fileSystem@*/
/*@modifies status@*/;
size_t
SH_Text_get_length (const struct SH_Text * text,
/*@null@*/ /*@out@*/ struct SH_Status * status)
......
......@@ -367,3 +367,158 @@ squash_text_segment (const struct text_segment * segment,
copy_seg->next = NULL;
}
}
static inline
/*@null@*/
/*@only@*/
struct text_segment *
copy_and_replace_text_segment (const struct text_segment * segment,
char old, char * new,
/*@null@*/ /*@out@*/
struct SH_Status * status)
/*@globals fileSystem@*/
/*@modifies fileSystem@*/
/*@modifies status@*/
{
const struct text_segment * start;
const struct text_segment * end;
struct text_segment * copy;
struct text_segment * copy_seg;
copy = malloc (sizeof (struct text_segment));
if (NULL == copy)
{
set_status (status, E_ALLOC, 3, "malloc failed");
return NULL;
}
copy->next = NULL;
/* copy_seg is the segment we're currently copying to */
copy_seg = copy;
/* start to end are the segments we're copying from. */
/* start points to the first segment to copy.
* end points to the first segment not being copied in
* the current iteration. */
end = segment;
start = end;
/* At the beginning of each iteration start == end.
* This is ensured before the loop and at the end of the outer
* loop with the last for loop, which does the actual copying.
*
* Then end is adjusted to point after the last segment to be
* copied. If it isn't NULL afterwards another loop iteration
* has to take place.
*
* With start and end properly set, and the length and size of
* the resulting segment determined, the copying can start,
* which is just a repeated string concatenation.
*
* If another iteration is following, the next segment has to be
* allocated. This can't be done at the beginning, because
* before the first iteration the pointer to the allocated
* segment must be written to copy directly to create the
* anchor of the linked list. (So there is no ?->next
* to write to.)
* Actually copy_seg could be typed (struct text_segment **)
* and then be set to &(copy) before the loop and to
* &((*copy_seg)->next) after each iteration, but that would
* complicate things with another indirection...
* Implementing the loop as for loop and writing the allocation
* code into their head is also not possible, because compound
* statements aren't allowed there.
* Thus the allocation has to take place at the end of the loop. */
while (TRUE)
{
char * text;
size_t r_length;
/* calculate length, adjust end */
for (copy_seg->length = 0; end != NULL; end = end->next)
{
/* catch overflow, use <= instead of <
* to prevent overflow of copy_seg->size */
if (SIZE_MAX - end->length <= copy_seg->length)
{
/* stop copying */
end = end->next;
/*@innerbreak@*/
break;
}
copy_seg->length += end->length;
}
/* initialize marks
* TODO: copy and adjust the marks regarding to
* the concatenated segment */
init_marks (copy_seg);
/* This addition can not overflow, because in the
* for-loop it was tested with > instead of >= which
* would be appropriate. See comment there. */
copy_seg->size = get_alloc_size (copy_seg->length + 1);
copy_seg->text = malloc (copy_seg->size);
if (NULL == copy_seg->text)
{
set_status (status, E_ALLOC, 3, "malloc failed");
free_text_segment (copy);
return NULL;
}
text = copy_seg->text;
r_length = strlen (new);
/* actual copying */
/* Initialization was done since the beginning of
* the outer loop. So think of all this code standing
* | here.
* v */
for (; start != end; start = start->next)
{
char * s_start;
char * s_end;
s_start = start->text,
s_end = s_start + start->length;
while (s_end != s_start)
{
if (old == *s_start)
{
memcpy (text, new, r_length);
text += r_length;
copy_seg->length += r_length-1;
s_start++;
}
else
{
*text++ = *s_start++;
}
}
}
text[0] = '\0';
/* See comment of outer loop. (4th paragraph) */
if (end == NULL)
{
return copy;
}
copy_seg->next = malloc (sizeof (struct text_segment));
if (NULL == copy_seg->next)
{
set_status (status, E_ALLOC, 3, "malloc failed");
free_text_segment (copy);
return NULL;
}
copy_seg = copy_seg->next;
copy_seg->next = NULL;
}
}
......@@ -161,6 +161,33 @@ START_TEST (test_text_copy_with_status)
}
END_TEST
START_TEST (test_text_copy_replace_with_status)
{
struct SH_Status status;
struct SH_Text * text;
struct SH_Text * copy;
/* setup */
text = SH_Text_new_from_string ("Text12345", NULL);
ck_assert_ptr_ne (NULL, text);
/* test */
_status_preinit (status);
copy = SH_Text_copy_and_replace (text, '1', "000", &status);
ck_assert_int_eq (status.status, SUCCESS);
ck_assert_ptr_ne (copy, NULL);
ck_assert_ptr_ne (copy, text);
ck_assert_ptr_ne (copy->data->text, text->data->text);
ck_assert_str_ne (copy->data->text, text->data->text);
ck_assert_str_eq ("Text0002345", copy->data->text);
/* cleanup */
SH_Text_free (copy);
SH_Text_free (text);
}
END_TEST
START_TEST(test_text_get_length_no_status)
{
struct SH_Text * text;
......@@ -671,6 +698,7 @@ Suite * text_suite (void)
tcase_add_test (tc_core, test_text_string_with_status);
tcase_add_test (tc_core, test_text_copy_no_status);
tcase_add_test (tc_core, test_text_copy_with_status);
tcase_add_test (tc_core, test_text_copy_replace_with_status);
tcase_add_test (tc_core, test_text_get_length_no_status);
tcase_add_test (tc_core, test_text_get_length_with_status);
tcase_add_test (tc_core, test_text_get_char_no_status);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment