Пример #1
0
/** Generate all output in LLnextgen style

	This function opens the output files, and writes all necessary output
	to them.
*/
void generateLLgenStyle(void) {
	int i;
	
	openOutputs();
	/* First generate all the default declarations and defines. */
	generateHeaderFile(hOutput);
	generateDefaultGlobalDeclarations(cOutput, NULL);
	/* We do this here, because for LLnextgen style output we don't want this
	   in generateDefaultGlobalDeclarations. */
	if (!option.noLLreissue)
		tfputs(cOutput, "#define LL_NEW_TOKEN (-2)\n");
	generateDirectiveCodeAtEnd(cOutput);
	
	/* These are necessary PER .c file */
	for (i = 0; i < listSize(outputs); i++) {
		FileListItem *lOutput = (FileListItem *) listIndex(outputs, i);
		generateDefaultLocalDeclarations(lOutput->output, hOutput->name);
		generateDirectiveDeclarations(lOutput->output);
	}
	/* Now where ready to generate the code. */
	generateCode();

	closeFile(hOutput, true);
	closeFile(cOutput, true);
	for (i = 0; i < listSize(outputs); i++) {
		FileListItem *lOutput = (FileListItem *) listIndex(outputs, i);
		closeFile(lOutput->output, true);
		free(lOutput);
	}
	deleteList(outputs);
}
Пример #2
0
void lindexCommand(redisClient *c) {
    robj *o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk);
    if (o == NULL || checkType(c,o,REDIS_LIST)) return;
    int index = atoi(c->argv[2]->ptr);
    robj *value = NULL;

    if (o->encoding == REDIS_ENCODING_ZIPLIST) {
        unsigned char *p;
        unsigned char *vstr;
        unsigned int vlen;
        long long vlong;
        p = ziplistIndex(o->ptr,index);
        if (ziplistGet(p,&vstr,&vlen,&vlong)) {
            if (vstr) {
                value = createStringObject((char*)vstr,vlen);
            } else {
                value = createStringObjectFromLongLong(vlong);
            }
            addReplyBulk(c,value);
            decrRefCount(value);
        } else {
            addReply(c,shared.nullbulk);
        }
    } else if (o->encoding == REDIS_ENCODING_LINKEDLIST) {
        listNode *ln = listIndex(o->ptr,index);
        if (ln != NULL) {
            value = listNodeValue(ln);
            addReplyBulk(c,value);
        } else {
            addReply(c,shared.nullbulk);
        }
    } else {
        redisPanic("Unknown list encoding");
    }
}
Пример #3
0
/** Write code for code fragements and @a NonTerminal's to file

	Note: for LLgen style code generation, each @a NonTerminal is written to
	the output file corresponding to the input file in which it was declared.
*/
static void generateCode(void) {
	int i;
	Declaration *declaration;
	FileListItem *output;
	
	for (i = 0; i < listSize(declarations); i++) {
		declaration = (Declaration *) listIndex(declarations, i);
		switch (declaration->subtype) {
			case CODE:
				output = findOutput(declaration->uCode->fileName);
				outputCode(output->output, declaration->uCode, false);
				break;
			case DIRECTIVE:
				/* output = findOutput(declaration->uDirective->token[0]->fileName); */
				break;
			case NONTERMINAL:
				output = findOutput(declaration->uNonTerminal->token->fileName);
				/* Generate the declarations for all generated NonTerminal
				   functions right before the first one (for each file), so we
				   always declare them before use. */
				if (output->firstNonTerminal) {
					output->firstNonTerminal = false;
					generatePrototypes(output->output);
				}
				generateNonTerminalCode(output->output, declaration->uNonTerminal);
				break;
			default:
				PANIC();
		}
	}
}
Пример #4
0
/** Print the alternatives of a @a Term
	@param term The @a Term to print
*/
static void printTerm(Term *term) {
	int i;
	Alternative *alternative;
	for (i = 0; i < listSize(term->rule); i++) {
		alternative = (Alternative *) listIndex(term->rule, i);
		if (listSize(term->rule) != 1)
			printSet("Alternative on", alternative->first);
		if (alternative->flags & ALTERNATIVE_PREFER) {
			printIndent();
			fputs("%prefer\n", printRuleOutput);
		}
		if (alternative->flags & ALTERNATIVE_AVOID) {
			printIndent();
			fputs("%avoid\n", printRuleOutput);
		}
		if (alternative->flags & ALTERNATIVE_IF) {
			printIndent();
			fprintf(printRuleOutput, "%%if %s\n", alternative->expression->text);
		}
		if (alternative->flags & ALTERNATIVE_DEFAULT && listSize(term->rule) != 1) {
			printIndent();
			fputs("%default\n", printRuleOutput);
		}
	
		printAlternative(alternative);
		if (i < listSize(term->rule) - 1) {
			indent--;
			printIndent();
			fputs("|\n", printRuleOutput);
			indent++;
		}
	}
}
Пример #5
0
void lrangeCommand(redisClient *c) {
    robj *o;
    long start, end, llen, rangelen;

    if ((getLongFromObjectOrReply(c, c->argv[2], &start, NULL) != REDIS_OK) ||
        (getLongFromObjectOrReply(c, c->argv[3], &end, NULL) != REDIS_OK)) return;

    if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.emptymultibulk)) == NULL
         || checkType(c,o,REDIS_LIST)) return;
    llen = listTypeLength(o);

    /* convert negative indexes */
    if (start < 0) start = llen+start;
    if (end < 0) end = llen+end;
    if (start < 0) start = 0;

    /* Invariant: start >= 0, so this test will be true when end < 0.
     * The range is empty when start > end or start >= length. */
    if (start > end || start >= llen) {
        addReply(c,shared.emptymultibulk);
        return;
    }
    if (end >= llen) end = llen-1;
    rangelen = (end-start)+1;

    /* Return the result in form of a multi-bulk reply */
    addReplyMultiBulkLen(c,rangelen);
    if (o->encoding == REDIS_ENCODING_ZIPLIST) {
        unsigned char *p = ziplistIndex(o->ptr,start);
        unsigned char *vstr;
        unsigned int vlen;
        long long vlong;

        while(rangelen--) {
            ziplistGet(p,&vstr,&vlen,&vlong);
            if (vstr) {
                addReplyBulkCBuffer(c,vstr,vlen);
            } else {
                addReplyBulkLongLong(c,vlong);
            }
            p = ziplistNext(o->ptr,p);
        }
    } else if (o->encoding == REDIS_ENCODING_LINKEDLIST) {
        listNode *ln;

        /* If we are nearest to the end of the list, reach the element
         * starting from tail and going backward, as it is faster. */
        if (start > llen/2) start -= llen;
        ln = listIndex(o->ptr,start);

        while(rangelen--) {
            addReplyBulk(c,ln->value);
            ln = ln->next;
        }
    } else {
        redisPanic("List encoding is not LINKEDLIST nor ZIPLIST!");
    }
}
Пример #6
0
/* Initialize an iterator at the specified index. */
listTypeIterator *listTypeInitIterator(robj *subject, long index, unsigned char direction) {
    listTypeIterator *li = zmalloc(sizeof(listTypeIterator));
    li->subject = subject;
    li->encoding = subject->encoding;
    li->direction = direction;
    if (li->encoding == REDIS_ENCODING_ZIPLIST) {
        li->zi = ziplistIndex(subject->ptr,index);
    } else if (li->encoding == REDIS_ENCODING_LINKEDLIST) {
        li->ln = listIndex(subject->ptr,index);
    } else {
        redisPanic("Unknown list encoding");
    }
    return li;
}
Пример #7
0
/** Find the output file for the specified input file
	@param filename The name of the input file
*/
static FileListItem *findOutput(const char *inputName) {
	static FileListItem *lastFound = NULL;
	int i;
	
	if (lastFound != NULL && lastFound->sourceFileName == inputName)
		return lastFound;
	
	for (i = 0; i < listSize(outputs); i++) {
		lastFound = (FileListItem *) listIndex(outputs, i);
		if (lastFound->sourceFileName == inputName)
			return lastFound;
	}
	PANIC();
}
Пример #8
0
/** Determine whether a Term contains a conflict
	@a term The Term to check.
*/
static bool termContainsConflict(Term *term) {
	int i;
	Alternative *alternative;
	
	if (term->flags & TERM_RCONFLICT)
		return true;
	
	for (i = 0; i < listSize(term->rule); i++) {
		alternative = (Alternative *) listIndex(term->rule, i);
		if (alternativeContainsConflict(alternative))
			return true;
	}
	return false;
}
Пример #9
0
/** Determine whether an Alternative contains a conflict
	@a alternative The Alternative to check.
*/
static bool alternativeContainsConflict(Alternative *alternative) {
	int i;
	GrammarPart *grammarPart;
	
	if (alternative->flags & ALTERNATIVE_ACONFLICT)
		return true;
	
	for (i = 0; i < listSize(alternative->parts); i++) {
		grammarPart = (GrammarPart *) listIndex(alternative->parts, i);
		if (grammarPart->subtype == PART_TERM &&
				termContainsConflict(&grammarPart->uTerm))
			return true;
	}
	return false;
}
Пример #10
0
/** Print the parts of an @a Alternative
	@param alternative The @a Alternative to print

	Note: actions are printed only as {...}
*/
static void printAlternative(Alternative *alternative) {
	GrammarPart *grammarPart;
	int i;
	
	for (i = 0; i < listSize(alternative->parts); i++) {
		grammarPart = (GrammarPart *) listIndex(alternative->parts, i);
		printIndent();
		switch (grammarPart->subtype) {
			case PART_ACTION:
				fputs("{...}", printRuleOutput);
				break;
			case PART_TERMINAL:
			case PART_LITERAL:
				fputs(grammarPart->token->text, printRuleOutput);
				break;
			case PART_NONTERMINAL:
			case PART_UNDETERMINED:
				fputs(grammarPart->token->text, printRuleOutput);
				break;
			case PART_TERM:
				fputs("[\n", printRuleOutput);
				/* Only print the sets for repeating terms */
				if (!(grammarPart->uTerm.repeats.subtype == FIXED && grammarPart->uTerm.repeats.number == 1)) {
					printSet("First-set", grammarPart->uTerm.first);
					printSet("Contains-set", grammarPart->uTerm.contains);
					printSet("Follow-set", grammarPart->uTerm.follow);
				}
				indent++;
				if (grammarPart->uTerm.flags & TERM_WHILE) {
					printIndent();
					fprintf(printRuleOutput, "%%while %s\n", grammarPart->uTerm.expression->text);
				}
				if (grammarPart->uTerm.flags & TERM_PERSISTENT) {
					printIndent();
					fputs("%persistent\n", printRuleOutput);
				}
				printTerm(&grammarPart->uTerm);
				indent--;
				printIndent();
				fputc(']', printRuleOutput);
				printRepeats(grammarPart->uTerm.repeats);
				break;
			default:
				PANIC();
		}
		fputc('\n', printRuleOutput);
	}
}
Пример #11
0
void lsetCommand(redisClient *c) {
	int slotnum = keyHashSlot(c->argv[1]->ptr, sdslen(c->argv[1]->ptr));
    robj *o = lookupKeyWriteOrReply(c,c->argv[1],shared.nokeyerr,slotnum);
    if (o == NULL || checkType(c,o,REDIS_LIST)) return;
    long index;
    robj *value = (c->argv[3] = tryObjectEncoding(c->argv[3]));

    if ((getLongFromObjectOrReply(c, c->argv[2], &index, NULL) != REDIS_OK))
        return;

    listTypeTryConversion(o,value);
    if (o->encoding == REDIS_ENCODING_ZIPLIST) {
        unsigned char *p, *zl = o->ptr;
        p = ziplistIndex(zl,index);
        if (p == NULL) {
            addReply(c,shared.outofrangeerr);
        } else {
            o->ptr = ziplistDelete(o->ptr,&p);
            value = getDecodedObject(value);
            o->ptr = ziplistInsert(o->ptr,p,value->ptr,sdslen(value->ptr));
            decrRefCount(value);
            addReply(c,shared.ok);
            signalModifiedKey(c->db,c->argv[1],slotnum);
            notifyKeyspaceEvent(REDIS_NOTIFY_LIST,"lset",c->argv[1],c->db->id);
            server.dirty++;
        }
    } else if (o->encoding == REDIS_ENCODING_LINKEDLIST) {
        listNode *ln = listIndex(o->ptr,index);
        if (ln == NULL) {
            addReply(c,shared.outofrangeerr);
        } else {
            decrRefCount((robj*)listNodeValue(ln));
            listNodeValue(ln) = value;
            incrRefCount(value);
            addReply(c,shared.ok);
            signalModifiedKey(c->db,c->argv[1],slotnum);
            notifyKeyspaceEvent(REDIS_NOTIFY_LIST,"lset",c->argv[1],c->db->id);
            server.dirty++;
        }
    } else {
        redisPanic("Unknown list encoding");
    }
}
Пример #12
0
void lsetCommand(redisClient *c) {
    robj *o = lookupKeyWriteOrReply(c,c->argv[1],shared.nokeyerr);
    if (o == NULL || checkType(c,o,REDIS_LIST)) return;
    int index = atoi(c->argv[2]->ptr);
    robj *value = (c->argv[3] = tryObjectEncoding(c->argv[3]));

    listTypeTryConversion(o,value);
    if (o->encoding == REDIS_ENCODING_ZIPLIST) {
        unsigned char *p, *zl = o->ptr;
        p = ziplistIndex(zl,index);
        if (p == NULL) {
            addReply(c,shared.outofrangeerr);
        } else {
            o->ptr = ziplistDelete(o->ptr,&p);
            value = getDecodedObject(value);
            o->ptr = ziplistInsert(o->ptr,p,value->ptr,sdslen(value->ptr));
            decrRefCount(value);
            addReply(c,shared.ok);
            signalModifiedKey(c->db,c->argv[1]);
            server.dirty++;
        }
    } else if (o->encoding == REDIS_ENCODING_LINKEDLIST) {
        listNode *ln = listIndex(o->ptr,index);
        if (ln == NULL) {
            addReply(c,shared.outofrangeerr);
        } else {
            decrRefCount((robj*)listNodeValue(ln));
            listNodeValue(ln) = value;
            incrRefCount(value);
            addReply(c,shared.ok);
            signalModifiedKey(c->db,c->argv[1]);
            server.dirty++;
        }
    } else {
        redisPanic("Unknown list encoding");
    }
}
Пример #13
0
int 
main(int argc, char *argv[])
{
    unsigned char *zl, *p;
    unsigned char *entry;
    unsigned int elen;
    long long value;

    /* If an argument is given, use it as the random seed. */
    if (argc == 2)
        srand(atoi(argv[1]));

    zl = createIntList();
    ziplistRepr(zl);

    zl = createList();
    ziplistRepr(zl);

    pop(zl,ZIPLIST_TAIL);
    ziplistRepr(zl);

    pop(zl,ZIPLIST_HEAD);
    ziplistRepr(zl);

    pop(zl,ZIPLIST_TAIL);
    ziplistRepr(zl);

    pop(zl,ZIPLIST_TAIL);
    ziplistRepr(zl);

    printf("Get element at index 3:\n");
    {
        zl = createList();
        p = ziplistIndex(zl, 3);
        if (!ziplistGet(p, &entry, &elen, &value)) {
            printf("ERROR: Could not access index 3\n");
            return 1;
        }
        if (entry) {
            if (elen && fwrite(entry,elen,1,stdout) == 0) perror("fwrite");
            printf("\n");
        } else {
            printf("%lld\n", value);
        }
        printf("\n");
    }

    printf("Get element at index 4 (out of range):\n");
    {
        zl = createList();
        p = ziplistIndex(zl, 4);
        if (p == NULL) {
            printf("No entry\n");
        } else {
            printf("ERROR: Out of range index should return NULL, returned offset: %ld\n", p-zl);
            return 1;
        }
        printf("\n");
    }

    printf("Get element at index -1 (last element):\n");
    {
        zl = createList();
        p = ziplistIndex(zl, -1);
        if (!ziplistGet(p, &entry, &elen, &value)) {
            printf("ERROR: Could not access index -1\n");
            return 1;
        }
        if (entry) {
            if (elen && fwrite(entry,elen,1,stdout) == 0) perror("fwrite");
            printf("\n");
        } else {
            printf("%lld\n", value);
        }
        printf("\n");
    }

    printf("Get element at index -4 (first element):\n");
    {
        zl = createList();
        p = ziplistIndex(zl, -4);
        if (!ziplistGet(p, &entry, &elen, &value)) {
            printf("ERROR: Could not access index -4\n");
            return 1;
        }
        if (entry) {
            if (elen && fwrite(entry,elen,1,stdout) == 0) perror("fwrite");
            printf("\n");
        } else {
            printf("%lld\n", value);
        }
        printf("\n");
    }

    printf("Get element at index -5 (reverse out of range):\n");
    {
        zl = createList();
        p = ziplistIndex(zl, -5);
        if (p == NULL) {
            printf("No entry\n");
        } else {
            printf("ERROR: Out of range index should return NULL, returned offset: %ld\n", p-zl);
            return 1;
        }
        printf("\n");
    }

    printf("Iterate list from 0 to end:\n");
    {
        zl = createList();
        p = ziplistIndex(zl, 0);
        while (ziplistGet(p, &entry, &elen, &value)) {
            printf("Entry: ");
            if (entry) {
                if (elen && fwrite(entry,elen,1,stdout) == 0) perror("fwrite");
            } else {
                printf("%lld", value);
            }
            p = ziplistNext(zl,p);
            printf("\n");
        }
        printf("\n");
    }

    printf("Iterate list from 1 to end:\n");
    {
        zl = createList();
        p = ziplistIndex(zl, 1);
        while (ziplistGet(p, &entry, &elen, &value)) {
            printf("Entry: ");
            if (entry) {
                if (elen && fwrite(entry,elen,1,stdout) == 0) perror("fwrite");
            } else {
                printf("%lld", value);
            }
            p = ziplistNext(zl,p);
            printf("\n");
        }
        printf("\n");
    }

    printf("Iterate list from 2 to end:\n");
    {
        zl = createList();
        p = ziplistIndex(zl, 2);
        while (ziplistGet(p, &entry, &elen, &value)) {
            printf("Entry: ");
            if (entry) {
                if (elen && fwrite(entry,elen,1,stdout) == 0) perror("fwrite");
            } else {
                printf("%lld", value);
            }
            p = ziplistNext(zl,p);
            printf("\n");
        }
        printf("\n");
    }

    printf("Iterate starting out of range:\n");
    {
        zl = createList();
        p = ziplistIndex(zl, 4);
        if (!ziplistGet(p, &entry, &elen, &value)) {
            printf("No entry\n");
        } else {
            printf("ERROR\n");
        }
        printf("\n");
    }

    printf("Iterate from back to front:\n");
    {
        zl = createList();
        p = ziplistIndex(zl, -1);
        while (ziplistGet(p, &entry, &elen, &value)) {
            printf("Entry: ");
            if (entry) {
                if (elen && fwrite(entry,elen,1,stdout) == 0) perror("fwrite");
            } else {
                printf("%lld", value);
            }
            p = ziplistPrev(zl,p);
            printf("\n");
        }
        printf("\n");
    }

    printf("Iterate from back to front, deleting all items:\n");
    {
        zl = createList();
        p = ziplistIndex(zl, -1);
        while (ziplistGet(p, &entry, &elen, &value)) {
            printf("Entry: ");
            if (entry) {
                if (elen && fwrite(entry,elen,1,stdout) == 0) perror("fwrite");
            } else {
                printf("%lld", value);
            }
            zl = ziplistDelete(zl,&p);
            p = ziplistPrev(zl,p);
            printf("\n");
        }
        printf("\n");
    }

    printf("Delete inclusive range 0,0:\n");
    {
        zl = createList();
        zl = ziplistDeleteRange(zl, 0, 1);
        ziplistRepr(zl);
    }

    printf("Delete inclusive range 0,1:\n");
    {
        zl = createList();
        zl = ziplistDeleteRange(zl, 0, 2);
        ziplistRepr(zl);
    }

    printf("Delete inclusive range 1,2:\n");
    {
        zl = createList();
        zl = ziplistDeleteRange(zl, 1, 2);
        ziplistRepr(zl);
    }

    printf("Delete with start index out of range:\n");
    {
        zl = createList();
        zl = ziplistDeleteRange(zl, 5, 1);
        ziplistRepr(zl);
    }

    printf("Delete with num overflow:\n");
    {
        zl = createList();
        zl = ziplistDeleteRange(zl, 1, 5);
        ziplistRepr(zl);
    }

    printf("Delete foo while iterating:\n");
    {
        zl = createList();
        p = ziplistIndex(zl,0);
        while (ziplistGet(p,&entry,&elen,&value)) {
            if (entry && strncmp("foo",(char*)entry,elen) == 0) {
                printf("Delete foo\n");
                zl = ziplistDelete(zl,&p);
            } else {
                printf("Entry: ");
                if (entry) {
                    if (elen && fwrite(entry,elen,1,stdout) == 0)
                        perror("fwrite");
                } else {
                    printf("%lld",value);
                }
                p = ziplistNext(zl,p);
                printf("\n");
            }
        }
        printf("\n");
        ziplistRepr(zl);
    }

    printf("Regression test for >255 byte strings:\n");
    {
        char v1[257],v2[257];
        memset(v1,'x',256);
        memset(v2,'y',256);
        zl = ziplistNew();
        zl = ziplistPush(zl,(unsigned char*)v1,strlen(v1),ZIPLIST_TAIL);
        zl = ziplistPush(zl,(unsigned char*)v2,strlen(v2),ZIPLIST_TAIL);

        /* Pop values again and compare their value. */
        p = ziplistIndex(zl,0);
        assert(ziplistGet(p,&entry,&elen,&value));
        assert(strncmp(v1,(char*)entry,elen) == 0);
        p = ziplistIndex(zl,1);
        assert(ziplistGet(p,&entry,&elen,&value));
        assert(strncmp(v2,(char*)entry,elen) == 0);
        printf("SUCCESS\n\n");
    }

    printf("Regression test deleting next to last entries:\n");
    {
        char v[3][257];
        zlentry e[3];
        int i;

        for (i = 0; i < (sizeof(v)/sizeof(v[0])); i++) {
            memset(v[i], 'a' + i, sizeof(v[0]));
        }

        v[0][256] = '\0';
        v[1][  1] = '\0';
        v[2][256] = '\0';

        zl = ziplistNew();
        for (i = 0; i < (sizeof(v)/sizeof(v[0])); i++) {
            zl = ziplistPush(zl, (unsigned char *) v[i], strlen(v[i]), ZIPLIST_TAIL);
        }

        verify(zl, e);

        assert(e[0].prevrawlensize == 1);
        assert(e[1].prevrawlensize == 5);
        assert(e[2].prevrawlensize == 1);

        /* Deleting entry 1 will increase `prevrawlensize` for entry 2 */
        unsigned char *p = e[1].p;
        zl = ziplistDelete(zl, &p);

        verify(zl, e);

        assert(e[0].prevrawlensize == 1);
        assert(e[1].prevrawlensize == 5);

        printf("SUCCESS\n\n");
    }

    printf("Create long list and check indices:\n");
    {
        zl = ziplistNew();
        char buf[32];
        int i,len;
        for (i = 0; i < 1000; i++) {
            len = sprintf(buf,"%d",i);
            zl = ziplistPush(zl,(unsigned char*)buf,len,ZIPLIST_TAIL);
        }
        for (i = 0; i < 1000; i++) {
            p = ziplistIndex(zl,i);
            assert(ziplistGet(p,NULL,NULL,&value));
            assert(i == value);

            p = ziplistIndex(zl,-i-1);
            assert(ziplistGet(p,NULL,NULL,&value));
            assert(999-i == value);
        }
        printf("SUCCESS\n\n");
    }

    printf("Compare strings with ziplist entries:\n");
    {
        zl = createList();
        p = ziplistIndex(zl,0);
        if (!ziplistCompare(p,(unsigned char*)"hello",5)) {
            printf("ERROR: not \"hello\"\n");
            return 1;
        }
        if (ziplistCompare(p,(unsigned char*)"hella",5)) {
            printf("ERROR: \"hella\"\n");
            return 1;
        }

        p = ziplistIndex(zl,3);
        if (!ziplistCompare(p,(unsigned char*)"1024",4)) {
            printf("ERROR: not \"1024\"\n");
            return 1;
        }
        if (ziplistCompare(p,(unsigned char*)"1025",4)) {
            printf("ERROR: \"1025\"\n");
            return 1;
        }
        printf("SUCCESS\n\n");
    }

    printf("Stress with random payloads of different encoding:\n");
    {
        int i,j,len,where;
        unsigned char *p;
        char buf[1024];
        int buflen;
        list *ref;
        listNode *refnode;

        /* Hold temp vars from ziplist */
        unsigned char *sstr;
        unsigned int slen;
        long long sval;

        for (i = 0; i < 20000; i++) {
            zl = ziplistNew();
            ref = listCreate();
            listSetFreeMethod(ref, sdsfree);
            len = rand() % 256;

            /* Create lists */
            for (j = 0; j < len; j++) {
                where = (rand() & 1) ? ZIPLIST_HEAD : ZIPLIST_TAIL;
                if (rand() % 2) {
                    buflen = randstring(buf,1,sizeof(buf)-1);
                } else {
                    switch(rand() % 3) {
                    case 0:
                        buflen = sprintf(buf,"%lld",(0LL + rand()) >> 20);
                        break;
                    case 1:
                        buflen = sprintf(buf,"%lld",(0LL + rand()));
                        break;
                    case 2:
                        buflen = sprintf(buf,"%lld",(0LL + rand()) << 20);
                        break;
                    default:
                        assert(NULL);
                    }
                }

                /* Add to ziplist */
                zl = ziplistPush(zl, (unsigned char*)buf, buflen, where);

                /* Add to reference list */
                if (where == ZIPLIST_HEAD) {
                    listAddNodeHead(ref,sdsnewlen(buf, buflen));
                } else if (where == ZIPLIST_TAIL) {
                    listAddNodeTail(ref,sdsnewlen(buf, buflen));
                } else {
                    assert(NULL);
                }
            }

            assert(listLength(ref) == ziplistLen(zl));
            for (j = 0; j < len; j++) {
                /* Naive way to get elements, but similar to the stresser
                 * executed from the Tcl test suite. */
                p = ziplistIndex(zl,j);
                refnode = listIndex(ref,j);

                assert(ziplistGet(p,&sstr,&slen,&sval));
                if (sstr == NULL) {
                    buflen = sprintf(buf,"%lld",sval);
                } else {
                    buflen = slen;
                    memcpy(buf,sstr,buflen);
                    buf[buflen] = '\0';
                }
                assert(memcmp(buf,listNodeValue(refnode),buflen) == 0);
            }
            zfree(zl);
            listRelease(ref);
        }
        printf("SUCCESS\n\n");
    }

    printf("Stress with variable ziplist size:\n");
    {
        stress(ZIPLIST_HEAD,100000,16384,256);
        stress(ZIPLIST_TAIL,100000,16384,256);
    }

    return 0;
}
Пример #14
0
/** Open all required output files
	
	Note: for LLgen output an output file is created for each input file. 
	Further, two files, <prefix>pars.h and <prefix>pars.c, are created.
*/
static void openOutputs(void) {
	const char *cExtension = "c", *hExtension = "h";
	FileListItem *currentItem;
	const char *inputName, *prefixText;
	char *outputName;
	size_t lenPrefix;
	int i;

	if (option.extensions) {
		char *extension = listIndex(option.extensions, 0);
		if (extension != NULL)
			cExtension = extension;
		if (listSize(option.extensions) > 1 && (extension = listIndex(option.extensions, 1)) != NULL)
			hExtension = extension;
	}
	
	outputs = newList();
	
	if (listSize(option.inputFileList) == 0) {
		ASSERT(option.outputBaseName != NULL);
		currentItem = (FileListItem *) safeMalloc(sizeof(FileListItem), "openOutputs");
		/* Note that for LLgen style outputs the use of include files is
		   prohibited, so fileName still points to the string "<stdin>". */
		currentItem->sourceFileName = fileName;
		currentItem->firstNonTerminal = true;
		outputName = createNameWithExtension(option.outputBaseName, cExtension);
		currentItem->output = checkAndOpenFile(outputName, true);
		listAppend(outputs, currentItem);
	} else {
		/* Open the different output files */
		for (i = 0; i < listSize(option.inputFileList); i++) {
			inputName = (const char *) listIndex(option.inputFileList, i);
			
			currentItem = (FileListItem *) safeMalloc(sizeof(FileListItem), "openOutputs");
			currentItem->sourceFileName = inputName;
			/* Set the flag that indicates that we haven't yet generated a
			   NonTerminal */
			currentItem->firstNonTerminal = true;
			
			/* For LLgen style outputs we never keep the directory, as multiple 
			   directories may be present for different files. */
			inputName = baseName(inputName);
			outputName = createNameWithExtension(inputName, cExtension);
			for (i = 0; i < listSize(outputs); i++) {
				FileListItem *itemToCheck = (FileListItem *) listIndex(outputs, i);
				if (strcmp(outputName, itemToCheck->output->name) == 0)
					fatal("Input files %s and %s map to the same output name.\n", itemToCheck->output->name, outputName);
			}
			currentItem->output = checkAndOpenFile(outputName, true);
			listAppend(outputs, currentItem);
		}
	}
	
	/* Open Lpars.h and Lpars.c, or appropriatly prefixed version of them */
	if (prefixDirective == NULL) {
		prefixText = "L";
		lenPrefix = 1;
	} else {
		prefixText = prefixDirective->token[0]->text;
		lenPrefix = strlen(prefixText);
	}

	outputName = (char *) safeMalloc(strlen(prefixText) + 6 + strlen(hExtension), "openOutputs");
	sprintf(outputName, "%spars.%s", prefixText, hExtension);
	hOutput = checkAndOpenFile(outputName, false);
	outputName = (char *) safeMalloc(strlen(prefixText) + 6 + strlen(cExtension), "openOutputs");
	sprintf(outputName, "%spars.%s", prefixText, cExtension);
	cOutput = checkAndOpenFile(outputName, true);
}