const char *get_type(RfListItem *typed) { if (!typed) return "*0"; if (typed->IsChar()) { if (is_capital(typed->charcode)) return "Lu"; if (is_lower(typed->charcode)) return "Ll"; return "Ol"; } if (typed->IsLeftMarkup()) return "B0"; SExpressionInt *ti; ti = typed->symb_val.DynamicCastGetPtr<SExpressionInt>(); if (ti) return "N0"; SExpressionFloat *tf; tf = typed->symb_val.DynamicCastGetPtr<SExpressionFloat>(); if (tf) return "D0"; SString repr = typed->symb_val->TextRepresentation(); char *str = (char *)repr.c_str(); if (is_ident(str)) return "Wi"; return "Wq"; }
/* parse an entry reference string into routine, label & offset */ void lref_parse(unsigned char *label_ref, mstr* routine, mstr* label, int* offset) { unsigned char ch, *c, *c1; int i, label_len; error_def (ERR_RUNPARAMERR); routine->addr = label->addr = (char *)label_ref; *offset = 0; label_len = STRLEN((const char *)label_ref); for (i = 0, c = label_ref; i < label_len; i++) { ch = *c++; if (ch == '^' || ch == '+') { label->len = i; if (ch == '+') { *offset = (int)STRTOL((const char *)c, (char**)&c1, 10); if (c == c1 ||*c1 != '^') rts_error(VARLSTCNT(1) ERR_RUNPARAMERR); c = c1 + 1; } routine->addr = (char *)c; routine->len = INTCAST(label_ref + label_len - c); break; } } if (routine->addr == (char *)label_ref) { routine->len = label_len; routine->addr = (char *)label_ref; label->len = 0; } if (!is_ident(routine)) rts_error(VARLSTCNT(1) ERR_RUNPARAMERR); if (label->len && !is_ident(label)) rts_error(VARLSTCNT(1) ERR_RUNPARAMERR); routine->len = routine->len > MAX_MIDENT_LEN ? MAX_MIDENT_LEN : routine->len; label->len = label->len > MAX_MIDENT_LEN ? MAX_MIDENT_LEN : label->len; }
void write_cmos_layout_header(const char *header_filename) { FILE *fp; const cmos_entry_t *cmos_entry; cmos_checksum_layout_t layout; if ((fp = fopen(header_filename, "w+")) == NULL) { fprintf(stderr, "%s: Can't open file %s for writing: %s\n", prog_name, header_filename, strerror(errno)); exit(1); } fprintf(fp, "/**\n * This is an autogenerated file. Do not EDIT.\n" " * All changes made to this file will be lost.\n" " * See mainboard's cmos.layout file.\n */\n" "\n#ifndef __OPTION_TABLE_H\n" "#define __OPTION_TABLE_H\n\n"); for (cmos_entry = first_cmos_entry(); cmos_entry != NULL; cmos_entry = next_cmos_entry(cmos_entry)) { if (!is_ident((char *)cmos_entry->name)) { fprintf(stderr, "Error - Name %s is an invalid identifier\n", cmos_entry->name); fclose(fp); exit(1); } fprintf(fp, "#define CMOS_VSTART_%s\t%d\n", cmos_entry->name, cmos_entry->bit); fprintf(fp, "#define CMOS_VLEN_%s\t%d\n", cmos_entry->name, cmos_entry->length); } layout.summed_area_start = cmos_checksum_start; layout.summed_area_end = cmos_checksum_end; layout.checksum_at = cmos_checksum_index; checksum_layout_to_bits(&layout); fprintf(fp, "\n#define LB_CKS_RANGE_START %d\n", layout.summed_area_start / 8); fprintf(fp, "#define LB_CKS_RANGE_END %d\n", layout.summed_area_end / 8); fprintf(fp, "#define LB_CKS_LOC %d\n", layout.checksum_at / 8); fprintf(fp, "\n#endif /* __OPTION_TABLE_H */\n"); fclose(fp); }
int inv_test(u8 * in, u8 * inv, u8 * sav, int n) { memcpy(sav, in, n * n); if (gf_invert_matrix(in, inv, n)) { printf("Given singular matrix\n"); print_matrix(sav, n); return -1; } matrix_mult(inv, sav, in, n); if (is_ident(in, n)) { printf("fail\n"); print_matrix(sav, n); print_matrix(inv, n); print_matrix(in, n); return -1; } putchar('.'); return 0; }
/** * This routine builds the cmos definition table from the cmos layout file * * The input comes from the configuration file which contains two parts * entries and enumerations. Each section is started with the key words * entries and enumerations. Records then follow in their respective * formats. * * The output of this program is the cmos definitions table. It is stored * in the cmos_table array. If this module is called, and the global * table_file has been implimented by the user, the table is also written * to the specified file. * * This program exits with a return code of 1 on error. It returns 0 on * successful completion */ int main(int argc, char **argv) { int i; char *config=0; char *binary=0; char *option=0; char *header=0; FILE *fp; int tempfile; char tempfilename[TMPFILE_LEN]; struct cmos_option_table *ct; struct cmos_entries *ce; struct cmos_enums *c_enums, *c_enums_start; struct cmos_checksum *cs, *new_cs; char line[INPUT_LINE_MAX]; unsigned char uc; int entry_mode=0; int enum_mode=0; int checksum_mode=0; int cnt; char *cptr; void *entry_start, *entry_end; int entries_length; int enum_length; int len; char buf[16]; char val; for(i=1;i<argc;i++) { if(argv[i][0]!='-') { display_usage(argv[0]); } switch(argv[i][1]) { case '-': /* data is requested from a file */ switch(argv[i][2]) { case 'c': /* use a configuration file */ if(strcmp(&argv[i][2],"config")) { display_usage(argv[0]); } config=argv[++i]; break; case 'b': /* Emit a binary file */ if(strcmp(&argv[i][2],"binary")) { display_usage(argv[0]); } binary=argv[++i]; break; case 'o': /* use a cmos definitions table file */ if(strcmp(&argv[i][2],"option")) { display_usage(argv[0]); } option=argv[++i]; break; case 'h': /* Output a header file */ if (strcmp(&argv[i][2], "header") != 0) { display_usage(argv[0]); } header=argv[++i]; break; default: display_usage(argv[0]); break; } break; default: display_usage(argv[0]); break; } } /* Has the user specified a configuration file */ if(config) { /* if yes, open it */ if((fp=fopen(config,"r"))==NULL){ fprintf(stderr, "Error - Can not open config file %s\n",config); exit(1); /* exit if it can not be opened */ } } else { /* no configuration file specified, so try the default */ if((fp=fopen("cmos.layout","r"))==NULL){ fprintf(stderr, "Error - Can not open cmos.layout\n"); exit(1); /* end of no configuration file is found */ } } /* type cast a pointer, so we can us the structure */ ct=(struct cmos_option_table*)cmos_table; /* start the table with the type signature */ ct->tag = LB_TAG_CMOS_OPTION_TABLE; /* put in the header length */ ct->header_length=sizeof(*ct); /* Get the entry records */ ce=(struct cmos_entries*)(cmos_table+(ct->header_length)); cptr = (char*)ce; for(;;){ /* this section loops through the entry records */ if(fgets(line,INPUT_LINE_MAX,fp)==NULL) break; /* end if no more input */ // FIXME mode should be a single enum. if(!entry_mode) { /* skip input until the entries key word */ if (strstr(line,"entries") != 0) { entry_mode=1; enum_mode=0; checksum_mode=0; continue; } } else { /* Test if we are done with entries and starting enumerations */ if (strstr(line,"enumerations") != 0){ entry_mode=0; enum_mode=1; checksum_mode=0; break; } if (strstr(line, "checksums") != 0) { entry_mode=0; enum_mode=0; checksum_mode=1; break; } } /* skip commented and blank lines */ val = line[strspn(line," ")]; /* takes care of *nix, Mac and Windows line ending formats */ if (val=='#' || val=='\n' || val=='\r') continue; /* scan in the input data */ sscanf(line,"%d %d %c %d %s", &ce->bit,&ce->length,&uc,&ce->config_id,&ce->name[0]); ce->config=(int)uc; /* check bit and length ranges */ if(ce->bit>(CMOS_IMAGE_BUFFER_SIZE*8)) { fprintf(stderr, "Error - bit is to big in line \n%s\n",line); exit(1); } if((ce->length>(MAX_VALUE_BYTE_LENGTH*8))&&(uc!='r')) { fprintf(stderr, "Error - Length is to long in line \n%s\n",line); exit(1); } if (!is_ident((char *)ce->name)) { fprintf(stderr, "Error - Name %s is an invalid identifier in line\n %s\n", ce->name, line); exit(1); } /* put in the record type */ ce->tag=LB_TAG_OPTION; /* calculate and save the record length */ len=strlen((char *)ce->name)+1; /* make the record int aligned */ if(len%4) len+=(4-(len%4)); ce->size=sizeof(struct cmos_entries)-32+len; cptr = (char*)ce; cptr += ce->size; /* increment to the next table position */ ce = (struct cmos_entries*) cptr; } /* put the length of the entries into the header section */ entries_length = (cptr - (char *)&cmos_table) - ct->header_length; /* compute the start of the enumerations section */ entry_start = ((char*)&cmos_table) + ct->header_length; entry_end = ((char *)entry_start) + entries_length; c_enums_start = c_enums = (struct cmos_enums*)entry_end; /* test for overlaps in the entry records */ test_for_entry_overlaps(entry_start, entry_end); for(;enum_mode;){ /* loop to build the enumerations section */ long ptr; if(fgets(line,INPUT_LINE_MAX,fp)==NULL) break; /* go till end of input */ if (strstr(line, "checksums") != 0) { enum_mode=0; checksum_mode=1; break; } /* skip commented and blank lines */ if(line[0]=='#') continue; if(line[strspn(line," ")]=='\n') continue; /* scan in the data */ for(ptr=0;(line[ptr]==' ')||(line[ptr]=='\t');ptr++); c_enums->config_id=strtol(&line[ptr],(char**)NULL,10); for(;(line[ptr]!=' ')&&(line[ptr]!='\t');ptr++); for(;(line[ptr]==' ')||(line[ptr]=='\t');ptr++); c_enums->value=strtol(&line[ptr],(char**)NULL,10); for(;(line[ptr]!=' ')&&(line[ptr]!='\t');ptr++); for(;(line[ptr]==' ')||(line[ptr]=='\t');ptr++); for(cnt=0;(line[ptr]!='\n')&&(cnt<31);ptr++,cnt++) c_enums->text[cnt]=line[ptr]; c_enums->text[cnt]=0; /* make the record int aligned */ cnt++; if(cnt%4) cnt+=4-(cnt%4); /* store the record length */ c_enums->size=((char *)&c_enums->text[cnt]) - (char *)c_enums; /* store the record type */ c_enums->tag=LB_TAG_OPTION_ENUM; /* increment to the next record */ c_enums=(struct cmos_enums*)&c_enums->text[cnt]; } /* save the enumerations length */ enum_length= (char *)c_enums - (char *)c_enums_start; ct->size=ct->header_length+enum_length+entries_length; /* Get the checksum records */ new_cs = (struct cmos_checksum *)(cmos_table+(ct->size)); for(;checksum_mode;) { /* This section finds the checksums */ char *ptr; if(fgets(line, INPUT_LINE_MAX,fp)==NULL) break; /* end if no more input */ /* skip commented and blank lines */ if (line[0]=='#') continue; if (line[strspn(line, " ")]=='\n') continue; if (memcmp(line, "checksum", 8) != 0) continue; /* We actually found a new cmos checksum entry */ cs = new_cs; /* get the information */ ptr = line + 8; skip_spaces(line, &ptr); cs->range_start = get_number(line, &ptr, 10); skip_spaces(line, &ptr); cs->range_end = get_number(line, &ptr, 10); skip_spaces(line, &ptr); cs->location = get_number(line, &ptr, 10); /* Make certain there are spaces until the end of the line */ skip_spaces(line, &ptr); if ((cs->range_start%8) != 0) { fprintf(stderr, "Error - range start is not byte aligned in line\n%s\n", line); exit(1); } if (cs->range_start >= (CMOS_IMAGE_BUFFER_SIZE*8)) { fprintf(stderr, "Error - range start is to big in line\n%s\n", line); exit(1); } if ((cs->range_end%8) != 7) { fprintf(stderr, "Error - range end is not byte aligned in line\n%s\n", line); exit(1); } if ((cs->range_end) >= (CMOS_IMAGE_BUFFER_SIZE*8)) { fprintf(stderr, "Error - range end is to long in line\n%s\n", line); exit(1); } if ((cs->location%8) != 0) { fprintf(stderr, "Error - location is not byte aligned in line\n%s\n", line); exit(1); } if ((cs->location >= (CMOS_IMAGE_BUFFER_SIZE*8)) || ((cs->location + 16) > (CMOS_IMAGE_BUFFER_SIZE*8))) { fprintf(stderr, "Error - location is to big in line\n%s\n", line); exit(1); } cs->tag = LB_TAG_OPTION_CHECKSUM; cs->size = sizeof(*cs); cs->type = CHECKSUM_PCBIOS; cptr = (char *)cs; cptr += cs->size; new_cs = (struct cmos_checksum *)cptr; } ct->size += (cptr - (char *)(cmos_table + ct->size)); fclose(fp); /* See if we want to output a C source file */ if(option) { int err=0; snprintf(tempfilename, TMPFILE_LEN, "%s%s", dirname(strdup(option)), TMPFILE_TEMPLATE); tempfile = mkstemp(tempfilename); if(tempfile == -1) { perror("Error - Could not create temporary file"); exit(1); } if((fp=fdopen(tempfile,"w"))==NULL){ perror("Error - Could not open temporary file"); unlink(tempfilename); exit(1); } /* write the header */ if(fwrite("unsigned char option_table[] = {",1,32,fp) != 32) { perror("Error - Could not write image file"); fclose(fp); unlink(tempfilename); exit(1); } /* write the array values */ for(i=0; i<(int)(ct->size-1); i++) { if(!(i%10) && !err) err=(fwrite("\n\t",1,2,fp) != 2); sprintf(buf,"0x%02x,",cmos_table[i]); if(!err) err=(fwrite(buf,1,5,fp) != 5); } /* write the end */ sprintf(buf,"0x%02x\n",cmos_table[i]); if(!err) err=(fwrite(buf,1,4,fp) != 4); if(fwrite("};\n",1,3,fp) != 3) { perror("Error - Could not write image file"); fclose(fp); unlink(tempfilename); exit(1); } fclose(fp); UNLINK_IF_NECESSARY(option); if (rename(tempfilename, option)) { fprintf(stderr, "Error - Could not write %s: ", option); perror(NULL); unlink(tempfilename); exit(1); } } /* See if we also want to output a binary file */ if(binary) { int err=0; snprintf(tempfilename, TMPFILE_LEN, "%s%s", dirname(strdup(binary)), TMPFILE_TEMPLATE); tempfile = mkstemp(tempfilename); if(tempfile == -1) { perror("Error - Could not create temporary file"); exit(1); } if((fp=fdopen(tempfile,"wb"))==NULL){ perror("Error - Could not open temporary file"); unlink(tempfilename); exit(1); } /* write the array values */ if(fwrite(cmos_table, (int)(ct->size-1), 1, fp) != 1) { perror("Error - Could not write image file"); fclose(fp); unlink(tempfilename); exit(1); } fclose(fp); UNLINK_IF_NECESSARY(binary); if (rename(tempfilename, binary)) { fprintf(stderr, "Error - Could not write %s: ", binary); perror(NULL); unlink(tempfilename); exit(1); } } /* See if we also want to output a C header file */ if (header) { struct cmos_option_table *hdr; struct lb_record *ptr, *end; snprintf(tempfilename, TMPFILE_LEN, "%s%s", dirname(strdup(header)), TMPFILE_TEMPLATE); tempfile = mkstemp(tempfilename); if(tempfile == -1) { perror("Error - Could not create temporary file"); exit(1); } fp = fdopen(tempfile, "w"); if (!fp) { perror("Error - Could not open temporary file"); unlink(tempfilename); exit(1); } /* Get the cmos table header */ hdr = (struct cmos_option_table *)cmos_table; /* Walk through the entry records */ ptr = (struct lb_record *)(cmos_table + hdr->header_length); end = (struct lb_record *)(cmos_table + hdr->size); fprintf(fp, "/* This file is autogenerated.\n" " * See mainboard's cmos.layout file.\n */\n\n" "#ifndef __OPTION_TABLE_H\n#define __OPTION_TABLE_H\n\n"); for(;ptr < end; ptr = (struct lb_record *)(((char *)ptr) + ptr->size)) { if (ptr->tag != LB_TAG_OPTION) { continue; } ce = (struct cmos_entries *)ptr; if (!is_ident((char *)ce->name)) { fprintf(stderr, "Invalid identifier: %s\n", ce->name); fclose(fp); unlink(tempfilename); exit(1); } fprintf(fp, "#define CMOS_VSTART_%s %d\n", ce->name, ce->bit); fprintf(fp, "#define CMOS_VLEN_%s %d\n", ce->name, ce->length); } if (cs != NULL) { fprintf(fp, "\n#define LB_CKS_RANGE_START %d\n", cs->range_start / 8); fprintf(fp, "#define LB_CKS_RANGE_END %d\n", cs->range_end / 8); fprintf(fp, "#define LB_CKS_LOC %d\n", cs->location / 8); } else { fprintf(stderr, "Error - No checksums defined.\n"); fclose(fp); unlink(tempfilename); exit(1); } fprintf(fp, "\n#endif // __OPTION_TABLE_H\n"); fclose(fp); UNLINK_IF_NECESSARY(header); if (rename(tempfilename, header)) { fprintf(stderr, "Error - Could not write %s: ", header); perror(NULL); unlink(tempfilename); exit(1); } } return 0; }
int write_cmos_layout_bin(FILE *f) { const cmos_entry_t *cmos_entry; const cmos_enum_t *cmos_enum; cmos_checksum_layout_t layout; struct cmos_option_table table; struct cmos_entries entry; struct cmos_enums cenum; struct cmos_checksum csum; size_t sum = 0; int len; for (cmos_entry = first_cmos_entry(); cmos_entry != NULL; cmos_entry = next_cmos_entry(cmos_entry)) { if (cmos_entry == first_cmos_entry()) { sum += sizeof(table); table.header_length = sizeof(table); table.tag = LB_TAG_CMOS_OPTION_TABLE; table.size = 0; if (fwrite((char *)&table, sizeof(table), 1, f) != 1) { perror("Error writing image file"); goto err; } } memset(&entry, 0, sizeof(entry)); entry.tag = LB_TAG_OPTION; entry.config = cmos_entry->config; entry.config_id = (uint32_t)cmos_entry->config_id; entry.bit = cmos_entry->bit; entry.length = cmos_entry->length; if (!is_ident((char *)cmos_entry->name)) { fprintf(stderr, "Error - Name %s is an invalid identifier\n", cmos_entry->name); goto err; } memcpy(entry.name, cmos_entry->name, strlen(cmos_entry->name)); entry.name[strlen(cmos_entry->name)] = '\0'; len = strlen(cmos_entry->name) + 1; if (len % 4) ROUNDUP4(len); entry.size = sizeof(entry) - CMOS_MAX_NAME_LENGTH + len; sum += entry.size; if (fwrite((char *)&entry, entry.size, 1, f) != 1) { perror("Error writing image file"); goto err; } } for (cmos_enum = first_cmos_enum(); cmos_enum != NULL; cmos_enum = next_cmos_enum(cmos_enum)) { memset(&cenum, 0, sizeof(cenum)); cenum.tag = LB_TAG_OPTION_ENUM; memcpy(cenum.text, cmos_enum->text, strlen(cmos_enum->text)); cenum.text[strlen(cmos_enum->text)] = '\0'; len = strlen((char *)cenum.text) + 1; if (len % 4) ROUNDUP4(len); cenum.config_id = cmos_enum->config_id; cenum.value = cmos_enum->value; cenum.size = sizeof(cenum) - CMOS_MAX_TEXT_LENGTH + len; sum += cenum.size; if (fwrite((char *)&cenum, cenum.size, 1, f) != 1) { perror("Error writing image file"); goto err; } } layout.summed_area_start = cmos_checksum_start; layout.summed_area_end = cmos_checksum_end; layout.checksum_at = cmos_checksum_index; checksum_layout_to_bits(&layout); csum.tag = LB_TAG_OPTION_CHECKSUM; csum.size = sizeof(csum); csum.range_start = layout.summed_area_start; csum.range_end = layout.summed_area_end; csum.location = layout.checksum_at; csum.type = CHECKSUM_PCBIOS; sum += csum.size; if (fwrite((char *)&csum, csum.size, 1, f) != 1) { perror("Error writing image file"); goto err; } if (fseek(f, 0, SEEK_SET) != 0) { perror("Error while seeking"); goto err; } table.size = sum; if (fwrite((char *)&table, sizeof(table), 1, f) != 1) { perror("Error writing image file"); goto err; } return sum; err: fclose(f); exit(1); }
/** * \brief Read a token from a buffer * \param File Parser state */ int GetToken(tParser *File) { int ret; if( File->ErrorHit ) { return TOK_INVAL; } if( File->NextState.Token != TOK_INVAL ) { // Save Last File->PrevState = File->Cur; // Restore Next File->Cur = File->NextState; // Set State File->CurPos = File->Cur.TokenStr + File->Cur.TokenLen; File->NextState.Token = TOK_INVAL; #if DEBUG printf(" GetToken: FAST Return %i (%i long) (%.*s)\n", File->Cur.Token, File->Cur.TokenLen, File->Cur.TokenLen, File->Cur.TokenStr); #endif return File->Cur.Token; } //printf(" GetToken: File=%p, File->CurPos = %p\n", File, File->CurPos); // Clear whitespace (including comments) for( ;; ) { // Whitespace while( isspace( *File->CurPos ) ) { //printf("whitespace 0x%x, line = %i\n", *File->CurPos, File->CurLine); if( *File->CurPos == '\n' ) File->Cur.Line ++; File->CurPos ++; } // # Line Comments if( *File->CurPos == '#' ) { while( *File->CurPos && *File->CurPos != '\n' ) File->CurPos ++; continue ; } // C-Style Line Comments if( *File->CurPos == '/' && File->CurPos[1] == '/' ) { while( *File->CurPos && *File->CurPos != '\n' ) File->CurPos ++; continue ; } // C-Style Block Comments if( *File->CurPos == '/' && File->CurPos[1] == '*' ) { File->CurPos += 2; // Eat the '/*' while( *File->CurPos && !(File->CurPos[-1] == '*' && *File->CurPos == '/') ) { if( *File->CurPos == '\n' ) File->Cur.Line ++; File->CurPos ++; } File->CurPos ++; // Eat the '/' continue ; } // No more "whitespace" break; } // Save previous tokens (speeds up PutBack and LookAhead) File->PrevState = File->Cur; // Read token File->Cur.TokenStr = File->CurPos; switch( *File->CurPos++ ) { case '\0': ret = TOK_EOF; break; // Operations case '^': if( *File->CurPos == '^' ) { File->CurPos ++; ret = TOK_LOGICXOR; break; } ret = TOK_XOR; break; case '|': if( *File->CurPos == '|' ) { File->CurPos ++; ret = TOK_LOGICOR; break; } ret = TOK_OR; break; case '&': if( *File->CurPos == '&' ) { File->CurPos ++; ret = TOK_LOGICAND; break; } ret = TOK_AND; break; case '/': if( *File->CurPos == '=' ) { File->CurPos ++; ret = TOK_ASSIGN_DIV; break; } ret = TOK_DIV; break; case '%': if( *File->CurPos == '=' ) { File->CurPos ++; ret = TOK_ASSIGN_MODULO; break; } ret = TOK_MODULO; break; case '*': if( *File->CurPos == '=' ) { File->CurPos ++; ret = TOK_ASSIGN_MUL; break; } ret = TOK_MUL; break; case '+': if( *File->CurPos == '+' ) { File->CurPos ++; ret = TOK_INCREMENT; break; } if( *File->CurPos == '=' ) { File->CurPos ++; ret = TOK_ASSIGN_PLUS; break; } ret = TOK_PLUS; break; case '-': if( *File->CurPos == '-' ) { File->CurPos ++; ret = TOK_DECREMENT; break; } if( *File->CurPos == '=' ) { File->CurPos ++; ret = TOK_ASSIGN_MINUS; break; } if( *File->CurPos == '>' ) { File->CurPos ++; ret = TOK_ELEMENT; break; } ret = TOK_MINUS; break; // Strings case '"': while( *File->CurPos && !(*File->CurPos == '"' && File->CurPos[-1] != '\\') ) File->CurPos ++; if( *File->CurPos ) { File->CurPos ++; ret = TOK_STR; } else ret = TOK_EOF; break; // Brackets case '(': ret = TOK_PAREN_OPEN; break; case ')': ret = TOK_PAREN_CLOSE; break; case '{': ret = TOK_BRACE_OPEN; break; case '}': ret = TOK_BRACE_CLOSE; break; case '[': ret = TOK_SQUARE_OPEN; break; case ']': ret = TOK_SQUARE_CLOSE; break; // Core symbols case ';': ret = TOK_SEMICOLON; break; case ',': ret = TOK_COMMA; break; case ':': ret = TOK_COLON; break; case '?': if( *File->CurPos == ':' ) { File->CurPos ++; ret = TOK_QMARKCOLON; } else ret = TOK_QUESTIONMARK; break; case '.': if( *File->CurPos == '.' && File->CurPos[1] == '.' ) { File->CurPos += 2; ret = TOK_ELIPSIS; } else #if USE_SCOPE_CHAR ret = TOK_SCOPE; #else goto default; #endif break; // Equals case '=': if( *File->CurPos != '=' ) { // Assignment Equals ret = TOK_ASSIGN; break; } File->CurPos ++; if( *File->CurPos != '=' ) { // Comparison Equals ret = TOK_EQUALS; break; } File->CurPos ++; ret = TOK_REFEQUALS; break; // Less-Than case '<': // Less-Than or Equal if( *File->CurPos == '=' ) { File->CurPos ++; ret = TOK_LTE; break; } ret = TOK_LT; break; // Greater-Than case '>': // Greater-Than or Equal if( *File->CurPos == '=' ) { File->CurPos ++; ret = TOK_GTE; break; } ret = TOK_GT; break; // Logical NOT case '!': if( *File->CurPos != '=' ) { ret = TOK_LOGICNOT; break; } File->CurPos ++; if( *File->CurPos != '=' ) { ret = TOK_NOTEQUALS; break; } File->CurPos ++; ret = TOK_REFNOTEQUALS; break; // Bitwise NOT case '~': ret = TOK_BWNOT; break; // Variables // \$[0-9]+ or \$[_a-zA-Z][_a-zA-Z0-9]* case '$': // Numeric Variable if( isdigit( *File->CurPos ) ) { while( isdigit(*File->CurPos) ) File->CurPos ++; } // Ident Variable else { while( is_ident(*File->CurPos) || isdigit(*File->CurPos) ) File->CurPos ++; } ret = TOK_VARIABLE; break; // Default (Numbers and Identifiers) default: File->CurPos --; // Numbers if( isdigit(*File->CurPos) ) { ret = TOK_INTEGER; if( *File->CurPos == '0' && File->CurPos[1] == 'x' ) { File->CurPos += 2; while(('0' <= *File->CurPos && *File->CurPos <= '9') || ('A' <= *File->CurPos && *File->CurPos <= 'F') || ('a' <= *File->CurPos && *File->CurPos <= 'f') ) { File->CurPos ++; } } else { while( isdigit(*File->CurPos) ) File->CurPos ++; // printf("*File->CurPos = '%c'\n", *File->CurPos); // Decimal if( *File->CurPos == '.' ) { ret = TOK_REAL; File->CurPos ++; while( isdigit(*File->CurPos) ) File->CurPos ++; } // Exponent if( *File->CurPos == 'e' || *File->CurPos == 'E' ) { ret = TOK_REAL; File->CurPos ++; if(*File->CurPos == '-' || *File->CurPos == '+') File->CurPos ++; while( isdigit(*File->CurPos) ) File->CurPos ++; } // printf(" ret = %i\n", ret); } break; } // Identifier if( is_ident(*File->CurPos) ) { ret = TOK_IDENT; // Identifier while( is_ident(*File->CurPos) || isdigit(*File->CurPos) ) File->CurPos ++; // This is set later too, but we use it below const char *tokstr = File->Cur.TokenStr; size_t len = File->CurPos - tokstr; // Check if it's a reserved word for( int i = 0; i < ARRAY_SIZE(csaReservedWords); i ++ ) { if( strncmp(csaReservedWords[i].Name, tokstr, len) != 0 ) continue ; if( csaReservedWords[i].Name[len] != '\0' ) continue ; ret = csaReservedWords[i].Value; break ; } // If there's no match, just keep ret as TOK_IDENT break; } // Syntax Error ret = TOK_INVAL; File->ErrorHit = 1; SyntaxError_(File, -1, "Unknown symbol '%c'", *File->CurPos); break; } // Return File->Cur.Token = ret; File->Cur.TokenLen = File->CurPos - File->Cur.TokenStr; #if DEBUG printf(" GetToken: Return %i (%i long) (%.*s)\n", ret, File->Cur.TokenLen, File->Cur.TokenLen, File->Cur.TokenStr); #endif return ret; }
static enum rules_token lex(struct scanner *s, union lvalue *val) { skip_more_whitespace_and_comments: /* Skip spaces. */ while (chr(s, ' ') || chr(s, '\t')); /* Skip comments. */ if (lit(s, "//")) { while (!eof(s) && !eol(s)) next(s); } /* New line. */ if (eol(s)) { while (eol(s)) next(s); return TOK_END_OF_LINE; } /* Escaped line continuation. */ if (chr(s, '\\')) { if (!eol(s)) { scanner_err(s, "illegal new line escape; must appear at end of line"); return TOK_ERROR; } next(s); goto skip_more_whitespace_and_comments; } /* See if we're done. */ if (eof(s)) return TOK_END_OF_FILE; /* New token. */ s->token_line = s->line; s->token_column = s->column; /* Operators and punctuation. */ if (chr(s, '!')) return TOK_BANG; if (chr(s, '=')) return TOK_EQUALS; if (chr(s, '*')) return TOK_STAR; /* Group name. */ if (chr(s, '$')) { val->string.start = s->s + s->pos; val->string.len = 0; while (is_ident(peek(s))) { next(s); val->string.len++; } if (val->string.len == 0) { scanner_err(s, "unexpected character after \'$\'; expected name"); return TOK_ERROR; } return TOK_GROUP_NAME; } /* Identifier. */ if (is_ident(peek(s))) { val->string.start = s->s + s->pos; val->string.len = 0; while (is_ident(peek(s))) { next(s); val->string.len++; } return TOK_IDENTIFIER; } scanner_err(s, "unrecognized token"); return TOK_ERROR; }
static bool shunting_yard(const TCHAR *input, TCHAR *output) { const TCHAR *strpos = input, *strend = input + _tcslen(input); TCHAR c, *outpos = output; TCHAR stack[STACK_SIZE]; // operator stack unsigned int sl = 0; // stack length TCHAR sc; // used for record stack element while(strpos < strend) { if (sl >= STACK_SIZE) return false; // read one token from the input stream c = *strpos; if(c != ' ') { // If the token is a number (identifier), then add it to the output queue. if(is_ident(c)) { *outpos = c; ++outpos; } // If the token is a function token, then push it onto the stack. else if(is_function(c)) { stack[sl] = c; ++sl; } // If the token is a function argument separator (e.g., a comma): else if(c == ',') { bool pe = false; while(sl > 0) { sc = stack[sl - 1]; if(sc == '(') { pe = true; break; } else { // Until the token at the top of the stack is a left parenthesis, // pop operators off the stack onto the output queue. *outpos = sc; ++outpos; sl--; } } // If no left parentheses are encountered, either the separator was misplaced // or parentheses were mismatched. if(!pe) { calc_log ((_T("Error: separator or parentheses mismatched\n"))); return false; } } // If the token is an operator, op1, then: else if(is_operator(c)) { while(sl > 0) { sc = stack[sl - 1]; // While there is an operator token, o2, at the top of the stack // op1 is left-associative and its precedence is less than or equal to that of op2, // or op1 is right-associative and its precedence is less than that of op2, if(is_operator(sc) && ((op_left_assoc(c) && (op_preced(c) <= op_preced(sc))) || (!op_left_assoc(c) && (op_preced(c) < op_preced(sc))))) { // Pop o2 off the stack, onto the output queue; *outpos = sc; ++outpos; sl--; } else { break; } } // push op1 onto the stack. stack[sl] = c; ++sl; } // If the token is a left parenthesis, then push it onto the stack. else if(c == '(') { stack[sl] = c; ++sl; } // If the token is a right parenthesis: else if(c == ')') { bool pe = false; // Until the token at the top of the stack is a left parenthesis, // pop operators off the stack onto the output queue while(sl > 0) { sc = stack[sl - 1]; if(sc == '(') { pe = true; break; } else { *outpos = sc; ++outpos; sl--; } } // If the stack runs out without finding a left parenthesis, then there are mismatched parentheses. if(!pe) { calc_log ((_T("Error: parentheses mismatched\n"))); return false; } // Pop the left parenthesis from the stack, but not onto the output queue. sl--; // If the token at the top of the stack is a function token, pop it onto the output queue. if(sl > 0) { sc = stack[sl - 1]; if(is_function(sc)) { *outpos = sc; ++outpos; sl--; } } } else { calc_log ((_T("Unknown token %c\n"), c)); return false; // Unknown token } } ++strpos; } // When there are no more tokens to read: // While there are still operator tokens in the stack: while(sl > 0) { sc = stack[sl - 1]; if(sc == '(' || sc == ')') { printf("Error: parentheses mismatched\n"); return false; } *outpos = sc; ++outpos; --sl; } *outpos = 0; // Null terminator return true; }
static bool execution_order(const TCHAR *input, double *outval) { const TCHAR *strpos = input, *strend = input + _tcslen(input); TCHAR c, res[4]; unsigned int sl = 0, rn = 0; struct calcstack stack[STACK_SIZE] = { {0, .0} }, *sc, *sc2; double val = 0; int i; bool ok = false; // While there are input tokens left while(strpos < strend) { if (sl >= STACK_SIZE) return false; // Read the next token from input. c = *strpos; // If the token is a value or identifier if(is_ident(c)) { // Push it onto the stack. stack[sl].s = chartostack (c); ++sl; } // Otherwise, the token is an operator (operator here includes both operators, and functions). else if(is_operator(c) || is_function(c)) { _stprintf(res, _T("_%02d"), rn); calc_log ((_T("%s = "), res)); ++rn; // It is known a priori that the operator takes n arguments. unsigned int nargs = op_arg_count(c); // If there are fewer than n values on the stack if(sl < nargs) { // (Error) The user has not input sufficient values in the expression. return false; } // Else, Pop the top n values from the stack. // Evaluate the operator, with the values as arguments. if(is_function(c)) { calc_log ((_T("%c("), c)); while(nargs > 0){ sc = &stack[sl - nargs]; // to remove reverse order of arguments if(nargs > 1) { calc_log ((_T("%s, "), sc)); } else { calc_log ((_T("%s)\n"), sc)); } --nargs; } sl-=op_arg_count(c); } else { if(nargs == 1) { sc = &stack[sl - 1]; sl--; val = docalc1 (c, sc, val); calc_log ((_T("%c %s = %f;\n"), c, stacktostr(sc), val)); } else { sc = &stack[sl - 2]; calc_log ((_T("%s %c "), stacktostr(sc), c)); sc2 = &stack[sl - 1]; val = docalc2 (c, sc, sc2); sl--;sl--; calc_log ((_T("%s = %f;\n"), stacktostr(sc2), val)); } } // Push the returned results, if any, back onto the stack. stack[sl].val = val; stack[sl].s = NULL; ++sl; } ++strpos; } // If there is only one value in the stack // That value is the result of the calculation. if(sl == 1) { sc = &stack[sl - 1]; sl--; calc_log ((_T("result = %f\n"), val)); if (outval) *outval = val; ok = true; } for (i = 0; i < STACK_SIZE; i++) xfree (stack[i].s); // If there are more values in the stack // (Error) The user input has too many values. return ok; }
static int parse_table(HTable table, char *buf, long int *pos, int top_level) { char *token=NULL; char *name; int res; while (1) { if (! token) token = read_token(buf, pos); if (! token) { if (top_level) return 0; else return -1; } if (! strcmp(token, "{")) { if (add_field_to_array(table, token, buf, pos)) { free(token); return -1; } free(token); token = read_token(buf, pos); if (! token) { if (top_level) return 0; else return -1; } if ((! strcmp(token, ";")) || (! strcmp(token, ","))) { free(token); token = NULL; } continue; } else if (! strcmp(token, "}")) { free(token); if (top_level) return -1; else return 0; } name = token; token = read_token(buf, pos); if (token && (! strcmp(token, "="))) { free(token); if (! is_ident(name)) { free(name); return -1; } token = read_token(buf, pos); if (! token) { free(name); return -1; } res = add_field(table, name, token, buf, pos); free(name); free(token); if (res) { return -1; } token = read_token(buf, pos); if (! token) { if (top_level) return 0; else return -1; } if ((! strcmp(token, ";")) || (! strcmp(token, ","))) { free(token); token = NULL; } else if (strcmp(token, "}")) { free(token); return -1; } } else { if ((! token) && (! top_level)) { free(name); return -1; } if (! (token && ((! strcmp(token, ";")) || (! strcmp(token, ",")) || (! strcmp(token, "}"))))) { free(name); if (token) free(token); return -1; } res = add_field_to_array(table, name, buf, pos); free(name); if (res) { free(token); return -1; } if ((! token) || (! strcmp(token, "}"))) { if (token) free(token); return 0; } if (token && ((! strcmp(token, ",")) || ((! strcmp(token, ";"))))) { free(token); token = NULL; } } } return 0; }
static obj_t parse_atom(struct Parser *st) { struct token *t = next(st); size_t i; switch (t->type) { case DOT: reportlocf(st->rep, t->loc, "datum expected"); return unspecific; case CPAREN: reportlocf(st->rep, t->loc, "unmatched parenthesis"); return unspecific; case END: return unspecific; case CHAR: if (t->len == 2) { reportlocf(st->rep, t->loc, "end-of-input in character literal"); return unspecific; } else if (t->len == 3) { return make_char(t->text[2]); } else { /* Convert to lowercase */ for (i = 0; i < t->len; i++) t->text[i] = tolower(t->text[i]); if (atom_eq("#\\space", t->text, t->len)) { /* Space character literal */ return make_char(' '); } else if (atom_eq("#\\newline", t->text, t->len)) { /* Newline character literal */ return make_char('\n'); } else { reportlocf(st->rep, t->loc, "illegal character literal"); return unspecific; } } case ATOM: /* Convert to lowercase */ for (i = 0; i < t->len; i++) t->text[i] = tolower(t->text[i]); if (atom_eq("#f", t->text, t->len)) { /* False constant */ return false_obj; } else if (atom_eq("#t", t->text, t->len)) { /* True constant */ return true_obj; } else if (is_number(t->text, t->len)) { /* Copy to buffer to make null-terminated */ char *buf = GC_MALLOC_ATOMIC((t->len+1) * sizeof(char)); strncpy(buf, t->text, t->len); buf[t->len] = 0; /* Convert to number */ return make_num(atol(buf)); } else if (is_ident(t->text, t->len)) { /* Symbol */ return make_symbol(intern_string(string_from(t->text, t->len))); } else { /* Invalid atom */ reportlocf(st->rep, t->loc, "unrecognized atom"); return unspecific; } case STRING: return parse_string(st, t); case OARRAY: reportlocf(st->rep, t->loc, "array literals are not supported"); /* fallthrough: continue processing as lists */ case OPAREN: return parse_list(st); case QUOTE: return parse_quotation(S_QUOTE, st); case QUASIQUOTE: return parse_quotation(S_QUASIQUOTE, st); case UNQUOTE: return parse_quotation(S_UNQUOTE, st); case UNQUOTE_SPLICING: return parse_quotation(S_UNQUOTE_SPLICING, st); } /* We should never get to here */ return unspecific; }
bool execution_order(const char *input) { printf("order: (arguments in reverse order)\n"); const char *strpos = input, *strend = input + strlen(input); char c, res[4]; unsigned int sl = 0, sc, stack[32], rn = 0; // While there are input tokens left while(strpos < strend) { // Read the next token from input. c = *strpos; // If the token is a value or identifier if(is_ident(c)) { // Push it onto the stack. stack[sl] = c; ++sl; } // Otherwise, the token is an operator (operator here includes both operators, and functions). else if(is_operator(c) || is_function(c)) { sprintf(res, "_%02d", rn); printf("%s = ", res); ++rn; // It is known a priori that the operator takes n arguments. unsigned int nargs = op_arg_count(c); // If there are fewer than n values on the stack if(sl < nargs) { // (Error) The user has not input sufficient values in the expression. return false; } // Else, Pop the top n values from the stack. // Evaluate the operator, with the values as arguments. if(is_function(c)) { printf("%c(", c); while(nargs > 0) { sc = stack[sl - 1]; sl--; if(nargs > 1) { printf("%s, ", &sc); } else { printf("%s)\n", &sc); } --nargs; } } else { if(nargs == 1) { sc = stack[sl - 1]; sl--; printf("%c %s;\n", c, &sc); } else { sc = stack[sl - 1]; sl--; printf("%s %c ", &sc, c); sc = stack[sl - 1]; sl--; printf("%s;\n",&sc); } } // Push the returned results, if any, back onto the stack. stack[sl] = *(unsigned int*)res; ++sl; } ++strpos; } // If there is only one value in the stack // That value is the result of the calculation. if(sl == 1) { sc = stack[sl - 1]; sl--; printf("%s is a result\n", &sc); return true; } // If there are more values in the stack // (Error) The user input has too many values. return false; }
int main(int argc, char *argv[]) { int i, k, t; u8 *test_mat, *save_mat, *invr_mat; u8 test1[] = { 1, 1, 6, 1, 1, 1, 7, 1, 9 }; u8 test2[] = { 0, 1, 6, 1, 0, 1, 0, 1, 9 }; u8 test3[] = { 0, 0, 1, 1, 0, 0, 0, 1, 1 }; u8 test4[] = { 0, 1, 6, 7, 1, 1, 0, 0, 0, 1, 2, 3, 3, 2, 2, 3 }; // = row3+3*row2 printf("gf_inverse_test: max=%d ", KMAX); test_mat = malloc(KMAX * KMAX); save_mat = malloc(KMAX * KMAX); invr_mat = malloc(KMAX * KMAX); if (NULL == test_mat || NULL == save_mat || NULL == invr_mat) return -1; // Test with lots of leading 1's k = 3; memcpy(test_mat, test1, k * k); if (inv_test(test_mat, invr_mat, save_mat, k)) return -1; // Test with leading zeros k = 3; memcpy(test_mat, test2, k * k); if (inv_test(test_mat, invr_mat, save_mat, k)) return -1; // Test 3 k = 3; memcpy(test_mat, test3, k * k); if (inv_test(test_mat, invr_mat, save_mat, k)) return -1; // Test 4 - try a singular matrix k = 4; memcpy(test_mat, test4, k * k); if (!gf_invert_matrix(test_mat, invr_mat, k)) { printf("Fail: didn't catch singular matrix\n"); print_matrix(test4, 4); return -1; } // Do random test of size KMAX k = KMAX; for (i = 0; i < k * k; i++) test_mat[i] = save_mat[i] = rand(); if (gf_invert_matrix(test_mat, invr_mat, k)) { printf("rand picked a singular matrix, try again\n"); return -1; } matrix_mult(invr_mat, save_mat, test_mat, k); if (is_ident(test_mat, k)) { printf("fail\n"); print_matrix(save_mat, k); print_matrix(invr_mat, k); print_matrix(test_mat, k); return -1; } // Do Randoms. Random size and coefficients for (t = 0; t < RANDOMS; t++) { k = rand() % KMAX; for (i = 0; i < k * k; i++) test_mat[i] = save_mat[i] = rand(); if (gf_invert_matrix(test_mat, invr_mat, k)) continue; matrix_mult(invr_mat, save_mat, test_mat, k); if (is_ident(test_mat, k)) { printf("fail rand k=%d\n", k); print_matrix(save_mat, k); print_matrix(invr_mat, k); print_matrix(test_mat, k); return -1; } if (0 == (t % 8)) putchar('.'); } printf(" Pass\n"); return 0; }
bool shunting_yard(const char *input, char *output) { const char *strpos = input, *strend = input + strlen(input); char c, *outpos = output; char stack[512]; // operator stack unsigned int sl = 0; // stack length char sc; // used for record stack element while(strpos < strend) { // read one token from the input stream c = *strpos; if(c != ' ') { // If the token is a number (identifier), then add it to the output queue. if(is_ident(c)) { *outpos = c; ++outpos; } // If the token is a function token, then push it onto the stack. else if(is_function(c)) { stack[sl] = c; ++sl; } // If the token is a function argument separator (e.g., a comma): else if(c == ',') { bool pe = false; while(sl > 0) { sc = stack[sl - 1]; if(sc == '(') { pe = true; break; } else { // Until the token at the top of the stack is a left parenthesis, // pop operators off the stack onto the output queue. *outpos = sc; ++outpos; sl--; } } // If no left parentheses are encountered, either the separator was misplaced // or parentheses were mismatched. if(!pe) { printf("Error: separator or parentheses mismatched\n"); return false; } } // If the token is an operator, op1, then: else if(is_operator(c)) { while(sl > 0) { sc = stack[sl - 1]; if(is_operator(sc) && ((op_left_assoc(c) && (op_preced(c) >= op_preced(sc))) || (op_preced(c) > op_preced(sc)))) { // Pop op2 off the stack, onto the output queue; *outpos = sc; ++outpos; sl--; } else { break; } } // push op1 onto the stack. stack[sl] = c; ++sl; } // If the token is a left parenthesis, then push it onto the stack. else if(c == '(') { stack[sl] = c; ++sl; } // If the token is a right parenthesis: else if(c == ')') { bool pe = false; // Until the token at the top of the stack is a left parenthesis, // pop operators off the stack onto the output queue while(sl > 0) { sc = stack[sl - 1]; if(sc == '(') { pe = true; break; } else { *outpos = sc; ++outpos; sl--; } } // If the stack runs out without finding a left parenthesis, then there are mismatched parentheses. if(!pe) { printf("Error: parentheses mismatched\n"); return false; } // Pop the left parenthesis from the stack, but not onto the output queue. sl--; // If the token at the top of the stack is a function token, pop it onto the output queue. if(sl > 0) { sc = stack[sl - 1]; if(is_function(sc)) { *outpos = sc; ++outpos; sl--; } } } else { printf("Unknown token <%c>\n", c); return false; // Unknown token } } ++strpos; } // When there are no more tokens to read: // While there are still operator tokens in the stack: while(sl > 0) { sc = stack[sl - 1]; if(sc == '(' || sc == ')') { printf("Error: parentheses mismatched\n"); return false; } *outpos = sc; ++outpos; --sl; } *outpos = 0; // Null terminator return true; }