/** * Check checksum */ int checksum_true(uint8_t *buf){ uint8_t *eol; uint8_t checksum = 0, cs[3]; if(*buf != '$' || !(eol = ustrchr(buf, '*'))){ DBG("Wrong data: "); DBG(buf); DBG("\n"); return 0; } while(++buf != eol) checksum ^= *buf; ++buf; cs[0] = hex(checksum >> 4); cs[1] = hex(checksum & 0x0f); if(buf[0] == cs[0] && buf[1] == cs[1]) return 1; #ifdef EBUG cs[2] = 0; P("CHS, get "); P(buf); P(" need "); P(cs); usb_send('\n'); #endif return 0; }
int paramfile::GetLine(){ if (eof) return 0; if (!rline) return 1; if (NULL == fgets((char *)GivenLine,256,f)){ eof = 1; return 0; } UNCH *p = ustrchr(GivenLine,'\n'); if (NULL != p)p[0] = 0; lno++; return 1; };
void HandleSub(XlateEntryData * xp){ XlateEntryData* p = xp; UNCH /* boolean */ ccol[256]; memset(ccol, FALSE, 256); // for (int oc = 0; oc <= 255; oc++) ccol[oc] = FALSE; while (p != 0){ccol[p->c] = TRUE; p = p->f;} p = xp; while (p != 0) { UNCH * upos = ustrchr(UpperCharList, p->c), * lpos = ustrchr(LowerCharList, p->c), ox; if ((upos != 0) || (lpos != 0)) { if (upos != 0) ox = *upos; else ox = *lpos; } if (!ccol[ox]){ XlateEntryData* np = new XlateEntryData(ox, p); p->f = np; p = np; if (p->n != 0) HandleSub(p->n); } p = p->f; } }
static bool_t csmins_deal(void) { recv.offset = 0; uint8_t* ptr = ustrchr(recv.buf, ","); if (ptr != NULL) { ptr++; if (*ptr == 0x31) { return TRUE; } } gprs_info.gprs_state = SIM_ERROR; return FALSE; }
static bool_t cgatt_deal(void) { recv.offset = 0; uint8_t* ptr = ustrchr(recv.buf, ":"); if (ptr != NULL) { ptr += 2; if (*ptr == 0x31) { return TRUE; } else { return FALSE; } } gprs_info.gprs_state = GPRS_NET_ERROR; return FALSE; }
static bool_t cipmode_deal(void) { recv.offset = 0; uint8_t* ptr = ustrchr(recv.buf, ":"); if (ptr != NULL) { ptr += 2; if (*ptr == 0x31) { return TRUE; } else { write_fifo(CIPMODE, sizeof(CIPMODE) - 1); vTaskDelay(300 / portTICK_RATE_MS); if (my_strstr((const char*)recv.buf, (const char*)ATOK) != NULL) return TRUE; else return FALSE; } } return FALSE; }
parseritem * myscanner::getitem(){ UNCH work[100], strch, *tch, s[2]; unsigned workpos; #define EXPECTELE 1 #define EXPECTVAR 2 #define EXPECTNOTHING 0 int specchar = EXPECTNOTHING; while (1) { switch (State) { case FILEEOF: return new myitem(ENDOFFILE, (*elup)[ENDOFFILE], 0); case PASTEND: break; case FINDSTART: while ((GivenLine[pos] == 0) || (GivenLine[pos] == COMMENTID)) { if (NULL == (GivenLine = pfile->Data())){ State = FILEEOF; return new myitem(ENDOFFILE, (*elup)[ENDOFFILE], 0); } pos = 0; } case SKIPBLANKS: if ((GivenLine[pos] != ' ')&&(GivenLine[pos] != '\t')) State = WHATISIT; else pos++; specchar = EXPECTNOTHING; break; case WHATISIT: if ((GivenLine[pos] == 0) || (GivenLine[pos] == COMMENTID)) { State = FINDSTART; if (NULL == (GivenLine = pfile->Data())) State = FILEEOF; pos = 0; return new myitem(STATEMENTEND, (*elup)[STATEMENTEND], pfile->LineNo()-1); } else if (GivenLine[pos] == ANNOUNCEELE) { strch = GivenLine[pos++]; specchar = EXPECTELE; State = MUSTBEALPHA; } else if (GivenLine[pos] == ANNOUNCEVAR) { strch = GivenLine[pos++]; specchar = EXPECTVAR; State = MUSTBEALPHA; } else if ((isalpha(GivenLine[pos]))||(GivenLine[pos]=='\\')) { State = COLLECTALPHA; workpos = 0; } else if ((GivenLine[pos] == '"')||(GivenLine[pos] == '\'')){ State = COLLECTSTRING; workpos = 0; strch = GivenLine[pos++]; } else if (NULL != (tch = ustrchr(singlesstr, GivenLine[pos]))){ State = SKIPBLANKS; work[1] = 0; work[0] = GivenLine[pos++]; return new myitem(SINGLESOFFSET + (tch - singlesstr), work, pfile->LineNo()); } else if ((GivenLine[pos]>='0')&&(GivenLine[pos]<='9') ) { State = COLLECTNUMBER; workpos = 0; } else { /*RES OLD MSG 587 File %0: Unrecognized character "%1" found in line %2. */ ResFile->MsgData(epmfilename); ResFile->MsgData((unsigned short)GivenLine[pos]); ResFile->MsgData(pfile->LineNo()); ResFile->PutResError(/*RES REM INS*/ 587); s[1] = 0; s[0] = GivenLine[pos]; return new myitem(9999, s, pfile->LineNo()); } break; case MUSTBEALPHA: if ((isalpha(GivenLine[pos]))||(GivenLine[pos]=='\\')) { State = COLLECTALPHA; workpos = 0; } else { /*RES OLD MSG 599 File %0: A name does not follow "%1" on in line %2. */ ResFile->MsgData(epmfilename); ResFile->MsgData(strch); ResFile->MsgData(pfile->LineNo()); ResFile->PutResError(/*RES REM INS*/ 599); s[1] = 0; s[0] = strch; return new myitem(9999, s, pfile->LineNo()); } break; case COLLECTALPHA: if (IsNameChar(GivenLine[pos]))work[workpos++] = toupper(GivenLine[pos++]); else if (GivenLine[pos] == '\\'){ if (GivenLine[pos+1] != 0)pos++; work[workpos++] = GivenLine[pos++]; } else { work[workpos] = 0; State = CHECKALPHA; } break; case CHECKALPHA: etd *fndetd; // basevalue *fndid; int rslt; varname *vn; State = SKIPBLANKS; if (specchar == EXPECTELE){ if ((fndetd = IsElementName(work)) != NULL) return new etditem(ELEMENTNAME, work, pfile->LineNo(), fndetd); /*RES OLD MSG 600 File %0: "%1" is not an element name, on line %2. */ ResFile->MsgData(epmfilename); ResFile->MsgData(work); ResFile->MsgData(pfile->LineNo()); ResFile->PutResError(/*RES REM INS*/ 600); return new myitem(9999, work, pfile->LineNo()); } else if (specchar == EXPECTVAR){ if ((vn = IsVarName(globalvars,work)) != NULL) return new varitem(VARIABLENAME, work, pfile->LineNo(), vn); /*RES OLD MSG 601 File %0: "%1" is not a global variable or TACTid name, on line %2. */ ResFile->MsgData(epmfilename); ResFile->MsgData(work); ResFile->MsgData(pfile->LineNo()); ResFile->PutResError(/*RES REM INS*/ 601); return new myitem(9999, work, pfile->LineNo()); } if (0 != (rslt = slup->Lookup(work))) return new myitem(STRINGSSTART + rslt, work, pfile->LineNo()); else if ((fndetd = IsElementName(work)) != NULL) return new etditem(ELEMENTNAME, work, pfile->LineNo(), fndetd); if ((vn = IsVarName(localvars,work)) != NULL) return new varitem(VARIABLENAME, work, pfile->LineNo(), vn); if ((vn = IsVarName(globalvars,work)) != NULL) return new varitem(VARIABLENAME, work, pfile->LineNo(), vn); else return new myitem(UNDECLAREDNAME, work, pfile->LineNo()); case COLLECTSTRING: if ((GivenLine[pos] == COMMENTID)|(GivenLine[pos] == 0)) { /*RES OLD MSG 584 File %0: A string without a closing character was found on line %1 */ ResFile->MsgData(epmfilename); ResFile->MsgData(pfile->LineNo()); ResFile->PutResError(/*RES REM INS*/ 584); return new myitem(9999, work, pfile->LineNo()); } if (GivenLine[pos] == strch) { pos++; State = SKIPBLANKS; work[workpos] = 0; return new myitem(STRING, work, pfile->LineNo()); } else work[workpos++] = GivenLine[pos++]; break; case COLLECTNUMBER: if ((GivenLine[pos]>='0')&&(GivenLine[pos]<='9') ) work[workpos++] = GivenLine[pos++]; else { State = SKIPBLANKS; work[workpos] = 0; return new myitem(NUMBER, work, pfile->LineNo()); } break; } } };
/* fs_flist_putter: * Callback routine for for_each_file() to fill the file selector listbox. */ static void fs_flist_putter(AL_CONST char *str, int attrib, int param) { char ext_tokens[32]; char *s, *ext, *tok, *name; char tmp[512], tmp2[32]; int c, c2, i, k, sign; /* attribute flags (rhsda order) * 0 = not required, 1 = must be set, -1 = must be unset */ int attr_flag[5+5] = { 0, -1, -1, 0, 0, FA_RDONLY, FA_HIDDEN, FA_SYSTEM, FA_DIREC, FA_ARCH }; c = usetc(ext_tokens, ' '); c += usetc(ext_tokens+c, ','); c += usetc(ext_tokens+c, ';'); usetc(ext_tokens+c, 0); s = get_filename(str); fix_filename_case(s); if (fext) { ustrcpy(tmp, fext); ustrtok(tmp, ext_tokens); c = (ustrtok(NULL, ext_tokens) ? 1 : 0); if (!c) { if (!ustrchr(fext, '/')) c = 1; } if (c && (!(attrib & FA_DIREC))) { ustrcpy(tmp, fext); ext = get_extension(s); tok = ustrtok(tmp, ext_tokens); while (tok) { if (ustricmp(ext, tok) == 0) break; tok = ustrtok(NULL, ext_tokens); } if (!tok) return; } c = usetc(ext_tokens, ' '); c += usetc(ext_tokens+c, ','); c += usetc(ext_tokens+c, ';'); c += usetc(ext_tokens+c, '/'); usetc(ext_tokens+c, 0); ustrcpy(tmp, fext); tok = ustrchr(tmp, '/'); if (tok) tok = ustrtok(tok, ext_tokens); if (tok) { sign = 1; c = usetc(tmp2, 'r'); c += usetc(tmp2+c, 'h'); c += usetc(tmp2+c, 's'); c += usetc(tmp2+c, 'd'); c += usetc(tmp2+c, 'a'); c += usetc(tmp2+c, '+'); c += usetc(tmp2+c, '-'); usetc(tmp2+c, 0); /* scan the string */ i = 0; while ((c = utolower(ugetat(tok, i)))) { k = 0; while ((c2 = ugetat(tmp2, k))!=0) { if (c == c2) { if (k<5) { attr_flag[k] = sign; break; } else sign = (k==5) ? 1 : -1; } k++; } i++; } } } /* check if file attributes match */ if (!(attr_flag[3+5] & attrib)) { /* if not a directory, we check all attributes except FA_DIREC */ for (c=0; c<5; c++) { if (c == 3) continue; if ((attr_flag[c] == 1) && (!(attrib & attr_flag[c+5]))) return; if ((attr_flag[c] == -1) && (attrib & attr_flag[c+5])) return; } } else { /* if a directory, we check only FA_DIREC */ if (attr_flag[3] == -1) return; } if ((flist->size < FLIST_SIZE) && ((ugetc(s) != '.') || (ugetat(s, 1)))) { name = malloc(ustrsizez(s) + ((attrib & FA_DIREC) ? ucwidth(OTHER_PATH_SEPARATOR) : 0)); if (!name) return; for (c=0; c<flist->size; c++) { if (ugetat(flist->name[c], -1) == OTHER_PATH_SEPARATOR) { if (attrib & FA_DIREC) if (ustrfilecmp(s, flist->name[c]) < 0) break; } else { if (attrib & FA_DIREC) break; if (ustrfilecmp(s, flist->name[c]) < 0) break; } } for (c2=flist->size; c2>c; c2--) flist->name[c2] = flist->name[c2-1]; flist->name[c] = name; ustrcpy(flist->name[c], s); if (attrib & FA_DIREC) put_backslash(flist->name[c]); flist->size++; } }
/** * file_open - open a file on given secondary * @secondary: secondary address used in OPEN call * * This function opens the file named in command_buffer on the given * secondary address. All special names and prefixes/suffixed are handled * here, e.g. $/#/@/,S,W */ void file_open(uint8_t secondary) { buffer_t *buf; uint8_t i = 0; uint8_t recordlen = 0; /* If the secondary is already in use, close the existing buffer */ buf = find_buffer(secondary); if (buf != NULL) { /* FIXME: What should we do if an error occurs? */ cleanup_and_free_buffer(buf); } /* Assume everything will go well unless proven otherwise */ set_error(ERROR_OK); /* Strip 0x0d characters from end of name (C2BD-C2CA) */ if (command_length > 1) { if (command_buffer[command_length-1] == 0x0d) command_length -= 1; else if (command_buffer[command_length-2] == 0x0d) command_length -= 2; } /* Clear the remainder of the command buffer, simplifies parsing */ memset(command_buffer+command_length, 0, sizeof(command_buffer)-command_length); uart_trace(command_buffer,0,command_length); /* Direct access? */ if (command_buffer[0] == '#') { open_buffer(secondary); return; } /* Parse type+mode suffixes */ uint8_t *ptr = command_buffer; enum open_modes mode = OPEN_READ; uint8_t filetype = TYPE_DEL; while(i++ < 2 && *ptr && (ptr = ustrchr(ptr, ','))) { *ptr = 0; ptr++; switch (*ptr) { case 0: break; case 'R': /* Read */ mode = OPEN_READ; break; case 'W': /* Write */ mode = OPEN_WRITE; break; case 'A': /* Append */ mode = OPEN_APPEND; break; case 'M': /* Modify */ mode = OPEN_MODIFY; break; case 'D': /* DEL */ filetype = TYPE_DEL; break; case 'S': /* SEQ */ filetype = TYPE_SEQ; break; case 'P': /* PRG */ filetype = TYPE_PRG; break; case 'U': /* USR */ filetype = TYPE_USR; break; case 'L': /* REL */ filetype = TYPE_REL; mode = OPEN_WRITE; if((ptr = ustrchr(ptr, ','))) recordlen = *(++ptr); i = 2; // stop the scan break; } } /* Load directory? */ if (command_buffer[0] == '$') { load_directory(secondary); return; } /* Parse path+partition numbers */ uint8_t *fname; int8_t res; cbmdirent_t dent; path_t path; /* Parse path and file name */ if (parse_path(command_buffer, &path, &fname, 0)) return; #ifdef CONFIG_M2I /* For M2I only: Remove trailing spaces from name */ if (partition[path.part].fop == &m2iops) { res = ustrlen(fname); while (--res && fname[res] == ' ') fname[res] = 0; } #endif /* Filename matching */ if (opendir(&matchdh, &path)) return; do { res = next_match(&matchdh, fname, NULL, NULL, FLAG_HIDDEN, &dent); if (res > 0) /* Error, abort */ return; /* Don't match on DEL or DIR */ if ((dent.typeflags & TYPE_MASK) != TYPE_DEL && (dent.typeflags & TYPE_MASK) != TYPE_DIR) break; /* But do match if it's for writing */ if (mode == OPEN_WRITE || secondary == 1) break; } while (res == 0); if(res && filetype == TYPE_REL && !recordlen) { set_error(ERROR_SYNTAX_UNABLE); return; } /* If match found is a REL... */ if(!res && (dent.typeflags & TYPE_MASK) == TYPE_REL) { /* requested type must be REL or DEL */ if(filetype != TYPE_REL && filetype != TYPE_DEL) { set_error(ERROR_FILE_TYPE_MISMATCH); return; } filetype = TYPE_REL; mode = OPEN_MODIFY; } /* Force mode+type for secondaries 0/1 */ switch (secondary) { case 0: mode = OPEN_READ; if (filetype == TYPE_DEL) filetype = TYPE_PRG; break; case 1: mode = OPEN_WRITE; if (filetype == TYPE_DEL) filetype = TYPE_PRG; break; default: if (filetype == TYPE_DEL) filetype = TYPE_SEQ; } if (mode == OPEN_WRITE) { if (res == 0) { /* Match found */ if (command_buffer[0] == '@') { /* Make sure there is a free buffer to open the new file later */ if (!check_free_buffers()) { set_error(ERROR_NO_CHANNEL); return; } /* Copy dent because file_delete may change it */ cbmdirent_t dentcopy = dent; /* Rewrite existing file: Delete the old one */ if (file_delete(&path, &dentcopy) == 255) return; /* Force fatops to create a new name based on the (long) CBM- */ /* name instead of creating one with the old SFN and no LFN. */ if (dent.opstype == OPSTYPE_FAT || dent.opstype == OPSTYPE_FAT_X00) dent.pvt.fat.realname[0] = 0; } else { /* Write existing file without replacement: Raise error */ set_error(ERROR_FILE_EXISTS); return; } } else { /* Normal write or non-existing rewrite */ /* Doesn't exist: Copy name to dent */ memset(&dent, 0, sizeof(dent)); ustrncpy(dent.name, fname, CBM_NAME_LENGTH); set_error(ERROR_OK); // because first_match has set FNF } } else if (res != 0) { /* File not found */ set_error(ERROR_FILE_NOT_FOUND); return; } /* Grab a buffer */ buf = alloc_buffer(); if (!buf) return; buf->secondary = secondary; if(filetype == TYPE_REL) { display_filename_write(path.part,CBM_NAME_LENGTH,dent.name); open_rel(&path, &dent, buf, recordlen, (mode == OPEN_MODIFY)); return; } switch (mode) { case OPEN_MODIFY: case OPEN_READ: /* Modify is the same as read, but allows reading *ed files. */ /* FAT doesn't have anything equivalent, so both are mapped to READ */ display_filename_read(path.part,CBM_NAME_LENGTH,dent.name); open_read(&path, &dent, buf); break; case OPEN_WRITE: case OPEN_APPEND: display_filename_write(path.part,CBM_NAME_LENGTH,dent.name); open_write(&path, &dent, filetype, buf, (mode == OPEN_APPEND)); break; } }
/** * load_directory - Prepare directory generation and create header * @secondary: secondary address used for reading the directory * * This function prepeares directory reading and fills the buffer * with the header line of the directory listing. * BUG: There is a not-well-known feature in the 1541/1571 disk * drives (and possibly others) that returns unparsed directory * sectors if $ is opened with a secondary address != 0. This * is not emulated here. */ static void load_directory(uint8_t secondary) { buffer_t *buf; path_t path; uint8_t pos=1; buf = alloc_buffer(); if (!buf) return; uint8_t *name; buf->secondary = secondary; buf->read = 1; buf->lastused = 31; if (command_length > 2 && secondary == 0) { if(command_buffer[1]=='=') { if(command_buffer[2]=='P') { /* Parse Partition Directory */ /* copy static header to start of buffer */ memcpy_P(buf->data, dirheader, sizeof(dirheader)); memcpy_P(buf->data + 32, syspart_line, sizeof(syspart_line)); buf->lastused = 63; /* set partition number */ buf->data[HEADER_OFFSET_DRIVE] = max_part; /* Let the refill callback handle everything else */ buf->refill = pdir_refill; if(command_length>3) { /* Parse the name pattern */ if (parse_path(command_buffer+3, &path, &name, 0)) return; buf->pvt.pdir.matchstr = name; } stick_buffer(buf); return; } else if(command_buffer[2]=='T') { buf->pvt.dir.format = DIR_FMT_CMD_SHORT; pos=3; } } } if (command_buffer[pos]) { /* do we have a path to scan? */ if (command_length > 2) { /* Parse the name pattern */ if (parse_path(command_buffer+pos, &path, &name, 0)) return; if (opendir(&buf->pvt.dir.dh, &path)) return; buf->pvt.dir.matchstr = name; /* Check for a filetype match */ name = ustrchr(name, '='); if (name != NULL) { *name++ = 0; switch (*name) { case 'S': buf->pvt.dir.filetype = TYPE_SEQ; break; case 'P': buf->pvt.dir.filetype = TYPE_PRG; break; case 'U': buf->pvt.dir.filetype = TYPE_USR; break; case 'R': buf->pvt.dir.filetype = TYPE_REL; break; case 'C': /* This is guessed, not verified */ buf->pvt.dir.filetype = TYPE_CBM; break; case 'B': /* CMD compatibility */ case 'D': /* Specifying DEL matches everything anyway */ buf->pvt.dir.filetype = TYPE_DIR; break; case 'H': /* Extension: Also show hidden files */ buf->pvt.dir.filetype = FLAG_HIDDEN; break; } if(buf->pvt.dir.filetype) { name++; if(*name++ != ',') { goto scandone; } } while(*name) { switch(*name++) { case '>': if(parse_date(&date_match_start,&name)) goto scandone; if(date_match_start.month && date_match_start.day) // ignore 00/00/00 buf->pvt.dir.match_start = &date_match_start; break; case '<': if(parse_date(&date_match_end,&name)) goto scandone; if(date_match_end.month && date_match_end.day) // ignore 00/00/00 buf->pvt.dir.match_end = &date_match_end; break; case 'L': /* don't switch to long format if 'N' has already been sent */ if(buf->pvt.dir.format != DIR_FMT_CBM) buf->pvt.dir.format = DIR_FMT_CMD_LONG; break; case 'N': buf->pvt.dir.format=DIR_FMT_CBM; /* turn off extended listing */ break; default: goto scandone; } if(*name && *name++ != ',') { goto scandone; } } } } else { /* Command string is two characters long, parse the drive */ if (command_buffer[1] == '0') path.part = current_part; else path.part = command_buffer[1] - '0' - 1; if (path.part >= max_part) { set_error(ERROR_DRIVE_NOT_READY); return; } path.dir = partition[path.part].current_dir; if (opendir(&buf->pvt.dir.dh, &path)) return; } } else { path.part = current_part; path.dir = partition[path.part].current_dir; // if you do not do this, get_label will fail below. if (opendir(&buf->pvt.dir.dh, &path)) return; } scandone: if (secondary != 0) { /* Raw directory */ if (partition[path.part].fop == &d64ops) { /* No need to fake it for D64 files */ d64_raw_directory(&path, buf); return; } /* prepare a fake BAM sector */ memset(buf->data, 0, 256); memset(buf->data + BAM_OFFSET_NAME - 2, 0xa0, BAM_A0_AREA_SIZE); /* fill label and id */ if (dir_label(&path, buf->data + BAM_OFFSET_NAME - 2)) return; if (disk_id(&path, buf->data + BAM_OFFSET_ID - 2)) return; /* change padding of label and id to 0xa0 */ name = buf->data + BAM_OFFSET_NAME - 2 + CBM_NAME_LENGTH; while (*--name == ' ') *name = 0xa0; if (buf->data[BAM_OFFSET_ID+2-2] == 0x20) buf->data[BAM_OFFSET_ID+2-2] = 0xa0; /* DOS version marker */ buf->data[0] = 'A'; buf->refill = rawdir_refill; buf->lastused = 253; } else { /* copy static header to start of buffer */ memcpy_P(buf->data, dirheader, sizeof(dirheader)); /* set partition number */ buf->data[HEADER_OFFSET_DRIVE] = path.part+1; /* read directory name */ if (dir_label(&path, buf->data+HEADER_OFFSET_NAME)) return; /* read id */ if (disk_id(&path,buf->data+HEADER_OFFSET_ID)) return; /* Let the refill callback handle everything else */ buf->refill = dir_refill; } /* Keep the buffer around */ stick_buffer(buf); return; }