pike.git / lib / modules / Array.pmod

version» Context lines:

pike.git/lib/modules/Array.pmod:254:    for (int i = 0, j = 0; j < sizeof (seq_bc); i++)    if (b[i] == c[seq_bc[j]]) beq[i] |= 2, ceq[seq_bc[j]] |= 1, j++;    for (int i = 0, j = 0; j < sizeof (seq_ca); i++)    if (c[i] == a[seq_ca[j]]) ceq[i] |= 2, aeq[seq_ca[j]] |= 1, j++;       array(array) ares = ({}), bres = ({}), cres = ({});    int ai = 0, bi = 0, ci = 0;    int prevodd = -2;       while (!(aeq[ai] & beq[bi] & ceq[ci] & 4)) { +  /* werror ("aeq[%d]=%d beq[%d]=%d ceq[%d]=%d prevodd=%d\n", +  ai, aeq[ai], bi, beq[bi], ci, ceq[ci], prevodd); */    array empty = ({}), apart = empty, bpart = empty, cpart = empty; -  +  int intersect;       if (aeq[ai] == 2 && beq[bi] == 1) { // a and b are equal.    do apart += ({a[ai++]}), bi++; while (aeq[ai] == 2 && beq[bi] == 1);    bpart = apart;    while (!ceq[ci]) cpart += ({c[ci++]});    prevodd = 2;    }    else if (beq[bi] == 2 && ceq[ci] == 1) { // b and c are equal.    do bpart += ({b[bi++]}), ci++; while (beq[bi] == 2 && ceq[ci] == 1);    cpart = bpart;    while (!aeq[ai]) apart += ({a[ai++]});    prevodd = 0;    }    else if (ceq[ci] == 2 && aeq[ai] == 1) { // c and a are equal.    do cpart += ({c[ci++]}), ai++; while (ceq[ci] == 2 && aeq[ai] == 1);    apart = cpart;    while (!beq[bi]) bpart += ({b[bi++]});    prevodd = 1;    } -  else if (aeq[ai] & beq[bi] & ceq[ci] == 3) { // All are equal. +  else if ((intersect = aeq[ai] & beq[bi] & ceq[ci]) == 3) { // All are equal.    do apart += ({a[ai++]}), bi++, ci++; while (aeq[ai] & beq[bi] & ceq[ci] == 3);    cpart = bpart = apart;    prevodd = -1;    }    else {    // Haven't got any equivalences in this block. Avoid adjacent    // complementary blocks (e.g. ({({"foo"}),({}),({})}) next to    // ({({}),({"bar"}),({"bar"})})). Besides that, leave the    // odd-one-out sequence empty in a block where two are equal.    -  if (aeq[ai] & beq[bi] & ceq[ci]) { +  if (intersect && (aeq[ai] | beq[bi] | ceq[ci]) != 3) {    // Got cyclically interlocking equivalences. Have to break one    // of them. Prefer the shortest.    int which, newblock, mask, i, oi;    array(int) eq, oeq;    array arr;    for (i = 0;; i++)    if (aeq[ai] != aeq[ai + i]) {    which = 0, newblock = prevodd != 0 && (prevodd == -2 || sizeof (ares[-1]));    mask = aeq[ai] ^ 3, i = ai, eq = aeq, arr = a;    if (mask == 1) oi = bi, oeq = beq; else oi = ci, oeq = ceq;
pike.git/lib/modules/Array.pmod:310:    mask = beq[bi] ^ 3, i = bi, eq = beq, arr = b;    if (mask == 1) oi = ci, oeq = ceq; else oi = ai, oeq = aeq;    break;    }    else if (ceq[ci] != ceq[ci + i]) {    which = 2, newblock = prevodd != 2 && (prevodd == -2 || sizeof (cres[-1]));    mask = ceq[ci] ^ 3, i = ci, eq = ceq, arr = c;    if (mask == 1) oi = ai, oeq = aeq; else oi = bi, oeq = beq;    break;    } +  /* werror ("which=%d newblock=%d mask=%d i=%d oi=%d\n", +  which, newblock, mask, i, oi); */    if (newblock)    ares += ({empty}), bres += ({empty}), cres += ({empty}), prevodd = -1;    while (oeq[oi] != mask) oi++;    array part = ({});    mask ^= 3;    do part += ({arr[i++]}), oeq[oi++] = 0; while (eq[i] == mask);    switch (which) {    case 0: ai = i; ares[-1] += part; break;    case 1: bi = i; bres[-1] += part; break;    case 2: ci = i; cres[-1] += part; break;    }    continue;    }       else { -  +  if (intersect) { +  // One matches on both sides and the other two doesn't match +  // each other. This occurs when the matches aren't +  // synchronized. E.g. for a = ({"a"}), b = ({"b","a"}), c = +  // ({"a","b","a"}) we got a[0]->b[1], b[0..1]->c[1..2], +  // c[0]->a[0]. We shift the match forward to catch the +  // all-three match later, i.e. replace c[0]->a[0] with +  // c[2]->a[0] in this case. +  int i; +  array(int) eq; +  array arr; +  if (aeq[ai] == 3) +  if (intersect == 1) i = bi, eq = beq, arr = b; else i = ci, eq = ceq, arr = c; +  else if (beq[bi] == 3) +  if (intersect == 1) i = ci, eq = ceq, arr = c; else i = ai, eq = aeq, arr = a; +  else +  if (intersect == 1) i = ai, eq = aeq, arr = a; else i = bi, eq = beq, arr = b; +  while (eq[i] == intersect) { +  mixed el = arr[i]; +  eq[i] = 0; +  int j = ++i; +  while (arr[j] != el || eq[j] & intersect) j++; +  eq[j] |= intersect; +  } +  } +     switch (prevodd) {    case 0: apart = ares[-1], ares[-1] = ({}); break;    case 1: bpart = bres[-1], bres[-1] = ({}); break;    case 2: cpart = cres[-1], cres[-1] = ({}); break;    }    prevodd = -1;    while (!aeq[ai]) apart += ({a[ai++]});    while (!beq[bi]) bpart += ({b[bi++]});    while (!ceq[ci]) cpart += ({c[ci++]});    }