void emitString(char* msg) { while (*msg) { emitChar(*msg++); } }
void process_fill() { char sz = 'b'; int64_t count; int64_t val; int64_t nn; if (*inptr=='.') { inptr++; if (strchr("bchwBCHW",*inptr)) { sz = tolower(*inptr); inptr++; } else printf("Illegal fill size.\r\n"); } SkipSpaces(); NextToken(); count = expr(); prevToken(); need(','); NextToken(); val = expr(); prevToken(); for (nn = 0; nn < count; nn++) switch(sz) { case 'b': emitByte(val); break; case 'c': emitChar(val); break; case 'h': emitHalf(val); break; case 'w': emitWord(val); break; } }
void process_dc() { int64_t val; SkipSpaces(); while(token!=tk_eol) { SkipSpaces(); if (*inptr=='"') { inptr++; while (*inptr!='"') { if (*inptr=='\\') { inptr++; switch(*inptr) { case '\\': emitChar('\\'); inptr++; break; case 'r': emitChar(0x13); inptr++; break; case 'n': emitChar(0x0A); inptr++; break; case 'b': emitChar('\b'); inptr++; break; case '"': emitChar('"'); inptr++; break; default: inptr++; break; } } else { emitChar(*inptr); inptr++; } } inptr++; } else if (*inptr=='\'') { inptr++; emitChar(*inptr); inptr++; if (*inptr!='\'') { printf("Missing ' in character constant.\r\n"); } } else { NextToken(); val = expr(); emitChar(val); prevToken(); } SkipSpaces(); if (*inptr!=',') break; inptr++; } ScanToEOL(); }
static void emitString( FILE *file, char **buffer, char *string, int width, int flags, int *left) { char pad; char *str = string; int i; int strLen; /* padding: FL_ZERO or normal ' ' * align: FL_ALIGN_LEFT (left) or normal (right) */ pad = (flags & FL_ZERO) ? '0' : ' '; if( flags & FL_ALIGN_LEFT ) { for(i=0; str[i]; i++) { emitChar(file,buffer,str[i],left); } /* Pad the rest */ for(; i<width; i++) { emitChar(file,buffer,pad,left); } } else { strLen = strlen(string); /* Pad first */ if( width > strLen ) { for(i=0; i<(width-strLen); i++) { emitChar(file,buffer,pad,left); } } for(i=0; i<strLen; i++) { emitChar(file,buffer,string[i],left); } } }
/** * Write formatted output to an array with a maximum number of characters. * * This is the mother of the formatted print family. The main goal here * is to be very small and memory efficient. * * Support: * Parameter: None * Flags : '-' and '0' * Width : Normal padding is supported, '*' is not. * Precision: None * Length : None * C99 : None * Type : d,u,x,s,and c * * @param file The file descriptor * @param buffer A pointer to the place to store the output * If NULL the output is instead * @param n The maximum number of characters to write * @param format The format string * @param ap The va list * @return */ int print(FILE *file, char **buffer, size_t n, const char *format, va_list ap) { char ch; int flags; char *str; int width; int left = n; char wBuff[4]; while ( (ch = *format++) ) { if (ch == '%') { ch = *format++; if( ch == '%') { emitChar(file,buffer,ch,&left); continue; } /* Find flags */ if (ch == '0') { flags = FL_ZERO; } else if (ch == ' ') { flags = FL_SPACE; } else if (ch == '-') { flags = FL_ALIGN_LEFT; } else { /* Not supported or no flag */ flags = FL_NONE; format--; } ch = *format++; /* Width */ if( (ch >= '0') && (ch <= '9') ) { int a = 1; wBuff[0] = ch; while( (*format >= '0') && (*format <= '9') ) { wBuff[a++] = *format++; } wBuff[a] = '\0'; width = strtoul(wBuff,NULL,10); ch = *format++; } else { width = 0; } /* Length, "eat" length for now */ if( (ch == 'h') || (ch == 'l') || (ch == 'L') ) { ch = *format++; } /* Find type */ if (ch =='c') { emitChar(file,buffer,(char )va_arg( ap, int ),&left); } else if (ch == 'd')
/** @brief Controls the meat of the processing. Basically a state machine, which accumulates the incoming stream of characters and chops them up into meaningful chunks, then passes those chunks off to other routines to further process and output. @param[in] inFile the file to process @param[out] outFile where to write the result @return int @retval 0 everything went smoothly @retval -108 unable to allocate memory */ int processFile(FILE *outFile, FILE *inFile) { tBuffer *buf; int prevc, c, nextc; /* needs to be int to hold EOF */ int depthCurly,depthRound; bool inComment, inCppComment; bool inPreprocessor; bool inSingleQuotes, inDoubleQuotes; bool inBetween, isLiteral, isChar1; bool atStart, doFlush; buf = (tBuffer *)malloc(sizeof(tBuffer)); if (buf == NULL) { fprintf(stderr, "### error: unable to allocate a buffer\n"); return (-108); } initBuffer(buf,outFile); depthCurly = 0; depthRound = 0; isLiteral = false; inComment = false; inCppComment = false; inPreprocessor = false; inSingleQuotes = false; inDoubleQuotes = false; atStart = true; inBetween = true; isChar1 = true; doFlush = false; prevc = '\0'; c = fgetc(inFile); while (c != EOF) { nextc = fgetc(inFile); /* the main state machine */ if (isLiteral) { /* normally the 'literal' is a single character. but in the odd case of DOS cr/lf pairs, they should be treated as one logical character */ if ((c != '\r' || nextc != '\n') && (c != '\n' || nextc != '\r')) { isLiteral = false; } } else if (inComment) { if (inCppComment) { if (c == '\n' || c == '\r') { inCppComment = false; inComment = false; inPreprocessor = false; isChar1 = true; if (depthCurly == 0) { buf->description.end = buf->ptr; ++buf->description.count; if (buf->fileComment) { flushBuffer(buf); buf->fileComment = false; } } else { parseComment(buf); } } } else { if (prevc == '*' && c == '/') { inComment = false; if (depthCurly == 0) { buf->description.end = buf->ptr + 1; ++buf->description.count; if (buf->fileComment) { doFlush = true; } } else { parseComment(buf); } } } } else if (inPreprocessor) { switch (c) { case '\n': case '\r': if (inCppComment) { inCppComment = false; inComment = false; if (depthCurly == 0) { buf->description.end = buf->ptr; ++buf->description.count; } else { parseComment(buf); } } if (depthCurly == 0 && !inComment) { doFlush = true; } inPreprocessor = false; isChar1 = true; break; case '/': switch (nextc) { case '/': inCppComment = true; /* fall through */ case '*': inComment = true; break; } if (inComment) { if (depthCurly == 0) { flushBuffer(buf); buf->description.start = buf->ptr; } else { buf->commentStart = buf->ptr; } } break; } } else if (inSingleQuotes) { switch (c) { case '\'': inSingleQuotes = false; break; case '\\': isLiteral = true; break; } } else if (inDoubleQuotes) { switch (c) { case '"': inDoubleQuotes = false; break; case '\\': isLiteral = true; break; } } else { switch (c) { case '\\': isLiteral = true; break; case '/': switch (nextc) { case '*': inComment = true; break; case '/': inCppComment = true; inComment = true; break; } if (inComment) { if (depthCurly == 0) { flushBuffer(buf); buf->description.start = buf->ptr; } else { buf->commentStart = buf->ptr; } } break; case '#': /* is this the first non-whitepace char on the line? */ if (isChar1) { if (depthCurly == 0) { /* if there was a comment preceeding this pre- processor directive, it wasn't a description */ buf->description.count = 0; buf->description.start = NULL; buf->description.end = NULL; } inPreprocessor = true; } break; case '\'': inSingleQuotes = true; break; case '"': inDoubleQuotes = true; break; case '(': if (depthCurly == 0 && depthRound == 0) { buf->function.end = buf->ptr; ++buf->function.count; buf->arglist.start = buf->ptr; } ++depthRound; break; case ')': --depthRound; if (depthCurly == 0 && depthRound == 0) { buf->arglist.end = buf->ptr + 1; ++buf->arglist.count; } break; case '{': if (depthCurly == 0) { buf->body.start = buf->ptr; } else parseStatement(buf); ++depthCurly; inBetween = true; break; case '}': --depthCurly; if (depthCurly == 0) { buf->body.end = buf->ptr + 1; ++buf->body.count; doFlush = true; } else parseStatement(buf); inBetween = true; break; case ';': if (depthCurly == 0) doFlush = true; else parseStatement(buf); inBetween = true; break; case '\n': case '\r': isChar1 = true; break; default: if (inBetween && !isspace(c)) { if (depthCurly == 0) buf->function.start = buf->ptr; else buf->statementStart = buf->ptr; inBetween = false; } break; } } /* check the first non-whitespace characters to see if it's the start of a comment. If so, assume it's the file's header comment and flag to handle it specially */ if (atStart && !isspace(c)) { atStart = false; if (inComment) { /* set flag to act at the end of the comment */ buf->fileComment = true; } else { /* it's not a comment, so insert a new file comment */ newFileComment(buf); } } if (emitChar(buf, c) != 0) { /* buffer overflowed! hopefully this won't happen very often... no choice but to flush */ doFlush = true; } if (doFlush) { doFlush = false; flushBuffer(buf); buf->fileComment = false; } /* if the currect character isn't whitespace, we're not at the first character of the line any more. */ if (isChar1 && !isspace(c)) isChar1 = false; prevc = c; c = nextc; } /* end while */ /* flush whatever may be left in the buffer */ flushBuffer(buf); free(buf); return 0; }
void emitHalf(int64_t cd) { emitChar(cd & 65535LL); emitChar((cd >> 16) & 65535LL); }