cupsArrayAdd:
   74|    121|{
   75|    121|  DEBUG_printf("2cupsArrayAdd(a=%p, e=%p)", (void *)a, e);
   76|       |
   77|       |  // Range check input...
   78|    121|  if (!a || !e)
  ------------------
  |  Branch (78:7): [True: 0, False: 121]
  |  Branch (78:13): [True: 0, False: 121]
  ------------------
   79|      0|  {
   80|      0|    DEBUG_puts("3cupsArrayAdd: returning 0");
   81|      0|    return (0);
   82|      0|  }
   83|       |
   84|       |  // Append the element...
   85|    121|  return (cups_array_add(a, e, 0));
   86|    121|}
cupsArrayClear:
  191|    121|{
  192|       |  // Range check input...
  193|    121|  if (!a)
  ------------------
  |  Branch (193:7): [True: 0, False: 121]
  ------------------
  194|      0|    return;
  195|       |
  196|       |  // Free the existing elements as needed..
  197|    121|  if (a->freefunc)
  ------------------
  |  Branch (197:7): [True: 121, False: 0]
  ------------------
  198|    121|  {
  199|    121|    int		i;			// Looping var
  200|    121|    void	**e;			// Current element
  201|       |
  202|    220|    for (i = a->num_elements, e = a->elements; i > 0; i --, e ++)
  ------------------
  |  Branch (202:48): [True: 99, False: 121]
  ------------------
  203|     99|      (a->freefunc)(*e, a->data);
  204|    121|  }
  205|       |
  206|       |  // Set the number of elements to 0; we don't actually free the memory
  207|       |  // here - that is done in cupsArrayDelete()...
  208|    121|  a->num_elements = 0;
  209|    121|  a->current      = -1;
  210|    121|  a->insert       = -1;
  211|    121|  a->unique       = 1;
  212|    121|  a->num_saved    = 0;
  213|    121|}
cupsArrayCurrent:
  240|  4.47k|{
  241|  4.47k|  return (cupsArrayGetCurrent(a));
  242|  4.47k|}
cupsArrayDelete:
  256|    242|{
  257|       |  // Range check input...
  258|    242|  if (!a)
  ------------------
  |  Branch (258:7): [True: 0, False: 242]
  ------------------
  259|      0|    return;
  260|       |
  261|       |  // Free the elements if we have a free function (otherwise the caller is
  262|       |  // responsible for doing the dirty work...)
  263|    242|  if (a->freefunc)
  ------------------
  |  Branch (263:7): [True: 121, False: 121]
  ------------------
  264|    121|  {
  265|    121|    int		i;			// Looping var
  266|    121|    void	**e;			// Current element
  267|       |
  268|    121|    for (i = a->num_elements, e = a->elements; i > 0; i --, e ++)
  ------------------
  |  Branch (268:48): [True: 0, False: 121]
  ------------------
  269|      0|      (a->freefunc)(*e, a->data);
  270|    121|  }
  271|       |
  272|       |  // Free the array of element pointers...
  273|    242|  if (a->alloc_elements)
  ------------------
  |  Branch (273:7): [True: 242, False: 0]
  ------------------
  274|    242|    free(a->elements);
  275|       |
  276|    242|  if (a->hashsize)
  ------------------
  |  Branch (276:7): [True: 0, False: 242]
  ------------------
  277|      0|    free(a->hash);
  278|       |
  279|    242|  free(a);
  280|    242|}
cupsArrayDup:
  291|    121|{
  292|    121|  cups_array_t	*da;			// Duplicate array
  293|       |
  294|       |
  295|       |  // Range check input...
  296|    121|  if (!a)
  ------------------
  |  Branch (296:7): [True: 0, False: 121]
  ------------------
  297|      0|    return (NULL);
  298|       |
  299|       |  // Allocate memory for the array...
  300|    121|  da = calloc(1, sizeof(cups_array_t));
  301|    121|  if (!da)
  ------------------
  |  Branch (301:7): [True: 0, False: 121]
  ------------------
  302|      0|    return (NULL);
  303|       |
  304|    121|  da->compare   = a->compare;
  305|    121|  da->data      = a->data;
  306|    121|  da->current   = a->current;
  307|    121|  da->insert    = a->insert;
  308|    121|  da->unique    = a->unique;
  309|    121|  da->num_saved = a->num_saved;
  310|       |
  311|    121|  memcpy(da->saved, a->saved, sizeof(a->saved));
  312|       |
  313|    121|  if (a->num_elements)
  ------------------
  |  Branch (313:7): [True: 121, False: 0]
  ------------------
  314|    121|  {
  315|       |    // Allocate memory for the elements...
  316|    121|    da->elements = malloc((size_t)a->num_elements * sizeof(void *));
  317|    121|    if (!da->elements)
  ------------------
  |  Branch (317:9): [True: 0, False: 121]
  ------------------
  318|      0|    {
  319|      0|      free(da);
  320|      0|      return (NULL);
  321|      0|    }
  322|       |
  323|       |    // Copy the element pointers...
  324|    121|    if (a->copyfunc)
  ------------------
  |  Branch (324:9): [True: 121, False: 0]
  ------------------
  325|    121|    {
  326|       |      // Use the copy function to make a copy of each element...
  327|    121|      int	i;			// Looping var
  328|       |
  329|    242|      for (i = 0; i < a->num_elements; i ++)
  ------------------
  |  Branch (329:19): [True: 121, False: 121]
  ------------------
  330|    121|	da->elements[i] = (a->copyfunc)(a->elements[i], a->data);
  331|    121|    }
  332|      0|    else
  333|      0|    {
  334|       |      // Just copy raw pointers...
  335|      0|      memcpy(da->elements, a->elements, (size_t)a->num_elements * sizeof(void *));
  336|      0|    }
  337|       |
  338|    121|    da->num_elements   = a->num_elements;
  339|    121|    da->alloc_elements = a->num_elements;
  340|    121|  }
  341|       |
  342|       |  // Return the new array...
  343|    121|  return (da);
  344|    121|}
cupsArrayFind:
  356|    121|{
  357|    121|  int	current,			// Current element
  358|    121|	diff,				// Difference
  359|    121|	hash;				// Hash index
  360|       |
  361|       |
  362|       |  // Range check input...
  363|    121|  if (!a || !e)
  ------------------
  |  Branch (363:7): [True: 0, False: 121]
  |  Branch (363:13): [True: 0, False: 121]
  ------------------
  364|      0|    return (NULL);
  365|       |
  366|       |  // See if we have any elements...
  367|    121|  if (!a->num_elements)
  ------------------
  |  Branch (367:7): [True: 0, False: 121]
  ------------------
  368|      0|    return (NULL);
  369|       |
  370|       |  // Yes, look for a match...
  371|    121|  if (a->hash)
  ------------------
  |  Branch (371:7): [True: 0, False: 121]
  ------------------
  372|      0|  {
  373|      0|    hash = (*(a->hashfunc))(e, a->data);
  374|       |
  375|      0|    if (hash < 0 || hash >= a->hashsize)
  ------------------
  |  Branch (375:9): [True: 0, False: 0]
  |  Branch (375:21): [True: 0, False: 0]
  ------------------
  376|      0|    {
  377|      0|      current = a->current;
  378|      0|      hash    = -1;
  379|      0|    }
  380|      0|    else
  381|      0|    {
  382|      0|      current = a->hash[hash];
  383|       |
  384|      0|      if (current < 0 || current >= a->num_elements)
  ------------------
  |  Branch (384:11): [True: 0, False: 0]
  |  Branch (384:26): [True: 0, False: 0]
  ------------------
  385|      0|        current = a->current;
  386|      0|    }
  387|      0|  }
  388|    121|  else
  389|    121|  {
  390|    121|    current = a->current;
  391|    121|    hash    = -1;
  392|    121|  }
  393|       |
  394|    121|  current = cups_array_find(a, e, current, &diff);
  395|    121|  if (!diff)
  ------------------
  |  Branch (395:7): [True: 121, False: 0]
  ------------------
  396|    121|  {
  397|       |    // Found a match!  If the array does not contain unique values, find
  398|       |    // the first element that is the same...
  399|    121|    if (!a->unique && a->compare)
  ------------------
  |  Branch (399:9): [True: 0, False: 121]
  |  Branch (399:23): [True: 0, False: 0]
  ------------------
  400|      0|    {
  401|       |      // The array is not unique, find the first match...
  402|      0|      while (current > 0 && !(*(a->compare))(e, a->elements[current - 1], a->data))
  ------------------
  |  Branch (402:14): [True: 0, False: 0]
  |  Branch (402:29): [True: 0, False: 0]
  ------------------
  403|      0|        current --;
  404|      0|    }
  405|       |
  406|    121|    a->current = current;
  407|       |
  408|    121|    if (hash >= 0)
  ------------------
  |  Branch (408:9): [True: 0, False: 121]
  ------------------
  409|      0|      a->hash[hash] = current;
  410|       |
  411|    121|    return (a->elements[current]);
  412|    121|  }
  413|      0|  else
  414|      0|  {
  415|       |    // No match...
  416|      0|    a->current = -1;
  417|       |
  418|       |    return (NULL);
  419|      0|  }
  420|    121|}
_cupsArrayFree:
  443|    121|{
  444|    121|  (void)data;
  445|       |
  446|    121|  free(s);
  447|    121|}
cupsArrayGetCount:
  458|    242|{
  459|       |  // Range check input...
  460|    242|  if (!a)
  ------------------
  |  Branch (460:7): [True: 0, False: 242]
  ------------------
  461|      0|    return (0);
  462|       |
  463|       |  // Return the number of elements...
  464|    242|  return (a->num_elements);
  465|    242|}
cupsArrayGetCurrent:
  479|  4.59k|{
  480|       |  // Range check input...
  481|  4.59k|  if (!a)
  ------------------
  |  Branch (481:7): [True: 0, False: 4.59k]
  ------------------
  482|      0|    return (NULL);
  483|       |
  484|       |  // Return the current element...
  485|  4.59k|  if (a->current >= 0 && a->current < a->num_elements)
  ------------------
  |  Branch (485:7): [True: 4.47k, False: 121]
  |  Branch (485:26): [True: 363, False: 4.11k]
  ------------------
  486|    363|    return (a->elements[a->current]);
  487|  4.23k|  else
  488|  4.23k|    return (NULL);
  489|  4.59k|}
cupsArrayGetFirst:
  519|    242|{
  520|       |  // Range check input...
  521|    242|  if (!a)
  ------------------
  |  Branch (521:7): [True: 0, False: 242]
  ------------------
  522|      0|    return (NULL);
  523|       |
  524|       |  // Return the first element...
  525|    242|  a->current = 0;
  526|       |
  527|    242|  return (cupsArrayCurrent(a));
  528|    242|}
cupsArrayGetLast:
  574|    121|{
  575|       |  // Range check input...
  576|    121|  if (!a)
  ------------------
  |  Branch (576:7): [True: 0, False: 121]
  ------------------
  577|      0|    return (NULL);
  578|       |
  579|       |  // Return the last element...
  580|    121|  a->current = a->num_elements - 1;
  581|       |
  582|    121|  return (cupsArrayCurrent(a));
  583|    121|}
cupsArrayGetNext:
  600|  3.99k|{
  601|       | /*
  602|       |  * Range check input...
  603|       |  */
  604|       |
  605|  3.99k|  if (!a)
  ------------------
  |  Branch (605:7): [True: 0, False: 3.99k]
  ------------------
  606|      0|    return (NULL);
  607|       |
  608|       | /*
  609|       |  * Return the next element...
  610|       |  */
  611|       |
  612|  3.99k|  if (a->current < a->num_elements)
  ------------------
  |  Branch (612:7): [True: 121, False: 3.87k]
  ------------------
  613|    121|    a->current ++;
  614|       |
  615|  3.99k|  return (cupsArrayCurrent(a));
  616|  3.99k|}
cupsArrayGetPrev:
  633|    121|{
  634|       |  // Range check input...
  635|    121|  if (!a)
  ------------------
  |  Branch (635:7): [True: 0, False: 121]
  ------------------
  636|      0|    return (NULL);
  637|       |
  638|       |  // Return the previous element...
  639|    121|  if (a->current >= 0)
  ------------------
  |  Branch (639:7): [True: 121, False: 0]
  ------------------
  640|    121|    a->current --;
  641|       |
  642|    121|  return (cupsArrayCurrent(a));
  643|    121|}
cupsArrayGetUserData:
  654|    121|{
  655|    121|  if (a)
  ------------------
  |  Branch (655:7): [True: 121, False: 0]
  ------------------
  656|    121|    return (a->data);
  657|      0|  else
  658|      0|    return (NULL);
  659|    121|}
cupsArrayNew3:
  788|    121|{
  789|    121|  cups_array_t	*a;			// Array
  790|       |
  791|       |
  792|       |  // Allocate memory for the array...
  793|    121|  a = calloc(1, sizeof(cups_array_t));
  794|    121|  if (!a)
  ------------------
  |  Branch (794:7): [True: 0, False: 121]
  ------------------
  795|      0|    return (NULL);
  796|       |
  797|    121|  a->compare   = f;
  798|    121|  a->data      = d;
  799|    121|  a->current   = -1;
  800|    121|  a->insert    = -1;
  801|    121|  a->num_saved = 0;
  802|    121|  a->unique    = 1;
  803|       |
  804|    121|  if (hsize > 0 && h)
  ------------------
  |  Branch (804:7): [True: 0, False: 121]
  |  Branch (804:20): [True: 0, False: 0]
  ------------------
  805|      0|  {
  806|      0|    a->hashfunc  = h;
  807|      0|    a->hashsize  = hsize;
  808|      0|    a->hash      = malloc((size_t)hsize * sizeof(int));
  809|       |
  810|      0|    if (!a->hash)
  ------------------
  |  Branch (810:9): [True: 0, False: 0]
  ------------------
  811|      0|    {
  812|      0|      free(a);
  813|      0|      return (NULL);
  814|      0|    }
  815|       |
  816|      0|    memset(a->hash, -1, (size_t)hsize * sizeof(int));
  817|      0|  }
  818|       |
  819|    121|  a->copyfunc = cf;
  820|    121|  a->freefunc = ff;
  821|       |
  822|    121|  return (a);
  823|    121|}
cupsArrayRemove:
  904|    121|{
  905|    121|  ssize_t	i,			// Looping var
  906|    121|		current;		// Current element
  907|    121|  int		diff;			// Difference
  908|       |
  909|       |
  910|       |  // Range check input...
  911|    121|  if (!a || !e)
  ------------------
  |  Branch (911:7): [True: 0, False: 121]
  |  Branch (911:13): [True: 0, False: 121]
  ------------------
  912|      0|    return (0);
  913|       |
  914|       |  // See if the element is in the array...
  915|    121|  if (!a->num_elements)
  ------------------
  |  Branch (915:7): [True: 0, False: 121]
  ------------------
  916|      0|    return (0);
  917|       |
  918|    121|  current = cups_array_find(a, e, a->current, &diff);
  919|    121|  if (diff)
  ------------------
  |  Branch (919:7): [True: 99, False: 22]
  ------------------
  920|     99|    return (0);
  921|       |
  922|       |  // Yes, now remove it...
  923|     22|  a->num_elements --;
  924|       |
  925|     22|  if (a->freefunc)
  ------------------
  |  Branch (925:7): [True: 22, False: 0]
  ------------------
  926|     22|    (a->freefunc)(a->elements[current], a->data);
  927|       |
  928|     22|  if (current < a->num_elements)
  ------------------
  |  Branch (928:7): [True: 0, False: 22]
  ------------------
  929|      0|    memmove(a->elements + current, a->elements + current + 1, (size_t)(a->num_elements - current) * sizeof(void *));
  930|       |
  931|     22|  if (current <= a->current)
  ------------------
  |  Branch (931:7): [True: 22, False: 0]
  ------------------
  932|     22|    a->current --;
  933|       |
  934|     22|  if (current < a->insert)
  ------------------
  |  Branch (934:7): [True: 0, False: 22]
  ------------------
  935|      0|    a->insert --;
  936|     22|  else if (current == a->insert)
  ------------------
  |  Branch (936:12): [True: 22, False: 0]
  ------------------
  937|     22|    a->insert = -1;
  938|       |
  939|     22|  for (i = 0; i < a->num_saved; i ++)
  ------------------
  |  Branch (939:15): [True: 0, False: 22]
  ------------------
  940|      0|  {
  941|      0|    if (current <= a->saved[i])
  ------------------
  |  Branch (941:9): [True: 0, False: 0]
  ------------------
  942|      0|      a->saved[i] --;
  943|      0|  }
  944|       |
  945|     22|  if (a->num_elements <= 1)
  ------------------
  |  Branch (945:7): [True: 22, False: 0]
  ------------------
  946|     22|    a->unique = 1;
  947|       |
  948|     22|  return (1);
  949|    121|}
cupsArrayRestore:
  960|  3.87k|{
  961|  3.87k|  if (!a)
  ------------------
  |  Branch (961:7): [True: 0, False: 3.87k]
  ------------------
  962|      0|    return (NULL);
  963|       |
  964|  3.87k|  if (a->num_saved <= 0)
  ------------------
  |  Branch (964:7): [True: 0, False: 3.87k]
  ------------------
  965|      0|    return (NULL);
  966|       |
  967|  3.87k|  a->num_saved --;
  968|  3.87k|  a->current = a->saved[a->num_saved];
  969|       |
  970|  3.87k|  if (a->current >= 0 && a->current < a->num_elements)
  ------------------
  |  Branch (970:7): [True: 3.87k, False: 0]
  |  Branch (970:26): [True: 0, False: 3.87k]
  ------------------
  971|      0|    return (a->elements[a->current]);
  972|  3.87k|  else
  973|  3.87k|    return (NULL);
  974|  3.87k|}
cupsArraySave:
  991|  3.87k|{
  992|  3.87k|  if (!a)
  ------------------
  |  Branch (992:7): [True: 0, False: 3.87k]
  ------------------
  993|      0|    return (0);
  994|       |
  995|  3.87k|  if (a->num_saved >= _CUPS_MAXSAVE)
  ------------------
  |  |   21|  3.87k|#define _CUPS_MAXSAVE	32		// Maximum number of saves
  ------------------
  |  Branch (995:7): [True: 0, False: 3.87k]
  ------------------
  996|      0|    return (0);
  997|       |
  998|  3.87k|  a->saved[a->num_saved] = a->current;
  999|  3.87k|  a->num_saved ++;
 1000|       |
 1001|  3.87k|  return (1);
 1002|  3.87k|}
_cupsArrayStrcmp:
 1028|    242|{
 1029|    242|  (void)data;
 1030|       |
 1031|    242|  return (strcmp((const char *)s, (const char *)t));
 1032|    242|}
_cupsArrayStrdup:
 1042|    242|{
 1043|    242|  (void)data;
 1044|       |
 1045|    242|  return (strdup((const char *)s));
 1046|    242|}
array.c:cups_array_add:
 1070|    121|{
 1071|    121|  int		i,			// Looping var
 1072|    121|		current;		// Current element
 1073|    121|  int		diff;			// Comparison with current element
 1074|       |
 1075|       |
 1076|    121|  DEBUG_printf("7cups_array_add(a=%p, e=%p, insert=%d)", (void *)a, e, insert);
 1077|       |
 1078|       |  // Verify we have room for the new element...
 1079|    121|  if (a->num_elements >= a->alloc_elements)
  ------------------
  |  Branch (1079:7): [True: 121, False: 0]
  ------------------
 1080|    121|  {
 1081|       |    // Allocate additional elements; start with 16 elements, then
 1082|       |    // double the size until 1024 elements, then add 1024 elements
 1083|       |    // thereafter...
 1084|    121|    void	**temp;			// New array elements
 1085|    121|    int		count;			// New allocation count
 1086|       |
 1087|       |
 1088|    121|    if (a->alloc_elements == 0)
  ------------------
  |  Branch (1088:9): [True: 121, False: 0]
  ------------------
 1089|    121|    {
 1090|    121|      count = 16;
 1091|    121|      temp  = malloc((size_t)count * sizeof(void *));
 1092|    121|    }
 1093|      0|    else
 1094|      0|    {
 1095|      0|      if (a->alloc_elements < 1024)
  ------------------
  |  Branch (1095:11): [True: 0, False: 0]
  ------------------
 1096|      0|        count = a->alloc_elements * 2;
 1097|      0|      else
 1098|      0|        count = a->alloc_elements + 1024;
 1099|       |
 1100|      0|      temp = realloc(a->elements, (size_t)count * sizeof(void *));
 1101|      0|    }
 1102|       |
 1103|    121|    DEBUG_printf("9cups_array_add: count=" CUPS_LLFMT, CUPS_LLCAST count);
 1104|       |
 1105|    121|    if (!temp)
  ------------------
  |  Branch (1105:9): [True: 0, False: 121]
  ------------------
 1106|      0|    {
 1107|      0|      DEBUG_puts("9cups_array_add: allocation failed, returning 0");
 1108|      0|      return (0);
 1109|      0|    }
 1110|       |
 1111|    121|    a->alloc_elements = count;
 1112|    121|    a->elements       = temp;
 1113|    121|  }
 1114|       |
 1115|       |  // Find the insertion point for the new element; if there is no
 1116|       |  // compare function or elements, just add it to the beginning or end...
 1117|    121|  if (!a->num_elements || !a->compare)
  ------------------
  |  Branch (1117:7): [True: 121, False: 0]
  |  Branch (1117:27): [True: 0, False: 0]
  ------------------
 1118|    121|  {
 1119|       |    // No elements or comparison function, insert/append as needed...
 1120|    121|    if (insert)
  ------------------
  |  Branch (1120:9): [True: 0, False: 121]
  ------------------
 1121|      0|      current = 0;			// Insert at beginning
 1122|    121|    else
 1123|    121|      current = a->num_elements;	// Append to the end
 1124|    121|  }
 1125|      0|  else
 1126|      0|  {
 1127|       |    // Do a binary search for the insertion point...
 1128|      0|    current = cups_array_find(a, e, a->insert, &diff);
 1129|       |
 1130|      0|    if (diff > 0)
  ------------------
  |  Branch (1130:9): [True: 0, False: 0]
  ------------------
 1131|      0|    {
 1132|       |      // Insert after the current element...
 1133|      0|      current ++;
 1134|      0|    }
 1135|      0|    else if (!diff)
  ------------------
  |  Branch (1135:14): [True: 0, False: 0]
  ------------------
 1136|      0|    {
 1137|       |      // Compared equal, make sure we add to the beginning or end of
 1138|       |      // the current run of equal elements...
 1139|      0|      a->unique = 0;
 1140|       |
 1141|      0|      if (insert)
  ------------------
  |  Branch (1141:11): [True: 0, False: 0]
  ------------------
 1142|      0|      {
 1143|       |        // Insert at beginning of run...
 1144|      0|	while (current > 0 && !(*(a->compare))(e, a->elements[current - 1], a->data))
  ------------------
  |  Branch (1144:9): [True: 0, False: 0]
  |  Branch (1144:24): [True: 0, False: 0]
  ------------------
 1145|      0|          current --;
 1146|      0|      }
 1147|      0|      else
 1148|      0|      {
 1149|       |        // Append at end of run...
 1150|      0|	do
 1151|      0|	{
 1152|      0|          current ++;
 1153|      0|	}
 1154|      0|	while (current < a->num_elements && !(*(a->compare))(e, a->elements[current], a->data));
  ------------------
  |  Branch (1154:9): [True: 0, False: 0]
  |  Branch (1154:38): [True: 0, False: 0]
  ------------------
 1155|      0|      }
 1156|      0|    }
 1157|      0|  }
 1158|       |
 1159|       |  // Insert or append the element...
 1160|    121|  if (current < a->num_elements)
  ------------------
  |  Branch (1160:7): [True: 0, False: 121]
  ------------------
 1161|      0|  {
 1162|       |    // Shift other elements to the right...
 1163|      0|    memmove(a->elements + current + 1, a->elements + current, (size_t)(a->num_elements - current) * sizeof(void *));
 1164|       |
 1165|      0|    if (a->current >= current)
  ------------------
  |  Branch (1165:9): [True: 0, False: 0]
  ------------------
 1166|      0|      a->current ++;
 1167|       |
 1168|      0|    for (i = 0; i < a->num_saved; i ++)
  ------------------
  |  Branch (1168:17): [True: 0, False: 0]
  ------------------
 1169|      0|    {
 1170|      0|      if (a->saved[i] >= current)
  ------------------
  |  Branch (1170:11): [True: 0, False: 0]
  ------------------
 1171|      0|	a->saved[i] ++;
 1172|      0|    }
 1173|       |
 1174|      0|    DEBUG_printf("9cups_array_add: insert element at index " CUPS_LLFMT, CUPS_LLCAST current);
 1175|      0|  }
 1176|       |#ifdef DEBUG
 1177|       |  else
 1178|       |  {
 1179|       |    DEBUG_printf("9cups_array_add: append element at " CUPS_LLFMT, CUPS_LLCAST current);
 1180|       |  }
 1181|       |#endif // DEBUG
 1182|       |
 1183|    121|  if (a->copyfunc)
  ------------------
  |  Branch (1183:7): [True: 121, False: 0]
  ------------------
 1184|    121|  {
 1185|    121|    if ((a->elements[current] = (a->copyfunc)(e, a->data)) == NULL)
  ------------------
  |  Branch (1185:9): [True: 0, False: 121]
  ------------------
 1186|      0|    {
 1187|      0|      DEBUG_puts("8cups_array_add: Copy function returned NULL, returning 0");
 1188|      0|      return (0);
 1189|      0|    }
 1190|    121|  }
 1191|      0|  else
 1192|      0|  {
 1193|      0|    a->elements[current] = e;
 1194|      0|  }
 1195|       |
 1196|    121|  a->num_elements ++;
 1197|    121|  a->insert = current;
 1198|       |
 1199|    121|  DEBUG_puts("9cups_array_add: returning 1");
 1200|       |
 1201|    121|  return (1);
 1202|    121|}
array.c:cups_array_find:
 1214|    242|{
 1215|    242|  int	left,				// Left side of search
 1216|    242|	right,				// Right side of search
 1217|    242|	current,			// Current element
 1218|    242|	diff;				// Comparison with current element
 1219|       |
 1220|       |
 1221|    242|  DEBUG_printf("7cups_array_find(a=%p, e=%p, prev=%d, rdiff=%p)", (void *)a, e, prev, (void *)rdiff);
 1222|       |
 1223|    242|  if (a->compare)
  ------------------
  |  Branch (1223:7): [True: 242, False: 0]
  ------------------
 1224|    242|  {
 1225|       |    // Do a binary search for the element...
 1226|    242|    DEBUG_puts("9cups_array_find: binary search");
 1227|       |
 1228|    242|    if (prev >= 0 && prev < a->num_elements)
  ------------------
  |  Branch (1228:9): [True: 121, False: 121]
  |  Branch (1228:22): [True: 121, False: 0]
  ------------------
 1229|    121|    {
 1230|       |      // Start search on either side of previous...
 1231|    121|      if ((diff = (*(a->compare))(e, a->elements[prev], a->data)) == 0 || (diff < 0 && prev == 0) || (diff > 0 && prev == (a->num_elements - 1)))
  ------------------
  |  Branch (1231:11): [True: 22, False: 99]
  |  Branch (1231:76): [True: 82, False: 17]
  |  Branch (1231:88): [True: 82, False: 0]
  |  Branch (1231:103): [True: 17, False: 0]
  |  Branch (1231:115): [True: 17, False: 0]
  ------------------
 1232|    121|      {
 1233|       |        // Exact or edge match, return it!
 1234|    121|        DEBUG_printf("9cups_array_find: Returning %d, diff=%d", prev, diff);
 1235|       |
 1236|    121|	*rdiff = diff;
 1237|       |
 1238|    121|	return (prev);
 1239|    121|      }
 1240|      0|      else if (diff < 0)
  ------------------
  |  Branch (1240:16): [True: 0, False: 0]
  ------------------
 1241|      0|      {
 1242|       |        // Start with previous on right side...
 1243|      0|	left  = 0;
 1244|      0|	right = prev;
 1245|      0|      }
 1246|      0|      else
 1247|      0|      {
 1248|       |        // Start with previous on left side...
 1249|      0|        left  = prev;
 1250|      0|	right = a->num_elements - 1;
 1251|      0|      }
 1252|    121|    }
 1253|    121|    else
 1254|    121|    {
 1255|       |      // Start search in the middle...
 1256|    121|      left  = 0;
 1257|    121|      right = a->num_elements - 1;
 1258|    121|    }
 1259|       |
 1260|    121|    do
 1261|    121|    {
 1262|    121|      current = (left + right) / 2;
 1263|    121|      diff    = (*(a->compare))(e, a->elements[current], a->data);
 1264|       |
 1265|    121|      DEBUG_printf("9cups_array_find: left=%d, right=%d, current=%d, diff=%d", left, right, current, diff);
 1266|       |
 1267|    121|      if (diff == 0)
  ------------------
  |  Branch (1267:11): [True: 121, False: 0]
  ------------------
 1268|    121|	break;
 1269|      0|      else if (diff < 0)
  ------------------
  |  Branch (1269:16): [True: 0, False: 0]
  ------------------
 1270|      0|	right = current;
 1271|      0|      else
 1272|      0|	left = current;
 1273|    121|    }
 1274|    121|    while ((right - left) > 1);
  ------------------
  |  Branch (1274:12): [True: 0, False: 0]
  ------------------
 1275|       |
 1276|    121|    if (diff != 0)
  ------------------
  |  Branch (1276:9): [True: 0, False: 121]
  ------------------
 1277|      0|    {
 1278|       |      // Check the last 1 or 2 elements...
 1279|      0|      if ((diff = (*(a->compare))(e, a->elements[left], a->data)) <= 0)
  ------------------
  |  Branch (1279:11): [True: 0, False: 0]
  ------------------
 1280|      0|      {
 1281|      0|        current = left;
 1282|      0|      }
 1283|      0|      else
 1284|      0|      {
 1285|      0|        diff    = (*(a->compare))(e, a->elements[right], a->data);
 1286|      0|        current = right;
 1287|      0|      }
 1288|      0|    }
 1289|    121|  }
 1290|      0|  else
 1291|      0|  {
 1292|       |    // Do a linear pointer search...
 1293|      0|    DEBUG_puts("9cups_array_find: linear search");
 1294|       |
 1295|      0|    diff = 1;
 1296|       |
 1297|      0|    for (current = 0; current < a->num_elements; current ++)
  ------------------
  |  Branch (1297:23): [True: 0, False: 0]
  ------------------
 1298|      0|    {
 1299|      0|      if (a->elements[current] == e)
  ------------------
  |  Branch (1299:11): [True: 0, False: 0]
  ------------------
 1300|      0|      {
 1301|      0|        diff = 0;
 1302|      0|        break;
 1303|      0|      }
 1304|      0|    }
 1305|      0|  }
 1306|       |
 1307|       |  // Return the closest element and the difference...
 1308|    121|  DEBUG_printf("8cups_array_find: Returning %d, diff=%d", current, diff);
 1309|       |
 1310|    121|  *rdiff = diff;
 1311|       |
 1312|    121|  return (current);
 1313|    242|}

LLVMFuzzerTestOneInput:
   34|    123|int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
   35|    123|  int		i;			// Looping var
   36|    123|  cups_array_t	*array,			// Test array
   37|    123|	  *dup_array;		// Duplicate array
   38|    123|  int		status;			// Exit status
   39|    123|  char		*text;			// Text from array
   40|       |  // int string_size;
   41|    123|  char		*saved[32];		// Saved entries
   42|       |
   43|       |  // No errors so far...
   44|    123|  status = 0;
   45|       |
   46|    123|  if (Size < 4) {
  ------------------
  |  Branch (46:7): [True: 2, False: 121]
  ------------------
   47|      2|    return 0; 
   48|      2|  }
   49|       |
   50|    121|  FuzzArray fuzzInput;
   51|    121|  generate_fuzz_array_data(Data, Size, &fuzzInput);
   52|    121|  char* first_string = fuzzInput.str1;
   53|    121|  char* second_string = fuzzInput.str2;
   54|       |
   55|       |  // cupsArrayNew()
   56|    121|  array = cupsArrayNew3((cups_array_func_t)_cupsArrayStrcmp, (void *)first_string, NULL, 0, (cups_acopy_cb_t)_cupsArrayStrdup, (cups_afree_cb_t)_cupsArrayFree);
   57|       |
   58|    121|  if (!array)
  ------------------
  |  Branch (58:7): [True: 0, False: 121]
  ------------------
   59|      0|  {
   60|      0|    printf("returned NULL, expected pointer");
   61|      0|    abort();
   62|      0|  }
   63|       |
   64|       |  // cupsArrayGetUserData()
   65|    121|  if (cupsArrayGetUserData(array) != first_string)
  ------------------
  |  Branch (65:7): [True: 0, False: 121]
  ------------------
   66|      0|  {
   67|      0|    printf("returned %p instead of %p", cupsArrayGetUserData(array), first_string);
   68|      0|    abort();
   69|      0|  }
   70|       |
   71|       |  // cupsArrayAdd()
   72|    121|  if (!cupsArrayAdd(array, second_string))
  ------------------
  |  Branch (72:7): [True: 0, False: 121]
  ------------------
   73|      0|  {
   74|      0|    printf("Add String Error");
   75|      0|    abort();
   76|      0|  }
   77|       |
   78|       |  // cupsArrayGetCount()
   79|    121|  cupsArrayGetCount(array);
   80|       |
   81|       |  // cupsArrayGetFirst()
   82|    121|  text = (char *)cupsArrayGetFirst(array);
   83|    121|  if (text == NULL)
  ------------------
  |  Branch (83:7): [True: 0, False: 121]
  ------------------
   84|      0|  {
   85|      0|    printf("Error Reading");
   86|      0|  }
   87|       |
   88|       |  // cupsArrayGetNext()
   89|    121|  text = (char *)cupsArrayGetNext(array);
   90|    121|  if (text == NULL)
  ------------------
  |  Branch (90:7): [True: 121, False: 0]
  ------------------
   91|    121|  {
   92|    121|    printf("Error Reading");
   93|    121|  }
   94|       |
   95|       |  // cupsArrayGetLast()
   96|    121|  text = (char *)cupsArrayGetLast(array);
   97|    121|  if (text == NULL)
  ------------------
  |  Branch (97:7): [True: 0, False: 121]
  ------------------
   98|      0|  {
   99|      0|    printf("Error Reading");
  100|      0|  }
  101|       |
  102|       |  // cupsArrayGetPrev()
  103|    121|  text = (char *)cupsArrayGetPrev(array);
  104|    121|  if (text == NULL)
  ------------------
  |  Branch (104:7): [True: 121, False: 0]
  ------------------
  105|    121|  {
  106|    121|    printf("Error Reading");
  107|    121|  }
  108|       |
  109|       |  // cupsArrayFind()
  110|    121|  text = (char *)cupsArrayFind(array, second_string);
  111|    121|  if (text == NULL)
  ------------------
  |  Branch (111:7): [True: 0, False: 121]
  ------------------
  112|      0|  {
  113|      0|    printf("Error Finding");
  114|      0|  }
  115|       |
  116|       |  // cupsArrayGetCurrent()
  117|    121|  text = (char *)cupsArrayGetCurrent(array);
  118|    121|  if (text == NULL)
  ------------------
  |  Branch (118:7): [True: 0, False: 121]
  ------------------
  119|      0|  {
  120|      0|    printf("Error Finding");
  121|      0|  }
  122|       |
  123|       |  // cupsArrayDup()
  124|    121|  dup_array = cupsArrayDup(array);
  125|       |
  126|       |  // cupsArrayRemove()
  127|    121|  if (!cupsArrayRemove(array, first_string))
  ------------------
  |  Branch (127:7): [True: 99, False: 22]
  ------------------
  128|     99|  {
  129|     99|    printf("Error Finding");
  130|     99|  }
  131|       |
  132|       |  // cupsArrayClear()
  133|    121|  cupsArrayClear(array);
  134|    121|  if (cupsArrayGetCount(array) != 0)
  ------------------
  |  Branch (134:7): [True: 0, False: 121]
  ------------------
  135|      0|    {
  136|      0|        printf("Error Clearing");
  137|      0|  }
  138|       |
  139|       |  // Test save/restore...
  140|  3.99k|  for (i = 0, text = (char *)cupsArrayGetFirst(array); i < 32; i ++, text = (char *)cupsArrayGetNext(array))
  ------------------
  |  Branch (140:56): [True: 3.87k, False: 121]
  ------------------
  141|  3.87k|  {
  142|  3.87k|    saved[i] = text;
  143|       |
  144|  3.87k|    if (!cupsArraySave(array))
  ------------------
  |  Branch (144:9): [True: 0, False: 3.87k]
  ------------------
  145|      0|      break;
  146|  3.87k|  }
  147|       |
  148|  3.99k|  while (i > 0)
  ------------------
  |  Branch (148:10): [True: 3.87k, False: 121]
  ------------------
  149|  3.87k|  {
  150|  3.87k|    i --;
  151|       |
  152|  3.87k|    text = cupsArrayRestore(array);
  153|  3.87k|    if (text != saved[i])
  ------------------
  |  Branch (153:9): [True: 0, False: 3.87k]
  ------------------
  154|      0|      break;
  155|  3.87k|  }
  156|       |
  157|       |  // Delete the arrays...
  158|    121|  cupsArrayDelete(array);
  159|    121|  cupsArrayDelete(dup_array);
  160|       |
  161|    121|  free(first_string);
  162|    121|  free(second_string);
  163|       |
  164|    121|  if (status != 0) {
  ------------------
  |  Branch (164:7): [True: 0, False: 121]
  ------------------
  165|      0|    abort();
  166|      0|  }
  167|       |
  168|    121|  return 0;
  169|    121|}

generate_fuzz_array_data:
   14|    121|    void generate_fuzz_array_data(const uint8_t *data, size_t size, FuzzArray *outData) {
   15|       |
   16|    121|    FuzzedDataProvider fuzz_data(data, size);
   17|    121|    std::string fuzz_str1 = fuzz_data.ConsumeRandomLengthString(1);
   18|    121|    std::string fuzz_str2 = fuzz_data.ConsumeRandomLengthString(1);
   19|       |    // int num = fuzz_data.ConsumeIntegral<int>();
   20|       |
   21|    121|    outData->str1 = new char[fuzz_str1.length() + 1];
   22|    121|    std::strcpy(outData->str1, fuzz_str1.c_str());
   23|       |
   24|    121|    outData->str2 = new char[fuzz_str2.length() + 1];
   25|    121|    std::strcpy(outData->str2, fuzz_str2.c_str());
   26|       |    // outData->num = num;
   27|    121|    }

