View | Details | Raw Unified | Return to bug 17284 | Differences between
and this patch

Collapse All | Expand All

(-)bind.c (-30 / +58 lines)
Lines 1-8 Link Here
1
/*
1
/*
2
 *  R : A Computer Language for Statistical Data Analysis
2
 *  R : A Computer Language for Statistical Data Analysis
3
 *  Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
3
 *  Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
4
 *  Copyright (C) 1997--2016  The R Core Team
4
 *  Copyright (C) 1997--2017  The R Core Team
5
 *  Copyright (C) 2002--2016  The R Foundation
5
 *  Copyright (C) 2002--2017  The R Foundation
6
 *
6
 *
7
 *  This program is free software; you can redistribute it and/or modify
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
8
 *  it under the terms of the GNU General Public License as published by
Lines 508-517 Link Here
508
    return ans;
508
    return ans;
509
}
509
}
510
510
511
static SEXP NewName(SEXP base, SEXP tag, int seqno)
511
static SEXP NewName(SEXP base, SEXP tag, int seqno, int count)
512
{
512
{
513
/* Construct a new Name/Tag, using
513
/* Construct a new Name/Tag, using
514
 *	base.tag
514
 *	base.tag
515
 *	base
515
 *	base<seqno>	or
516
 *	base<seqno>	or
516
 *	tag
517
 *	tag
517
 *
518
 *
Lines 529-534 Link Here
529
	ans = mkCharCE(cbuf, CE_UTF8);
530
	ans = mkCharCE(cbuf, CE_UTF8);
530
	vmaxset(vmax);
531
	vmaxset(vmax);
531
    }
532
    }
533
    else if (*CHAR(base) && count == 1) ans = base;
532
    else if (*CHAR(base)) {
534
    else if (*CHAR(base)) {
533
	const void *vmax = vmaxget();
535
	const void *vmax = vmaxget();
534
	const char *sb = translateCharUTF8(base);
536
	const char *sb = translateCharUTF8(base);
Lines 568-595 Link Here
568
struct NameData {
570
struct NameData {
569
 int count;
571
 int count;
570
 int seqno;
572
 int seqno;
571
 int firstpos;
572
};
573
};
573
574
574
575
576
static void NewCount(SEXP v, int recurse, struct NameData *nameData)
577
{
578
    SEXP names, namei;
579
    R_xlen_t i, n;
580
581
    n = xlength(v);
582
    PROTECT(names = getAttrib(v, R_NamesSymbol));
583
584
    switch(TYPEOF(v)) {
585
    case NILSXP:
586
	break;
587
    case LISTSXP:
588
	if (recurse) {
589
	    for (i = 0; i < n && nameData->count <= 1; i++) {
590
		PROTECT(namei = ItemName(names, i));
591
		if (namei == R_NilValue)
592
		    NewCount(CAR(v), recurse, nameData);
593
		v = CDR(v);
594
		UNPROTECT(1); /*namei*/
595
	    }
596
	    break;
597
	} /* else fall through */
598
    case VECSXP:
599
    case EXPRSXP:
600
	if (recurse) {
601
	    for (i = 0; i < n && nameData->count <= 1; i++) {
602
		namei = ItemName(names, i);
603
		if (namei == R_NilValue)
604
		    NewCount(VECTOR_ELT(v, i), recurse, nameData);
605
	    }
606
	    break;
607
	} /* else fall through */
608
    case LGLSXP:
609
    case INTSXP:
610
    case REALSXP:
611
    case CPLXSXP:
612
    case STRSXP:
613
    case RAWSXP:
614
	for (i = 0; i < n && nameData->count <= 1; i++)
615
	    nameData->count++;
616
	break;
617
    default:
618
	nameData->count++;
619
    }
620
    UNPROTECT(1); /*names*/
621
}
622
575
static void NewExtractNames(SEXP v, SEXP base, SEXP tag, int recurse,
623
static void NewExtractNames(SEXP v, SEXP base, SEXP tag, int recurse,
576
			     struct BindData *data, struct NameData *nameData)
624
			     struct BindData *data, struct NameData *nameData)
577
{
625
{
578
    SEXP names, namei;
626
    SEXP names, namei;
579
    R_xlen_t i, n;
627
    R_xlen_t i, n;
580
    int savecount=0, saveseqno, savefirstpos=0;
628
    int savecount=0, saveseqno;
581
629
582
    /* If we beneath a new tag, we reset the index */
630
    /* If we beneath a new tag, we reset the index */
583
    /* sequence and create the new basename string. */
631
    /* sequence and create the new basename string. */
584
632
585
    if (tag != R_NilValue) {
633
    if (tag != R_NilValue) {
586
	PROTECT(base = NewBase(base, tag));
634
	PROTECT(base = NewBase(base, tag));
587
	savefirstpos = nameData->firstpos;
588
	saveseqno = nameData->seqno;
635
	saveseqno = nameData->seqno;
589
	savecount = nameData->count;
636
	savecount = nameData->count;
590
	nameData->count = 0;
637
	nameData->count = 0;
638
	NewCount(v, recurse, nameData);
591
	nameData->seqno = 0;
639
	nameData->seqno = 0;
592
	nameData->firstpos = -1;
593
    }
640
    }
594
    else saveseqno = 0;
641
    else saveseqno = 0;
595
642
Lines 606-615 Link Here
606
		NewExtractNames(CAR(v), base, namei, recurse, data, nameData);
653
		NewExtractNames(CAR(v), base, namei, recurse, data, nameData);
607
	    }
654
	    }
608
	    else {
655
	    else {
609
		if (namei == R_NilValue && nameData->count == 0)
656
		namei = NewName(base, namei, ++(nameData->seqno), nameData->count);
610
		    nameData->firstpos = data->ans_nnames;
611
		nameData->count++;
612
		namei = NewName(base, namei, ++(nameData->seqno));
613
		SET_STRING_ELT(data->ans_names, (data->ans_nnames)++, namei);
657
		SET_STRING_ELT(data->ans_names, (data->ans_nnames)++, namei);
614
	    }
658
	    }
615
	    v = CDR(v);
659
	    v = CDR(v);
Lines 624-633 Link Here
624
		NewExtractNames(VECTOR_ELT(v, i), base, namei, recurse, data, nameData);
668
		NewExtractNames(VECTOR_ELT(v, i), base, namei, recurse, data, nameData);
625
	    }
669
	    }
626
	    else {
670
	    else {
627
		if (namei == R_NilValue && nameData->count == 0)
671
		namei = NewName(base, namei, ++(nameData->seqno), nameData->count);
628
		    nameData->firstpos = data->ans_nnames;
629
		nameData->count++;
630
		namei = NewName(base, namei, ++(nameData->seqno));
631
		SET_STRING_ELT(data->ans_names, (data->ans_nnames)++, namei);
672
		SET_STRING_ELT(data->ans_names, (data->ans_nnames)++, namei);
632
	    }
673
	    }
633
	}
674
	}
Lines 640-663 Link Here
640
    case RAWSXP:
681
    case RAWSXP:
641
	for (i = 0; i < n; i++) {
682
	for (i = 0; i < n; i++) {
642
	    namei = ItemName(names, i);
683
	    namei = ItemName(names, i);
643
	    if (namei == R_NilValue && nameData->count == 0)
684
	    namei = NewName(base, namei, ++(nameData->seqno), nameData->count);
644
		nameData->firstpos = data->ans_nnames;
645
	    nameData->count++;
646
	    namei = NewName(base, namei, ++(nameData->seqno));
647
	    SET_STRING_ELT(data->ans_names, (data->ans_nnames)++, namei);
685
	    SET_STRING_ELT(data->ans_names, (data->ans_nnames)++, namei);
648
	}
686
	}
649
	break;
687
	break;
650
    default:
688
    default:
651
	if (nameData->count == 0)
689
	namei = NewName(base, R_NilValue, ++(nameData->seqno), nameData->count);
652
	    nameData->firstpos = data->ans_nnames;
653
	nameData->count++;
654
	namei = NewName(base, R_NilValue, ++(nameData->seqno));
655
	SET_STRING_ELT(data->ans_names, (data->ans_nnames)++, namei);
690
	SET_STRING_ELT(data->ans_names, (data->ans_nnames)++, namei);
656
    }
691
    }
657
    if (tag != R_NilValue) {
692
    if (tag != R_NilValue) {
658
	if (nameData->firstpos >= 0 && nameData->count == 1)
659
	    SET_STRING_ELT(data->ans_names, nameData->firstpos, base);
660
	nameData->firstpos = savefirstpos;
661
	nameData->count = savecount;
693
	nameData->count = savecount;
662
	UNPROTECT(1);
694
	UNPROTECT(1);
663
    }
695
    }
Lines 822-828 Link Here
822
	while (args != R_NilValue) {
854
	while (args != R_NilValue) {
823
	    struct NameData nameData;
855
	    struct NameData nameData;
824
	    nameData.seqno = 0;
856
	    nameData.seqno = 0;
825
	    nameData.firstpos = 0;
826
	    nameData.count = 0;
857
	    nameData.count = 0;
827
	    NewExtractNames(CAR(args), R_NilValue, TAG(args), recurse, &data, &nameData);
858
	    NewExtractNames(CAR(args), R_NilValue, TAG(args), recurse, &data, &nameData);
828
	    args = CDR(args);
859
	    args = CDR(args);
Lines 946-952 Link Here
946
		SEXP names = getAttrib(args, R_NamesSymbol);
977
		SEXP names = getAttrib(args, R_NamesSymbol);
947
		data.ans_nnames = 0;
978
		data.ans_nnames = 0;
948
		nameData.seqno = 0;
979
		nameData.seqno = 0;
949
		nameData.firstpos = 0;
950
		nameData.count = 0;
980
		nameData.count = 0;
951
		for (i = 0; i < n; i++) {
981
		for (i = 0; i < n; i++) {
952
		    NewExtractNames(VECTOR_ELT(args, i), R_NilValue,
982
		    NewExtractNames(VECTOR_ELT(args, i), R_NilValue,
Lines 956-962 Link Here
956
	    else if (TYPEOF(args) == LISTSXP) {
986
	    else if (TYPEOF(args) == LISTSXP) {
957
		data.ans_nnames = 0;
987
		data.ans_nnames = 0;
958
		nameData.seqno = 0;
988
		nameData.seqno = 0;
959
		nameData.firstpos = 0;
960
		nameData.count = 0;
989
		nameData.count = 0;
961
		while (args != R_NilValue) {
990
		while (args != R_NilValue) {
962
		    NewExtractNames(CAR(args), R_NilValue,
991
		    NewExtractNames(CAR(args), R_NilValue,
Lines 968-974 Link Here
968
	else {
997
	else {
969
	    data.ans_nnames = 0;
998
	    data.ans_nnames = 0;
970
	    nameData.seqno = 0;
999
	    nameData.seqno = 0;
971
	    nameData.firstpos = 0;
972
	    nameData.count = 0;
1000
	    nameData.count = 0;
973
	    NewExtractNames(args, R_NilValue, R_NilValue, recurse, &data, &nameData);
1001
	    NewExtractNames(args, R_NilValue, R_NilValue, recurse, &data, &nameData);
974
	}
1002
	}

Return to bug 17284