/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/_static_tuple_c.c

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-10-21 16:30:17 UTC
  • mfrom: (4759.2.12 2.1-st-concat)
  • Revision ID: pqm@pqm.ubuntu.com-20091021163017-itbys2a178vt5605
(jam, andrew) Allow StaticTuple to hold more types,
        and implement the + operator.

Show diffs side-by-side

added added

removed removed

Lines of Context:
145
145
        return NULL;
146
146
    }
147
147
 
 
148
    if (size < 0 || size > 255) {
 
149
        /* Too big or too small */
 
150
        PyErr_SetString(PyExc_ValueError, "StaticTuple(...)"
 
151
            " takes from 0 to 255 items");
 
152
        return NULL;
 
153
    }
148
154
    if (size == 0 && _empty_tuple != NULL) {
149
155
        Py_INCREF(_empty_tuple);
150
156
        return _empty_tuple;
220
226
}
221
227
 
222
228
 
 
229
/* Check that all items we point to are 'valid' */
 
230
static int
 
231
StaticTuple_check_items(StaticTuple *self)
 
232
{
 
233
    int i;
 
234
    PyObject *obj;
 
235
 
 
236
    for (i = 0; i < self->size; ++i) {
 
237
        obj = self->items[i];
 
238
        if (obj == NULL) {
 
239
            PyErr_SetString(PyExc_RuntimeError, "StaticTuple(...)"
 
240
                " should not have a NULL entry.");
 
241
            return 0;
 
242
        }
 
243
        if (PyString_CheckExact(obj)
 
244
            || StaticTuple_CheckExact(obj)
 
245
            || obj == Py_None
 
246
            || PyBool_Check(obj)
 
247
            || PyInt_CheckExact(obj)
 
248
            || PyLong_CheckExact(obj)
 
249
            || PyFloat_CheckExact(obj)
 
250
            || PyUnicode_CheckExact(obj)
 
251
            ) continue;
 
252
        PyErr_Format(PyExc_TypeError, "StaticTuple(...)"
 
253
            " requires that all items are one of"
 
254
            " str, StaticTuple, None, bool, int, long, float, or unicode"
 
255
            " not %s.", Py_TYPE(obj)->tp_name);
 
256
        return 0;
 
257
    }
 
258
    return 1;
 
259
}
 
260
 
223
261
static PyObject *
224
262
StaticTuple_new_constructor(PyTypeObject *type, PyObject *args, PyObject *kwds)
225
263
{
236
274
        return NULL;
237
275
    }
238
276
    len = PyTuple_GET_SIZE(args);
239
 
    if (len < 0 || len > 255) {
240
 
        /* Too big or too small */
241
 
        PyErr_SetString(PyExc_ValueError, "StaticTuple.__init__(...)"
242
 
            " takes from 0 to 255 items");
243
 
        return NULL;
244
 
    }
245
277
    self = (StaticTuple *)StaticTuple_New(len);
246
278
    if (self == NULL) {
247
279
        return NULL;
248
280
    }
249
281
    for (i = 0; i < len; ++i) {
250
282
        obj = PyTuple_GET_ITEM(args, i);
251
 
        if (!PyString_CheckExact(obj)) {
252
 
            if (!StaticTuple_CheckExact(obj)) {
253
 
                PyErr_SetString(PyExc_TypeError, "StaticTuple.__init__(...)"
254
 
                    " requires that all items are strings or StaticTuple.");
255
 
                type->tp_dealloc((PyObject *)self);
256
 
                return NULL;
257
 
            }
258
 
        }
259
283
        Py_INCREF(obj);
260
284
        self->items[i] = obj;
261
285
    }
 
286
    if (!StaticTuple_check_items(self)) {
 
287
        type->tp_dealloc((PyObject *)self);
 
288
        return NULL;
 
289
    }
262
290
    return (PyObject *)self;
263
291
}
264
292
 
457
485
            /* Both are StaticTuple types, so recurse */
458
486
            result = StaticTuple_richcompare(v_obj, w_obj, Py_EQ);
459
487
        } else {
460
 
            /* Not the same type, obviously they won't compare equal */
461
 
            break;
 
488
            /* Fall back to generic richcompare */
 
489
            result = PyObject_RichCompare(v_obj, w_obj, Py_EQ);
462
490
        }
463
491
        if (result == NULL) {
464
492
            return NULL; /* There seems to be an error */
465
493
        }
466
 
        if (result == Py_NotImplemented) {
467
 
            Py_DECREF(result);
468
 
            /* One side must have had a string and the other a StaticTuple.
469
 
             * This clearly means that they are not equal.
470
 
             */
471
 
            if (op == Py_EQ) {
472
 
                Py_INCREF(Py_False);
473
 
                return Py_False;
474
 
            }
475
 
            result = PyObject_RichCompare(v_obj, w_obj, Py_EQ);
476
 
        }
477
494
        if (result == Py_False) {
478
 
            /* This entry is not identical
479
 
             * Shortcut for Py_EQ
480
 
             */
 
495
            // This entry is not identical, Shortcut for Py_EQ
481
496
            if (op == Py_EQ) {
482
497
                return result;
483
498
            }
531
546
        /* Both are StaticTuple types, so recurse */
532
547
        return StaticTuple_richcompare(v_obj, w_obj, op);
533
548
    } else {
534
 
        Py_INCREF(Py_NotImplemented);
535
 
        return Py_NotImplemented;
 
549
        return PyObject_RichCompare(v_obj, w_obj, op);
536
550
    }
537
551
}
538
552
 
560
574
 
561
575
 
562
576
static PyObject *
 
577
StaticTuple_add(PyObject *v, PyObject *w)
 
578
{
 
579
    Py_ssize_t i, len_v, len_w;
 
580
    PyObject *item;
 
581
    StaticTuple *result;
 
582
     /* StaticTuples and plain tuples may be added (concatenated) to
 
583
      * StaticTuples.
 
584
      */
 
585
    if (StaticTuple_CheckExact(v)) {
 
586
        len_v = ((StaticTuple*)v)->size;
 
587
    } else if (PyTuple_Check(v)) {
 
588
        len_v = PyTuple_GET_SIZE(v);
 
589
    } else {
 
590
        Py_INCREF(Py_NotImplemented);
 
591
        return Py_NotImplemented;
 
592
    }
 
593
    if (StaticTuple_CheckExact(w)) {
 
594
        len_w = ((StaticTuple*)w)->size;
 
595
    } else if (PyTuple_Check(w)) {
 
596
        len_w = PyTuple_GET_SIZE(w);
 
597
    } else {
 
598
        Py_INCREF(Py_NotImplemented);
 
599
        return Py_NotImplemented;
 
600
    }
 
601
    result = StaticTuple_New(len_v + len_w);
 
602
    if (result == NULL)
 
603
        return NULL;
 
604
    for (i = 0; i < len_v; ++i) {
 
605
        // This returns a new reference, which we then 'steal' with 
 
606
        // StaticTuple_SET_ITEM
 
607
        item = PySequence_GetItem(v, i);
 
608
        if (item == NULL) {
 
609
            Py_DECREF(result);
 
610
            return NULL;
 
611
        }
 
612
        StaticTuple_SET_ITEM(result, i, item);
 
613
    }
 
614
    for (i = 0; i < len_w; ++i) {
 
615
        item = PySequence_GetItem(w, i);
 
616
        if (item == NULL) {
 
617
            Py_DECREF(result);
 
618
            return NULL;
 
619
        }
 
620
        StaticTuple_SET_ITEM(result, i+len_v, item);
 
621
    }
 
622
    if (!StaticTuple_check_items(result)) {
 
623
        Py_DECREF(result);
 
624
        return NULL;
 
625
    }
 
626
    return (PyObject *)result;
 
627
}
 
628
 
 
629
static PyObject *
563
630
StaticTuple_item(StaticTuple *self, Py_ssize_t offset)
564
631
{
565
632
    PyObject *obj;
624
691
    {NULL, NULL} /* sentinel */
625
692
};
626
693
 
 
694
 
 
695
static PyNumberMethods StaticTuple_as_number = {
 
696
    (binaryfunc) StaticTuple_add,   /* nb_add */
 
697
    0,                              /* nb_subtract */
 
698
    0,                              /* nb_multiply */
 
699
    0,                              /* nb_divide */
 
700
    0,                              /* nb_remainder */
 
701
    0,                              /* nb_divmod */
 
702
    0,                              /* nb_power */
 
703
    0,                              /* nb_negative */
 
704
    0,                              /* nb_positive */
 
705
    0,                              /* nb_absolute */
 
706
    0,                              /* nb_nonzero */
 
707
    0,                              /* nb_invert */
 
708
    0,                              /* nb_lshift */
 
709
    0,                              /* nb_rshift */
 
710
    0,                              /* nb_and */
 
711
    0,                              /* nb_xor */
 
712
    0,                              /* nb_or */
 
713
    0,                              /* nb_coerce */
 
714
};
 
715
    
 
716
 
627
717
static PySequenceMethods StaticTuple_as_sequence = {
628
718
    (lenfunc)StaticTuple_length,            /* sq_length */
629
719
    0,                              /* sq_concat */
654
744
    0,                                           /* tp_setattr */
655
745
    0,                                           /* tp_compare */
656
746
    (reprfunc)StaticTuple_repr,                  /* tp_repr */
657
 
    0,                                           /* tp_as_number */
 
747
    &StaticTuple_as_number,                      /* tp_as_number */
658
748
    &StaticTuple_as_sequence,                    /* tp_as_sequence */
659
749
    0,                                           /* tp_as_mapping */
660
750
    (hashfunc)StaticTuple_hash,                  /* tp_hash */
663
753
    0,                                           /* tp_getattro */
664
754
    0,                                           /* tp_setattro */
665
755
    0,                                           /* tp_as_buffer */
666
 
    Py_TPFLAGS_DEFAULT,                          /* tp_flags*/
 
756
    /* Py_TPFLAGS_CHECKTYPES tells the number operations that they shouldn't
 
757
     * try to 'coerce' but instead stuff like 'add' will check it arguments.
 
758
     */
 
759
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES,  /* tp_flags*/
667
760
    StaticTuple_doc,                             /* tp_doc */
668
761
    /* gc.get_referents checks the IS_GC flag before it calls tp_traverse
669
762
     * And we don't include this object in the garbage collector because we
767
860
     */
768
861
    set_module = PyImport_ImportModule("bzrlib._simple_set_pyx");
769
862
    if (set_module == NULL) {
770
 
        // fprintf(stderr, "Failed to import bzrlib._simple_set_pyx\n");
771
863
        goto end;
772
864
    }
773
865
    /* Add the _simple_set_pyx into sys.modules at the appropriate location. */
774
866
    sys_module = PyImport_ImportModule("sys");
775
867
    if (sys_module == NULL) {
776
 
        // fprintf(stderr, "Failed to import sys\n");
777
868
        goto end;
778
869
    }
779
870
    modules = PyObject_GetAttrString(sys_module, "modules");
780
871
    if (modules == NULL || !PyDict_Check(modules)) {
781
 
        // fprintf(stderr, "Failed to find sys.modules\n");
782
872
        goto end;
783
873
    }
784
874
    PyDict_SetItemString(modules, "_simple_set_pyx", set_module);
817
907
    setup_empty_tuple(m);
818
908
    setup_c_api(m);
819
909
}
 
910
 
 
911
// vim: tabstop=4 sw=4 expandtab