コード例 #1
0
/*
 * substitute the argument list into the replacement string
 *  This would be simple except for ## and #
 */
void
substargs(Nlist* np, Tokenrow* rtr, Tokenrow** atr) {
    Tokenrow tatr;
    Token* tp;
    int ntok, argno;

    for (rtr->tp = rtr->bp; rtr->tp < rtr->lp;) {
        if (rtr->tp->type == SHARP) { /* string operator */
            tp = rtr->tp;
            rtr->tp += 1;
            if ((argno = lookuparg(np, rtr->tp)) < 0) {
                error(ERROR, "# not followed by macro parameter");
                continue;
            }
            ntok = 1 + (rtr->tp - tp);
            rtr->tp = tp;
            insertrow(rtr, ntok, stringify(atr[argno]));
            continue;
        }
        if (rtr->tp->type == NAME
                && (argno = lookuparg(np, rtr->tp)) >= 0) {
            if ((rtr->tp + 1)->type == DSHARP
                    || (rtr->tp != rtr->bp && (rtr->tp - 1)->type == DSHARP))
                insertrow(rtr, 1, atr[argno]);
            else {
                copytokenrow(&tatr, atr[argno]);
                expandrow(&tatr, "<macro>");
                insertrow(rtr, 1, &tatr);
                dofree(tatr.bp);
            }
            continue;
        }
        rtr->tp++;
    }
}
コード例 #2
0
ファイル: cpp.c プロジェクト: GrangerHub/tremulous
void process(Tokenrow *trp)
{
    int anymacros = 0;

    for (;;)
    {
        if (trp->tp >= trp->lp)
        {
            trp->tp = trp->lp = trp->bp;
            outbufp = outbuf;
            anymacros |= gettokens(trp, 1);
            trp->tp = trp->bp;
        }
        if (trp->tp->type == END)
        {
            if (--incdepth >= 0)
            {
                if (cursource->ifdepth)
                    error(ERROR, "Unterminated conditional in #include");
                unsetsource();
                cursource->line += cursource->lineinc;
                trp->tp = trp->lp;
                genline();
                continue;
            }
            if (ifdepth)
                error(ERROR, "Unterminated #if/#ifdef/#ifndef");
            break;
        }
        if (trp->tp->type == SHARP)
        {
            trp->tp += 1;
            control(trp);
        }
        else if (!skipping && anymacros)
            expandrow(trp, NULL);
        if (skipping)
            setempty(trp);
        puttokens(trp);
        anymacros = 0;
        cursource->line += cursource->lineinc;
        if (cursource->lineinc > 1)
        {
            genline();
        }
    }
}
コード例 #3
0
ファイル: cpp.c プロジェクト: nikon77/lcc42
/**
 * process - 处理c源程序的总函数
 * @trp: 用来存储c源程序中的一行Token
 */
void process(Tokenrow *trp) {
	int anymacros = 0;

	for (;;) {
		if (trp->tp >= trp->lp) { /* 如果当前token row中没有有效数据 */
			trp->tp = trp->lp = trp->bp; /* 重置token row的当前token指针 */
			outp = outbuf; /* 重置输出缓冲区的当前指针 */
			anymacros |= gettokens(trp, 1); /* 得到一行Token */
			trp->tp = trp->bp;
		}
		if (trp->tp->type == END) { /* 如果遇到EOFC结束符 */
			if (--incdepth >= 0) {
				if (cursource->ifdepth)
					error(ERROR,"Unterminated conditional in #include");
				unsetsource();
				cursource->line += cursource->lineinc;
				trp->tp = trp->lp;
				genline();
				continue;
			}
			if (ifdepth)
				error(ERROR, "Unterminated #if/#ifdef/#ifndef");
			break;
		}
		if (trp->tp->type==SHARP) { /* 如果当前Token是'#'字符 */
			trp->tp += 1; /* tp移动到token row中的下一个token */
			control(trp); /* 处理预处理指令部分(宏定义,条件编译,头文件包含) */
		} else if (!skipping && anymacros)
			expandrow(trp, NULL);
		if (skipping) /* 如果当前是忽略状态 */
			setempty(trp); /* 置空当前行 */
		puttokens(trp); /* 输出当前行 */
		anymacros = 0;
		cursource->line += cursource->lineinc;
		if (cursource->lineinc>1) {
			genline();
		}
	}
}
コード例 #4
0
ファイル: vd_sgi.c プロジェクト: NeeMeese/mplayer-ce
/* decode a run length encoded sgi image */
static void
decode_rle_sgi(SGIInfo *info, unsigned char *data, mp_image_t *mpi)
{
  unsigned char *rle_data, *dest_row;
  uint32_t *starttab;
  int y, z, xsize, ysize, zsize, chan_offset;
  long start_offset;

  xsize = info->xsize;
  ysize = info->ysize;
  zsize = info->zsize;

  /* rle offset table is right after the header */
  starttab = (uint32_t*)(data + SGI_HEADER_LEN);

   for (z = 0; z < zsize; z++) {

     /* set chan_offset so RGB ends up BGR */
     chan_offset = (zsize - 1) - z;

     /* The origin for SGI images is the lower-left corner
        so read scan lines from bottom to top */
     for (y = ysize - 1; y >= 0; y--) {
       dest_row = mpi->planes[0] + mpi->stride[0] * (ysize - 1 - y);

      /* set start of next run (offsets are from start of header) */
      start_offset = AV_RB32(&starttab[y + z * ysize]);

      rle_data = &data[start_offset];

      if(info->zsize == SGI_GRAYSCALE_IMAGE) {
        expandrow_gs(dest_row, rle_data);
      } else {
        expandrow(dest_row, rle_data, chan_offset);
      }
    }
  }
}
コード例 #5
0
ファイル: eval.c プロジェクト: DevenLu/lcc
/*
 * Evaluate an #if #elif #ifdef #ifndef line.  trp->tp points to the keyword.
 */
long
eval(Tokenrow *trp, int kw)
{
	Token *tp;
	Nlist *np;
	int ntok, rand;

	trp->tp++;
	if (kw==KIFDEF || kw==KIFNDEF) {
		if (trp->lp - trp->bp != 4 || trp->tp->type!=NAME) {
			error(ERROR, "Syntax error in #ifdef/#ifndef");
			return 0;
		}
		np = lookup(trp->tp, 0);
		return (kw==KIFDEF) == (np && np->flag&(ISDEFINED|ISMAC));
	}
	ntok = trp->tp - trp->bp;
	kwdefined->val = KDEFINED;	/* activate special meaning of defined */
	expandrow(trp, "<if>");
	kwdefined->val = NAME;
	vp = vals;
	op = ops;
	*op++ = END;
	for (rand=0, tp = trp->bp+ntok; tp < trp->lp; tp++) {
		switch(tp->type) {
		case WS:
		case NL:
			continue;

		/* nilary */
		case NAME:
		case NAME1:
		case NUMBER:
		case CCON:
		case STRING:
			if (rand)
				goto syntax;
			if (vp == &vals[NSTAK]) {
				error(ERROR, "Eval botch (stack overflow)");
				return 0;
			}
			*vp++ = tokval(tp);
			rand = 1;
			continue;

		/* unary */
		case DEFINED:
		case TILDE:
		case NOT:
			if (rand)
				goto syntax;
			*op++ = tp->type;
			continue;

		/* unary-binary */
		case PLUS: case MINUS: case STAR: case AND:
			if (rand==0) {
				if (tp->type==MINUS)
					*op++ = UMINUS;
				if (tp->type==STAR || tp->type==AND) {
					error(ERROR, "Illegal operator * or & in #if/#elsif");
					return 0;
				}
				continue;
			}
			/* flow through */

		/* plain binary */
		case EQ: case NEQ: case LEQ: case GEQ: case LSH: case RSH:
		case LAND: case LOR: case SLASH: case PCT:
		case LT: case GT: case CIRC: case OR: case QUEST:
		case COLON: case COMMA:
			if (rand==0)
				goto syntax;
			if (evalop(priority[tp->type])!=0)
				return 0;
			*op++ = tp->type;
			rand = 0;
			continue;

		case LP:
			if (rand)
				goto syntax;
			*op++ = LP;
			continue;

		case RP:
			if (!rand)
				goto syntax;
			if (evalop(priority[RP])!=0)
				return 0;
			if (op<=ops || op[-1]!=LP) {
				goto syntax;
			}
			op--;
			continue;

		default:
			error(ERROR,"Bad operator (%t) in #if/#elsif", tp);
			return 0;
		}
	}
	if (rand==0)
		goto syntax;
	if (evalop(priority[END])!=0)
		return 0;
	if (op!=&ops[1] || vp!=&vals[1]) {
		error(ERROR, "Botch in #if/#elsif");
		return 0;
	}
	if (vals[0].type==UND)
		error(ERROR, "Undefined expression value");
	return vals[0].val;
syntax:
	error(ERROR, "Syntax error in #if/#elsif");
	return 0;
}
コード例 #6
0
ファイル: cpp.c プロジェクト: angeld29/TF2003-qvm
void
control(Tokenrow *trp)
{
	Nlist *np;
	Token *tp;

	tp = trp->tp;
	if (tp->type!=NAME) {
		if (tp->type==NUMBER)
			goto kline;
		if (tp->type != NL)
			error(ERROR, "Unidentifiable control line");
		return;			/* else empty line */
	}
	if ((np = lookup(tp, 0))==NULL || (np->flag&ISKW)==0 && !skipping) {
		error(WARNING, "Unknown preprocessor control %t", tp);
		return;
	}
	if (skipping) {
		if ((np->flag&ISKW)==0)
			return;
		switch (np->val) {
		case KENDIF:
			if (--ifdepth<skipping)
				skipping = 0;
			--cursource->ifdepth;
			setempty(trp);
			return;

		case KIFDEF:
		case KIFNDEF:
		case KIF:
			if (++ifdepth >= NIF)
				error(FATAL, "#if too deeply nested");
			++cursource->ifdepth;
			return;

		case KELIF:
		case KELSE:
			if (ifdepth<=skipping)
				break;
			return;

		default:
			return;
		}
	}
	switch (np->val) {
	case KDEFINE:
		dodefine(trp);
		break;

	case KUNDEF:
		tp += 1;
		if (tp->type!=NAME || trp->lp - trp->bp != 4) {
			error(ERROR, "Syntax error in #undef");
			break;
		}
		if ((np = lookup(tp, 0)) != NULL)
			np->flag &= ~ISDEFINED;
		break;

	case KPRAGMA:
		return;

	case KIFDEF:
	case KIFNDEF:
	case KIF:
		if (++ifdepth >= NIF)
			error(FATAL, "#if too deeply nested");
		++cursource->ifdepth;
		ifsatisfied[ifdepth] = 0;
		if (eval(trp, np->val))
			ifsatisfied[ifdepth] = 1;
		else
			skipping = ifdepth;
		break;

	case KELIF:
		if (ifdepth==0) {
			error(ERROR, "#elif with no #if");
			return;
		}
		if (ifsatisfied[ifdepth]==2)
			error(ERROR, "#elif after #else");
		if (eval(trp, np->val)) {
			if (ifsatisfied[ifdepth])
				skipping = ifdepth;
			else {
				skipping = 0;
				ifsatisfied[ifdepth] = 1;
			}
		} else
			skipping = ifdepth;
		break;

	case KELSE:
		if (ifdepth==0 || cursource->ifdepth==0) {
			error(ERROR, "#else with no #if");
			return;
		}
		if (ifsatisfied[ifdepth]==2)
			error(ERROR, "#else after #else");
		if (trp->lp - trp->bp != 3)
			error(ERROR, "Syntax error in #else");
		skipping = ifsatisfied[ifdepth]? ifdepth: 0;
		ifsatisfied[ifdepth] = 2;
		break;

	case KENDIF:
		if (ifdepth==0 || cursource->ifdepth==0) {
			error(ERROR, "#endif with no #if");
			return;
		}
		--ifdepth;
		--cursource->ifdepth;
		if (trp->lp - trp->bp != 3)
			error(WARNING, "Syntax error in #endif");
		break;

	case KERROR:
		trp->tp = tp+1;
		error(WARNING, "#error directive: %r", trp);
		break;

	case KLINE:
		trp->tp = tp+1;
		expandrow(trp, "<line>");
		tp = trp->bp+2;
	kline:
		if (tp+1>=trp->lp || tp->type!=NUMBER || tp+3<trp->lp
		 || (tp+3==trp->lp && ((tp+1)->type!=STRING)||*(tp+1)->t=='L')){
			error(ERROR, "Syntax error in #line");
			return;
		}
		cursource->line = atol((char*)tp->t)-1;
		if (cursource->line<0 || cursource->line>=32768)
			error(WARNING, "#line specifies number out of range");
		tp = tp+1;
		if (tp+1<trp->lp)
			cursource->filename=(char*)newstring(tp->t+1,tp->len-2,0);
		return;

	case KDEFINED:
		error(ERROR, "Bad syntax for control line");
		break;

	case KINCLUDE:
		doinclude(trp);
		trp->lp = trp->bp;
		return;

	case KEVAL:
		eval(trp, np->val);
		break;

	default:
		error(ERROR, "Preprocessor control `%t' not yet implemented", tp);
		break;
	}
	setempty(trp);
	return;
}
コード例 #7
0
void
doinclude(Tokenrow* trp) {
    char fname[256], iname[256];
    Includelist* ip;
    int angled, len, fd, i;

    trp->tp += 1;
    if (trp->tp >= trp->lp)
        goto syntax;
    if (trp->tp->type != STRING && trp->tp->type != LT) {
        len = trp->tp - trp->bp;
        expandrow(trp, "<include>");
        trp->tp = trp->bp + len;
    }
    if (trp->tp->type == STRING) {
        len = trp->tp->len - 2;
        if (len > sizeof(fname) - 1)
            len = sizeof(fname) - 1;
        strncpy(fname, (char*)trp->tp->t + 1, len);
        angled = 0;
    } else if (trp->tp->type == LT) {
        len = 0;
        trp->tp++;
        while (trp->tp->type != GT) {
            if (trp->tp > trp->lp || len + trp->tp->len + 2 >= sizeof(fname))
                goto syntax;
            strncpy(fname + len, (char*)trp->tp->t, trp->tp->len);
            len += trp->tp->len;
            trp->tp++;
        }
        angled = 1;
    } else
        goto syntax;
    trp->tp += 2;
    if (trp->tp < trp->lp || len == 0)
        goto syntax;
    fname[len] = '\0';

    appendDirToIncludeList(basepath(fname));

    if (fname[0] == '/') {
        fd = open(fname, 0);
        strcpy(iname, fname);
    } else for (fd = -1, i = NINCLUDE - 1; i >= 0; i--) {
            ip = &includelist[i];
            if (ip->file == NULL || ip->deleted || (angled && ip->always == 0))
                continue;
            if (strlen(fname) + strlen(ip->file) + 2 > sizeof(iname))
                continue;
            strcpy(iname, ip->file);
            strcat(iname, "/");
            strcat(iname, fname);
            if ((fd = open(iname, 0)) >= 0)
                break;
        }
    if (Mflag > 1 || (!angled && Mflag == 1)) {
        write(1, objname, strlen(objname));
        write(1, iname, strlen(iname));
        write(1, "\n", 1);
    }
    if (fd >= 0) {
        if (++incdepth > 10)
            error(FATAL, "#include too deeply nested");
        setsource((char*)newstring((uchar*)iname, strlen(iname), 0), fd, NULL);
        genline();
    } else {
        trp->tp = trp->bp + 2;
        error(ERROR, "Could not find include file %r", trp);
    }
    return;
syntax:
    error(ERROR, "Syntax error in #include");
    return;
}
コード例 #8
0
ファイル: cpp.c プロジェクト: nikon77/lcc42
/**
 * control - 处理预处理控制指令(头文件包含指令,行控制指令,条件编译指令)
 * @trp: 一行源程序的Token
 * 返回值:无
 */
void control(Tokenrow *trp) {
	Nlist *np;
	Token *tp;

	tp = trp->tp; /* 获得Tokenrow中的当前Token(指向预处理控制指令关键字) */
	if (tp->type!=NAME) { /* 如果当前Token不是标识符 */
		if (tp->type==NUMBER) /* 如果当前Token是数字 */
			goto kline; /* 跳转,处理行控制指令 */
		if (tp->type != NL) /* 如果该Token既不是标识符,也不是数字 */
			error(ERROR, "Unidentifiable control line"); /* 则,打印信息`无法识别的控制指令行' */
		return; /* 该行处理完毕,函数返回(该行为空行,无控制信息,else empty line) */
	}
	/* 如果当前Token是标识符但标识符不在标识符hash表中 或 标识符在hash表中但不是关键字且不能略过(TODO:啥是略过?) */
	if ((np = lookup(tp, 0))==NULL || (np->flag&ISKW)==0 && !skipping) {
		error(WARNING, "Unknown preprocessor control %t", tp); /* 打印信息,无法识别的预处理控制指令 */
		return; /* 该行处理完毕 */
	}
	if (skipping) { /* TODO: 啥是skipping? */
		if ((np->flag&ISKW)==0) /* 如果np不是关键字 */
			return; /* 函数返回 */
		switch (np->val) {
		case KENDIF:
			if (--ifdepth<skipping)
				skipping = 0;
			--cursource->ifdepth;
			setempty(trp);
			return;

		case KIFDEF:
		case KIFNDEF:
		case KIF:
			if (++ifdepth >= NIF)
				error(FATAL, "#if too deeply nested");
			++cursource->ifdepth;
			return;

		case KELIF:
		case KELSE:
			if (ifdepth<=skipping)
				break;
			return;

		default:
			return;
		}
	}
	switch (np->val) {
	case KDEFINE: /* #define,定义宏 */
		dodefine(trp); /* 定义宏 */
		break;

	case KUNDEF: /* #undef */
		tp += 1; /* tp指向宏名 */
		if (tp->type!=NAME || trp->lp - trp->bp != 4) { /* 如果tp不是标识符类型 或者 lp-bp!=4 (lp和bp之间有4个Token) */
			error(ERROR, "Syntax error in #undef"); /* 打印错误信息 */
			break;
		}
		if ((np = lookup(tp, 0)) != NULL) /* 如果在hash表中找到了tp所指向的宏名 */
			np->flag &= ~ISDEFINED; /* 清零ISDEFINED标志位 */
		break;

	case KPRAGMA: /* #pragma */
		return;

	case KIFDEF: /* #ifdef */
	case KIFNDEF: /* #ifndef */
	case KIF: /* #if */
		if (++ifdepth >= NIF) /* 全局条件编译语句的嵌套深度值加1 */
			error(FATAL, "#if too deeply nested"); /* 如果嵌套深度值大于NIF,则打印错误信息 `#if中嵌入太深' */
		++cursource->ifdepth; /* 当前输入源的条件编译语句的嵌套深度值加1 */
		ifsatisfied[ifdepth] = 0; /* 设定条件编译语句的嵌套深度值对应的if语句还未被满足 */
		if (eval(trp, np->val))
			ifsatisfied[ifdepth] = 1;
		else
			skipping = ifdepth;
		break;

	case KELIF: /* #elif */
		if (ifdepth==0) {
			error(ERROR, "#elif with no #if");
			return;
		}
		if (ifsatisfied[ifdepth]==2)
			error(ERROR, "#elif after #else");
		if (eval(trp, np->val)) {
			if (ifsatisfied[ifdepth])
				skipping = ifdepth;
			else {
				skipping = 0;
				ifsatisfied[ifdepth] = 1;
			}
		} else
			skipping = ifdepth;
		break;

	case KELSE: /* #else */
		if (ifdepth==0 || cursource->ifdepth==0) {
			error(ERROR, "#else with no #if");
			return;
		}
		if (ifsatisfied[ifdepth]==2)
			error(ERROR, "#else after #else");
		if (trp->lp - trp->bp != 3)
			error(ERROR, "Syntax error in #else");
		skipping = ifsatisfied[ifdepth]? ifdepth: 0;
		ifsatisfied[ifdepth] = 2;
		break;

	case KENDIF: /* #endif */
		if (ifdepth==0 || cursource->ifdepth==0) {
			error(ERROR, "#endif with no #if");
			return;
		}
		--ifdepth;
		--cursource->ifdepth;
		if (trp->lp - trp->bp != 3)
			error(WARNING, "Syntax error in #endif");
		break;

	case KERROR: /* #error */
		trp->tp = tp+1;
		error(WARNING, "#error directive: %r", trp);
		break;

	case KLINE: /* #line */
		trp->tp = tp+1;
		expandrow(trp, "<line>");
		tp = trp->bp+2;
	kline: /* 行控制信息处理(line control)*/
		if (tp+1>=trp->lp || tp->type!=NUMBER || tp+3<trp->lp
		 || (tp+3==trp->lp && ((tp+1)->type!=STRING)||*(tp+1)->t=='L')) { /* 如果行控制语法有误 */
			/* 上面的if判断中共有5种语法错误检查:
			 * 1. 如果只有`# 123\n'
			 * 2. 如果当前token不是数字类型
			 * 3. 如果有类似`# 123 "file.c" 2 3'的行,那么这种行不被lcc的预处理程序支持。TODO:lcc不支持行控制中的flag语法.
			 * 4. 如果在`# linenum filename'中,filename不是字符串
			 * 5. 如果filename是宽字符字符串
			 */
			error(ERROR, "Syntax error in #line"); /* 打印错误信息 */
			return; /* 该函数返回 */
		}
		cursource->line = atol((char*)tp->t)-1; /* 更新当前输入源的行号信息 */
		if (cursource->line<0 || cursource->line>=32768) /* 如果转化后的行号小于0或者行号大于32768 */
			error(WARNING, "#line specifies number out of range"); /* 打印错误信息 */
		tp = tp+1; /* 指针移动到filename位置 */
		if (tp+1<trp->lp) /* 如果filename存在(因为filename后通常紧跟一个换行符token) */
			cursource->filename=(char*)newstring(tp->t+1,tp->len-2,0); /* 保存输入源的文件名 */
		return; /* 该行处理完毕,函数返回 */

	case KDEFINED: /* #defined */
		error(ERROR, "Bad syntax for control line"); /* 打印语法错误提示 */
		break;

	case KINCLUDE: /* #include */
		doinclude(trp);
		trp->lp = trp->bp;
		return;

	case KEVAL: /* #eval */
		eval(trp, np->val);
		break;

	default: /* # other */
		error(ERROR, "Preprocessor control `%t' not yet implemented", tp); /* 未实现的预处理控制指令 */
		break;
	}
	setempty(trp); /* 置空Tokenrow */
	return;
}