Leptonica 1.83.1
Image processing and image analysis suite
Loading...
Searching...
No Matches
sarray1.c
Go to the documentation of this file.
1/*====================================================================*
2 - Copyright (C) 2001 Leptonica. All rights reserved.
3 -
4 - Redistribution and use in source and binary forms, with or without
5 - modification, are permitted provided that the following conditions
6 - are met:
7 - 1. Redistributions of source code must retain the above copyright
8 - notice, this list of conditions and the following disclaimer.
9 - 2. Redistributions in binary form must reproduce the above
10 - copyright notice, this list of conditions and the following
11 - disclaimer in the documentation and/or other materials
12 - provided with the distribution.
13 -
14 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18 - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *====================================================================*/
26
137
138#ifdef HAVE_CONFIG_H
139#include <config_auto.h>
140#endif /* HAVE_CONFIG_H */
141
142#include <string.h>
143#ifndef _WIN32
144#include <dirent.h> /* unix only */
145#include <sys/stat.h>
146#include <limits.h> /* needed for realpath() */
147#include <stdlib.h> /* needed for realpath() */
148#endif /* ! _WIN32 */
149#include "allheaders.h"
150#include "array_internal.h"
151
152static const l_uint32 MaxPtrArraySize = 50000000; /* 50 million */
153static const l_int32 InitialPtrArraySize = 50;
154
155 /* Static functions */
156static l_int32 sarrayExtendArray(SARRAY *sa);
157
158
159/*--------------------------------------------------------------------------*
160 * String array create/destroy/copy/extend *
161 *--------------------------------------------------------------------------*/
168SARRAY *
169sarrayCreate(l_int32 n)
170{
171SARRAY *sa;
172
173 if (n <= 0 || n > MaxPtrArraySize)
175
176 sa = (SARRAY *)LEPT_CALLOC(1, sizeof(SARRAY));
177 if ((sa->array = (char **)LEPT_CALLOC(n, sizeof(char *))) == NULL) {
178 sarrayDestroy(&sa);
179 return (SARRAY *)ERROR_PTR("ptr array not made", __func__, NULL);
180 }
181
182 sa->nalloc = n;
183 sa->n = 0;
184 sa->refcount = 1;
185 return sa;
186}
187
188
196SARRAY *
198 const char *initstr)
199{
200l_int32 i;
201SARRAY *sa;
202
203 if (n <= 0)
204 return (SARRAY *)ERROR_PTR("n must be > 0", __func__, NULL);
205 if (!initstr)
206 return (SARRAY *)ERROR_PTR("initstr not defined", __func__, NULL);
207
208 sa = sarrayCreate(n);
209 for (i = 0; i < n; i++)
210 sarrayAddString(sa, initstr, L_COPY);
211 return sa;
212}
213
214
227SARRAY *
229{
230char separators[] = " \n\t";
231l_int32 i, nsub, size, inword;
232SARRAY *sa;
233
234 if (!string)
235 return (SARRAY *)ERROR_PTR("textstr not defined", __func__, NULL);
236
237 /* Find the number of words */
238 size = strlen(string);
239 nsub = 0;
240 inword = FALSE;
241 for (i = 0; i < size; i++) {
242 if (inword == FALSE &&
243 (string[i] != ' ' && string[i] != '\t' && string[i] != '\n')) {
244 inword = TRUE;
245 nsub++;
246 } else if (inword == TRUE &&
247 (string[i] == ' ' || string[i] == '\t' || string[i] == '\n')) {
248 inword = FALSE;
249 }
250 }
251
252 if ((sa = sarrayCreate(nsub)) == NULL)
253 return (SARRAY *)ERROR_PTR("sa not made", __func__, NULL);
254 sarraySplitString(sa, string, separators);
255
256 return sa;
257}
258
259
275SARRAY *
277 l_int32 blankflag)
278{
279l_int32 i, nsub, size, startptr;
280char *cstring, *substring;
281SARRAY *sa;
282
283 if (!string)
284 return (SARRAY *)ERROR_PTR("textstr not defined", __func__, NULL);
285
286 /* Find the number of lines */
287 size = strlen(string);
288 nsub = 0;
289 for (i = 0; i < size; i++) {
290 if (string[i] == '\n')
291 nsub++;
292 }
293
294 if ((sa = sarrayCreate(nsub)) == NULL)
295 return (SARRAY *)ERROR_PTR("sa not made", __func__, NULL);
296
297 if (blankflag) { /* keep blank lines as null strings */
298 /* Make a copy for munging */
299 if ((cstring = stringNew(string)) == NULL) {
300 sarrayDestroy(&sa);
301 return (SARRAY *)ERROR_PTR("cstring not made", __func__, NULL);
302 }
303 /* We'll insert nulls like strtok */
304 startptr = 0;
305 for (i = 0; i < size; i++) {
306 if (cstring[i] == '\n') {
307 cstring[i] = '\0';
308 if (i > 0 && cstring[i - 1] == '\r')
309 cstring[i - 1] = '\0'; /* also remove Windows CR */
310 if ((substring = stringNew(cstring + startptr)) == NULL) {
311 sarrayDestroy(&sa);
312 LEPT_FREE(cstring);
313 return (SARRAY *)ERROR_PTR("substring not made",
314 __func__, NULL);
315 }
316 sarrayAddString(sa, substring, L_INSERT);
317/* lept_stderr("substring = %s\n", substring); */
318 startptr = i + 1;
319 }
320 }
321 if (startptr < size) { /* no newline at end of last line */
322 if ((substring = stringNew(cstring + startptr)) == NULL) {
323 sarrayDestroy(&sa);
324 LEPT_FREE(cstring);
325 return (SARRAY *)ERROR_PTR("substring not made",
326 __func__, NULL);
327 }
328 sarrayAddString(sa, substring, L_INSERT);
329/* lept_stderr("substring = %s\n", substring); */
330 }
331 LEPT_FREE(cstring);
332 } else { /* remove blank lines; use strtok */
333 sarraySplitString(sa, string, "\r\n");
334 }
335
336 return sa;
337}
338
339
352void
354{
355l_int32 i;
356SARRAY *sa;
357
358 if (psa == NULL) {
359 L_WARNING("ptr address is NULL!\n", __func__);
360 return;
361 }
362 if ((sa = *psa) == NULL)
363 return;
364
365 if (--sa->refcount == 0) {
366 if (sa->array) {
367 for (i = 0; i < sa->n; i++) {
368 if (sa->array[i])
369 LEPT_FREE(sa->array[i]);
370 }
371 LEPT_FREE(sa->array);
372 }
373 LEPT_FREE(sa);
374 }
375 *psa = NULL;
376}
377
378
385SARRAY *
387{
388l_int32 i;
389SARRAY *csa;
390
391 if (!sa)
392 return (SARRAY *)ERROR_PTR("sa not defined", __func__, NULL);
393
394 if ((csa = sarrayCreate(sa->nalloc)) == NULL)
395 return (SARRAY *)ERROR_PTR("csa not made", __func__, NULL);
396
397 for (i = 0; i < sa->n; i++)
398 sarrayAddString(csa, sa->array[i], L_COPY);
399
400 return csa;
401}
402
403
410SARRAY *
412{
413 if (!sa)
414 return (SARRAY *)ERROR_PTR("sa not defined", __func__, NULL);
415 ++sa->refcount;
416 return sa;
417}
418
419
434l_ok
436 const char *string,
437 l_int32 copyflag)
438{
439l_int32 n;
440
441 if (!sa)
442 return ERROR_INT("sa not defined", __func__, 1);
443 if (!string)
444 return ERROR_INT("string not defined", __func__, 1);
445 if (copyflag != L_INSERT && copyflag != L_NOCOPY && copyflag != L_COPY)
446 return ERROR_INT("invalid copyflag", __func__, 1);
447
448 n = sarrayGetCount(sa);
449 if (n >= sa->nalloc) {
450 if (sarrayExtendArray(sa))
451 return ERROR_INT("extension failed", __func__, 1);
452 }
453
454 if (copyflag == L_COPY)
455 sa->array[n] = stringNew(string);
456 else /* L_INSERT or L_NOCOPY */
457 sa->array[n] = (char *)string;
458 sa->n++;
459 return 0;
460}
461
462
475static l_int32
477{
478size_t oldsize, newsize;
479
480 if (!sa)
481 return ERROR_INT("sa not defined", __func__, 1);
482 if (sa->nalloc >= MaxPtrArraySize)
483 return ERROR_INT("sa at maximum ptr size; can't extend", __func__, 1);
484 oldsize = sa->nalloc * sizeof(char *);
485 if (sa->nalloc > MaxPtrArraySize / 2) {
486 newsize = MaxPtrArraySize * sizeof(char *);
487 sa->nalloc = MaxPtrArraySize;
488 } else {
489 newsize = 2 * oldsize;
490 sa->nalloc *= 2;
491 }
492 if ((sa->array = (char **)reallocNew((void **)&sa->array,
493 oldsize, newsize)) == NULL)
494 return ERROR_INT("new ptr array not returned", __func__, 1);
495
496 return 0;
497}
498
499
507char *
509 l_int32 index)
510{
511char *string;
512char **array;
513l_int32 i, n, nalloc;
514
515 if (!sa)
516 return (char *)ERROR_PTR("sa not defined", __func__, NULL);
517
518 if ((array = sarrayGetArray(sa, &nalloc, &n)) == NULL)
519 return (char *)ERROR_PTR("array not returned", __func__, NULL);
520
521 if (index < 0 || index >= n)
522 return (char *)ERROR_PTR("array index out of bounds", __func__, NULL);
523
524 string = array[index];
525
526 /* If removed string is not at end of array, shift
527 * to fill in, maintaining original ordering.
528 * Note: if we didn't care about the order, we could
529 * put the last string array[n - 1] directly into the hole. */
530 for (i = index; i < n - 1; i++)
531 array[i] = array[i + 1];
532
533 sa->n--;
534 return string;
535}
536
537
556l_ok
558 l_int32 index,
559 char *newstr,
560 l_int32 copyflag)
561{
562char *str;
563l_int32 n;
564
565 if (!sa)
566 return ERROR_INT("sa not defined", __func__, 1);
567 n = sarrayGetCount(sa);
568 if (index < 0 || index >= n)
569 return ERROR_INT("array index out of bounds", __func__, 1);
570 if (!newstr)
571 return ERROR_INT("newstr not defined", __func__, 1);
572 if (copyflag != L_INSERT && copyflag != L_COPY)
573 return ERROR_INT("invalid copyflag", __func__, 1);
574
575 LEPT_FREE(sa->array[index]);
576 if (copyflag == L_INSERT)
577 str = newstr;
578 else /* L_COPY */
579 str = stringNew(newstr);
580 sa->array[index] = str;
581 return 0;
582}
583
584
591l_ok
593{
594l_int32 i;
595
596 if (!sa)
597 return ERROR_INT("sa not defined", __func__, 1);
598 for (i = 0; i < sa->n; i++) { /* free strings and null ptrs */
599 LEPT_FREE(sa->array[i]);
600 sa->array[i] = NULL;
601 }
602 sa->n = 0;
603 return 0;
604}
605
606
607/*----------------------------------------------------------------------*
608 * Accessors *
609 *----------------------------------------------------------------------*/
616l_int32
618{
619 if (!sa)
620 return ERROR_INT("sa not defined", __func__, 0);
621 return sa->n;
622}
623
624
639char **
641 l_int32 *pnalloc,
642 l_int32 *pn)
643{
644char **array;
645
646 if (!sa)
647 return (char **)ERROR_PTR("sa not defined", __func__, NULL);
648
649 array = sa->array;
650 if (pnalloc) *pnalloc = sa->nalloc;
651 if (pn) *pn = sa->n;
652
653 return array;
654}
655
656
672char *
674 l_int32 index,
675 l_int32 copyflag)
676{
677 if (!sa)
678 return (char *)ERROR_PTR("sa not defined", __func__, NULL);
679 if (index < 0 || index >= sa->n)
680 return (char *)ERROR_PTR("index not valid", __func__, NULL);
681 if (copyflag != L_NOCOPY && copyflag != L_COPY)
682 return (char *)ERROR_PTR("invalid copyflag", __func__, NULL);
683
684 if (copyflag == L_NOCOPY)
685 return sa->array[index];
686 else /* L_COPY */
687 return stringNew(sa->array[index]);
688}
689
690
691/*----------------------------------------------------------------------*
692 * Conversion to string *
693 *----------------------------------------------------------------------*/
715char *
717 l_int32 addnlflag)
718{
719 if (!sa)
720 return (char *)ERROR_PTR("sa not defined", __func__, NULL);
721
722 return sarrayToStringRange(sa, 0, 0, addnlflag);
723}
724
725
748char *
750 l_int32 first,
751 l_int32 nstrings,
752 l_int32 addnlflag)
753{
754char *dest, *src, *str;
755l_int32 n, i, last, size, index, len;
756
757 if (!sa)
758 return (char *)ERROR_PTR("sa not defined", __func__, NULL);
759 if (addnlflag != 0 && addnlflag != 1 && addnlflag != 2 && addnlflag != 3)
760 return (char *)ERROR_PTR("invalid addnlflag", __func__, NULL);
761
762 n = sarrayGetCount(sa);
763
764 /* Empty sa; return char corresponding to addnlflag only */
765 if (n == 0) {
766 if (first == 0) {
767 if (addnlflag == 0)
768 return stringNew("");
769 if (addnlflag == 1)
770 return stringNew("\n");
771 if (addnlflag == 2)
772 return stringNew(" ");
773 else /* addnlflag == 3) */
774 return stringNew(",");
775 } else {
776 return (char *)ERROR_PTR("first not valid", __func__, NULL);
777 }
778 }
779
780 /* Determine the range of string indices to be used */
781 if (first < 0 || first >= n)
782 return (char *)ERROR_PTR("first not valid", __func__, NULL);
783 if (nstrings == 0 || (nstrings > n - first))
784 nstrings = n - first; /* no overflow */
785 last = first + nstrings - 1;
786
787 /* Determine the size of the output string */
788 size = 0;
789 for (i = first; i <= last; i++) {
790 if ((str = sarrayGetString(sa, i, L_NOCOPY)) == NULL)
791 return (char *)ERROR_PTR("str not found", __func__, NULL);
792 size += strlen(str) + 2;
793 }
794 if ((dest = (char *)LEPT_CALLOC(size + 1, sizeof(char))) == NULL)
795 return (char *)ERROR_PTR("dest not made", __func__, NULL);
796
797 /* Construct the output */
798 index = 0;
799 for (i = first; i <= last; i++) {
800 src = sarrayGetString(sa, i, L_NOCOPY);
801 len = strlen(src);
802 memcpy(dest + index, src, len);
803 index += len;
804 if (addnlflag == 1) {
805 dest[index] = '\n';
806 index++;
807 } else if (addnlflag == 2) {
808 dest[index] = ' ';
809 index++;
810 } else if (addnlflag == 3) {
811 dest[index] = ',';
812 index++;
813 }
814 }
815
816 return dest;
817}
818
819
820/*----------------------------------------------------------------------*
821 * Concatenate strings uniformly within the sarray *
822 *----------------------------------------------------------------------*/
843SARRAY *
845 l_int32 n,
846 l_int32 addnlflag)
847{
848l_int32 i, first, ntot, nstr;
849char *str;
850NUMA *na;
851SARRAY *saout;
852
853 if (!sa)
854 return (SARRAY *)ERROR_PTR("sa not defined", __func__, NULL);
855 ntot = sarrayGetCount(sa);
856 if (n < 1)
857 return (SARRAY *)ERROR_PTR("n must be >= 1", __func__, NULL);
858 if (n > ntot) {
859 L_ERROR("n = %d > ntot = %d\n", __func__, n, ntot);
860 return NULL;
861 }
862 if (addnlflag != 0 && addnlflag != 1 && addnlflag != 2 && addnlflag != 3)
863 return (SARRAY *)ERROR_PTR("invalid addnlflag", __func__, NULL);
864
865 saout = sarrayCreate(0);
866 na = numaGetUniformBinSizes(ntot, n);
867 for (i = 0, first = 0; i < n; i++) {
868 numaGetIValue(na, i, &nstr);
869 str = sarrayToStringRange(sa, first, nstr, addnlflag);
870 sarrayAddString(saout, str, L_INSERT);
871 first += nstr;
872 }
873 numaDestroy(&na);
874 return saout;
875}
876
877
878/*----------------------------------------------------------------------*
879 * Join 2 sarrays *
880 *----------------------------------------------------------------------*/
893l_ok
895 SARRAY *sa2)
896{
897char *str;
898l_int32 n, i;
899
900 if (!sa1)
901 return ERROR_INT("sa1 not defined", __func__, 1);
902 if (!sa2)
903 return ERROR_INT("sa2 not defined", __func__, 1);
904
905 n = sarrayGetCount(sa2);
906 for (i = 0; i < n; i++) {
907 str = sarrayGetString(sa2, i, L_NOCOPY);
908 if (sarrayAddString(sa1, str, L_COPY) == 1) {
909 L_ERROR("failed to add string at i = %d\n", __func__, i);
910 return 1;
911 }
912 }
913 return 0;
914}
915
916
934l_ok
936 SARRAY *sa2,
937 l_int32 start,
938 l_int32 end)
939{
940char *str;
941l_int32 n, i;
942
943 if (!sa1)
944 return ERROR_INT("sa1 not defined", __func__, 1);
945 if (!sa2)
946 return ERROR_INT("sa2 not defined", __func__, 1);
947
948 if (start < 0)
949 start = 0;
950 n = sarrayGetCount(sa2);
951 if (end < 0 || end >= n)
952 end = n - 1;
953 if (start > end)
954 return ERROR_INT("start > end", __func__, 1);
955
956 for (i = start; i <= end; i++) {
957 str = sarrayGetString(sa2, i, L_NOCOPY);
958 sarrayAddString(sa1, str, L_COPY);
959 }
960
961 return 0;
962}
963
964
965/*----------------------------------------------------------------------*
966 * Pad an sarray to be the same size as another sarray *
967 *----------------------------------------------------------------------*/
984l_ok
986 SARRAY *sa2,
987 const char *padstring)
988{
989l_int32 i, n1, n2;
990
991 if (!sa1 || !sa2)
992 return ERROR_INT("both sa1 and sa2 not defined", __func__, 1);
993
994 n1 = sarrayGetCount(sa1);
995 n2 = sarrayGetCount(sa2);
996 if (n1 < n2) {
997 for (i = n1; i < n2; i++)
998 sarrayAddString(sa1, padstring, L_COPY);
999 } else if (n1 > n2) {
1000 for (i = n2; i < n1; i++)
1001 sarrayAddString(sa2, padstring, L_COPY);
1002 }
1003
1004 return 0;
1005}
1006
1007
1008/*----------------------------------------------------------------------*
1009 * Convert word sarray to line sarray *
1010 *----------------------------------------------------------------------*/
1041SARRAY *
1043 l_int32 linesize)
1044{
1045char *wd, *strl;
1046char emptystring[] = "";
1047l_int32 n, i, len, totlen;
1048SARRAY *sal, *saout;
1049
1050 if (!sa)
1051 return (SARRAY *)ERROR_PTR("sa not defined", __func__, NULL);
1052
1053 saout = sarrayCreate(0);
1054 n = sarrayGetCount(sa);
1055 totlen = 0;
1056 sal = NULL;
1057 for (i = 0; i < n; i++) {
1058 if (!sal)
1059 sal = sarrayCreate(0);
1060 wd = sarrayGetString(sa, i, L_NOCOPY);
1061 len = strlen(wd);
1062 if (len == 0) { /* end of paragraph: end line & insert blank line */
1063 if (totlen > 0) {
1064 strl = sarrayToString(sal, 2);
1065 sarrayAddString(saout, strl, L_INSERT);
1066 }
1067 sarrayAddString(saout, emptystring, L_COPY);
1068 sarrayDestroy(&sal);
1069 totlen = 0;
1070 } else if (totlen == 0 && len + 1 > linesize) { /* long word! */
1071 sarrayAddString(saout, wd, L_COPY); /* copy to one line */
1072 } else if (totlen + len + 1 > linesize) { /* end line & start new */
1073 strl = sarrayToString(sal, 2);
1074 sarrayAddString(saout, strl, L_INSERT);
1075 sarrayDestroy(&sal);
1076 sal = sarrayCreate(0);
1077 sarrayAddString(sal, wd, L_COPY);
1078 totlen = len + 1;
1079 } else { /* add to current line */
1080 sarrayAddString(sal, wd, L_COPY);
1081 totlen += len + 1;
1082 }
1083 }
1084 if (totlen > 0) { /* didn't end with blank line; output last line */
1085 strl = sarrayToString(sal, 2);
1086 sarrayAddString(saout, strl, L_INSERT);
1087 sarrayDestroy(&sal);
1088 }
1089
1090 return saout;
1091}
1092
1093
1094/*----------------------------------------------------------------------*
1095 * Split string on separator list *
1096 *----------------------------------------------------------------------*/
1097/*
1098 * \brief sarraySplitString()
1099 *
1100 * \param[in] sa to append to; typically empty initially
1101 * \param[in] str string to split; not changed
1102 * \param[in] separators characters that split input string
1103 * \return 0 if OK, 1 on error.
1104 *
1105 * <pre>
1106 * Notes:
1107 * (1) This uses strtokSafe(). See the notes there in utils.c.
1108 * </pre>
1109 */
1110l_int32
1111sarraySplitString(SARRAY *sa,
1112 const char *str,
1113 const char *separators)
1114{
1115char *cstr, *substr, *saveptr;
1116
1117 if (!sa)
1118 return ERROR_INT("sa not defined", __func__, 1);
1119 if (!str)
1120 return ERROR_INT("str not defined", __func__, 1);
1121 if (!separators)
1122 return ERROR_INT("separators not defined", __func__, 1);
1123
1124 cstr = stringNew(str); /* preserves const-ness of input str */
1125 saveptr = NULL;
1126 substr = strtokSafe(cstr, separators, &saveptr);
1127 if (substr)
1128 sarrayAddString(sa, substr, L_INSERT);
1129 while ((substr = strtokSafe(NULL, separators, &saveptr)))
1130 sarrayAddString(sa, substr, L_INSERT);
1131 LEPT_FREE(cstr);
1132
1133 return 0;
1134}
1135
1136
1137/*----------------------------------------------------------------------*
1138 * Filter sarray *
1139 *----------------------------------------------------------------------*/
1155SARRAY *
1157 const char *substr)
1158{
1159char *str;
1160l_int32 n, i, offset, found;
1161SARRAY *saout;
1162
1163 if (!sain)
1164 return (SARRAY *)ERROR_PTR("sain not defined", __func__, NULL);
1165
1166 n = sarrayGetCount(sain);
1167 if (!substr || n == 0)
1168 return sarrayCopy(sain);
1169
1170 saout = sarrayCreate(n);
1171 for (i = 0; i < n; i++) {
1172 str = sarrayGetString(sain, i, L_NOCOPY);
1173 arrayFindSequence((l_uint8 *)str, strlen(str), (l_uint8 *)substr,
1174 strlen(substr), &offset, &found);
1175 if (found)
1176 sarrayAddString(saout, str, L_COPY);
1177 }
1178
1179 return saout;
1180}
1181
1182
1199SARRAY *
1201 l_int32 first,
1202 l_int32 last)
1203{
1204char *str;
1205l_int32 n, i;
1206SARRAY *saout;
1207
1208 if (!sain)
1209 return (SARRAY *)ERROR_PTR("sain not defined", __func__, NULL);
1210 if (first < 0) first = 0;
1211 n = sarrayGetCount(sain);
1212 if (last <= 0) last = n - 1;
1213 if (last >= n) {
1214 L_WARNING("last > n - 1; setting to n - 1\n", __func__);
1215 last = n - 1;
1216 }
1217 if (first > last)
1218 return (SARRAY *)ERROR_PTR("first must be >= last", __func__, NULL);
1219
1220 saout = sarrayCreate(0);
1221 for (i = first; i <= last; i++) {
1222 str = sarrayGetString(sain, i, L_COPY);
1223 sarrayAddString(saout, str, L_INSERT);
1224 }
1225
1226 return saout;
1227}
1228
1229
1266l_int32
1268 l_int32 start,
1269 l_int32 *pactualstart,
1270 l_int32 *pend,
1271 l_int32 *pnewstart,
1272 const char *substr,
1273 l_int32 loc)
1274{
1275char *str;
1276l_int32 n, i, offset, found;
1277
1278 if (!sa)
1279 return ERROR_INT("sa not defined", __func__, 1);
1280 if (!pactualstart || !pend || !pnewstart)
1281 return ERROR_INT("not all range addresses defined", __func__, 1);
1282 n = sarrayGetCount(sa);
1283 *pactualstart = *pend = *pnewstart = n;
1284 if (!substr)
1285 return ERROR_INT("substr not defined", __func__, 1);
1286
1287 /* Look for the first string without the marker */
1288 if (start < 0 || start >= n)
1289 return 1;
1290 for (i = start; i < n; i++) {
1291 str = sarrayGetString(sa, i, L_NOCOPY);
1292 arrayFindSequence((l_uint8 *)str, strlen(str), (l_uint8 *)substr,
1293 strlen(substr), &offset, &found);
1294 if (loc < 0) {
1295 if (!found) break;
1296 } else {
1297 if (!found || offset != loc) break;
1298 }
1299 }
1300 start = i;
1301 if (i == n) /* couldn't get started */
1302 return 1;
1303
1304 /* Look for the last string without the marker */
1305 *pactualstart = start;
1306 for (i = start + 1; i < n; i++) {
1307 str = sarrayGetString(sa, i, L_NOCOPY);
1308 arrayFindSequence((l_uint8 *)str, strlen(str), (l_uint8 *)substr,
1309 strlen(substr), &offset, &found);
1310 if (loc < 0) {
1311 if (found) break;
1312 } else {
1313 if (found && offset == loc) break;
1314 }
1315 }
1316 *pend = i - 1;
1317 start = i;
1318 if (i == n) /* no further range */
1319 return 0;
1320
1321 /* Look for the first string after *pend without the marker.
1322 * This will start the next run of strings, if it exists. */
1323 for (i = start; i < n; i++) {
1324 str = sarrayGetString(sa, i, L_NOCOPY);
1325 arrayFindSequence((l_uint8 *)str, strlen(str), (l_uint8 *)substr,
1326 strlen(substr), &offset, &found);
1327 if (loc < 0) {
1328 if (!found) break;
1329 } else {
1330 if (!found || offset != loc) break;
1331 }
1332 }
1333 if (i < n)
1334 *pnewstart = i;
1335
1336 return 0;
1337}
1338
1339
1340/*----------------------------------------------------------------------*
1341 * Serialize for I/O *
1342 *----------------------------------------------------------------------*/
1349SARRAY *
1350sarrayRead(const char *filename)
1351{
1352FILE *fp;
1353SARRAY *sa;
1354
1355 if (!filename)
1356 return (SARRAY *)ERROR_PTR("filename not defined", __func__, NULL);
1357
1358 if ((fp = fopenReadStream(filename)) == NULL)
1359 return (SARRAY *)ERROR_PTR("stream not opened", __func__, NULL);
1360 sa = sarrayReadStream(fp);
1361 fclose(fp);
1362 if (!sa)
1363 return (SARRAY *)ERROR_PTR("sa not read", __func__, NULL);
1364 return sa;
1365}
1366
1367
1385SARRAY *
1387{
1388char *stringbuf;
1389l_int32 i, n, size, index, bufsize, version, ignore, success;
1390SARRAY *sa;
1391
1392 if (!fp)
1393 return (SARRAY *)ERROR_PTR("stream not defined", __func__, NULL);
1394
1395 if (fscanf(fp, "\nSarray Version %d\n", &version) != 1)
1396 return (SARRAY *)ERROR_PTR("not an sarray file", __func__, NULL);
1397 if (version != SARRAY_VERSION_NUMBER)
1398 return (SARRAY *)ERROR_PTR("invalid sarray version", __func__, NULL);
1399 if (fscanf(fp, "Number of strings = %d\n", &n) != 1)
1400 return (SARRAY *)ERROR_PTR("error on # strings", __func__, NULL);
1401 if (n < 0)
1402 return (SARRAY *)ERROR_PTR("num string ptrs <= 0", __func__, NULL);
1403 if (n > MaxPtrArraySize)
1404 return (SARRAY *)ERROR_PTR("too many string ptrs", __func__, NULL);
1405 if (n == 0) L_INFO("the sarray is empty\n", __func__);
1406
1407 success = TRUE;
1408 if ((sa = sarrayCreate(n)) == NULL)
1409 return (SARRAY *)ERROR_PTR("sa not made", __func__, NULL);
1410 bufsize = 512 + 1;
1411 stringbuf = (char *)LEPT_CALLOC(bufsize, sizeof(char));
1412
1413 for (i = 0; i < n; i++) {
1414 /* Get the size of the stored string */
1415 if ((fscanf(fp, "%d[%d]:", &index, &size) != 2) || (size > (1 << 30))) {
1416 success = FALSE;
1417 L_ERROR("error on string size\n", __func__);
1418 goto cleanup;
1419 }
1420 /* Expand the string buffer if necessary */
1421 if (size > bufsize - 5) {
1422 LEPT_FREE(stringbuf);
1423 bufsize = (l_int32)(1.5 * size);
1424 stringbuf = (char *)LEPT_CALLOC(bufsize, sizeof(char));
1425 }
1426 /* Read the stored string, plus leading spaces and trailing \n */
1427 if (fread(stringbuf, 1, size + 3, fp) != size + 3) {
1428 success = FALSE;
1429 L_ERROR("error reading string\n", __func__);
1430 goto cleanup;
1431 }
1432 /* Remove the \n that was added by sarrayWriteStream() */
1433 stringbuf[size + 2] = '\0';
1434 /* Copy it in, skipping the 2 leading spaces */
1435 sarrayAddString(sa, stringbuf + 2, L_COPY);
1436 }
1437 ignore = fscanf(fp, "\n");
1438
1439cleanup:
1440 LEPT_FREE(stringbuf);
1441 if (!success) sarrayDestroy(&sa);
1442 return sa;
1443}
1444
1445
1453SARRAY *
1454sarrayReadMem(const l_uint8 *data,
1455 size_t size)
1456{
1457FILE *fp;
1458SARRAY *sa;
1459
1460 if (!data)
1461 return (SARRAY *)ERROR_PTR("data not defined", __func__, NULL);
1462 if ((fp = fopenReadFromMemory(data, size)) == NULL)
1463 return (SARRAY *)ERROR_PTR("stream not opened", __func__, NULL);
1464
1465 sa = sarrayReadStream(fp);
1466 fclose(fp);
1467 if (!sa) L_ERROR("sarray not read\n", __func__);
1468 return sa;
1469}
1470
1471
1479l_ok
1480sarrayWrite(const char *filename,
1481 SARRAY *sa)
1482{
1483l_int32 ret;
1484FILE *fp;
1485
1486 if (!filename)
1487 return ERROR_INT("filename not defined", __func__, 1);
1488 if (!sa)
1489 return ERROR_INT("sa not defined", __func__, 1);
1490
1491 if ((fp = fopenWriteStream(filename, "w")) == NULL)
1492 return ERROR_INT("stream not opened", __func__, 1);
1493 ret = sarrayWriteStream(fp, sa);
1494 fclose(fp);
1495 if (ret)
1496 return ERROR_INT("sa not written to stream", __func__, 1);
1497 return 0;
1498}
1499
1500
1514l_ok
1516 SARRAY *sa)
1517{
1518l_int32 i, n, len;
1519
1520 if (!fp)
1521 return ERROR_INT("stream not defined", __func__, 1);
1522 if (!sa)
1523 return sarrayWriteStderr(sa);
1524
1525 n = sarrayGetCount(sa);
1526 fprintf(fp, "\nSarray Version %d\n", SARRAY_VERSION_NUMBER);
1527 fprintf(fp, "Number of strings = %d\n", n);
1528 for (i = 0; i < n; i++) {
1529 len = strlen(sa->array[i]);
1530 fprintf(fp, " %d[%d]: %s\n", i, len, sa->array[i]);
1531 }
1532 fprintf(fp, "\n");
1533
1534 return 0;
1535}
1536
1537
1544l_ok
1546{
1547l_int32 i, n, len;
1548
1549 if (!sa)
1550 return ERROR_INT("sa not defined", __func__, 1);
1551
1552 n = sarrayGetCount(sa);
1553 lept_stderr("\nSarray Version %d\n", SARRAY_VERSION_NUMBER);
1554 lept_stderr("Number of strings = %d\n", n);
1555 for (i = 0; i < n; i++) {
1556 len = strlen(sa->array[i]);
1557 lept_stderr(" %d[%d]: %s\n", i, len, sa->array[i]);
1558 }
1559 lept_stderr("\n");
1560 return 0;
1561}
1562
1563
1577l_ok
1578sarrayWriteMem(l_uint8 **pdata,
1579 size_t *psize,
1580 SARRAY *sa)
1581{
1582l_int32 ret;
1583FILE *fp;
1584
1585 if (pdata) *pdata = NULL;
1586 if (psize) *psize = 0;
1587 if (!pdata)
1588 return ERROR_INT("&data not defined", __func__, 1);
1589 if (!psize)
1590 return ERROR_INT("&size not defined", __func__, 1);
1591 if (!sa)
1592 return ERROR_INT("sa not defined", __func__, 1);
1593
1594#if HAVE_FMEMOPEN
1595 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1596 return ERROR_INT("stream not opened", __func__, 1);
1597 ret = sarrayWriteStream(fp, sa);
1598 fputc('\0', fp);
1599 fclose(fp);
1600 *psize = *psize - 1;
1601#else
1602 L_INFO("work-around: writing to a temp file\n", __func__);
1603 #ifdef _WIN32
1604 if ((fp = fopenWriteWinTempfile()) == NULL)
1605 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1606 #else
1607 if ((fp = tmpfile()) == NULL)
1608 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1609 #endif /* _WIN32 */
1610 ret = sarrayWriteStream(fp, sa);
1611 rewind(fp);
1612 *pdata = l_binaryReadStream(fp, psize);
1613 fclose(fp);
1614#endif /* HAVE_FMEMOPEN */
1615 return ret;
1616}
1617
1618
1626l_ok
1627sarrayAppend(const char *filename,
1628 SARRAY *sa)
1629{
1630FILE *fp;
1631
1632 if (!filename)
1633 return ERROR_INT("filename not defined", __func__, 1);
1634 if (!sa)
1635 return ERROR_INT("sa not defined", __func__, 1);
1636
1637 if ((fp = fopenWriteStream(filename, "a")) == NULL)
1638 return ERROR_INT("stream not opened", __func__, 1);
1639 if (sarrayWriteStream(fp, sa)) {
1640 fclose(fp);
1641 return ERROR_INT("sa not appended to stream", __func__, 1);
1642 }
1643
1644 fclose(fp);
1645 return 0;
1646}
1647
1648
1649/*---------------------------------------------------------------------*
1650 * Directory filenames *
1651 *---------------------------------------------------------------------*/
1692SARRAY *
1694 const char *substr,
1695 l_int32 numpre,
1696 l_int32 numpost,
1697 l_int32 maxnum)
1698{
1699l_int32 nfiles;
1700SARRAY *sa, *saout;
1701
1702 if (!dirname)
1703 return (SARRAY *)ERROR_PTR("dirname not defined", __func__, NULL);
1704
1705 if ((sa = getSortedPathnamesInDirectory(dirname, substr, 0, 0)) == NULL)
1706 return (SARRAY *)ERROR_PTR("sa not made", __func__, NULL);
1707 if ((nfiles = sarrayGetCount(sa)) == 0) {
1708 sarrayDestroy(&sa);
1709 return sarrayCreate(1);
1710 }
1711
1712 saout = convertSortedToNumberedPathnames(sa, numpre, numpost, maxnum);
1713 sarrayDestroy(&sa);
1714 return saout;
1715}
1716
1717
1738SARRAY *
1740 const char *substr,
1741 l_int32 first,
1742 l_int32 nfiles)
1743{
1744char *fname, *fullname;
1745l_int32 i, n, last;
1746SARRAY *sa, *safiles, *saout;
1747
1748 if (!dirname)
1749 return (SARRAY *)ERROR_PTR("dirname not defined", __func__, NULL);
1750
1751 if ((sa = getFilenamesInDirectory(dirname)) == NULL)
1752 return (SARRAY *)ERROR_PTR("sa not made", __func__, NULL);
1753 safiles = sarraySelectBySubstring(sa, substr);
1754 sarrayDestroy(&sa);
1755 n = sarrayGetCount(safiles);
1756 if (n == 0) {
1757 L_WARNING("no files found\n", __func__);
1758 return safiles;
1759 }
1760
1761 sarraySort(safiles, safiles, L_SORT_INCREASING);
1762
1763 first = L_MIN(L_MAX(first, 0), n - 1);
1764 if (nfiles == 0)
1765 nfiles = n - first;
1766 last = L_MIN(first + nfiles - 1, n - 1);
1767
1768 saout = sarrayCreate(last - first + 1);
1769 for (i = first; i <= last; i++) {
1770 fname = sarrayGetString(safiles, i, L_NOCOPY);
1771 fullname = pathJoin(dirname, fname);
1772 sarrayAddString(saout, fullname, L_INSERT);
1773 }
1774
1775 sarrayDestroy(&safiles);
1776 return saout;
1777}
1778
1779
1796SARRAY *
1798 l_int32 numpre,
1799 l_int32 numpost,
1800 l_int32 maxnum)
1801{
1802char *fname, *str;
1803l_int32 i, nfiles, num, index;
1804SARRAY *saout;
1805
1806 if (!sa)
1807 return (SARRAY *)ERROR_PTR("sa not defined", __func__, NULL);
1808 if ((nfiles = sarrayGetCount(sa)) == 0)
1809 return sarrayCreate(1);
1810
1811 /* Find the last file in the sorted array that has a number
1812 * that (a) matches the count pattern and (b) does not
1813 * exceed %maxnum. %maxnum sets an upper limit on the size
1814 * of the sarray. */
1815 num = 0;
1816 for (i = nfiles - 1; i >= 0; i--) {
1817 fname = sarrayGetString(sa, i, L_NOCOPY);
1818 num = extractNumberFromFilename(fname, numpre, numpost);
1819 if (num < 0) continue;
1820 num = L_MIN(num + 1, maxnum);
1821 break;
1822 }
1823
1824 if (num <= 0) /* none found */
1825 return sarrayCreate(1);
1826
1827 /* Insert pathnames into the output sarray.
1828 * Ignore numbers that are out of the range of sarray. */
1829 saout = sarrayCreateInitialized(num, "");
1830 for (i = 0; i < nfiles; i++) {
1831 fname = sarrayGetString(sa, i, L_NOCOPY);
1832 index = extractNumberFromFilename(fname, numpre, numpost);
1833 if (index < 0 || index >= num) continue;
1834 str = sarrayGetString(saout, index, L_NOCOPY);
1835 if (str[0] != '\0') {
1836 L_WARNING("\n Multiple files with same number: %d\n",
1837 __func__, index);
1838 }
1839 sarrayReplaceString(saout, index, fname, L_COPY);
1840 }
1841
1842 return saout;
1843}
1844
1845
1873
1874#ifndef _WIN32
1875
1876SARRAY *
1877getFilenamesInDirectory(const char *dirname)
1878{
1879char dir[PATH_MAX + 1];
1880char *realdir, *stat_path, *ignore;
1881size_t size;
1882SARRAY *safiles;
1883DIR *pdir;
1884struct dirent *pdirentry;
1885int dfd, stat_ret;
1886struct stat st;
1887
1888 if (!dirname)
1889 return (SARRAY *)ERROR_PTR("dirname not defined", __func__, NULL);
1890 if (dirname[0] == '\0')
1891 return (SARRAY *)ERROR_PTR("dirname is empty", __func__, NULL);
1892
1893 /* Who would have thought it was this fiddly to open a directory
1894 and get the files inside? fstatat() works with relative
1895 directory paths, and stat() requires using the absolute path.
1896 realpath works as follows for files and directories:
1897 * If the file or directory exists, realpath returns its path;
1898 else it returns NULL.
1899 * If the second arg to realpath is passed in, the canonical path
1900 is returned there. Use a buffer of sufficient size. If the
1901 second arg is NULL, the path is malloc'd and returned if the
1902 file or directory exists.
1903 We pass in a buffer for the second arg, and check that the canonical
1904 directory path was made. The existence of the directory is checked
1905 later, after its actual path is returned by genPathname(). */
1906 dir[0] = '\0'; /* init empty in case realpath() fails to write it */
1907 ignore = realpath(dirname, dir);
1908 if (dir[0] == '\0')
1909 return (SARRAY *)ERROR_PTR("dir not made", __func__, NULL);
1910 realdir = genPathname(dir, NULL);
1911 if ((pdir = opendir(realdir)) == NULL) {
1912 LEPT_FREE(realdir);
1913 return (SARRAY *)ERROR_PTR("pdir not opened", __func__, NULL);
1914 }
1915 safiles = sarrayCreate(0);
1916 while ((pdirentry = readdir(pdir))) {
1917#if HAVE_DIRFD && HAVE_FSTATAT
1918 /* Platform issues: although Linux has these POSIX functions,
1919 * AIX doesn't have fstatat() and Solaris doesn't have dirfd(). */
1920 dfd = dirfd(pdir);
1921 stat_ret = fstatat(dfd, pdirentry->d_name, &st, 0);
1922#else
1923 size = strlen(realdir) + strlen(pdirentry->d_name) + 2;
1924 if (size > PATH_MAX) {
1925 L_ERROR("size = %zu too large; skipping\n", __func__, size);
1926 continue;
1927 }
1928 stat_path = (char *)LEPT_CALLOC(size, 1);
1929 snprintf(stat_path, size, "%s/%s", realdir, pdirentry->d_name);
1930 stat_ret = stat(stat_path, &st);
1931 LEPT_FREE(stat_path);
1932#endif
1933 if (stat_ret == 0 && S_ISDIR(st.st_mode))
1934 continue;
1935 sarrayAddString(safiles, pdirentry->d_name, L_COPY);
1936 }
1937 closedir(pdir);
1938 LEPT_FREE(realdir);
1939 return safiles;
1940}
1941
1942#else /* _WIN32 */
1943
1944 /* http://msdn2.microsoft.com/en-us/library/aa365200(VS.85).aspx */
1945#include <windows.h>
1946
1947SARRAY *
1948getFilenamesInDirectory(const char *dirname)
1949{
1950char *pszDir;
1951char *realdir;
1952HANDLE hFind = INVALID_HANDLE_VALUE;
1953SARRAY *safiles;
1954WIN32_FIND_DATAA ffd;
1955
1956 if (!dirname)
1957 return (SARRAY *)ERROR_PTR("dirname not defined", __func__, NULL);
1958
1959 realdir = genPathname(dirname, NULL);
1960 pszDir = stringJoin(realdir, "\\*");
1961 LEPT_FREE(realdir);
1962
1963 if (strlen(pszDir) + 1 > MAX_PATH) {
1964 LEPT_FREE(pszDir);
1965 return (SARRAY *)ERROR_PTR("dirname is too long", __func__, NULL);
1966 }
1967
1968 if ((safiles = sarrayCreate(0)) == NULL) {
1969 LEPT_FREE(pszDir);
1970 return (SARRAY *)ERROR_PTR("safiles not made", __func__, NULL);
1971 }
1972
1973 hFind = FindFirstFileA(pszDir, &ffd);
1974 if (INVALID_HANDLE_VALUE == hFind) {
1975 sarrayDestroy(&safiles);
1976 LEPT_FREE(pszDir);
1977 return (SARRAY *)ERROR_PTR("hFind not opened", __func__, NULL);
1978 }
1979
1980 while (FindNextFileA(hFind, &ffd) != 0) {
1981 if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) /* skip dirs */
1982 continue;
1983 convertSepCharsInPath(ffd.cFileName, UNIX_PATH_SEPCHAR);
1984 sarrayAddString(safiles, ffd.cFileName, L_COPY);
1985 }
1986
1987 FindClose(hFind);
1988 LEPT_FREE(pszDir);
1989 return safiles;
1990}
1991#endif /* _WIN32 */
struct Numa NUMA
Definition array.h:66
struct Sarray SARRAY
Definition array.h:81
#define SARRAY_VERSION_NUMBER
static const size_t InitialPtrArraySize
Definition boxbasic.c:143
@ L_COPY
Definition pix.h:505
@ L_NOCOPY
Definition pix.h:503
@ L_INSERT
Definition pix.h:504
@ L_SORT_INCREASING
Definition pix.h:522
SARRAY * getSortedPathnamesInDirectory(const char *dirname, const char *substr, l_int32 first, l_int32 nfiles)
getSortedPathnamesInDirectory()
Definition sarray1.c:1739
SARRAY * convertSortedToNumberedPathnames(SARRAY *sa, l_int32 numpre, l_int32 numpost, l_int32 maxnum)
convertSortedToNumberedPathnames()
Definition sarray1.c:1797
SARRAY * sarrayConvertWordsToLines(SARRAY *sa, l_int32 linesize)
sarrayConvertWordsToLines()
Definition sarray1.c:1042
SARRAY * sarrayCreate(l_int32 n)
sarrayCreate()
Definition sarray1.c:169
l_ok sarrayWriteStderr(SARRAY *sa)
sarrayWriteStderr()
Definition sarray1.c:1545
char * sarrayToStringRange(SARRAY *sa, l_int32 first, l_int32 nstrings, l_int32 addnlflag)
sarrayToStringRange()
Definition sarray1.c:749
l_ok sarrayJoin(SARRAY *sa1, SARRAY *sa2)
sarrayJoin()
Definition sarray1.c:894
SARRAY * sarrayRead(const char *filename)
sarrayRead()
Definition sarray1.c:1350
l_ok sarrayPadToSameSize(SARRAY *sa1, SARRAY *sa2, const char *padstring)
sarrayPadToSameSize()
Definition sarray1.c:985
char * sarrayRemoveString(SARRAY *sa, l_int32 index)
sarrayRemoveString()
Definition sarray1.c:508
l_ok sarrayReplaceString(SARRAY *sa, l_int32 index, char *newstr, l_int32 copyflag)
sarrayReplaceString()
Definition sarray1.c:557
l_ok sarrayAppend(const char *filename, SARRAY *sa)
sarrayAppend()
Definition sarray1.c:1627
SARRAY * sarraySelectRange(SARRAY *sain, l_int32 first, l_int32 last)
sarraySelectRange()
Definition sarray1.c:1200
char * sarrayToString(SARRAY *sa, l_int32 addnlflag)
sarrayToString()
Definition sarray1.c:716
SARRAY * sarraySelectBySubstring(SARRAY *sain, const char *substr)
sarraySelectBySubstring()
Definition sarray1.c:1156
char * sarrayGetString(SARRAY *sa, l_int32 index, l_int32 copyflag)
sarrayGetString()
Definition sarray1.c:673
l_int32 sarrayGetCount(SARRAY *sa)
sarrayGetCount()
Definition sarray1.c:617
void sarrayDestroy(SARRAY **psa)
sarrayDestroy()
Definition sarray1.c:353
SARRAY * sarrayCreateLinesFromString(const char *string, l_int32 blankflag)
sarrayCreateLinesFromString()
Definition sarray1.c:276
SARRAY * getFilenamesInDirectory(const char *dirname)
getFilenamesInDirectory()
Definition sarray1.c:1877
SARRAY * sarrayCreateInitialized(l_int32 n, const char *initstr)
sarrayCreateInitialized()
Definition sarray1.c:197
l_ok sarrayClear(SARRAY *sa)
sarrayClear()
Definition sarray1.c:592
SARRAY * sarrayReadMem(const l_uint8 *data, size_t size)
sarrayReadMem()
Definition sarray1.c:1454
char ** sarrayGetArray(SARRAY *sa, l_int32 *pnalloc, l_int32 *pn)
sarrayGetArray()
Definition sarray1.c:640
static l_int32 sarrayExtendArray(SARRAY *sa)
sarrayExtendArray()
Definition sarray1.c:476
l_ok sarrayAddString(SARRAY *sa, const char *string, l_int32 copyflag)
sarrayAddString()
Definition sarray1.c:435
SARRAY * sarrayReadStream(FILE *fp)
sarrayReadStream()
Definition sarray1.c:1386
SARRAY * sarrayClone(SARRAY *sa)
sarrayClone()
Definition sarray1.c:411
SARRAY * sarrayCreateWordsFromString(const char *string)
sarrayCreateWordsFromString()
Definition sarray1.c:228
l_ok sarrayWrite(const char *filename, SARRAY *sa)
sarrayWrite()
Definition sarray1.c:1480
l_int32 sarrayParseRange(SARRAY *sa, l_int32 start, l_int32 *pactualstart, l_int32 *pend, l_int32 *pnewstart, const char *substr, l_int32 loc)
sarrayParseRange()
Definition sarray1.c:1267
SARRAY * sarrayCopy(SARRAY *sa)
sarrayCopy()
Definition sarray1.c:386
SARRAY * getNumberedPathnamesInDirectory(const char *dirname, const char *substr, l_int32 numpre, l_int32 numpost, l_int32 maxnum)
getNumberedPathnamesInDirectory()
Definition sarray1.c:1693
l_ok sarrayWriteStream(FILE *fp, SARRAY *sa)
sarrayWriteStream()
Definition sarray1.c:1515
l_ok sarrayWriteMem(l_uint8 **pdata, size_t *psize, SARRAY *sa)
sarrayWriteMem()
Definition sarray1.c:1578
l_ok sarrayAppendRange(SARRAY *sa1, SARRAY *sa2, l_int32 start, l_int32 end)
sarrayAppendRange()
Definition sarray1.c:935
SARRAY * sarrayConcatUniformly(SARRAY *sa, l_int32 n, l_int32 addnlflag)
sarrayConcatUniformly()
Definition sarray1.c:844
l_int32 nalloc
char ** array
l_atomic refcount
l_int32 n