//this func is used after line_is_valid static int line_2_words(char* line, char* argv[], const int maxWords) { int nargs = 0; char cur = 0; for(cur = *line; is_space_char(cur); cur = *++line){} argv[nargs++] = line; for(;cur = *line, cur; ++line) { if(!is_space_char(cur))continue; //following do with space character *line = 0; for(cur = *++line; is_space_char(cur) && cur; cur = *++line){}//ignore all space between words if(!cur)break;//line ended argv[nargs++] = line; if(maxWords <= nargs){ err("too many words num %d, max is %d\n", nargs, maxWords); return 0; } } return nargs; }
static const char *skip_lws(const char *s) { for (;;) { while (is_space_char(*s)) s++; if (*s == '\n' && is_space_char(*(s + 1))) s += 1; else if (*s == '\r' && *(s + 1) == '\n' && is_space_char(*(s + 2))) s += 2; else break; } return s; }
static const char *read_token_or_quoted_string(const char *s, char **token) { while (is_space_char(*s)) s++; if (*s == '"') return read_quoted_string(s, token); else return read_token(s, token); }
/* See section 4.2 of RFC 2616 for header format. */ int http_parse_header(struct http_header **result, const char *header) { const char *p, *q; size_t value_len, value_offset; struct http_header *node, **prev; *result = NULL; prev = result; p = header; while (*p != '\0' && !is_crlf(p)) { /* Get the field name. */ q = p; while (*q != '\0' && is_token_char(*q)) q++; if (*q != ':') { http_header_free(*result); return 400; } node = (struct http_header *) safe_malloc(sizeof(*node)); node->name = mkstr(p, q); node->value = NULL; node->next = NULL; value_len = 0; value_offset = 0; /* Copy the header field value until we hit a CRLF. */ p = q + 1; p = skip_lws(p); for (;;) { q = p; while (*q != '\0' && !is_space_char(*q) && !is_crlf(q)) { /* Section 2.2 of RFC 2616 disallows control characters. */ if (iscntrl((int) (unsigned char) *q)) { http_header_node_free(node); return 400; } q++; } strbuf_append(&node->value, &value_len, &value_offset, p, q - p); p = skip_lws(q); if (is_crlf(p)) break; /* Replace LWS with a single space. */ strbuf_append_str(&node->value, &value_len, &value_offset, " "); } *prev = node; prev = &node->next; p = skip_crlf(p); } return 0; }
static int line_is_valid(char* line) { char c = 0; while(c = *line++, c) { int ret = is_delimeter(c) || is_valid_char(c) || is_space_char(c); if(!ret){ err("line contain invalid chars!! ascii val(0x%x)\n", c); return 0; } } return 1;//line is valid }
static const char *read_quoted_string(const char *s, char **quoted_string) { char *buf = NULL; size_t size = 0, offset = 0; const char *t; while (is_space_char(*s)) s++; if (*s != '"') return NULL; s++; t = s; while (*s != '"') { /* Get a block of normal characters. */ while (*t != '"' && *t != '\\') { /* This is qdtext, which is TEXT except for CTL. */ if (is_ctl_char(*t)) { free(buf); return NULL; } t++; } strbuf_append(&buf, &size, &offset, s, t - s); /* Now possibly handle an escape. */ if (*t == '\\') { t++; /* You can only escape a CHAR, octets 0-127. But we disallow 0. */ if (*t <= 0 || *t > 127) { free(buf); return NULL; } strbuf_append(&buf, &size, &offset, t, 1); t++; } s = t; } s++; *quoted_string = buf; return s; }
static const char *http_read_credentials(const char *s, struct http_credentials *credentials) { const char *p; char *scheme; credentials->scheme = AUTH_UNKNOWN; s = read_token(s, &scheme); if (s == NULL) return NULL; if (str_equal_i(scheme, "Basic")) { http_credentials_init_basic(credentials); } else if (str_equal_i(scheme, "Digest")) { http_credentials_init_digest(credentials); } else { free(scheme); return NULL; } free(scheme); while (is_space_char(*s)) s++; if (credentials->scheme == AUTH_BASIC) { p = s; /* Read base64. */ while (is_alpha_char(*p) || is_digit_char(*p) || *p == '+' || *p == '/' || *p == '=') p++; credentials->u.basic = mkstr(s, p); while (is_space_char(*p)) p++; s = p; } else if (credentials->scheme == AUTH_DIGEST) { char *name, *value; while (*s != '\0') { p = read_token(s, &name); if (p == NULL) goto bail; while (is_space_char(*p)) p++; /* It's not legal to combine multiple Authorization or Proxy-Authorization values. The productions are "Authorization" ":" credentials (section 14.8) "Proxy-Authorization" ":" credentials (section 14.34) Contrast this with WWW-Authenticate and Proxy-Authenticate and their handling in http_read_challenge. */ if (*p != '=') goto bail; p++; while (is_space_char(*p)) p++; p = read_token_or_quoted_string(p, &value); if (p == NULL) { free(name); goto bail; } if (str_equal_i(name, "username")) { if (credentials->u.digest.username != NULL) goto bail; credentials->u.digest.username = Strdup(value); } else if (str_equal_i(name, "realm")) { if (credentials->u.digest.realm != NULL) goto bail; credentials->u.digest.realm = Strdup(value); } else if (str_equal_i(name, "nonce")) { if (credentials->u.digest.nonce != NULL) goto bail; credentials->u.digest.nonce = Strdup(value); } else if (str_equal_i(name, "uri")) { if (credentials->u.digest.uri != NULL) goto bail; credentials->u.digest.uri = Strdup(value); } else if (str_equal_i(name, "response")) { if (credentials->u.digest.response != NULL) goto bail; credentials->u.digest.response = Strdup(value); } else if (str_equal_i(name, "algorithm")) { if (str_equal_i(value, "MD5")) credentials->u.digest.algorithm = ALGORITHM_MD5; else credentials->u.digest.algorithm = ALGORITHM_MD5; } else if (str_equal_i(name, "qop")) { if (str_equal_i(value, "auth")) credentials->u.digest.qop = QOP_AUTH; else if (str_equal_i(value, "auth-int")) credentials->u.digest.qop = QOP_AUTH_INT; else credentials->u.digest.qop = QOP_NONE; } else if (str_equal_i(name, "cnonce")) { if (credentials->u.digest.cnonce != NULL) goto bail; credentials->u.digest.cnonce = Strdup(value); } else if (str_equal_i(name, "nc")) { if (credentials->u.digest.nc != NULL) goto bail; credentials->u.digest.nc = Strdup(value); } free(name); free(value); while (is_space_char(*p)) p++; if (*p == ',') { p++; while (is_space_char(*p)) p++; if (*p == '\0') goto bail; } s = p; } } return s; bail: http_credentials_free(credentials); return NULL; }
static const char *http_read_challenge(const char *s, struct http_challenge *challenge) { const char *p; char *scheme; http_challenge_init(challenge); scheme = NULL; s = read_token(s, &scheme); if (s == NULL) goto bail; if (str_equal_i(scheme, "Basic")) { challenge->scheme = AUTH_BASIC; } else if (str_equal_i(scheme, "Digest")) { challenge->scheme = AUTH_DIGEST; } else { challenge->scheme = AUTH_UNKNOWN; } free(scheme); scheme = NULL; /* RFC 2617, section 1.2, requires at least one auth-param: challenge = auth-scheme 1*SP 1#auth-param But there are some schemes (NTLM and Negotiate) that can be without auth-params, so we allow that here. A comma indicates the end of this challenge and the beginning of the next (see the comment in the loop below). */ while (is_space_char(*s)) s++; if (*s == ',') { s++; while (is_space_char(*s)) s++; if (*s == '\0') goto bail; return s; } while (*s != '\0') { char *name, *value; p = read_token(s, &name); if (p == NULL) goto bail; while (is_space_char(*p)) p++; /* It's possible that we've hit the end of one challenge and the beginning of another. Section 14.33 says that the header value can be 1#challenge, in other words several challenges separated by commas. Because the auth-params are also separated by commas, the only way we can tell is if we find a token not followed by an equals sign. */ if (*p != '=') break; p++; while (is_space_char(*p)) p++; p = read_token_or_quoted_string(p, &value); if (p == NULL) { free(name); goto bail; } if (str_equal_i(name, "realm")) challenge->realm = Strdup(value); else if (challenge->scheme == AUTH_DIGEST) { if (str_equal_i(name, "nonce")) { if (challenge->digest.nonce != NULL) goto bail; challenge->digest.nonce = Strdup(value); } else if (str_equal_i(name, "opaque")) { if (challenge->digest.opaque != NULL) goto bail; challenge->digest.opaque = Strdup(value); } else if (str_equal_i(name, "algorithm")) { if (str_equal_i(value, "MD5")) challenge->digest.algorithm = ALGORITHM_MD5; else challenge->digest.algorithm = ALGORITHM_UNKNOWN; } else if (str_equal_i(name, "qop")) { char **tokens; size_t n; int i; const char *tmp; tmp = read_token_list(value, &tokens, &n); if (tmp == NULL) { free(name); free(value); goto bail; } for (i = 0; i < n; i++) { if (str_equal_i(tokens[i], "auth")) challenge->digest.qop |= QOP_AUTH; else if (str_equal_i(tokens[i], "auth-int")) challenge->digest.qop |= QOP_AUTH_INT; } for (i = 0; i < n; i++) free(tokens[i]); free(tokens); if (*tmp != '\0') { free(name); free(value); goto bail; } } } free(name); free(value); while (is_space_char(*p)) p++; if (*p == ',') { p++; while (is_space_char(*p)) p++; if (*p == '\0') goto bail; } s = p; } return s; bail: if (scheme != NULL) free(scheme); http_challenge_free(challenge); return NULL; }
int oj_compare_output(const char *file_out, const char *file_user) { FM_LOG_TRACE("start compare"); FILE *fp_std = fopen(file_out, "r"); if (fp_std == nullptr) { FM_LOG_FATAL("open standard output file (%s) failed: %s", file_out, strerror(errno)); exit(EXIT_COMPARE); } FILE *fp_exe = fopen(file_user, "r"); if (fp_exe == nullptr) { FM_LOG_FATAL("open user output file (%s) failed: %s", file_user, strerror(errno)); exit(EXIT_COMPARE); } int a, b, Na = 0, Nb = 0; enum { AC = OJ_AC, PE = OJ_PE, WA = OJ_WA } status = AC; while (true) { /* * Windows / DOS uses '\r\n'; * Unix / Linux / OS X uses '\n'; * Macs before OS X use '\r'; * TODO(power): out file with '\r' line ending get incorrect PE */ while ((a = fgetc(fp_std)) == '\r') {} while ((b = fgetc(fp_exe)) == '\r') {} Na++, Nb++; // deal with '\r' and '\n' if (a == '\r') a = '\n'; if (b == '\r') b = '\n'; if (feof(fp_std) && feof(fp_exe)) { break; } else if (feof(fp_std) || feof(fp_exe)) { // deal with tailing white spaces FILE *fp_tmp; if (feof(fp_std)) { FM_LOG_TRACE("std out file ended"); if (!is_space_char(b)) { FM_LOG_TRACE("WA exe['%c':0x%x @%d]", b, b, Nb); status = WA; break; } fp_tmp = fp_exe; } else { /* feof(fp_exe) */ FM_LOG_TRACE("user out file ended"); if (!is_space_char(a)) { FM_LOG_TRACE("WA std['%c':0x%x @%d]", a, a, Na); status = WA; break; } fp_tmp = fp_std; } int c; while (c = fgetc(fp_tmp), c != EOF) { if (c == '\r') c = '\n'; if (!is_space_char(c)) { FM_LOG_TRACE("WA ['%c':0x%x]", c, c); status = WA; break; } } break; } if (a != b) { status = PE; if (is_space_char(a) && is_space_char(b)) { continue; } if (is_space_char(a)) { ungetc(b, fp_exe); Nb--; } else if (is_space_char(b)) { ungetc(a, fp_std); Na--; } else { FM_LOG_TRACE("WA ['%c':0x%x @%d] : ['%c':0x%x @%d]", a, a, Na, b, b, Nb); status = WA; break; } } } // end of while fclose(fp_std); fclose(fp_exe); if (status == WA || status == PE) { make_diff_out2(file_out, file_user, oj_solution.work_dir, file_out); } FM_LOG_TRACE("compare finished, result=%s", status == AC ? "AC" : (status == PE ? "PE" : "WA")); return status; }
//1, Read the whole file content to buffer //2, parse file content to lines //3, parse each valid line static int parse_ini_file(const char* filePath, u8* iniBuf, const unsigned bufSz) { const int MaxLines = 1024;// const int MaxWordsALine = 32; char* lines[MaxLines]; char* wordsALine[MaxWordsALine]; int ret = 0; unsigned fileSz = 0; unsigned lineNum = 0; int nwords = 0; int currentSetIndex = -1; int hFile = -1; unsigned readLen = 0; unsigned i = 0; unsigned lineIndex = 0; fileSz = (unsigned)do_fat_get_fileSz(filePath); if(!fileSz){ err("File %s not exist in sdcard??\n", filePath); return __LINE__; } if(fileSz >= bufSz){ err("file size 0x%x illegal, buf size is 0x%x\n", fileSz, bufSz); return __LINE__; } DWN_MSG("ini sz 0x%xB\n", fileSz); hFile = do_fat_fopen(filePath); if(hFile < 0){ err("Fail to open file %s\n", filePath); return __LINE__; } readLen = do_fat_fread(hFile, iniBuf, fileSz); if(readLen != fileSz){ err("failed to load cfg file, want size 0x%x, but 0x%x\n", fileSz, readLen); do_fat_fclose(hFile); return __LINE__; } iniBuf[fileSz] = 0; do_fat_fclose(hFile); dbg("\\r is 0x%x\t, \\n is 0x%x\n", '\r', '\n'); char* curLine = (char*)iniBuf; char* pTemp = curLine; //step1:first loop to seprate buffer to lines for (i = 0; i < fileSz ; i++, ++pTemp) { char c = *pTemp; int isFileEnd = i + 1 >= fileSz; if(MaxLines <= lineNum){ err("total line number %d too many, at most %d lines!\n", lineNum, MaxLines); break; } if(isFileEnd) { lines[lineNum++] = curLine; break;//End to read file if file ended } if('\r' != c && '\n' != c) { continue; } *pTemp = 0;/// dbg("%3d: %s\n", lineNum, curLine); if('\r' == c)//for DOS \r\n mode { if('\n' == pTemp[1]) { lines[lineNum++] = curLine; ++pTemp; curLine = pTemp + 1; ++i;//skip '\n' which follows '\r' } else { err("Syntax error at line %d, DOS end \\r\\n, but \\r%x\n", lineNum + 1, pTemp[1]); return __LINE__; } } else if('\n' == c)//for UNIX '\n' mode { lines[lineNum++] = curLine; curLine = pTemp + 1; } } //step 2: abandon comment or space lines for (lineIndex = 0; lineIndex < lineNum ; lineIndex++) { int isSpaceLine = 1; char c = 0; curLine = lines[lineIndex]; while(c = *curLine++, c) { //escape space and tab if (is_space_char(c)) { continue; } isSpaceLine = 0;//no space line //test if frist char is comment delimeter if(';' == c) { lines[lineIndex] = NULL;//invalid comment lines } } //if all character is space or tab, also invlalid it if (isSpaceLine) { lines[lineIndex] = NULL; } } dbg("\nvalid lines:\n"); for (lineIndex = 0; lineIndex < lineNum ; lineIndex++) { int lineType = INI_LINE_TYPE_ERR; const char* iniKey = NULL; const char* iniVal = NULL; const char* iniSet = NULL; curLine = lines[lineIndex]; if(!curLine)continue; if(!line_is_valid(curLine)) //only comment lines can contain non-ASCII letters { err("line %d contain invalid chars\n", lineIndex + 1); ret = __LINE__; break; } dbg("%3d: %s\n",lineIndex, curLine); nwords = line_2_words(curLine, wordsALine, MaxWordsALine); if(nwords <= 0){ ret = __LINE__; break; } if(nwords > 3){ err("line %d error: ini support at most 3 words, but %d\n", lineIndex + 1, nwords); ret = __LINE__; break; } switch (nwords) { case 3: { if (!strcmp("=", wordsALine[1]))//k/v pair { lineType = INI_LINE_TYPE_KE_VALUE; iniKey = wordsALine[0]; iniVal = wordsALine[2]; break; } else if(!strcmp("[" , wordsALine[0]) && !strcmp("]" , wordsALine[2]))//set line { lineType = INI_LINE_TYPE_SET; iniSet = wordsALine[1]; break; } else { lineType = INI_LINE_TYPE_ERR; err("Ini syntax error when parse line %d\n", lineIndex + 1); ret = __LINE__; break; } } break; case 2: { if('[' == wordsALine[0][0])//set like "[set ]" or "[ set]" { if(!strcmp("]", wordsALine[1])) { lineType = INI_LINE_TYPE_SET; iniSet = wordsALine[0] + 1; break; } else if (']' == wordsALine[1][strlen(wordsALine[1]) - 1] && !strcmp("[", wordsALine[0])) { lineType = INI_LINE_TYPE_SET; iniSet = wordsALine[1]; wordsALine[1][strlen(wordsALine[1]) - 1] = 0; break; } } else if(!strcmp("=", wordsALine[1]))//k/v pair like "key = " { lineType = INI_LINE_TYPE_KE_VALUE; iniKey = wordsALine[0]; break; } else if('=' == wordsALine[1][0])//k/v pair like "key =v" or "key= v" { lineType = INI_LINE_TYPE_KE_VALUE; iniKey = wordsALine[0]; iniVal = wordsALine[1] + 1; break; } else if ('=' == wordsALine[0][strlen(wordsALine[0]) - 1])//k/v pair like "key= v" { wordsALine[0][strlen(wordsALine[0]) - 1] = 0; lineType = INI_LINE_TYPE_KE_VALUE; iniKey = wordsALine[0]; iniVal = wordsALine[1]; } } break; case 1: { char* word = wordsALine[0]; char firstChar = word[0]; char lastChar = word[strlen(word) - 1]; if('[' == firstChar && ']' == lastChar) { lineType = INI_LINE_TYPE_SET; iniSet = word + 1; word[strlen(word) - 1] = 0; break; } else { char c = 0; iniKey = word; while(c = *word++, c) { if ('=' == c)//TODO: not assert only delimeter in a line yet { lineType = INI_LINE_TYPE_KE_VALUE; *--word = 0; iniVal = ++word; iniVal = *iniVal ? iniVal : NULL; break; } } } } break; default: break; } if (INI_LINE_TYPE_SET == lineType) { const char* setname = NULL; dbg("set line, set is %s\n", iniSet); currentSetIndex = -1;//set index to invalid for (i = 0; i < TOTAL_SET_NUM; i++) { setname = _iniSets[i]; if (!strcmp(setname, iniSet))break;//set is useful for sdc burn } //set is useful if(i < TOTAL_SET_NUM) { if(!strcmp(setname, SET_BURN_PARTS)) { if(g_sdcBurnPara.setsBitMap.burnParts){ ret = __LINE__; goto _set_duplicated; } g_sdcBurnPara.setsBitMap.burnParts = 1; } if(!strcmp(setname, SET_BURN_PARA_EX)) { if(g_sdcBurnPara.setsBitMap.burnEx){ ret = __LINE__; goto _set_duplicated; } g_sdcBurnPara.setsBitMap.burnEx = 1; } if(!strcmp(setname, SET_CUSTOM_PARA)) { if(g_sdcBurnPara.setsBitMap.custom){ ret = __LINE__; goto _set_duplicated; } g_sdcBurnPara.setsBitMap.custom = 1; } currentSetIndex = i;//set set index to valid } } if(INI_LINE_TYPE_KE_VALUE == lineType) { dbg("k/v line, key (%s), val (%s)\n", iniKey, iniVal); if (currentSetIndex >= 0 && currentSetIndex < TOTAL_SET_NUM)//set is valid { const char* setName = _iniSets[currentSetIndex]; if (!strcmp(setName, SET_BURN_PARTS)) { ret = parse_burn_parts(iniKey, iniVal); if(ret){ ret = __LINE__; goto _line_err; } } if (!strcmp(setName, SET_BURN_PARA_EX)) { ret = parse_set_burnEx(iniKey, iniVal); if(ret){ ret = __LINE__; goto _line_err; } } if (!strcmp(setName, SET_CUSTOM_PARA)) { ret = parse_set_custom_para(iniKey, iniVal); if(ret){ ret = __LINE__; goto _line_err; } } } } } return ret; _line_err: err("Fail to parse line %d\n", lineIndex + 1); return ret; _set_duplicated: err("line %d err:set is duplicated!!\n", lineIndex + 1); return ret; }
char *mysql_query_digest_and_first_comment(char *s, int _len, char **first_comment){ int i = 0; char cur_comment[FIRST_COMMENT_MAX_LENGTH]; cur_comment[0]=0; int ccl=0; int cmd=0; int len = _len; if (_len > QUERY_DIGEST_MAX_LENGTH) { len = QUERY_DIGEST_MAX_LENGTH; } char *r = (char *) malloc(len + SIZECHAR); char *p_r = r; char *p_r_t = r; char prev_char = 0; char qutr_char = 0; char flag = 0; char fc=0; int fc_len=0; char fns=0; bool lowercase=0; lowercase=mysql_thread___query_digests_lowercase; while(i < len) { // ================================================= // START - read token char and set flag what's going on. // ================================================= if(flag == 0) { // store current position p_r_t = p_r; // comment type 1 - start with '/*' if(prev_char == '/' && *s == '*') { ccl=0; flag = 1; if (*(s+1)=='!') cmd=1; } // comment type 2 - start with '#' else if(*s == '#') { flag = 2; } // string - start with ' else if(*s == '\'' || *s == '"') { flag = 3; qutr_char = *s; } // may be digit - start with digit else if(is_token_char(prev_char) && is_digit_char(*s)) { flag = 4; if(len == i+1) continue; } // not above case - remove duplicated space char else { flag = 0; if (fns==0 && is_space_char(*s)) { s++; i++; continue; } if (fns==0) fns=1; if(is_space_char(prev_char) && is_space_char(*s)){ prev_char = ' '; *p_r = ' '; s++; i++; continue; } } } // ================================================= // PROCESS and FINISH - do something on each case // ================================================= else { // -------- // comment // -------- if (flag == 1) { if (cmd) { if (ccl<FIRST_COMMENT_MAX_LENGTH-1) { cur_comment[ccl]=*s; ccl++; } } if (fc==0) { fc=1; } if (fc==1) { if (fc_len<FIRST_COMMENT_MAX_LENGTH-1) { if (*first_comment==NULL) { *first_comment=(char *)malloc(FIRST_COMMENT_MAX_LENGTH); } char *c=*first_comment+fc_len; *c = !is_space_char(*s) ? *s : ' '; fc_len++; } if (prev_char == '*' && *s == '/') { if (fc_len>=2) fc_len-=2; char *c=*first_comment+fc_len; *c=0; //*first_comment[fc_len]=0; fc=2; } } } if( // comment type 1 - /* .. */ (flag == 1 && prev_char == '*' && *s == '/') || // comment type 2 - # ... \n (flag == 2 && (*s == '\n' || *s == '\r')) ) { p_r = flag == 1 ? p_r_t - SIZECHAR : p_r_t; if (cmd) { cur_comment[ccl]=0; if (ccl>=2) { ccl-=2; cur_comment[ccl]=0; char el=0; int fcc=0; while (el==0 && fcc<ccl ) { switch (cur_comment[fcc]) { case '/': case '*': case '!': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case ' ': fcc++; break; default: el=1; break; } } if (el) { memcpy(p_r,cur_comment+fcc,ccl-fcc); p_r+=(ccl-fcc); *p_r++=' '; } } cmd=0; } prev_char = ' '; flag = 0; s++; i++; continue; } // -------- // string // -------- else if(flag == 3) { // Last char process if(len == i + 1) { p_r = p_r_t; *p_r++ = '?'; flag = 0; break; } // need to be ignored case if(p_r > p_r_t + SIZECHAR) { if( (prev_char == '\\' && *s == '\\') || // to process '\\\\', '\\' (prev_char == '\\' && *s == qutr_char) || // to process '\'' (prev_char == qutr_char && *s == qutr_char) // to process '''' ) { prev_char = 'X'; s++; i++; continue; } } // satisfied closing string - swap string to ? if(*s == qutr_char && (len == i+1 || *(s + SIZECHAR) != qutr_char)) { p_r = p_r_t; *p_r++ = '?'; flag = 0; if(i < len) s++; i++; continue; } } // -------- // digit // -------- else if(flag == 4) { // last single char if(p_r_t == p_r) { *p_r++ = '?'; i++; continue; } // token char or last char if(is_token_char(*s) || len == i+1) { if(is_digit_string(p_r_t, p_r)) { p_r = p_r_t; *p_r++ = '?'; if(len == i+1) { if(is_token_char(*s)) *p_r++ = *s; i++; continue; } } flag = 0; } } } // ================================================= // COPY CHAR // ================================================= // convert every space char to ' ' if (lowercase==0) { *p_r++ = !is_space_char(*s) ? *s : ' '; } else { *p_r++ = !is_space_char(*s) ? (tolower(*s)) : ' '; } prev_char = *s++; i++; } // remove a trailing space if (p_r>r) { char *e=p_r; e--; if (*e==' ') { *e=0; } } *p_r = 0; // process query stats return r; }
static int compare_output(std::string file_std, std::string file_exec) { //这里可以不用写的 //仔细研究一下diff及其参数即可 //实现各种功能 FILE *fp_std = fopen(file_std.c_str(), "r"); if (fp_std == NULL) { FM_LOG_WARNING("Open standard output file failed."); exit(JUDGE_CONF::EXIT_COMPARE); } FILE *fp_exe = fopen(file_exec.c_str(), "r"); if (fp_exe == NULL) { FM_LOG_WARNING("Open executive output file failed."); exit(JUDGE_CONF::EXIT_COMPARE); } int a, b, Na = 0, Nb = 0; enum { AC = JUDGE_CONF::AC, PE = JUDGE_CONF::PE, WA = JUDGE_CONF::WA }status = AC; while (true) { a = fgetc(fp_std); b = fgetc(fp_exe); Na++, Nb++; //统一\r和\n之间的区别 if (a == '\r') { a = fgetc(fp_std); Na++; } if (b == '\r') { b = fgetc(fp_std); Nb++; } #define is_space_char(a) ((a == ' ') || (a == '\t') || (a == '\n')) if (feof(fp_std) && feof(fp_exe)){ //文件结束 break; } else if (feof(fp_std) || feof(fp_exe)) { //如果只有一个文件结束 //但是另一个文件的末尾是回车 //那么也当做AC处理 FILE *fp_tmp; if (feof(fp_std)) { if (!is_space_char(b)) { FM_LOG_TRACE("Well, Wrong Answer."); status = WA; break; } fp_tmp = fp_exe; } else { if (!is_space_char(a)) { FM_LOG_TRACE("Well, Wrong Answer."); status = WA; break; } fp_tmp = fp_std; } int c; while ((c = fgetc(fp_tmp)) != EOF) { if (c == '\r') c = '\n'; if (!is_space_char(c)) { FM_LOG_TRACE("Well, Wrong Answer."); status = WA; break; } } break; } //如果两个字符不同 if (a != b) { status = PE; //过滤空白字符 if (is_space_char(a) && is_space_char(b)) { continue; } if (is_space_char(a)) { //a是空白字符,过滤,退回b以便下一轮循环 ungetc(b, fp_exe); Nb--; } else if (is_space_char(b)) { ungetc(a, fp_std); Na--; } else { FM_LOG_TRACE("Well, Wrong Answer."); status = WA; break; } } } fclose(fp_std); fclose(fp_exe); return status; }
char *mysql_query_digest_and_first_comment(char *s, int len, char *first_comment){ int i = 0; char *r = (char *) malloc(len + SIZECHAR); char *p_r = r; char *p_r_t = r; char prev_char = 0; char qutr_char = 0; char flag = 0; char fc=0; int fc_len=0; char fns=0; while(i < len) { // ================================================= // START - read token char and set flag what's going on. // ================================================= if(flag == 0) { // store current position p_r_t = p_r; // comment type 1 - start with '/*' if(prev_char == '/' && *s == '*') { flag = 1; } // comment type 2 - start with '#' else if(*s == '#') { flag = 2; } // string - start with ' else if(*s == '\'' || *s == '"') { flag = 3; qutr_char = *s; } // may be digit - start with digit else if(is_token_char(prev_char) && is_digit_char(*s)) { flag = 4; if(len == i+1) continue; } // not above case - remove duplicated space char else { flag = 0; if (fns==0 && is_space_char(*s)) { s++; i++; continue; } if (fns==0) fns=1; if(is_space_char(prev_char) && is_space_char(*s)){ prev_char = ' '; *p_r = ' '; s++; i++; continue; } } } // ================================================= // PROCESS and FINISH - do something on each case // ================================================= else { // -------- // comment // -------- if (flag == 1) { if (fc==0) { fc=1; } if (fc==1) { if (fc_len<FIRST_COMMENT_MAX_LENGTH-1) { first_comment[fc_len]= !is_space_char(*s) ? *s : ' '; fc_len++; } if (prev_char == '*' && *s == '/') { if (fc_len>=2) fc_len-=2; first_comment[fc_len]=0; fc=2; } } } if( // comment type 1 - /* .. */ (flag == 1 && prev_char == '*' && *s == '/') || // comment type 2 - # ... \n (flag == 2 && (*s == '\n' || *s == '\r')) ) { p_r = flag == 1 ? p_r_t - SIZECHAR : p_r_t; prev_char = ' '; flag = 0; s++; i++; continue; } // -------- // string // -------- else if(flag == 3) { // Last char process if(len == i + 1) { p_r = p_r_t; *p_r++ = '?'; flag = 0; break; } // need to be ignored case if(p_r > p_r_t + SIZECHAR) { if( (prev_char == '\\' && *s == '\\') || // to process '\\\\', '\\' (prev_char == '\\' && *s == qutr_char) || // to process '\'' (prev_char == qutr_char && *s == qutr_char) // to process '''' ) { prev_char = 'X'; s++; i++; continue; } } // satisfied closing string - swap string to ? if(*s == qutr_char && (len == i+1 || *(s + SIZECHAR) != qutr_char)) { p_r = p_r_t; *p_r++ = '?'; flag = 0; if(i < len) s++; i++; continue; } } // -------- // digit // -------- else if(flag == 4) { // last single char if(p_r_t == p_r) { *p_r++ = '?'; i++; continue; } // token char or last char if(is_token_char(*s) || len == i+1) { if(is_digit_string(p_r_t, p_r)) { p_r = p_r_t; *p_r++ = '?'; if(len == i+1) { if(is_token_char(*s)) *p_r++ = *s; i++; continue; } } flag = 0; } } } // ================================================= // COPY CHAR // ================================================= // convert every space char to ' ' *p_r++ = !is_space_char(*s) ? *s : ' '; prev_char = *s++; i++; } // remove a trailing space if (p_r>r) { char *e=p_r; e--; if (*e==' ') { *e=0; } } *p_r = 0; // process query stats return r; }
void NCDConfigTokenizer_Tokenize (char *str, size_t left, NCDConfigTokenizer_output output, void *user) { size_t line = 1; size_t line_char = 1; while (left > 0) { size_t l; int error = 0; int token; void *token_val = NULL; size_t token_len = 0; if (*str == '#') { l = 1; while (l < left && str[l] != '\n') { l++; } token = 0; } else if (l = data_begins_with(str, left, "{")) { token = NCD_TOKEN_CURLY_OPEN; } else if (l = data_begins_with(str, left, "}")) { token = NCD_TOKEN_CURLY_CLOSE; } else if (l = data_begins_with(str, left, "(")) { token = NCD_TOKEN_ROUND_OPEN; } else if (l = data_begins_with(str, left, ")")) { token = NCD_TOKEN_ROUND_CLOSE; } else if (l = data_begins_with(str, left, ";")) { token = NCD_TOKEN_SEMICOLON; } else if (l = data_begins_with(str, left, ".")) { token = NCD_TOKEN_DOT; } else if (l = data_begins_with(str, left, ",")) { token = NCD_TOKEN_COMMA; } else if (l = data_begins_with(str, left, ":")) { token = NCD_TOKEN_COLON; } else if (l = data_begins_with(str, left, "[")) { token = NCD_TOKEN_BRACKET_OPEN; } else if (l = data_begins_with(str, left, "]")) { token = NCD_TOKEN_BRACKET_CLOSE; } else if (l = data_begins_with(str, left, "->")) { token = NCD_TOKEN_ARROW; } else if (l = data_begins_with(str, left, "If")) { token = NCD_TOKEN_IF; } else if (l = data_begins_with(str, left, "Elif")) { token = NCD_TOKEN_ELIF; } else if (l = data_begins_with(str, left, "elif")) { token = NCD_TOKEN_ELIF; } else if (l = data_begins_with(str, left, "Else")) { token = NCD_TOKEN_ELSE; } else if (l = data_begins_with(str, left, "else")) { token = NCD_TOKEN_ELSE; } else if (l = data_begins_with(str, left, "Foreach")) { token = NCD_TOKEN_FOREACH; } else if (l = data_begins_with(str, left, "As")) { token = NCD_TOKEN_AS; } else if (l = data_begins_with(str, left, "include_guard")) { token = NCD_TOKEN_INCLUDE_GUARD; } else if (l = data_begins_with(str, left, "include")) { token = NCD_TOKEN_INCLUDE; } else if (is_name_first_char(*str)) { l = 1; while (l < left && is_name_char(str[l])) { l++; } // allocate buffer bsize_t bufsize = bsize_add(bsize_fromsize(l), bsize_fromint(1)); char *buf; if (bufsize.is_overflow || !(buf = malloc(bufsize.value))) { BLog(BLOG_ERROR, "malloc failed"); error = 1; goto out; } // copy and terminate memcpy(buf, str, l); buf[l] = '\0'; if (!strcmp(buf, "process")) { token = NCD_TOKEN_PROCESS; free(buf); } else if (!strcmp(buf, "template")) { token = NCD_TOKEN_TEMPLATE; free(buf); } else { token = NCD_TOKEN_NAME; token_val = buf; token_len = l; } } else if (*str == '"') do { // init string ExpString estr; if (!ExpString_Init(&estr)) { BLog(BLOG_ERROR, "ExpString_Init failed"); goto string_fail0; } // skip start quote l = 1; // decode string while (l < left) { uint8_t dec_ch; // get character if (str[l] == '\\') { if (left - l < 2) { BLog(BLOG_ERROR, "escape character found in string but nothing follows"); goto string_fail1; } size_t extra = 0; switch (str[l + 1]) { case '\'': case '\"': case '\\': case '\?': dec_ch = str[l + 1]; break; case 'a': dec_ch = '\a'; break; case 'b': dec_ch = '\b'; break; case 'f': dec_ch = '\f'; break; case 'n': dec_ch = '\n'; break; case 'r': dec_ch = '\r'; break; case 't': dec_ch = '\t'; break; case 'v': dec_ch = '\v'; break; case '0': dec_ch = 0; break; case 'x': { if (left - l < 4) { BLog(BLOG_ERROR, "hexadecimal escape found in string but too little characters follow"); goto string_fail1; } uintmax_t hex_val; if (!parse_unsigned_hex_integer_bin(&str[l + 2], 2, &hex_val)) { BLog(BLOG_ERROR, "hexadecimal escape found in string but two hex characters don't follow"); goto string_fail1; } dec_ch = hex_val; extra = 2; } break; default: BLog(BLOG_ERROR, "bad escape sequence in string"); goto string_fail1; } l += 2 + extra; } else if (str[l] == '"') { break; } else { dec_ch = str[l]; l++; } // append character to string if (!ExpString_AppendByte(&estr, dec_ch)) { BLog(BLOG_ERROR, "ExpString_AppendChar failed"); goto string_fail1; } } // make sure ending quote was found if (l == left) { BLog(BLOG_ERROR, "missing ending quote for string"); goto string_fail1; } // skip ending quote l++; token = NCD_TOKEN_STRING; token_val = ExpString_Get(&estr); token_len = ExpString_Length(&estr); break; string_fail1: ExpString_Free(&estr); string_fail0: error = 1; } while (0); else if (is_space_char(*str)) { token = 0; l = 1; } else { BLog(BLOG_ERROR, "unrecognized character"); error = 1; } out: // report error if (error) { output(user, NCD_ERROR, NULL, 0, line, line_char); return; } // output token if (token) { if (!output(user, token, token_val, token_len, line, line_char)) { return; } } // update line/char counters for (size_t i = 0; i < l; i++) { if (str[i] == '\n') { line++; line_char = 1; } else { line_char++; } } str += l; left -= l; } output(user, NCD_EOF, NULL, 0, line, line_char); }
void NCDConfigTokenizer_Tokenize (char *str, size_t left, NCDConfigTokenizer_output output, void *user) { size_t line = 1; size_t line_char = 1; while (left > 0) { size_t l; int error = 0; int token; void *token_val = NULL; if (*str == '#') { l = 1; while (l < left && str[l] != '\n') { l++; } token = 0; } else if (l = data_begins_with(str, left, "{")) { token = NCD_TOKEN_CURLY_OPEN; } else if (l = data_begins_with(str, left, "}")) { token = NCD_TOKEN_CURLY_CLOSE; } else if (l = data_begins_with(str, left, "(")) { token = NCD_TOKEN_ROUND_OPEN; } else if (l = data_begins_with(str, left, ")")) { token = NCD_TOKEN_ROUND_CLOSE; } else if (l = data_begins_with(str, left, ";")) { token = NCD_TOKEN_SEMICOLON; } else if (l = data_begins_with(str, left, ".")) { token = NCD_TOKEN_DOT; } else if (l = data_begins_with(str, left, ",")) { token = NCD_TOKEN_COMMA; } else if (l = data_begins_with(str, left, ":")) { token = NCD_TOKEN_COLON; } else if (l = data_begins_with(str, left, "[")) { token = NCD_TOKEN_BRACKET_OPEN; } else if (l = data_begins_with(str, left, "]")) { token = NCD_TOKEN_BRACKET_CLOSE; } else if (l = data_begins_with(str, left, "->")) { token = NCD_TOKEN_ARROW; } else if (is_name_first_char(*str)) { l = 1; while (l < left && is_name_char(str[l])) { l++; } // allocate buffer bsize_t bufsize = bsize_add(bsize_fromsize(l), bsize_fromint(1)); char *buf; if (bufsize.is_overflow || !(buf = malloc(bufsize.value))) { BLog(BLOG_ERROR, "malloc failed"); error = 1; goto out; } // copy and terminate memcpy(buf, str, l); buf[l] = '\0'; if (!strcmp(buf, "process")) { token = NCD_TOKEN_PROCESS; free(buf); } else if (!strcmp(buf, "template")) { token = NCD_TOKEN_TEMPLATE; free(buf); } else { token = NCD_TOKEN_NAME; token_val = buf; } } else if (*str == '"') do { // init string ExpString estr; if (!ExpString_Init(&estr)) { BLog(BLOG_ERROR, "ExpString_Init failed"); goto string_fail0; } // skip start quote l = 1; // decode string while (l < left) { char dec_ch; // get character if (str[l] == '\\') { if (left - l < 2) { BLog(BLOG_ERROR, "escape character found in string but nothing follows"); goto string_fail1; } dec_ch = str[l + 1]; l += 2; } else if (str[l] == '"') { break; } else { dec_ch = str[l]; l++; } // string cannot contain zeros bytes if (dec_ch == '\0') { BLog(BLOG_ERROR, "string contains zero byte"); goto string_fail1; } // append character to string if (!ExpString_AppendChar(&estr, dec_ch)) { BLog(BLOG_ERROR, "ExpString_AppendChar failed"); goto string_fail1; } } // make sure ending quote was found if (l == left) { BLog(BLOG_ERROR, "missing ending quote for string"); goto string_fail1; } // skip ending quote l++; token = NCD_TOKEN_STRING; token_val = ExpString_Get(&estr); break; string_fail1: ExpString_Free(&estr); string_fail0: error = 1; } while (0); else if (is_space_char(*str)) { token = 0; l = 1; } else { BLog(BLOG_ERROR, "unrecognized character"); error = 1; } out: // report error if (error) { output(user, NCD_ERROR, NULL, line, line_char); return; } // output token if (token) { if (!output(user, token, token_val, line, line_char)) { return; } } // update line/char counters for (size_t i = 0; i < l; i++) { if (str[i] == '\n') { line++; line_char = 1; } else { line_char++; } } str += l; left -= l; } output(user, NCD_EOF, NULL, line, line_char); }