const char * strstr_s(const char * buf, const char * str) { int strlength = strlen(str); char * strlow_s = (char *)malloc(strlength+1); char * strcmp_s = (char *)malloc(strlength+1); const char * first = 0; strtolower(strlow_s, str); while(*buf) { first = strchr_s(buf, *strlow_s); if(!first) break; strncpy(strcmp_s, first, strlength); *(strcmp_s+strlength) = 0; strtolower(strcmp_s, strcmp_s); if(!strcmp(strlow_s, strcmp_s)) break; buf = first+1; } free(strlow_s); free(strcmp_s); return first; }
char * splitkey(char * key, int maxkey, char * val, int maxvalue, const char ** pend, const char * buf) { const char * pv; char *backupstr; if(!buf && *buf) return 0; backupstr = malloc_str(buf, -1); *key = 0; *val = 0; pv = strchr_s(backupstr, '='); if(pv != NULL) { backupstr[pv-backupstr] = ' '; //将key和alue使用空格分割 getkey(key, maxkey, 0, backupstr); getkey(val, maxvalue, pend, pv); } else { getkey(key, maxkey, pend, backupstr); } free(backupstr); if(*key == 0) return 0; return key; }
void anlizetextbtw(const char * buf, callback deal, void * parm) { char * texttw; const char * pstart = strchr_s(buf, '<'); if(pstart == 0 || pstart-buf == 0) return ; texttw = malloc_str(buf, pstart-buf); deal(MARK_BTW, texttw, pstart-buf, parm); free(texttw); }
char * anlizemark(char * mark, int maxsize, const char ** pend, const char *buf) { const char * pstart = strchr(buf, '<'); const char * pendstr = strchr_s(pstart, '>'); if(pstart && pendstr && pendstr-pstart < maxsize) { strncpy(mark, pstart+1, pendstr-pstart-1); mark[pendstr-pstart-1] = 0; *pend = pendstr+1; return mark; } else { return 0; } }
bsdlinfo *parse_extract_values(char *bsdlfilename) { FILE *fd; int filesize; bsdlinfo *ret; char *filedata; char *linedata; char *token; char *last; char *cmdbuf; int filepos = 0; int i,j; char done,valid,opens; int IR_size = -1; uint8_t found_IR_size = 0; uint32_t debug_cmd = TAP_CMD_INVALID; uint32_t user1_cmd = TAP_CMD_INVALID; uint32_t idcode_cmd = TAP_CMD_INVALID; uint8_t found_cmds = 0; uint32_t idcode = 0; uint32_t idcode_mask = 0xFFFFFFFF; // 'X' is a valid char in an IDCODE, set 0's here for X's. uint8_t found_idcode = 0; char *entityname = NULL; // Open the file fd = fopen(bsdlfilename, "r"); if(fd == NULL) { printf("ERROR: failed to open BSDL file %s\n", bsdlfilename); return NULL; } fseek(fd, 0, SEEK_END); filesize = ftell(fd); fseek(fd, 0, SEEK_SET); filedata = (char *) malloc(filesize); if(filedata == NULL) { printf("ERROR: failed to allocate memory for BSDL file %s\n", bsdlfilename); return NULL; } if(fread(filedata, 1, filesize, fd) < filesize) { // 1 long read will be faster than many short ones printf("Warning: failed to read entire BSDL file %s\n", bsdlfilename); } fclose(fd); // while there's more data and not all values have been found while((filepos < filesize) && (!found_IR_size || !found_cmds || !found_idcode)) { // Get a line. Replace any "--" with a \0 char filepos = get_line(filedata, filepos, &linedata, filesize); // look for each value token = strtok_r(linedata, " \t", &last); if(token == NULL) { printf("ERROR: End of file reached before END statement is BSDL file \'%s\'\n", bsdlfilename); break; } if(!strcmp(strtoupper(token), "ENTITY")) { // Parse an entity line token = strtok_r(NULL, " \t", &last); if(token != NULL) { entityname = (char *) malloc(strlen(token)); if(entityname != NULL) strcpy(entityname, token); debug("Found entity \'%s\'\n", entityname); } else { printf("Parse error near ENTITY token in file %s\n", bsdlfilename); } } else if(!strcmp(strtoupper(token), "CONSTANT")) { // Parse a constant declaration...we ignore them, just get lines until we find a ';' char // assume nothing else useful comes on the line after the ';' // Slightly awkward, since we have to search the rest of the line after the strtok, then possible // new lines as well. token = strtok_r(NULL, " \t", &last); // debug...don't worry about error, token only used in printf debug("Ignoring constant \'%s\'\n", token); // debug while(strchr(last, ';') == NULL) { filepos = get_line(filedata, filepos, &last, filesize); } } else if(!strcmp(strtoupper(token), "GENERIC")) { // Parse a generic declaration...we ignore them, just get lines until we find a ';' char // assume nothing else useful comes on the line after the ';' // Slightly awkward, since we have to search the rest of the line after the strtok, then possible // new lines as well. token = strtok_r(NULL, " \t", &last); // debug...don't worry about error, token only used in printf debug("Ignoring generic \'%s\'\n", token); // debug while(strchr(last, ';') == NULL) { filepos = get_line(filedata, filepos, &last, filesize); } } else if(!strcmp(strtoupper(token), "USE")) { // Parse a 'use' declaration...we ignore them, just get lines until we find a ';' char // assume nothing else useful comes on the line after the ';' // Note that there may be no space after the token, so add ';' to the tokenizing list in the debug bits. // Slightly awkward, since we have to search the rest of the line after the strtok, then possible // new lines as well. token = strtok_r(NULL, " \t;", &last); // debug ...don't worry about error, token only used in printf debug("Ignoring use \'%s\'\n", token); // debug while(strchr(last, ';') == NULL) { filepos = get_line(filedata, filepos, &last, filesize); } } else if(!strcmp(strtoupper(token), "END")) { // We're done, whether we've found what we want or not. Eject eject eject... debug("Found END token, stopping parser\n"); break; } else if(!strcmp(strtoupper(token), "PORT")) { // Parse a port list. Find a '(', find a ')', find a ';'. // Note that "()" pairs may occur in between. // 'last' must be set in the first two strchr() calls so that the next strchr() call will // begin parsing after the previous char position. Otherwise, e.g. a ';' before the ')' but on the same // line would (incorrectly) satisfy the search. while((last = strchr(last, '(')) == NULL) { filepos = get_line(filedata, filepos, &last, filesize); } opens = 1; last++; // don't leave 'last' pointing at the '(' char, since we're looking for another do { while((last = strchr_s(last, "()")) == NULL) { filepos = get_line(filedata, filepos, &last, filesize); // *** abort if new line is empty } if(*last == '(') opens++; else if(*last == ')') opens--; last++; // don't leave last pointing at the same "()" char, since we're looking for another } while(opens); while(strchr(last, ';') == NULL) { filepos = get_line(filedata, filepos, &last, filesize); } debug("Ignored port statement\n"); } else if(!strcmp(strtoupper(token), "ATTRIBUTE")) { // Parse an attribute token = strtok_r(NULL, " \t", &last); // *** check for error if(!strcmp(strtoupper(token), "INSTRUCTION_LENGTH")) { // Find ':', then "entity", then "is", then take anything before the ';' as the value while((last = strchr(last, ':')) == NULL) { filepos = get_line(filedata, filepos, &last, filesize); // *** check last actually has data? } while((last = strstr(last, "entity")) == NULL) { // don't do strtoupper() here, that would do the entire line filepos = get_line(filedata, filepos, &last, filesize); // *** check last actually has data? } while((last = strstr(last, "is")) == NULL) { filepos = get_line(filedata, filepos, &last, filesize); // *** check last actually has data? } // scan until the end of the line looking for data j = 0; done = 0; while(*last != '\0') { if(isdigit(*last)) tmpbuf[j++] = *last; else if(*last == ';') { done = 1; break;} last++; } // May need to go to additional lines while(!done) { filepos = get_line(filedata, filepos, &linedata, filesize); // *** break if linedata has no data while(*linedata != '\0') { if(isdigit(*linedata)) tmpbuf[j++] = *linedata; else if(*linedata == ';') { done = 1; break;} linedata++; } } tmpbuf[j] = '\0'; IR_size = strtoul(tmpbuf, NULL, 0); found_IR_size = 1; debug("Found IR size %i (%s)\n", IR_size, tmpbuf); } // end if INSTRUCTION_LENGTH else if(!strcmp(strtoupper(token), "INSTRUCTION_OPCODE")) { // Find ": entity is" while((last = strchr(last, ':')) == NULL) { filepos = get_line(filedata, filepos, &last, filesize); // *** check last actually has data? } while((last = strstr(last, "entity")) == NULL) { // don't do strtoupper() here, that would do the entire line filepos = get_line(filedata, filepos, &last, filesize); // *** check last actually has data? } while((last = strstr(last, "is")) == NULL) { filepos = get_line(filedata, filepos, &last, filesize); // *** check last actually has data? } // We're going to copy the entire attribute (all commands) into a temp. buffer. We need a big enough buffer, // and we can't just scan for ';' to find out because there's a '\0' at the end of this line. // But, it can't be bigger than the entire rest of the file, so... cmdbuf = (char *) malloc(filesize-filepos); // Parse until ';', and grab everything between each pair of "" found // Note that 'last' still points at "is" j = 0; done = 0; valid = 0; while(*last != '\0') { if(*last == ';') { done = 1; break;} // Put this first in case of badly formed BSDL files else if(valid && (*last != '\"')) cmdbuf[j++] = *last; else if(*last == '\"') valid = !valid; last++; } // May need to go to additional lines while(!done) { filepos = get_line(filedata, filepos, &linedata, filesize); // *** break if linedata has no data while(*linedata != '\0') { if(valid && (*linedata != '\"')) cmdbuf[j++] = *linedata; else if(*linedata == '\"') valid = !valid; else if(*linedata == ';') { done = 1; break;} linedata++; } } cmdbuf[j] = '\0'; // Parse the opcodes attribute. This is an exercise unto itself, so do it in another function. parse_opcodes(cmdbuf, &debug_cmd, &user1_cmd, &idcode_cmd); found_cmds = 1; free(cmdbuf); } // end if INSTRUCTION_OPCODE else if(!strcmp(strtoupper(token), "IDCODE_REGISTER")) { // Find : entity is while((last = strchr(last, ':')) == NULL) { filepos = get_line(filedata, filepos, &last, filesize); // *** check last actually has data? } while((last = strstr(last, "entity")) == NULL) { // don't do strtoupper() here, that would do the entire line filepos = get_line(filedata, filepos, &last, filesize); // *** check last actually has data? } while((last = strstr(last, "is")) == NULL) { filepos = get_line(filedata, filepos, &last, filesize); // *** check last actually has data? } // Parse until ';', and grab everything between each pair of "" found // Note that 'last' still points at "is" j = 0; done = 0; valid = 0; while(*last != '\0') { if(*last == ';') { done = 1; break;} // Put this first in case of badly formed BSDL files else if(valid && (*last != '\"')) tmpbuf[j++] = *last; else if(*last == '\"') valid = !valid; last++; } // May need to go to additional lines while(!done) { filepos = get_line(filedata, filepos, &linedata, filesize); // *** break if linedata has no data while(*linedata != '\0') { if(valid && (*linedata != '\"')) tmpbuf[j++] = *linedata; else if(*linedata == '\"') valid = !valid; else if(*linedata == ';') { done = 1; break;} linedata++; } } tmpbuf[j] = '\0'; // Parse the tmpbuf if(j != 32) printf("Warning: found %i chars (expected 32) while getting IDCODE in BSDL file %s.\n", j, bsdlfilename); // Sanity check debug("Got IDCODE string \'%s\'\n", tmpbuf); for(i = 0; i < j; i++) { if(tmpbuf[i] == '1') idcode |= 0x1<<(31-i); else if(toupper(tmpbuf[i]) == 'X') idcode_mask &= ~(0x1<<(31-i)); } debug("Found IDCODE 0x%08X (%s), mask is 0x%08X\n", idcode, tmpbuf, idcode_mask); found_idcode = 1; } // end if IDCODE_REGISTER else { debug("Ignoring attribute \'%s\'\n", token); // Consume chars until ';' found while(strchr(last, ';') == NULL) { filepos = get_line(filedata, filepos, &last, filesize); } } } else { debug("Unknown token \'%s\' found in BSDL file %s\n", token, bsdlfilename); } } free(filedata); // Put the data in a struct for return and storage ret = (bsdlinfo *) malloc(sizeof(bsdlinfo)); if(ret == NULL) { printf("Error: out of memory, unable to store BSDL info for file %s\n", bsdlfilename); return NULL; } ret->name = entityname; // this was malloc'd, so it's persistant, this is safe ret->idcode = idcode; ret->idcode_mask = idcode_mask; ret->IR_size = IR_size; ret->cmd_debug = debug_cmd; ret->cmd_user1 = user1_cmd; ret->cmd_idcode = idcode_cmd; ret->next = NULL; return ret; }
const char * anlizetext(const char * mark, const char * buf, callback deal, void * parm) { char * marklow = (char *)malloc(strlen(mark)+1); strtolower(marklow, mark); if(marklow[0] != '/') { int count = 1; char bname[1024]; char nameend[1024]; char tmpmark[1024]; const char * bufbp = buf; const char * next = buf; strcpy(nameend, "/"); strcat(nameend, marklow); if(!strcmp(marklow, "script")) // 跳过关于script内部的内容 { char * tw = 0; strcpy(nameend, "</"); strcat(nameend, marklow); buf = getmark(nameend, buf); if(buf == 0) { free(marklow); return bufbp; } tw = malloc_str(bufbp, buf-bufbp); if(tw) { deal(MARK_BTW, tw, buf-bufbp, parm); free(tw); } count = 0; } while(count) { buf = next; if(!anlizemark(tmpmark, 1024, &next, buf)) break ; if(isnote(tmpmark)) continue; if(!getkey(bname, 1024, 0, tmpmark)) break; strtolower(bname, bname); if(!strcmp(bname, marklow)) count++; if(!strcmp(bname, nameend)) count--; buf = strchr_s(buf, '<'); } while(count == 0) { char * tmpbuf = malloc_str(bufbp, buf-bufbp); if(!tmpbuf) break; deal(MARK_TXT, tmpbuf, buf-bufbp+1, parm); free(tmpbuf); break; } } free(marklow); return buf; }