Leptonica  1.83.1
Image processing and image analysis suite
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 
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 
152 static const l_uint32 MaxPtrArraySize = 50000000; /* 50 million */
153 static const l_int32 InitialPtrArraySize = 50;
155  /* Static functions */
156 static l_int32 sarrayExtendArray(SARRAY *sa);
157 
158 
159 /*--------------------------------------------------------------------------*
160  * String array create/destroy/copy/extend *
161  *--------------------------------------------------------------------------*/
168 SARRAY *
169 sarrayCreate(l_int32 n)
170 {
171 SARRAY *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 
196 SARRAY *
198  const char *initstr)
199 {
200 l_int32 i;
201 SARRAY *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 
227 SARRAY *
228 sarrayCreateWordsFromString(const char *string)
229 {
230 char separators[] = " \n\t";
231 l_int32 i, nsub, size, inword;
232 SARRAY *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 
275 SARRAY *
276 sarrayCreateLinesFromString(const char *string,
277  l_int32 blankflag)
278 {
279 l_int32 i, nsub, size, startptr;
280 char *cstring, *substring;
281 SARRAY *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 
352 void
354 {
355 l_int32 i;
356 SARRAY *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 
385 SARRAY *
387 {
388 l_int32 i;
389 SARRAY *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 
410 SARRAY *
412 {
413  if (!sa)
414  return (SARRAY *)ERROR_PTR("sa not defined", __func__, NULL);
415  ++sa->refcount;
416  return sa;
417 }
418 
419 
434 l_ok
436  const char *string,
437  l_int32 copyflag)
438 {
439 l_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 
475 static l_int32
477 {
478 size_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 
507 char *
509  l_int32 index)
510 {
511 char *string;
512 char **array;
513 l_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 
556 l_ok
558  l_int32 index,
559  char *newstr,
560  l_int32 copyflag)
561 {
562 char *str;
563 l_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 
591 l_ok
593 {
594 l_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  *----------------------------------------------------------------------*/
616 l_int32
618 {
619  if (!sa)
620  return ERROR_INT("sa not defined", __func__, 0);
621  return sa->n;
622 }
623 
624 
639 char **
641  l_int32 *pnalloc,
642  l_int32 *pn)
643 {
644 char **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 
672 char *
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  *----------------------------------------------------------------------*/
715 char *
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 
748 char *
750  l_int32 first,
751  l_int32 nstrings,
752  l_int32 addnlflag)
753 {
754 char *dest, *src, *str;
755 l_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  *----------------------------------------------------------------------*/
843 SARRAY *
845  l_int32 n,
846  l_int32 addnlflag)
847 {
848 l_int32 i, first, ntot, nstr;
849 char *str;
850 NUMA *na;
851 SARRAY *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  *----------------------------------------------------------------------*/
893 l_ok
895  SARRAY *sa2)
896 {
897 char *str;
898 l_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 
934 l_ok
936  SARRAY *sa2,
937  l_int32 start,
938  l_int32 end)
939 {
940 char *str;
941 l_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  *----------------------------------------------------------------------*/
984 l_ok
986  SARRAY *sa2,
987  const char *padstring)
988 {
989 l_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  *----------------------------------------------------------------------*/
1041 SARRAY *
1043  l_int32 linesize)
1044 {
1045 char *wd, *strl;
1046 char emptystring[] = "";
1047 l_int32 n, i, len, totlen;
1048 SARRAY *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  */
1110 l_int32
1111 sarraySplitString(SARRAY *sa,
1112  const char *str,
1113  const char *separators)
1114 {
1115 char *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  *----------------------------------------------------------------------*/
1155 SARRAY *
1157  const char *substr)
1158 {
1159 char *str;
1160 l_int32 n, i, offset, found;
1161 SARRAY *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 
1199 SARRAY *
1201  l_int32 first,
1202  l_int32 last)
1203 {
1204 char *str;
1205 l_int32 n, i;
1206 SARRAY *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 
1266 l_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 {
1275 char *str;
1276 l_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  *----------------------------------------------------------------------*/
1349 SARRAY *
1350 sarrayRead(const char *filename)
1351 {
1352 FILE *fp;
1353 SARRAY *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 
1385 SARRAY *
1387 {
1388 char *stringbuf;
1389 l_int32 i, n, size, index, bufsize, version, ignore, success;
1390 SARRAY *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 
1439 cleanup:
1440  LEPT_FREE(stringbuf);
1441  if (!success) sarrayDestroy(&sa);
1442  return sa;
1443 }
1444 
1445 
1453 SARRAY *
1454 sarrayReadMem(const l_uint8 *data,
1455  size_t size)
1456 {
1457 FILE *fp;
1458 SARRAY *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 
1479 l_ok
1480 sarrayWrite(const char *filename,
1481  SARRAY *sa)
1482 {
1483 l_int32 ret;
1484 FILE *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 
1514 l_ok
1516  SARRAY *sa)
1517 {
1518 l_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 
1544 l_ok
1546 {
1547 l_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 
1577 l_ok
1578 sarrayWriteMem(l_uint8 **pdata,
1579  size_t *psize,
1580  SARRAY *sa)
1581 {
1582 l_int32 ret;
1583 FILE *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 
1626 l_ok
1627 sarrayAppend(const char *filename,
1628  SARRAY *sa)
1629 {
1630 FILE *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  *---------------------------------------------------------------------*/
1692 SARRAY *
1694  const char *substr,
1695  l_int32 numpre,
1696  l_int32 numpost,
1697  l_int32 maxnum)
1698 {
1699 l_int32 nfiles;
1700 SARRAY *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 
1738 SARRAY *
1739 getSortedPathnamesInDirectory(const char *dirname,
1740  const char *substr,
1741  l_int32 first,
1742  l_int32 nfiles)
1743 {
1744 char *fname, *fullname;
1745 l_int32 i, n, last;
1746 SARRAY *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 
1796 SARRAY *
1798  l_int32 numpre,
1799  l_int32 numpost,
1800  l_int32 maxnum)
1801 {
1802 char *fname, *str;
1803 l_int32 i, nfiles, num, index;
1804 SARRAY *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 
1874 #ifndef _WIN32
1875 
1876 SARRAY *
1877 getFilenamesInDirectory(const char *dirname)
1878 {
1879 char dir[PATH_MAX + 1];
1880 char *realdir, *stat_path, *ignore;
1881 size_t size;
1882 SARRAY *safiles;
1883 DIR *pdir;
1884 struct dirent *pdirentry;
1885 int dfd, stat_ret;
1886 struct 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 
1947 SARRAY *
1948 getFilenamesInDirectory(const char *dirname)
1949 {
1950 char *pszDir;
1951 char *realdir;
1952 HANDLE hFind = INVALID_HANDLE_VALUE;
1953 SARRAY *safiles;
1954 WIN32_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 */
#define SARRAY_VERSION_NUMBER
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:357
l_ok numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:720
NUMA * numaGetUniformBinSizes(l_int32 ntotal, l_int32 nbins)
numaGetUniformBinSizes()
Definition: numafunc2.c:1890
@ 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 * sarraySelectBySubstring(SARRAY *sain, const char *substr)
sarraySelectBySubstring()
Definition: sarray1.c:1156
SARRAY * sarrayCreate(l_int32 n)
sarrayCreate()
Definition: sarray1.c:169
SARRAY * sarrayRead(const char *filename)
sarrayRead()
Definition: sarray1.c:1350
char * sarrayGetString(SARRAY *sa, l_int32 index, l_int32 copyflag)
sarrayGetString()
Definition: sarray1.c:673
l_ok sarrayWriteStderr(SARRAY *sa)
sarrayWriteStderr()
Definition: sarray1.c:1545
static const l_int32 InitialPtrArraySize
Definition: sarray1.c:153
l_ok sarrayJoin(SARRAY *sa1, SARRAY *sa2)
sarrayJoin()
Definition: sarray1.c:894
SARRAY * sarraySelectRange(SARRAY *sain, l_int32 first, l_int32 last)
sarraySelectRange()
Definition: sarray1.c:1200
char ** sarrayGetArray(SARRAY *sa, l_int32 *pnalloc, l_int32 *pn)
sarrayGetArray()
Definition: sarray1.c:640
char * sarrayToStringRange(SARRAY *sa, l_int32 first, l_int32 nstrings, l_int32 addnlflag)
sarrayToStringRange()
Definition: sarray1.c:749
l_ok sarrayPadToSameSize(SARRAY *sa1, SARRAY *sa2, const char *padstring)
sarrayPadToSameSize()
Definition: sarray1.c:985
SARRAY * getFilenamesInDirectory(const char *dirname)
getFilenamesInDirectory()
Definition: sarray1.c:1877
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 * sarrayConvertWordsToLines(SARRAY *sa, l_int32 linesize)
sarrayConvertWordsToLines()
Definition: sarray1.c:1042
SARRAY * sarrayReadStream(FILE *fp)
sarrayReadStream()
Definition: sarray1.c:1386
SARRAY * sarrayClone(SARRAY *sa)
sarrayClone()
Definition: sarray1.c:411
l_int32 sarrayGetCount(SARRAY *sa)
sarrayGetCount()
Definition: sarray1.c:617
void sarrayDestroy(SARRAY **psa)
sarrayDestroy()
Definition: sarray1.c:353
SARRAY * sarrayCreateWordsFromString(const char *string)
sarrayCreateWordsFromString()
Definition: sarray1.c:228
SARRAY * sarrayCreateLinesFromString(const char *string, l_int32 blankflag)
sarrayCreateLinesFromString()
Definition: sarray1.c:276
l_ok sarrayClear(SARRAY *sa)
sarrayClear()
Definition: sarray1.c:592
char * sarrayRemoveString(SARRAY *sa, l_int32 index)
sarrayRemoveString()
Definition: sarray1.c:508
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 * sarrayReadMem(const l_uint8 *data, size_t size)
sarrayReadMem()
Definition: sarray1.c:1454
SARRAY * sarrayCreateInitialized(l_int32 n, const char *initstr)
sarrayCreateInitialized()
Definition: sarray1.c:197
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
char * sarrayToString(SARRAY *sa, l_int32 addnlflag)
sarrayToString()
Definition: sarray1.c:716
SARRAY * getSortedPathnamesInDirectory(const char *dirname, const char *substr, l_int32 first, l_int32 nfiles)
getSortedPathnamesInDirectory()
Definition: sarray1.c:1739
SARRAY * sarrayConcatUniformly(SARRAY *sa, l_int32 n, l_int32 addnlflag)
sarrayConcatUniformly()
Definition: sarray1.c:844
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
SARRAY * convertSortedToNumberedPathnames(SARRAY *sa, l_int32 numpre, l_int32 numpost, l_int32 maxnum)
convertSortedToNumberedPathnames()
Definition: sarray1.c:1797
l_ok sarrayAppendRange(SARRAY *sa1, SARRAY *sa2, l_int32 start, l_int32 end)
sarrayAppendRange()
Definition: sarray1.c:935
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
SARRAY * sarraySort(SARRAY *saout, SARRAY *sain, l_int32 sortorder)
sarraySort()
Definition: sarray2.c:98
l_int32 nalloc
char ** array
l_atomic refcount
l_int32 n
void lept_stderr(const char *fmt,...)
lept_stderr()
Definition: utils1.c:306
char * stringNew(const char *src)
stringNew()
Definition: utils2.c:223
l_uint8 * l_binaryReadStream(FILE *fp, size_t *pnbytes)
l_binaryReadStream()
Definition: utils2.c:1358
char * strtokSafe(char *cstr, const char *seps, char **psaveptr)
strtokSafe()
Definition: utils2.c:631
FILE * fopenReadFromMemory(const l_uint8 *data, size_t size)
fopenReadFromMemory()
Definition: utils2.c:1937
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1905
char * pathJoin(const char *dir, const char *fname)
pathJoin()
Definition: utils2.c:2873
char * genPathname(const char *dir, const char *fname)
genPathname()
Definition: utils2.c:3068
l_ok convertSepCharsInPath(char *path, l_int32 type)
convertSepCharsInPath()
Definition: utils2.c:3004
char * stringJoin(const char *src1, const char *src2)
stringJoin()
Definition: utils2.c:506
void * reallocNew(void **pindata, size_t oldsize, size_t newsize)
reallocNew()
Definition: utils2.c:1262
FILE * fopenWriteWinTempfile(void)
fopenWriteWinTempfile()
Definition: utils2.c:1981
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1864
l_int32 extractNumberFromFilename(const char *fname, l_int32 numpre, l_int32 numpost)
extractNumberFromFilename()
Definition: utils2.c:3340
l_ok arrayFindSequence(const l_uint8 *data, size_t datalen, const l_uint8 *sequence, size_t seqlen, l_int32 *poffset, l_int32 *pfound)
arrayFindSequence()
Definition: utils2.c:1195