Leptonica  1.82.0
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 
140 #ifdef HAVE_CONFIG_H
141 #include <config_auto.h>
142 #endif /* HAVE_CONFIG_H */
143 
144 #include <string.h>
145 #ifndef _WIN32
146 #include <dirent.h> /* unix only */
147 #include <sys/stat.h>
148 #include <limits.h> /* needed for realpath() */
149 #include <stdlib.h> /* needed for realpath() */
150 #endif /* ! _WIN32 */
151 #include "allheaders.h"
152 
153 static const l_uint32 MaxPtrArraySize = 50000000; /* 50 million */
154 static const l_int32 InitialPtrArraySize = 50;
156  /* Static functions */
157 static l_int32 sarrayExtendArray(SARRAY *sa);
158 
159 
160 /*--------------------------------------------------------------------------*
161  * String array create/destroy/copy/extend *
162  *--------------------------------------------------------------------------*/
169 SARRAY *
170 sarrayCreate(l_int32 n)
171 {
172 SARRAY *sa;
173 
174  PROCNAME("sarrayCreate");
175 
176  if (n <= 0 || n > MaxPtrArraySize)
178 
179  sa = (SARRAY *)LEPT_CALLOC(1, sizeof(SARRAY));
180  if ((sa->array = (char **)LEPT_CALLOC(n, sizeof(char *))) == NULL) {
181  sarrayDestroy(&sa);
182  return (SARRAY *)ERROR_PTR("ptr array not made", procName, NULL);
183  }
184 
185  sa->nalloc = n;
186  sa->n = 0;
187  sa->refcount = 1;
188  return sa;
189 }
190 
191 
199 SARRAY *
201  const char *initstr)
202 {
203 l_int32 i;
204 SARRAY *sa;
205 
206  PROCNAME("sarrayCreateInitialized");
207 
208  if (n <= 0)
209  return (SARRAY *)ERROR_PTR("n must be > 0", procName, NULL);
210  if (!initstr)
211  return (SARRAY *)ERROR_PTR("initstr not defined", procName, NULL);
212 
213  sa = sarrayCreate(n);
214  for (i = 0; i < n; i++)
215  sarrayAddString(sa, initstr, L_COPY);
216  return sa;
217 }
218 
219 
232 SARRAY *
233 sarrayCreateWordsFromString(const char *string)
234 {
235 char separators[] = " \n\t";
236 l_int32 i, nsub, size, inword;
237 SARRAY *sa;
238 
239  PROCNAME("sarrayCreateWordsFromString");
240 
241  if (!string)
242  return (SARRAY *)ERROR_PTR("textstr not defined", procName, NULL);
243 
244  /* Find the number of words */
245  size = strlen(string);
246  nsub = 0;
247  inword = FALSE;
248  for (i = 0; i < size; i++) {
249  if (inword == FALSE &&
250  (string[i] != ' ' && string[i] != '\t' && string[i] != '\n')) {
251  inword = TRUE;
252  nsub++;
253  } else if (inword == TRUE &&
254  (string[i] == ' ' || string[i] == '\t' || string[i] == '\n')) {
255  inword = FALSE;
256  }
257  }
258 
259  if ((sa = sarrayCreate(nsub)) == NULL)
260  return (SARRAY *)ERROR_PTR("sa not made", procName, NULL);
261  sarraySplitString(sa, string, separators);
262 
263  return sa;
264 }
265 
266 
282 SARRAY *
283 sarrayCreateLinesFromString(const char *string,
284  l_int32 blankflag)
285 {
286 l_int32 i, nsub, size, startptr;
287 char *cstring, *substring;
288 SARRAY *sa;
289 
290  PROCNAME("sarrayCreateLinesFromString");
291 
292  if (!string)
293  return (SARRAY *)ERROR_PTR("textstr not defined", procName, NULL);
294 
295  /* Find the number of lines */
296  size = strlen(string);
297  nsub = 0;
298  for (i = 0; i < size; i++) {
299  if (string[i] == '\n')
300  nsub++;
301  }
302 
303  if ((sa = sarrayCreate(nsub)) == NULL)
304  return (SARRAY *)ERROR_PTR("sa not made", procName, NULL);
305 
306  if (blankflag) { /* keep blank lines as null strings */
307  /* Make a copy for munging */
308  if ((cstring = stringNew(string)) == NULL) {
309  sarrayDestroy(&sa);
310  return (SARRAY *)ERROR_PTR("cstring not made", procName, NULL);
311  }
312  /* We'll insert nulls like strtok */
313  startptr = 0;
314  for (i = 0; i < size; i++) {
315  if (cstring[i] == '\n') {
316  cstring[i] = '\0';
317  if (i > 0 && cstring[i - 1] == '\r')
318  cstring[i - 1] = '\0'; /* also remove Windows CR */
319  if ((substring = stringNew(cstring + startptr)) == NULL) {
320  sarrayDestroy(&sa);
321  LEPT_FREE(cstring);
322  return (SARRAY *)ERROR_PTR("substring not made",
323  procName, NULL);
324  }
325  sarrayAddString(sa, substring, L_INSERT);
326 /* lept_stderr("substring = %s\n", substring); */
327  startptr = i + 1;
328  }
329  }
330  if (startptr < size) { /* no newline at end of last line */
331  if ((substring = stringNew(cstring + startptr)) == NULL) {
332  sarrayDestroy(&sa);
333  LEPT_FREE(cstring);
334  return (SARRAY *)ERROR_PTR("substring not made",
335  procName, NULL);
336  }
337  sarrayAddString(sa, substring, L_INSERT);
338 /* lept_stderr("substring = %s\n", substring); */
339  }
340  LEPT_FREE(cstring);
341  } else { /* remove blank lines; use strtok */
342  sarraySplitString(sa, string, "\r\n");
343  }
344 
345  return sa;
346 }
347 
348 
361 void
363 {
364 l_int32 i;
365 SARRAY *sa;
366 
367  PROCNAME("sarrayDestroy");
368 
369  if (psa == NULL) {
370  L_WARNING("ptr address is NULL!\n", procName);
371  return;
372  }
373  if ((sa = *psa) == NULL)
374  return;
375 
376  sarrayChangeRefcount(sa, -1);
377  if (sarrayGetRefcount(sa) <= 0) {
378  if (sa->array) {
379  for (i = 0; i < sa->n; i++) {
380  if (sa->array[i])
381  LEPT_FREE(sa->array[i]);
382  }
383  LEPT_FREE(sa->array);
384  }
385  LEPT_FREE(sa);
386  }
387  *psa = NULL;
388 }
389 
390 
397 SARRAY *
399 {
400 l_int32 i;
401 SARRAY *csa;
402 
403  PROCNAME("sarrayCopy");
404 
405  if (!sa)
406  return (SARRAY *)ERROR_PTR("sa not defined", procName, NULL);
407 
408  if ((csa = sarrayCreate(sa->nalloc)) == NULL)
409  return (SARRAY *)ERROR_PTR("csa not made", procName, NULL);
410 
411  for (i = 0; i < sa->n; i++)
412  sarrayAddString(csa, sa->array[i], L_COPY);
413 
414  return csa;
415 }
416 
417 
424 SARRAY *
426 {
427  PROCNAME("sarrayClone");
428 
429  if (!sa)
430  return (SARRAY *)ERROR_PTR("sa not defined", procName, NULL);
431  sarrayChangeRefcount(sa, 1);
432  return sa;
433 }
434 
435 
450 l_ok
452  const char *string,
453  l_int32 copyflag)
454 {
455 l_int32 n;
456 
457  PROCNAME("sarrayAddString");
458 
459  if (!sa)
460  return ERROR_INT("sa not defined", procName, 1);
461  if (!string)
462  return ERROR_INT("string not defined", procName, 1);
463  if (copyflag != L_INSERT && copyflag != L_NOCOPY && copyflag != L_COPY)
464  return ERROR_INT("invalid copyflag", procName, 1);
465 
466  n = sarrayGetCount(sa);
467  if (n >= sa->nalloc) {
468  if (sarrayExtendArray(sa))
469  return ERROR_INT("extension failed", procName, 1);
470  }
471 
472  if (copyflag == L_COPY)
473  sa->array[n] = stringNew(string);
474  else /* L_INSERT or L_NOCOPY */
475  sa->array[n] = (char *)string;
476  sa->n++;
477  return 0;
478 }
479 
480 
493 static l_int32
495 {
496 size_t oldsize, newsize;
497 
498  PROCNAME("sarrayExtendArray");
499 
500  if (!sa)
501  return ERROR_INT("sa not defined", procName, 1);
502  if (sa->nalloc >= MaxPtrArraySize)
503  return ERROR_INT("sa at maximum ptr size; can't extend", procName, 1);
504  oldsize = sa->nalloc * sizeof(char *);
505  if (sa->nalloc > MaxPtrArraySize / 2) {
506  newsize = MaxPtrArraySize * sizeof(char *);
507  sa->nalloc = MaxPtrArraySize;
508  } else {
509  newsize = 2 * oldsize;
510  sa->nalloc *= 2;
511  }
512  if ((sa->array = (char **)reallocNew((void **)&sa->array,
513  oldsize, newsize)) == NULL)
514  return ERROR_INT("new ptr array not returned", procName, 1);
515 
516  return 0;
517 }
518 
519 
527 char *
529  l_int32 index)
530 {
531 char *string;
532 char **array;
533 l_int32 i, n, nalloc;
534 
535  PROCNAME("sarrayRemoveString");
536 
537  if (!sa)
538  return (char *)ERROR_PTR("sa not defined", procName, NULL);
539 
540  if ((array = sarrayGetArray(sa, &nalloc, &n)) == NULL)
541  return (char *)ERROR_PTR("array not returned", procName, NULL);
542 
543  if (index < 0 || index >= n)
544  return (char *)ERROR_PTR("array index out of bounds", procName, NULL);
545 
546  string = array[index];
547 
548  /* If removed string is not at end of array, shift
549  * to fill in, maintaining original ordering.
550  * Note: if we didn't care about the order, we could
551  * put the last string array[n - 1] directly into the hole. */
552  for (i = index; i < n - 1; i++)
553  array[i] = array[i + 1];
554 
555  sa->n--;
556  return string;
557 }
558 
559 
578 l_ok
580  l_int32 index,
581  char *newstr,
582  l_int32 copyflag)
583 {
584 char *str;
585 l_int32 n;
586 
587  PROCNAME("sarrayReplaceString");
588 
589  if (!sa)
590  return ERROR_INT("sa not defined", procName, 1);
591  n = sarrayGetCount(sa);
592  if (index < 0 || index >= n)
593  return ERROR_INT("array index out of bounds", procName, 1);
594  if (!newstr)
595  return ERROR_INT("newstr not defined", procName, 1);
596  if (copyflag != L_INSERT && copyflag != L_COPY)
597  return ERROR_INT("invalid copyflag", procName, 1);
598 
599  LEPT_FREE(sa->array[index]);
600  if (copyflag == L_INSERT)
601  str = newstr;
602  else /* L_COPY */
603  str = stringNew(newstr);
604  sa->array[index] = str;
605  return 0;
606 }
607 
608 
615 l_ok
617 {
618 l_int32 i;
619 
620  PROCNAME("sarrayClear");
621 
622  if (!sa)
623  return ERROR_INT("sa not defined", procName, 1);
624  for (i = 0; i < sa->n; i++) { /* free strings and null ptrs */
625  LEPT_FREE(sa->array[i]);
626  sa->array[i] = NULL;
627  }
628  sa->n = 0;
629  return 0;
630 }
631 
632 
633 /*----------------------------------------------------------------------*
634  * Accessors *
635  *----------------------------------------------------------------------*/
642 l_int32
644 {
645  PROCNAME("sarrayGetCount");
646 
647  if (!sa)
648  return ERROR_INT("sa not defined", procName, 0);
649  return sa->n;
650 }
651 
652 
667 char **
669  l_int32 *pnalloc,
670  l_int32 *pn)
671 {
672 char **array;
673 
674  PROCNAME("sarrayGetArray");
675 
676  if (!sa)
677  return (char **)ERROR_PTR("sa not defined", procName, NULL);
678 
679  array = sa->array;
680  if (pnalloc) *pnalloc = sa->nalloc;
681  if (pn) *pn = sa->n;
682 
683  return array;
684 }
685 
686 
702 char *
704  l_int32 index,
705  l_int32 copyflag)
706 {
707  PROCNAME("sarrayGetString");
708 
709  if (!sa)
710  return (char *)ERROR_PTR("sa not defined", procName, NULL);
711  if (index < 0 || index >= sa->n)
712  return (char *)ERROR_PTR("index not valid", procName, NULL);
713  if (copyflag != L_NOCOPY && copyflag != L_COPY)
714  return (char *)ERROR_PTR("invalid copyflag", procName, NULL);
715 
716  if (copyflag == L_NOCOPY)
717  return sa->array[index];
718  else /* L_COPY */
719  return stringNew(sa->array[index]);
720 }
721 
722 
729 l_int32
731 {
732  PROCNAME("sarrayGetRefcount");
733 
734  if (!sa)
735  return ERROR_INT("sa not defined", procName, UNDEF);
736  return sa->refcount;
737 }
738 
739 
747 l_ok
749  l_int32 delta)
750 {
751  PROCNAME("sarrayChangeRefcount");
752 
753  if (!sa)
754  return ERROR_INT("sa not defined", procName, UNDEF);
755  sa->refcount += delta;
756  return 0;
757 }
758 
759 
760 /*----------------------------------------------------------------------*
761  * Conversion to string *
762  *----------------------------------------------------------------------*/
784 char *
786  l_int32 addnlflag)
787 {
788  PROCNAME("sarrayToString");
789 
790  if (!sa)
791  return (char *)ERROR_PTR("sa not defined", procName, NULL);
792 
793  return sarrayToStringRange(sa, 0, 0, addnlflag);
794 }
795 
796 
819 char *
821  l_int32 first,
822  l_int32 nstrings,
823  l_int32 addnlflag)
824 {
825 char *dest, *src, *str;
826 l_int32 n, i, last, size, index, len;
827 
828  PROCNAME("sarrayToStringRange");
829 
830  if (!sa)
831  return (char *)ERROR_PTR("sa not defined", procName, NULL);
832  if (addnlflag != 0 && addnlflag != 1 && addnlflag != 2 && addnlflag != 3)
833  return (char *)ERROR_PTR("invalid addnlflag", procName, NULL);
834 
835  n = sarrayGetCount(sa);
836 
837  /* Empty sa; return char corresponding to addnlflag only */
838  if (n == 0) {
839  if (first == 0) {
840  if (addnlflag == 0)
841  return stringNew("");
842  if (addnlflag == 1)
843  return stringNew("\n");
844  if (addnlflag == 2)
845  return stringNew(" ");
846  else /* addnlflag == 3) */
847  return stringNew(",");
848  } else {
849  return (char *)ERROR_PTR("first not valid", procName, NULL);
850  }
851  }
852 
853  /* Determine the range of string indices to be used */
854  if (first < 0 || first >= n)
855  return (char *)ERROR_PTR("first not valid", procName, NULL);
856  if (nstrings == 0 || (nstrings > n - first))
857  nstrings = n - first; /* no overflow */
858  last = first + nstrings - 1;
859 
860  /* Determine the size of the output string */
861  size = 0;
862  for (i = first; i <= last; i++) {
863  if ((str = sarrayGetString(sa, i, L_NOCOPY)) == NULL)
864  return (char *)ERROR_PTR("str not found", procName, NULL);
865  size += strlen(str) + 2;
866  }
867  if ((dest = (char *)LEPT_CALLOC(size + 1, sizeof(char))) == NULL)
868  return (char *)ERROR_PTR("dest not made", procName, NULL);
869 
870  /* Construct the output */
871  index = 0;
872  for (i = first; i <= last; i++) {
873  src = sarrayGetString(sa, i, L_NOCOPY);
874  len = strlen(src);
875  memcpy(dest + index, src, len);
876  index += len;
877  if (addnlflag == 1) {
878  dest[index] = '\n';
879  index++;
880  } else if (addnlflag == 2) {
881  dest[index] = ' ';
882  index++;
883  } else if (addnlflag == 3) {
884  dest[index] = ',';
885  index++;
886  }
887  }
888 
889  return dest;
890 }
891 
892 
893 /*----------------------------------------------------------------------*
894  * Concatenate strings uniformly within the sarray *
895  *----------------------------------------------------------------------*/
916 SARRAY *
918  l_int32 n,
919  l_int32 addnlflag)
920 {
921 l_int32 i, first, ntot, nstr;
922 char *str;
923 NUMA *na;
924 SARRAY *saout;
925 
926  PROCNAME("sarrayConcatUniformly");
927 
928  if (!sa)
929  return (SARRAY *)ERROR_PTR("sa not defined", procName, NULL);
930  ntot = sarrayGetCount(sa);
931  if (n < 1)
932  return (SARRAY *)ERROR_PTR("n must be >= 1", procName, NULL);
933  if (n > ntot) {
934  L_ERROR("n = %d > ntot = %d\n", procName, n, ntot);
935  return NULL;
936  }
937  if (addnlflag != 0 && addnlflag != 1 && addnlflag != 2 && addnlflag != 3)
938  return (SARRAY *)ERROR_PTR("invalid addnlflag", procName, NULL);
939 
940  saout = sarrayCreate(0);
941  na = numaGetUniformBinSizes(ntot, n);
942  for (i = 0, first = 0; i < n; i++) {
943  numaGetIValue(na, i, &nstr);
944  str = sarrayToStringRange(sa, first, nstr, addnlflag);
945  sarrayAddString(saout, str, L_INSERT);
946  first += nstr;
947  }
948  numaDestroy(&na);
949  return saout;
950 }
951 
952 
953 /*----------------------------------------------------------------------*
954  * Join 2 sarrays *
955  *----------------------------------------------------------------------*/
968 l_ok
970  SARRAY *sa2)
971 {
972 char *str;
973 l_int32 n, i;
974 
975  PROCNAME("sarrayJoin");
976 
977  if (!sa1)
978  return ERROR_INT("sa1 not defined", procName, 1);
979  if (!sa2)
980  return ERROR_INT("sa2 not defined", procName, 1);
981 
982  n = sarrayGetCount(sa2);
983  for (i = 0; i < n; i++) {
984  str = sarrayGetString(sa2, i, L_NOCOPY);
985  if (sarrayAddString(sa1, str, L_COPY) == 1) {
986  L_ERROR("failed to add string at i = %d\n", procName, i);
987  return 1;
988  }
989  }
990  return 0;
991 }
992 
993 
1011 l_ok
1013  SARRAY *sa2,
1014  l_int32 start,
1015  l_int32 end)
1016 {
1017 char *str;
1018 l_int32 n, i;
1019 
1020  PROCNAME("sarrayAppendRange");
1021 
1022  if (!sa1)
1023  return ERROR_INT("sa1 not defined", procName, 1);
1024  if (!sa2)
1025  return ERROR_INT("sa2 not defined", procName, 1);
1026 
1027  if (start < 0)
1028  start = 0;
1029  n = sarrayGetCount(sa2);
1030  if (end < 0 || end >= n)
1031  end = n - 1;
1032  if (start > end)
1033  return ERROR_INT("start > end", procName, 1);
1034 
1035  for (i = start; i <= end; i++) {
1036  str = sarrayGetString(sa2, i, L_NOCOPY);
1037  sarrayAddString(sa1, str, L_COPY);
1038  }
1039 
1040  return 0;
1041 }
1042 
1043 
1044 /*----------------------------------------------------------------------*
1045  * Pad an sarray to be the same size as another sarray *
1046  *----------------------------------------------------------------------*/
1063 l_ok
1065  SARRAY *sa2,
1066  const char *padstring)
1067 {
1068 l_int32 i, n1, n2;
1069 
1070  PROCNAME("sarrayPadToSameSize");
1071 
1072  if (!sa1 || !sa2)
1073  return ERROR_INT("both sa1 and sa2 not defined", procName, 1);
1074 
1075  n1 = sarrayGetCount(sa1);
1076  n2 = sarrayGetCount(sa2);
1077  if (n1 < n2) {
1078  for (i = n1; i < n2; i++)
1079  sarrayAddString(sa1, padstring, L_COPY);
1080  } else if (n1 > n2) {
1081  for (i = n2; i < n1; i++)
1082  sarrayAddString(sa2, padstring, L_COPY);
1083  }
1084 
1085  return 0;
1086 }
1087 
1088 
1089 /*----------------------------------------------------------------------*
1090  * Convert word sarray to line sarray *
1091  *----------------------------------------------------------------------*/
1122 SARRAY *
1124  l_int32 linesize)
1125 {
1126 char *wd, *strl;
1127 char emptystring[] = "";
1128 l_int32 n, i, len, totlen;
1129 SARRAY *sal, *saout;
1130 
1131  PROCNAME("sarrayConvertWordsToLines");
1132 
1133  if (!sa)
1134  return (SARRAY *)ERROR_PTR("sa not defined", procName, NULL);
1135 
1136  saout = sarrayCreate(0);
1137  n = sarrayGetCount(sa);
1138  totlen = 0;
1139  sal = NULL;
1140  for (i = 0; i < n; i++) {
1141  if (!sal)
1142  sal = sarrayCreate(0);
1143  wd = sarrayGetString(sa, i, L_NOCOPY);
1144  len = strlen(wd);
1145  if (len == 0) { /* end of paragraph: end line & insert blank line */
1146  if (totlen > 0) {
1147  strl = sarrayToString(sal, 2);
1148  sarrayAddString(saout, strl, L_INSERT);
1149  }
1150  sarrayAddString(saout, emptystring, L_COPY);
1151  sarrayDestroy(&sal);
1152  totlen = 0;
1153  } else if (totlen == 0 && len + 1 > linesize) { /* long word! */
1154  sarrayAddString(saout, wd, L_COPY); /* copy to one line */
1155  } else if (totlen + len + 1 > linesize) { /* end line & start new */
1156  strl = sarrayToString(sal, 2);
1157  sarrayAddString(saout, strl, L_INSERT);
1158  sarrayDestroy(&sal);
1159  sal = sarrayCreate(0);
1160  sarrayAddString(sal, wd, L_COPY);
1161  totlen = len + 1;
1162  } else { /* add to current line */
1163  sarrayAddString(sal, wd, L_COPY);
1164  totlen += len + 1;
1165  }
1166  }
1167  if (totlen > 0) { /* didn't end with blank line; output last line */
1168  strl = sarrayToString(sal, 2);
1169  sarrayAddString(saout, strl, L_INSERT);
1170  sarrayDestroy(&sal);
1171  }
1172 
1173  return saout;
1174 }
1175 
1176 
1177 /*----------------------------------------------------------------------*
1178  * Split string on separator list *
1179  *----------------------------------------------------------------------*/
1180 /*
1181  * \brief sarraySplitString()
1182  *
1183  * \param[in] sa to append to; typically empty initially
1184  * \param[in] str string to split; not changed
1185  * \param[in] separators characters that split input string
1186  * \return 0 if OK, 1 on error.
1187  *
1188  * <pre>
1189  * Notes:
1190  * (1) This uses strtokSafe(). See the notes there in utils.c.
1191  * </pre>
1192  */
1193 l_int32
1194 sarraySplitString(SARRAY *sa,
1195  const char *str,
1196  const char *separators)
1197 {
1198 char *cstr, *substr, *saveptr;
1199 
1200  PROCNAME("sarraySplitString");
1201 
1202  if (!sa)
1203  return ERROR_INT("sa not defined", procName, 1);
1204  if (!str)
1205  return ERROR_INT("str not defined", procName, 1);
1206  if (!separators)
1207  return ERROR_INT("separators not defined", procName, 1);
1208 
1209  cstr = stringNew(str); /* preserves const-ness of input str */
1210  saveptr = NULL;
1211  substr = strtokSafe(cstr, separators, &saveptr);
1212  if (substr)
1213  sarrayAddString(sa, substr, L_INSERT);
1214  while ((substr = strtokSafe(NULL, separators, &saveptr)))
1215  sarrayAddString(sa, substr, L_INSERT);
1216  LEPT_FREE(cstr);
1217 
1218  return 0;
1219 }
1220 
1221 
1222 /*----------------------------------------------------------------------*
1223  * Filter sarray *
1224  *----------------------------------------------------------------------*/
1240 SARRAY *
1242  const char *substr)
1243 {
1244 char *str;
1245 l_int32 n, i, offset, found;
1246 SARRAY *saout;
1247 
1248  PROCNAME("sarraySelectBySubstring");
1249 
1250  if (!sain)
1251  return (SARRAY *)ERROR_PTR("sain not defined", procName, NULL);
1252 
1253  n = sarrayGetCount(sain);
1254  if (!substr || n == 0)
1255  return sarrayCopy(sain);
1256 
1257  saout = sarrayCreate(n);
1258  for (i = 0; i < n; i++) {
1259  str = sarrayGetString(sain, i, L_NOCOPY);
1260  arrayFindSequence((l_uint8 *)str, strlen(str), (l_uint8 *)substr,
1261  strlen(substr), &offset, &found);
1262  if (found)
1263  sarrayAddString(saout, str, L_COPY);
1264  }
1265 
1266  return saout;
1267 }
1268 
1269 
1286 SARRAY *
1288  l_int32 first,
1289  l_int32 last)
1290 {
1291 char *str;
1292 l_int32 n, i;
1293 SARRAY *saout;
1294 
1295  PROCNAME("sarraySelectRange");
1296 
1297  if (!sain)
1298  return (SARRAY *)ERROR_PTR("sain not defined", procName, NULL);
1299  if (first < 0) first = 0;
1300  n = sarrayGetCount(sain);
1301  if (last <= 0) last = n - 1;
1302  if (last >= n) {
1303  L_WARNING("last > n - 1; setting to n - 1\n", procName);
1304  last = n - 1;
1305  }
1306  if (first > last)
1307  return (SARRAY *)ERROR_PTR("first must be >= last", procName, NULL);
1308 
1309  saout = sarrayCreate(0);
1310  for (i = first; i <= last; i++) {
1311  str = sarrayGetString(sain, i, L_COPY);
1312  sarrayAddString(saout, str, L_INSERT);
1313  }
1314 
1315  return saout;
1316 }
1317 
1318 
1355 l_int32
1357  l_int32 start,
1358  l_int32 *pactualstart,
1359  l_int32 *pend,
1360  l_int32 *pnewstart,
1361  const char *substr,
1362  l_int32 loc)
1363 {
1364 char *str;
1365 l_int32 n, i, offset, found;
1366 
1367  PROCNAME("sarrayParseRange");
1368 
1369  if (!sa)
1370  return ERROR_INT("sa not defined", procName, 1);
1371  if (!pactualstart || !pend || !pnewstart)
1372  return ERROR_INT("not all range addresses defined", procName, 1);
1373  n = sarrayGetCount(sa);
1374  *pactualstart = *pend = *pnewstart = n;
1375  if (!substr)
1376  return ERROR_INT("substr not defined", procName, 1);
1377 
1378  /* Look for the first string without the marker */
1379  if (start < 0 || start >= n)
1380  return 1;
1381  for (i = start; i < n; i++) {
1382  str = sarrayGetString(sa, i, L_NOCOPY);
1383  arrayFindSequence((l_uint8 *)str, strlen(str), (l_uint8 *)substr,
1384  strlen(substr), &offset, &found);
1385  if (loc < 0) {
1386  if (!found) break;
1387  } else {
1388  if (!found || offset != loc) break;
1389  }
1390  }
1391  start = i;
1392  if (i == n) /* couldn't get started */
1393  return 1;
1394 
1395  /* Look for the last string without the marker */
1396  *pactualstart = start;
1397  for (i = start + 1; i < n; i++) {
1398  str = sarrayGetString(sa, i, L_NOCOPY);
1399  arrayFindSequence((l_uint8 *)str, strlen(str), (l_uint8 *)substr,
1400  strlen(substr), &offset, &found);
1401  if (loc < 0) {
1402  if (found) break;
1403  } else {
1404  if (found && offset == loc) break;
1405  }
1406  }
1407  *pend = i - 1;
1408  start = i;
1409  if (i == n) /* no further range */
1410  return 0;
1411 
1412  /* Look for the first string after *pend without the marker.
1413  * This will start the next run of strings, if it exists. */
1414  for (i = start; i < n; i++) {
1415  str = sarrayGetString(sa, i, L_NOCOPY);
1416  arrayFindSequence((l_uint8 *)str, strlen(str), (l_uint8 *)substr,
1417  strlen(substr), &offset, &found);
1418  if (loc < 0) {
1419  if (!found) break;
1420  } else {
1421  if (!found || offset != loc) break;
1422  }
1423  }
1424  if (i < n)
1425  *pnewstart = i;
1426 
1427  return 0;
1428 }
1429 
1430 
1431 /*----------------------------------------------------------------------*
1432  * Serialize for I/O *
1433  *----------------------------------------------------------------------*/
1440 SARRAY *
1441 sarrayRead(const char *filename)
1442 {
1443 FILE *fp;
1444 SARRAY *sa;
1445 
1446  PROCNAME("sarrayRead");
1447 
1448  if (!filename)
1449  return (SARRAY *)ERROR_PTR("filename not defined", procName, NULL);
1450 
1451  if ((fp = fopenReadStream(filename)) == NULL)
1452  return (SARRAY *)ERROR_PTR("stream not opened", procName, NULL);
1453  sa = sarrayReadStream(fp);
1454  fclose(fp);
1455  if (!sa)
1456  return (SARRAY *)ERROR_PTR("sa not read", procName, NULL);
1457  return sa;
1458 }
1459 
1460 
1478 SARRAY *
1480 {
1481 char *stringbuf;
1482 l_int32 i, n, size, index, bufsize, version, ignore, success;
1483 SARRAY *sa;
1484 
1485  PROCNAME("sarrayReadStream");
1486 
1487  if (!fp)
1488  return (SARRAY *)ERROR_PTR("stream not defined", procName, NULL);
1489 
1490  if (fscanf(fp, "\nSarray Version %d\n", &version) != 1)
1491  return (SARRAY *)ERROR_PTR("not an sarray file", procName, NULL);
1492  if (version != SARRAY_VERSION_NUMBER)
1493  return (SARRAY *)ERROR_PTR("invalid sarray version", procName, NULL);
1494  if (fscanf(fp, "Number of strings = %d\n", &n) != 1)
1495  return (SARRAY *)ERROR_PTR("error on # strings", procName, NULL);
1496  if (n < 0)
1497  return (SARRAY *)ERROR_PTR("num string ptrs <= 0", procName, NULL);
1498  if (n > MaxPtrArraySize)
1499  return (SARRAY *)ERROR_PTR("too many string ptrs", procName, NULL);
1500  if (n == 0) L_INFO("the sarray is empty\n", procName);
1501 
1502  success = TRUE;
1503  if ((sa = sarrayCreate(n)) == NULL)
1504  return (SARRAY *)ERROR_PTR("sa not made", procName, NULL);
1505  bufsize = 512 + 1;
1506  stringbuf = (char *)LEPT_CALLOC(bufsize, sizeof(char));
1507 
1508  for (i = 0; i < n; i++) {
1509  /* Get the size of the stored string */
1510  if ((fscanf(fp, "%d[%d]:", &index, &size) != 2) || (size > (1 << 30))) {
1511  success = FALSE;
1512  L_ERROR("error on string size\n", procName);
1513  goto cleanup;
1514  }
1515  /* Expand the string buffer if necessary */
1516  if (size > bufsize - 5) {
1517  LEPT_FREE(stringbuf);
1518  bufsize = (l_int32)(1.5 * size);
1519  stringbuf = (char *)LEPT_CALLOC(bufsize, sizeof(char));
1520  }
1521  /* Read the stored string, plus leading spaces and trailing \n */
1522  if (fread(stringbuf, 1, size + 3, fp) != size + 3) {
1523  success = FALSE;
1524  L_ERROR("error reading string\n", procName);
1525  goto cleanup;
1526  }
1527  /* Remove the \n that was added by sarrayWriteStream() */
1528  stringbuf[size + 2] = '\0';
1529  /* Copy it in, skipping the 2 leading spaces */
1530  sarrayAddString(sa, stringbuf + 2, L_COPY);
1531  }
1532  ignore = fscanf(fp, "\n");
1533 
1534 cleanup:
1535  LEPT_FREE(stringbuf);
1536  if (!success) sarrayDestroy(&sa);
1537  return sa;
1538 }
1539 
1540 
1548 SARRAY *
1549 sarrayReadMem(const l_uint8 *data,
1550  size_t size)
1551 {
1552 FILE *fp;
1553 SARRAY *sa;
1554 
1555  PROCNAME("sarrayReadMem");
1556 
1557  if (!data)
1558  return (SARRAY *)ERROR_PTR("data not defined", procName, NULL);
1559  if ((fp = fopenReadFromMemory(data, size)) == NULL)
1560  return (SARRAY *)ERROR_PTR("stream not opened", procName, NULL);
1561 
1562  sa = sarrayReadStream(fp);
1563  fclose(fp);
1564  if (!sa) L_ERROR("sarray not read\n", procName);
1565  return sa;
1566 }
1567 
1568 
1576 l_ok
1577 sarrayWrite(const char *filename,
1578  SARRAY *sa)
1579 {
1580 l_int32 ret;
1581 FILE *fp;
1582 
1583  PROCNAME("sarrayWrite");
1584 
1585  if (!filename)
1586  return ERROR_INT("filename not defined", procName, 1);
1587  if (!sa)
1588  return ERROR_INT("sa not defined", procName, 1);
1589 
1590  if ((fp = fopenWriteStream(filename, "w")) == NULL)
1591  return ERROR_INT("stream not opened", procName, 1);
1592  ret = sarrayWriteStream(fp, sa);
1593  fclose(fp);
1594  if (ret)
1595  return ERROR_INT("sa not written to stream", procName, 1);
1596  return 0;
1597 }
1598 
1599 
1613 l_ok
1615  SARRAY *sa)
1616 {
1617 l_int32 i, n, len;
1618 
1619  PROCNAME("sarrayWriteStream");
1620 
1621  if (!fp)
1622  return ERROR_INT("stream not defined", procName, 1);
1623  if (!sa)
1624  return sarrayWriteStderr(sa);
1625 
1626  n = sarrayGetCount(sa);
1627  fprintf(fp, "\nSarray Version %d\n", SARRAY_VERSION_NUMBER);
1628  fprintf(fp, "Number of strings = %d\n", n);
1629  for (i = 0; i < n; i++) {
1630  len = strlen(sa->array[i]);
1631  fprintf(fp, " %d[%d]: %s\n", i, len, sa->array[i]);
1632  }
1633  fprintf(fp, "\n");
1634 
1635  return 0;
1636 }
1637 
1638 
1645 l_ok
1647 {
1648 l_int32 i, n, len;
1649 
1650  PROCNAME("sarrayWriteStderr");
1651 
1652  if (!sa)
1653  return ERROR_INT("sa not defined", procName, 1);
1654 
1655  n = sarrayGetCount(sa);
1656  lept_stderr("\nSarray Version %d\n", SARRAY_VERSION_NUMBER);
1657  lept_stderr("Number of strings = %d\n", n);
1658  for (i = 0; i < n; i++) {
1659  len = strlen(sa->array[i]);
1660  lept_stderr(" %d[%d]: %s\n", i, len, sa->array[i]);
1661  }
1662  lept_stderr("\n");
1663  return 0;
1664 }
1665 
1666 
1680 l_ok
1681 sarrayWriteMem(l_uint8 **pdata,
1682  size_t *psize,
1683  SARRAY *sa)
1684 {
1685 l_int32 ret;
1686 FILE *fp;
1687 
1688  PROCNAME("sarrayWriteMem");
1689 
1690  if (pdata) *pdata = NULL;
1691  if (psize) *psize = 0;
1692  if (!pdata)
1693  return ERROR_INT("&data not defined", procName, 1);
1694  if (!psize)
1695  return ERROR_INT("&size not defined", procName, 1);
1696  if (!sa)
1697  return ERROR_INT("sa not defined", procName, 1);
1698 
1699 #if HAVE_FMEMOPEN
1700  if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1701  return ERROR_INT("stream not opened", procName, 1);
1702  ret = sarrayWriteStream(fp, sa);
1703  fputc('\0', fp);
1704  fclose(fp);
1705  *psize = *psize - 1;
1706 #else
1707  L_INFO("work-around: writing to a temp file\n", procName);
1708  #ifdef _WIN32
1709  if ((fp = fopenWriteWinTempfile()) == NULL)
1710  return ERROR_INT("tmpfile stream not opened", procName, 1);
1711  #else
1712  if ((fp = tmpfile()) == NULL)
1713  return ERROR_INT("tmpfile stream not opened", procName, 1);
1714  #endif /* _WIN32 */
1715  ret = sarrayWriteStream(fp, sa);
1716  rewind(fp);
1717  *pdata = l_binaryReadStream(fp, psize);
1718  fclose(fp);
1719 #endif /* HAVE_FMEMOPEN */
1720  return ret;
1721 }
1722 
1723 
1731 l_ok
1732 sarrayAppend(const char *filename,
1733  SARRAY *sa)
1734 {
1735 FILE *fp;
1736 
1737  PROCNAME("sarrayAppend");
1738 
1739  if (!filename)
1740  return ERROR_INT("filename not defined", procName, 1);
1741  if (!sa)
1742  return ERROR_INT("sa not defined", procName, 1);
1743 
1744  if ((fp = fopenWriteStream(filename, "a")) == NULL)
1745  return ERROR_INT("stream not opened", procName, 1);
1746  if (sarrayWriteStream(fp, sa)) {
1747  fclose(fp);
1748  return ERROR_INT("sa not appended to stream", procName, 1);
1749  }
1750 
1751  fclose(fp);
1752  return 0;
1753 }
1754 
1755 
1756 /*---------------------------------------------------------------------*
1757  * Directory filenames *
1758  *---------------------------------------------------------------------*/
1799 SARRAY *
1801  const char *substr,
1802  l_int32 numpre,
1803  l_int32 numpost,
1804  l_int32 maxnum)
1805 {
1806 l_int32 nfiles;
1807 SARRAY *sa, *saout;
1808 
1809  PROCNAME("getNumberedPathnamesInDirectory");
1810 
1811  if (!dirname)
1812  return (SARRAY *)ERROR_PTR("dirname not defined", procName, NULL);
1813 
1814  if ((sa = getSortedPathnamesInDirectory(dirname, substr, 0, 0)) == NULL)
1815  return (SARRAY *)ERROR_PTR("sa not made", procName, NULL);
1816  if ((nfiles = sarrayGetCount(sa)) == 0) {
1817  sarrayDestroy(&sa);
1818  return sarrayCreate(1);
1819  }
1820 
1821  saout = convertSortedToNumberedPathnames(sa, numpre, numpost, maxnum);
1822  sarrayDestroy(&sa);
1823  return saout;
1824 }
1825 
1826 
1847 SARRAY *
1848 getSortedPathnamesInDirectory(const char *dirname,
1849  const char *substr,
1850  l_int32 first,
1851  l_int32 nfiles)
1852 {
1853 char *fname, *fullname;
1854 l_int32 i, n, last;
1855 SARRAY *sa, *safiles, *saout;
1856 
1857  PROCNAME("getSortedPathnamesInDirectory");
1858 
1859  if (!dirname)
1860  return (SARRAY *)ERROR_PTR("dirname not defined", procName, NULL);
1861 
1862  if ((sa = getFilenamesInDirectory(dirname)) == NULL)
1863  return (SARRAY *)ERROR_PTR("sa not made", procName, NULL);
1864  safiles = sarraySelectBySubstring(sa, substr);
1865  sarrayDestroy(&sa);
1866  n = sarrayGetCount(safiles);
1867  if (n == 0) {
1868  L_WARNING("no files found\n", procName);
1869  return safiles;
1870  }
1871 
1872  sarraySort(safiles, safiles, L_SORT_INCREASING);
1873 
1874  first = L_MIN(L_MAX(first, 0), n - 1);
1875  if (nfiles == 0)
1876  nfiles = n - first;
1877  last = L_MIN(first + nfiles - 1, n - 1);
1878 
1879  saout = sarrayCreate(last - first + 1);
1880  for (i = first; i <= last; i++) {
1881  fname = sarrayGetString(safiles, i, L_NOCOPY);
1882  fullname = pathJoin(dirname, fname);
1883  sarrayAddString(saout, fullname, L_INSERT);
1884  }
1885 
1886  sarrayDestroy(&safiles);
1887  return saout;
1888 }
1889 
1890 
1907 SARRAY *
1909  l_int32 numpre,
1910  l_int32 numpost,
1911  l_int32 maxnum)
1912 {
1913 char *fname, *str;
1914 l_int32 i, nfiles, num, index;
1915 SARRAY *saout;
1916 
1917  PROCNAME("convertSortedToNumberedPathnames");
1918 
1919  if (!sa)
1920  return (SARRAY *)ERROR_PTR("sa not defined", procName, NULL);
1921  if ((nfiles = sarrayGetCount(sa)) == 0)
1922  return sarrayCreate(1);
1923 
1924  /* Find the last file in the sorted array that has a number
1925  * that (a) matches the count pattern and (b) does not
1926  * exceed %maxnum. %maxnum sets an upper limit on the size
1927  * of the sarray. */
1928  num = 0;
1929  for (i = nfiles - 1; i >= 0; i--) {
1930  fname = sarrayGetString(sa, i, L_NOCOPY);
1931  num = extractNumberFromFilename(fname, numpre, numpost);
1932  if (num < 0) continue;
1933  num = L_MIN(num + 1, maxnum);
1934  break;
1935  }
1936 
1937  if (num <= 0) /* none found */
1938  return sarrayCreate(1);
1939 
1940  /* Insert pathnames into the output sarray.
1941  * Ignore numbers that are out of the range of sarray. */
1942  saout = sarrayCreateInitialized(num, "");
1943  for (i = 0; i < nfiles; i++) {
1944  fname = sarrayGetString(sa, i, L_NOCOPY);
1945  index = extractNumberFromFilename(fname, numpre, numpost);
1946  if (index < 0 || index >= num) continue;
1947  str = sarrayGetString(saout, index, L_NOCOPY);
1948  if (str[0] != '\0') {
1949  L_WARNING("\n Multiple files with same number: %d\n",
1950  procName, index);
1951  }
1952  sarrayReplaceString(saout, index, fname, L_COPY);
1953  }
1954 
1955  return saout;
1956 }
1957 
1958 
1987 #ifndef _WIN32
1988 
1989 SARRAY *
1990 getFilenamesInDirectory(const char *dirname)
1991 {
1992 char dir[PATH_MAX + 1];
1993 char *realdir, *stat_path, *ignore;
1994 size_t size;
1995 SARRAY *safiles;
1996 DIR *pdir;
1997 struct dirent *pdirentry;
1998 int dfd, stat_ret;
1999 struct stat st;
2000 
2001  PROCNAME("getFilenamesInDirectory");
2002 
2003  if (!dirname)
2004  return (SARRAY *)ERROR_PTR("dirname not defined", procName, NULL);
2005  if (dirname[0] == '\0')
2006  return (SARRAY *)ERROR_PTR("dirname is empty", procName, NULL);
2007 
2008  /* Who would have thought it was this fiddly to open a directory
2009  and get the files inside? fstatat() works with relative
2010  directory paths, and stat() requires using the absolute path.
2011  realpath works as follows for files and directories:
2012  * If the file or directory exists, realpath returns its path;
2013  else it returns NULL.
2014  * If the second arg to realpath is passed in, the canonical path
2015  is returned there. Use a buffer of sufficient size. If the
2016  second arg is NULL, the path is malloc'd and returned if the
2017  file or directory exists.
2018  We pass in a buffer for the second arg, and check that the canonical
2019  directory path was made. The existence of the directory is checked
2020  later, after its actual path is returned by genPathname(). */
2021  dir[0] = '\0'; /* init empty in case realpath() fails to write it */
2022  ignore = realpath(dirname, dir);
2023  if (dir[0] == '\0')
2024  return (SARRAY *)ERROR_PTR("dir not made", procName, NULL);
2025  realdir = genPathname(dir, NULL);
2026  if ((pdir = opendir(realdir)) == NULL) {
2027  LEPT_FREE(realdir);
2028  return (SARRAY *)ERROR_PTR("pdir not opened", procName, NULL);
2029  }
2030  safiles = sarrayCreate(0);
2031  dfd = dirfd(pdir);
2032  while ((pdirentry = readdir(pdir))) {
2033 #if HAVE_FSTATAT
2034  stat_ret = fstatat(dfd, pdirentry->d_name, &st, 0);
2035 #else
2036  size = strlen(realdir) + strlen(pdirentry->d_name) + 2;
2037  if (size > PATH_MAX) {
2038  L_ERROR("size = %zu too large; skipping\n", procName, size);
2039  continue;
2040  }
2041  stat_path = (char *)LEPT_CALLOC(size, 1);
2042  snprintf(stat_path, size, "%s/%s", realdir, pdirentry->d_name);
2043  stat_ret = stat(stat_path, &st);
2044  LEPT_FREE(stat_path);
2045 #endif
2046  if (stat_ret == 0 && S_ISDIR(st.st_mode))
2047  continue;
2048  sarrayAddString(safiles, pdirentry->d_name, L_COPY);
2049  }
2050  closedir(pdir);
2051  LEPT_FREE(realdir);
2052  return safiles;
2053 }
2054 
2055 #else /* _WIN32 */
2056 
2057  /* http://msdn2.microsoft.com/en-us/library/aa365200(VS.85).aspx */
2058 #include <windows.h>
2059 
2060 SARRAY *
2061 getFilenamesInDirectory(const char *dirname)
2062 {
2063 char *pszDir;
2064 char *realdir;
2065 HANDLE hFind = INVALID_HANDLE_VALUE;
2066 SARRAY *safiles;
2067 WIN32_FIND_DATAA ffd;
2068 
2069  PROCNAME("getFilenamesInDirectory");
2070 
2071  if (!dirname)
2072  return (SARRAY *)ERROR_PTR("dirname not defined", procName, NULL);
2073 
2074  realdir = genPathname(dirname, NULL);
2075  pszDir = stringJoin(realdir, "\\*");
2076  LEPT_FREE(realdir);
2077 
2078  if (strlen(pszDir) + 1 > MAX_PATH) {
2079  LEPT_FREE(pszDir);
2080  return (SARRAY *)ERROR_PTR("dirname is too long", procName, NULL);
2081  }
2082 
2083  if ((safiles = sarrayCreate(0)) == NULL) {
2084  LEPT_FREE(pszDir);
2085  return (SARRAY *)ERROR_PTR("safiles not made", procName, NULL);
2086  }
2087 
2088  hFind = FindFirstFileA(pszDir, &ffd);
2089  if (INVALID_HANDLE_VALUE == hFind) {
2090  sarrayDestroy(&safiles);
2091  LEPT_FREE(pszDir);
2092  return (SARRAY *)ERROR_PTR("hFind not opened", procName, NULL);
2093  }
2094 
2095  while (FindNextFileA(hFind, &ffd) != 0) {
2096  if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) /* skip dirs */
2097  continue;
2098  convertSepCharsInPath(ffd.cFileName, UNIX_PATH_SEPCHAR);
2099  sarrayAddString(safiles, ffd.cFileName, L_COPY);
2100  }
2101 
2102  FindClose(hFind);
2103  LEPT_FREE(pszDir);
2104  return safiles;
2105 }
2106 #endif /* _WIN32 */
#define SARRAY_VERSION_NUMBER
Definition: array.h:123
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:366
l_ok numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:754
NUMA * numaGetUniformBinSizes(l_int32 ntotal, l_int32 nbins)
numaGetUniformBinSizes()
Definition: numafunc2.c:1945
@ L_COPY
Definition: pix.h:712
@ L_NOCOPY
Definition: pix.h:710
@ L_INSERT
Definition: pix.h:711
@ L_SORT_INCREASING
Definition: pix.h:729
SARRAY * sarraySelectBySubstring(SARRAY *sain, const char *substr)
sarraySelectBySubstring()
Definition: sarray1.c:1241
SARRAY * sarrayCreate(l_int32 n)
sarrayCreate()
Definition: sarray1.c:170
SARRAY * sarrayRead(const char *filename)
sarrayRead()
Definition: sarray1.c:1441
char * sarrayGetString(SARRAY *sa, l_int32 index, l_int32 copyflag)
sarrayGetString()
Definition: sarray1.c:703
l_ok sarrayWriteStderr(SARRAY *sa)
sarrayWriteStderr()
Definition: sarray1.c:1646
static const l_int32 InitialPtrArraySize
Definition: sarray1.c:154
l_ok sarrayJoin(SARRAY *sa1, SARRAY *sa2)
sarrayJoin()
Definition: sarray1.c:969
SARRAY * sarraySelectRange(SARRAY *sain, l_int32 first, l_int32 last)
sarraySelectRange()
Definition: sarray1.c:1287
char ** sarrayGetArray(SARRAY *sa, l_int32 *pnalloc, l_int32 *pn)
sarrayGetArray()
Definition: sarray1.c:668
char * sarrayToStringRange(SARRAY *sa, l_int32 first, l_int32 nstrings, l_int32 addnlflag)
sarrayToStringRange()
Definition: sarray1.c:820
l_ok sarrayPadToSameSize(SARRAY *sa1, SARRAY *sa2, const char *padstring)
sarrayPadToSameSize()
Definition: sarray1.c:1064
SARRAY * getFilenamesInDirectory(const char *dirname)
getFilenamesInDirectory()
Definition: sarray1.c:1990
l_ok sarrayReplaceString(SARRAY *sa, l_int32 index, char *newstr, l_int32 copyflag)
sarrayReplaceString()
Definition: sarray1.c:579
l_ok sarrayAppend(const char *filename, SARRAY *sa)
sarrayAppend()
Definition: sarray1.c:1732
SARRAY * sarrayConvertWordsToLines(SARRAY *sa, l_int32 linesize)
sarrayConvertWordsToLines()
Definition: sarray1.c:1123
SARRAY * sarrayReadStream(FILE *fp)
sarrayReadStream()
Definition: sarray1.c:1479
SARRAY * sarrayClone(SARRAY *sa)
sarrayClone()
Definition: sarray1.c:425
l_int32 sarrayGetCount(SARRAY *sa)
sarrayGetCount()
Definition: sarray1.c:643
void sarrayDestroy(SARRAY **psa)
sarrayDestroy()
Definition: sarray1.c:362
SARRAY * sarrayCreateWordsFromString(const char *string)
sarrayCreateWordsFromString()
Definition: sarray1.c:233
SARRAY * sarrayCreateLinesFromString(const char *string, l_int32 blankflag)
sarrayCreateLinesFromString()
Definition: sarray1.c:283
l_ok sarrayClear(SARRAY *sa)
sarrayClear()
Definition: sarray1.c:616
char * sarrayRemoveString(SARRAY *sa, l_int32 index)
sarrayRemoveString()
Definition: sarray1.c:528
static l_int32 sarrayExtendArray(SARRAY *sa)
sarrayExtendArray()
Definition: sarray1.c:494
l_ok sarrayAddString(SARRAY *sa, const char *string, l_int32 copyflag)
sarrayAddString()
Definition: sarray1.c:451
SARRAY * sarrayReadMem(const l_uint8 *data, size_t size)
sarrayReadMem()
Definition: sarray1.c:1549
SARRAY * sarrayCreateInitialized(l_int32 n, const char *initstr)
sarrayCreateInitialized()
Definition: sarray1.c:200
l_int32 sarrayGetRefcount(SARRAY *sa)
sarrayGetRefCount()
Definition: sarray1.c:730
l_ok sarrayWrite(const char *filename, SARRAY *sa)
sarrayWrite()
Definition: sarray1.c:1577
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:1356
l_ok sarrayChangeRefcount(SARRAY *sa, l_int32 delta)
sarrayChangeRefCount()
Definition: sarray1.c:748
char * sarrayToString(SARRAY *sa, l_int32 addnlflag)
sarrayToString()
Definition: sarray1.c:785
SARRAY * getSortedPathnamesInDirectory(const char *dirname, const char *substr, l_int32 first, l_int32 nfiles)
getSortedPathnamesInDirectory()
Definition: sarray1.c:1848
SARRAY * sarrayConcatUniformly(SARRAY *sa, l_int32 n, l_int32 addnlflag)
sarrayConcatUniformly()
Definition: sarray1.c:917
l_ok sarrayWriteStream(FILE *fp, SARRAY *sa)
sarrayWriteStream()
Definition: sarray1.c:1614
l_ok sarrayWriteMem(l_uint8 **pdata, size_t *psize, SARRAY *sa)
sarrayWriteMem()
Definition: sarray1.c:1681
SARRAY * convertSortedToNumberedPathnames(SARRAY *sa, l_int32 numpre, l_int32 numpost, l_int32 maxnum)
convertSortedToNumberedPathnames()
Definition: sarray1.c:1908
l_ok sarrayAppendRange(SARRAY *sa1, SARRAY *sa2, l_int32 start, l_int32 end)
sarrayAppendRange()
Definition: sarray1.c:1012
SARRAY * sarrayCopy(SARRAY *sa)
sarrayCopy()
Definition: sarray1.c:398
SARRAY * getNumberedPathnamesInDirectory(const char *dirname, const char *substr, l_int32 numpre, l_int32 numpost, l_int32 maxnum)
getNumberedPathnamesInDirectory()
Definition: sarray1.c:1800
SARRAY * sarraySort(SARRAY *saout, SARRAY *sain, l_int32 sortorder)
sarraySort()
Definition: sarray2.c:97
Definition: array.h:71
Definition: array.h:127
l_int32 refcount
Definition: array.h:130
l_int32 nalloc
Definition: array.h:128
char ** array
Definition: array.h:131
l_int32 n
Definition: array.h:129
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:1402
char * strtokSafe(char *cstr, const char *seps, char **psaveptr)
strtokSafe()
Definition: utils2.c:649
FILE * fopenReadFromMemory(const l_uint8 *data, size_t size)
fopenReadFromMemory()
Definition: utils2.c:2009
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1975
char * pathJoin(const char *dir, const char *fname)
pathJoin()
Definition: utils2.c:2973
char * genPathname(const char *dir, const char *fname)
genPathname()
Definition: utils2.c:3173
l_ok convertSepCharsInPath(char *path, l_int32 type)
convertSepCharsInPath()
Definition: utils2.c:3108
char * stringJoin(const char *src1, const char *src2)
stringJoin()
Definition: utils2.c:518
void * reallocNew(void **pindata, size_t oldsize, size_t newsize)
reallocNew()
Definition: utils2.c:1302
FILE * fopenWriteWinTempfile(void)
fopenWriteWinTempfile()
Definition: utils2.c:2055
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1932
l_int32 extractNumberFromFilename(const char *fname, l_int32 numpre, l_int32 numpost)
extractNumberFromFilename()
Definition: utils2.c:3453
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:1233