/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: Andrew Bennetts
  • Date: 2009-10-28 00:12:03 UTC
  • mfrom: (4774 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4775.
  • Revision ID: andrew.bennetts@canonical.com-20091028001203-m7lgs1wtnilgo3br
Merge lp:bzr, resolving NEWS conflict.

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;
174
180
}
175
181
 
176
182
 
 
183
static StaticTuple *
 
184
StaticTuple_FromSequence(PyObject *sequence)
 
185
{
 
186
    StaticTuple *new = NULL;
 
187
    PyObject *as_tuple = NULL;
 
188
    PyObject *item;
 
189
    Py_ssize_t i, size;
 
190
 
 
191
    if (StaticTuple_CheckExact(sequence)) {
 
192
        Py_INCREF(sequence);
 
193
        return (StaticTuple *)sequence;
 
194
    }
 
195
    if (!PySequence_Check(sequence)) {
 
196
        as_tuple = PySequence_Tuple(sequence);
 
197
        if (as_tuple == NULL)
 
198
            goto done;
 
199
        sequence = as_tuple;
 
200
    }
 
201
    size = PySequence_Size(sequence);
 
202
    if (size == -1) {
 
203
        goto done;
 
204
    }
 
205
    new = StaticTuple_New(size);
 
206
    if (new == NULL) {
 
207
        goto done;
 
208
    }
 
209
    for (i = 0; i < size; ++i) {
 
210
        // This returns a new reference, which we then 'steal' with 
 
211
        // StaticTuple_SET_ITEM
 
212
        item = PySequence_GetItem(sequence, i);
 
213
        if (item == NULL) {
 
214
            Py_DECREF(new);
 
215
            new = NULL;
 
216
            goto done;
 
217
        }
 
218
        StaticTuple_SET_ITEM(new, i, item);
 
219
    }
 
220
done:
 
221
    Py_XDECREF(as_tuple);
 
222
    return (StaticTuple *)new;
 
223
}
 
224
 
 
225
static StaticTuple *
 
226
StaticTuple_from_sequence(PyObject *self, PyObject *args, PyObject *kwargs)
 
227
{
 
228
    PyObject *sequence;
 
229
    if (!PyArg_ParseTuple(args, "O", &sequence))
 
230
        return NULL;
 
231
    return StaticTuple_FromSequence(sequence);
 
232
}
 
233
 
 
234
 
 
235
/* Check that all items we point to are 'valid' */
 
236
static int
 
237
StaticTuple_check_items(StaticTuple *self)
 
238
{
 
239
    int i;
 
240
    PyObject *obj;
 
241
 
 
242
    for (i = 0; i < self->size; ++i) {
 
243
        obj = self->items[i];
 
244
        if (obj == NULL) {
 
245
            PyErr_SetString(PyExc_RuntimeError, "StaticTuple(...)"
 
246
                " should not have a NULL entry.");
 
247
            return 0;
 
248
        }
 
249
        if (PyString_CheckExact(obj)
 
250
            || StaticTuple_CheckExact(obj)
 
251
            || obj == Py_None
 
252
            || PyBool_Check(obj)
 
253
            || PyInt_CheckExact(obj)
 
254
            || PyLong_CheckExact(obj)
 
255
            || PyFloat_CheckExact(obj)
 
256
            || PyUnicode_CheckExact(obj)
 
257
            ) continue;
 
258
        PyErr_Format(PyExc_TypeError, "StaticTuple(...)"
 
259
            " requires that all items are one of"
 
260
            " str, StaticTuple, None, bool, int, long, float, or unicode"
 
261
            " not %s.", Py_TYPE(obj)->tp_name);
 
262
        return 0;
 
263
    }
 
264
    return 1;
 
265
}
 
266
 
177
267
static PyObject *
178
268
StaticTuple_new_constructor(PyTypeObject *type, PyObject *args, PyObject *kwds)
179
269
{
190
280
        return NULL;
191
281
    }
192
282
    len = PyTuple_GET_SIZE(args);
193
 
    if (len < 0 || len > 255) {
194
 
        /* Too big or too small */
195
 
        PyErr_SetString(PyExc_ValueError, "StaticTuple.__init__(...)"
196
 
            " takes from 0 to 255 items");
197
 
        return NULL;
198
 
    }
199
283
    self = (StaticTuple *)StaticTuple_New(len);
200
284
    if (self == NULL) {
201
285
        return NULL;
202
286
    }
203
287
    for (i = 0; i < len; ++i) {
204
288
        obj = PyTuple_GET_ITEM(args, i);
205
 
        if (!PyString_CheckExact(obj)) {
206
 
            if (!StaticTuple_CheckExact(obj)) {
207
 
                PyErr_SetString(PyExc_TypeError, "StaticTuple.__init__(...)"
208
 
                    " requires that all items are strings or StaticTuple.");
209
 
                type->tp_dealloc((PyObject *)self);
210
 
                return NULL;
211
 
            }
212
 
        }
213
289
        Py_INCREF(obj);
214
290
        self->items[i] = obj;
215
291
    }
 
292
    if (!StaticTuple_check_items(self)) {
 
293
        type->tp_dealloc((PyObject *)self);
 
294
        return NULL;
 
295
    }
216
296
    return (PyObject *)self;
217
297
}
218
298
 
230
310
    if (tuple_repr == NULL) {
231
311
        return NULL;
232
312
    }
233
 
    result = PyString_FromFormat("%s%s", Py_TYPE(self)->tp_name,
234
 
                                         PyString_AsString(tuple_repr));
 
313
    result = PyString_FromFormat("StaticTuple%s",
 
314
                                 PyString_AsString(tuple_repr));
235
315
    return result;
236
316
}
237
317
 
411
491
            /* Both are StaticTuple types, so recurse */
412
492
            result = StaticTuple_richcompare(v_obj, w_obj, Py_EQ);
413
493
        } else {
414
 
            /* Not the same type, obviously they won't compare equal */
415
 
            break;
 
494
            /* Fall back to generic richcompare */
 
495
            result = PyObject_RichCompare(v_obj, w_obj, Py_EQ);
416
496
        }
417
497
        if (result == NULL) {
418
498
            return NULL; /* There seems to be an error */
419
499
        }
420
 
        if (result == Py_NotImplemented) {
421
 
            PyErr_BadInternalCall();
422
 
            Py_DECREF(result);
423
 
            return NULL;
424
 
        }
425
500
        if (result == Py_False) {
426
 
            /* This entry is not identical
427
 
             * Shortcut for Py_EQ
428
 
             */
 
501
            // This entry is not identical, Shortcut for Py_EQ
429
502
            if (op == Py_EQ) {
430
503
                return result;
431
504
            }
479
552
        /* Both are StaticTuple types, so recurse */
480
553
        return StaticTuple_richcompare(v_obj, w_obj, op);
481
554
    } else {
482
 
        Py_INCREF(Py_NotImplemented);
483
 
        return Py_NotImplemented;
 
555
        return PyObject_RichCompare(v_obj, w_obj, op);
484
556
    }
485
557
}
486
558
 
508
580
 
509
581
 
510
582
static PyObject *
 
583
StaticTuple_reduce(StaticTuple *self)
 
584
{
 
585
    PyObject *result = NULL, *as_tuple = NULL;
 
586
 
 
587
    result = PyTuple_New(2);
 
588
    if (!result) {
 
589
        return NULL;
 
590
    }
 
591
    as_tuple = StaticTuple_as_tuple(self);
 
592
    if (as_tuple == NULL) {
 
593
        Py_DECREF(result);
 
594
        return NULL;
 
595
    }
 
596
    Py_INCREF(&StaticTuple_Type);
 
597
    PyTuple_SET_ITEM(result, 0, (PyObject *)&StaticTuple_Type);
 
598
    PyTuple_SET_ITEM(result, 1, as_tuple);
 
599
    return result;
 
600
}
 
601
 
 
602
static char StaticTuple_reduce_doc[] = "__reduce__() => tuple\n";
 
603
 
 
604
 
 
605
static PyObject *
 
606
StaticTuple_add(PyObject *v, PyObject *w)
 
607
{
 
608
    Py_ssize_t i, len_v, len_w;
 
609
    PyObject *item;
 
610
    StaticTuple *result;
 
611
     /* StaticTuples and plain tuples may be added (concatenated) to
 
612
      * StaticTuples.
 
613
      */
 
614
    if (StaticTuple_CheckExact(v)) {
 
615
        len_v = ((StaticTuple*)v)->size;
 
616
    } else if (PyTuple_Check(v)) {
 
617
        len_v = PyTuple_GET_SIZE(v);
 
618
    } else {
 
619
        Py_INCREF(Py_NotImplemented);
 
620
        return Py_NotImplemented;
 
621
    }
 
622
    if (StaticTuple_CheckExact(w)) {
 
623
        len_w = ((StaticTuple*)w)->size;
 
624
    } else if (PyTuple_Check(w)) {
 
625
        len_w = PyTuple_GET_SIZE(w);
 
626
    } else {
 
627
        Py_INCREF(Py_NotImplemented);
 
628
        return Py_NotImplemented;
 
629
    }
 
630
    result = StaticTuple_New(len_v + len_w);
 
631
    if (result == NULL)
 
632
        return NULL;
 
633
    for (i = 0; i < len_v; ++i) {
 
634
        // This returns a new reference, which we then 'steal' with 
 
635
        // StaticTuple_SET_ITEM
 
636
        item = PySequence_GetItem(v, i);
 
637
        if (item == NULL) {
 
638
            Py_DECREF(result);
 
639
            return NULL;
 
640
        }
 
641
        StaticTuple_SET_ITEM(result, i, item);
 
642
    }
 
643
    for (i = 0; i < len_w; ++i) {
 
644
        item = PySequence_GetItem(w, i);
 
645
        if (item == NULL) {
 
646
            Py_DECREF(result);
 
647
            return NULL;
 
648
        }
 
649
        StaticTuple_SET_ITEM(result, i+len_v, item);
 
650
    }
 
651
    if (!StaticTuple_check_items(result)) {
 
652
        Py_DECREF(result);
 
653
        return NULL;
 
654
    }
 
655
    return (PyObject *)result;
 
656
}
 
657
 
 
658
static PyObject *
511
659
StaticTuple_item(StaticTuple *self, Py_ssize_t offset)
512
660
{
513
661
    PyObject *obj;
565
713
    {"intern", (PyCFunction)StaticTuple_Intern, METH_NOARGS, StaticTuple_Intern_doc},
566
714
    {"_is_interned", (PyCFunction)StaticTuple__is_interned, METH_NOARGS,
567
715
     StaticTuple__is_interned_doc},
 
716
    {"from_sequence", (PyCFunction)StaticTuple_from_sequence,
 
717
     METH_STATIC | METH_VARARGS,
 
718
     "Create a StaticTuple from a given sequence. This functions"
 
719
     " the same as the tuple() constructor."},
 
720
    {"__reduce__", (PyCFunction)StaticTuple_reduce, METH_NOARGS, StaticTuple_reduce_doc},
568
721
    {NULL, NULL} /* sentinel */
569
722
};
570
723
 
 
724
 
 
725
static PyNumberMethods StaticTuple_as_number = {
 
726
    (binaryfunc) StaticTuple_add,   /* nb_add */
 
727
    0,                              /* nb_subtract */
 
728
    0,                              /* nb_multiply */
 
729
    0,                              /* nb_divide */
 
730
    0,                              /* nb_remainder */
 
731
    0,                              /* nb_divmod */
 
732
    0,                              /* nb_power */
 
733
    0,                              /* nb_negative */
 
734
    0,                              /* nb_positive */
 
735
    0,                              /* nb_absolute */
 
736
    0,                              /* nb_nonzero */
 
737
    0,                              /* nb_invert */
 
738
    0,                              /* nb_lshift */
 
739
    0,                              /* nb_rshift */
 
740
    0,                              /* nb_and */
 
741
    0,                              /* nb_xor */
 
742
    0,                              /* nb_or */
 
743
    0,                              /* nb_coerce */
 
744
};
 
745
    
 
746
 
571
747
static PySequenceMethods StaticTuple_as_sequence = {
572
748
    (lenfunc)StaticTuple_length,            /* sq_length */
573
749
    0,                              /* sq_concat */
589
765
PyTypeObject StaticTuple_Type = {
590
766
    PyObject_HEAD_INIT(NULL)
591
767
    0,                                           /* ob_size */
592
 
    "StaticTuple",                               /* tp_name */
 
768
    "bzrlib._static_tuple_c.StaticTuple",        /* tp_name */
593
769
    sizeof(StaticTuple),                         /* tp_basicsize */
594
770
    sizeof(PyObject *),                          /* tp_itemsize */
595
771
    (destructor)StaticTuple_dealloc,             /* tp_dealloc */
598
774
    0,                                           /* tp_setattr */
599
775
    0,                                           /* tp_compare */
600
776
    (reprfunc)StaticTuple_repr,                  /* tp_repr */
601
 
    0,                                           /* tp_as_number */
 
777
    &StaticTuple_as_number,                      /* tp_as_number */
602
778
    &StaticTuple_as_sequence,                    /* tp_as_sequence */
603
779
    0,                                           /* tp_as_mapping */
604
780
    (hashfunc)StaticTuple_hash,                  /* tp_hash */
605
781
    0,                                           /* tp_call */
606
782
    0,                                           /* tp_str */
607
 
    PyObject_GenericGetAttr,                     /* tp_getattro */
 
783
    0,                                           /* tp_getattro */
608
784
    0,                                           /* tp_setattro */
609
785
    0,                                           /* tp_as_buffer */
610
 
    Py_TPFLAGS_DEFAULT,                          /* tp_flags*/
 
786
    /* Py_TPFLAGS_CHECKTYPES tells the number operations that they shouldn't
 
787
     * try to 'coerce' but instead stuff like 'add' will check it arguments.
 
788
     */
 
789
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES,  /* tp_flags*/
611
790
    StaticTuple_doc,                             /* tp_doc */
612
791
    /* gc.get_referents checks the IS_GC flag before it calls tp_traverse
613
792
     * And we don't include this object in the garbage collector because we
684
863
        "StaticTuple *(Py_ssize_t)");
685
864
    _export_function(m, "StaticTuple_Intern", StaticTuple_Intern,
686
865
        "StaticTuple *(StaticTuple *)");
 
866
    _export_function(m, "StaticTuple_FromSequence", StaticTuple_FromSequence,
 
867
        "StaticTuple *(PyObject *)");
687
868
    _export_function(m, "_StaticTuple_CheckExact", _StaticTuple_CheckExact,
688
869
        "int(PyObject *)");
689
870
}
709
890
     */
710
891
    set_module = PyImport_ImportModule("bzrlib._simple_set_pyx");
711
892
    if (set_module == NULL) {
712
 
        // fprintf(stderr, "Failed to import bzrlib._simple_set_pyx\n");
713
893
        goto end;
714
894
    }
715
895
    /* Add the _simple_set_pyx into sys.modules at the appropriate location. */
716
896
    sys_module = PyImport_ImportModule("sys");
717
897
    if (sys_module == NULL) {
718
 
        // fprintf(stderr, "Failed to import sys\n");
719
898
        goto end;
720
899
    }
721
900
    modules = PyObject_GetAttrString(sys_module, "modules");
722
901
    if (modules == NULL || !PyDict_Check(modules)) {
723
 
        // fprintf(stderr, "Failed to find sys.modules\n");
724
902
        goto end;
725
903
    }
726
904
    PyDict_SetItemString(modules, "_simple_set_pyx", set_module);
739
917
{
740
918
    PyObject* m;
741
919
 
 
920
    StaticTuple_Type.tp_getattro = PyObject_GenericGetAttr;
742
921
    if (PyType_Ready(&StaticTuple_Type) < 0)
743
922
        return;
744
923
 
758
937
    setup_empty_tuple(m);
759
938
    setup_c_api(m);
760
939
}
 
940
 
 
941
// vim: tabstop=4 sw=4 expandtab