⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linedisc_buddy.c

📁 C++ 编写的EROS RTOS
💻 C
📖 第 1 页 / 共 2 页
字号:
  uint32_t event_mask = CharSrc_ALL_Events;  uint32_t numRet;  uint32_t numToGet;    if (SHARED.readerWants == UINT32_MAX) {    /* no reader */    numToGet = DATABUFF_END - BUDDY.buffPos;    DEBUG(waitevent)      kprintf(KR_OSTREAM,	      "LineDiscBuddy: no reader -- numToGet %04x\n",	      numToGet);  } else {    uint32_t got = BUDDY.buffPos - DATABUFF;    DEBUG(waitevent)      kprintf(KR_OSTREAM,	      "LineDiscBuddy: reader -- got %04x, wants %04x\n",	      got, SHARED.readerWants);    if (got >= SHARED.readerWants) {      DEBUG(waitevent)	kprintf(KR_OSTREAM,		"LineDiscBuddy: reader got what he wants -- "		"post FilledBufferEvent\n");      POST_EVENT(CharSrc_FilledBufferEvent);      if (READER_READY()) {	raw_fork_reader(SHARED.readerWants);	return;      }      return;     } else {      numToGet = SHARED.readerWants - got;      DEBUG(waitevent)	kprintf(KR_OSTREAM,		"LineDiscBuddy: Reader needs %04x\n",		numToGet);    }  }    while (RC_OK == charsrc_wait_for_event(KR_CHRSRC,					 numToGet,					 BUDDY.buffPos,					 &numRet,					 event_mask,					 &BUDDY.chrSrcEvents)) {    DEBUG(waitevent)      kprintf(KR_OSTREAM,	      "LineDiscBuddy: WaitForEvent returned. (numRet %03x, "	      "events %02x)\n",	      numRet,	      BUDDY.chrSrcEvents);        BUDDY.wakeupEvents |= (BUDDY.chrSrcEvents & CharSrc_UserEventMask);    if (SHARED.postedEvents) {      DEBUG(postevent)	kprintf(KR_OSTREAM,		"LineDiscBuddy: Posting events %02x\n",SHARED.postedEvents);            BUDDY.currentLDEvents |= SHARED.postedEvents;      SHARED.postedEvents = 0u;    }    BUDDY.wakeupEvents &= ~LD_Wakeup_EventPosted;        if (WBUFF_NUM_WRITTEN(&SHARED.wrt_buff) != 0u) {      DEBUG(write)	kprintf(KR_OSTREAM, "LineDiscBuddy: Calling tty_write\n");      try_write();    }    BUDDY.wakeupEvents &= ~LD_Wakeup_WriteRequest;    /* process the characters */    if (BUDDY.curInpFlags & LD_In_DoInpProc) {      rawInputProcess(BUDDY.buffPos, numRet);    }    /* mark then as processed */    if (numRet) {      BUDDY.buffPos += numRet;    }    /* process events -- first, post any events from above that aren't     * for me.     */    POST_EVENT(BUDDY.chrSrcEvents	       & ~(CharSrc_FilledBufferEvent		   | CharSrc_UserEventMask));    /* then, if we have a reader, check readerwants. */    if (SHARED.readerWants != UINT32_MAX) {      uint32_t got = BUDDY.buffPos - DATABUFF;      if (got >= SHARED.readerWants) {	POST_EVENT(CharSrc_FilledBufferEvent);	numToGet = 0u;        } else {	numToGet = SHARED.readerWants - got;      }    }    if (WBUFF_NUM_WRITTEN(&SHARED.wrt_buff) != 0u)       try_write();    if (READER_READY())       raw_fork_reader(SHARED.readerWants);    if (SHARED.readerWants == UINT32_MAX) {      /* no reader */      numToGet = DATABUFF_END - BUDDY.buffPos;    }    if (BUDDY.wakeupEvents)      break;    /* FIXME: flush buffer? */  }  kprintf(KR_OSTREAM,	  "Linedisc_buddy -- end of loop!\n");    return;}uint8_t *linemode_find_first_special_char(void){  /* find the first non-escaped control character */  register uint8_t *pos;  register uint8_t *end = BUDDY.buffPos;  cc_type quote_char = BUDDY.current_CC[LD_CC_Quote];  if (quote_char) { /* we have to check for quoted chars */    int quoted = 0;    for (pos = DATABUFF; pos < end; pos++) {      if (quoted) continue;      if (CCLASS(*pos) == CC_NEWLINE)	break;       else if (*pos == (uint8_t)quote_char)	quoted = 1;      else if (CHECK_CHAR(SHARED.char_mask,*pos)) 	break; /* this is a special character */    }  } else {    for (pos = DATABUFF; pos < end; pos++) {      if (CCLASS(*pos) == CC_NEWLINE	  || CHECK_CHAR(SHARED.char_mask,*pos))	break;    }  }  if (pos == end) {    return NULL; /* no special characters */  }  return pos;}voidlinemode_fork_reader(void){  uint32_t numBytes;  /* SEND to the reader.  */  if (BUDDY.currentLDEvents & CharSrc_SpecialCharEvent) {    if (!BUDDY.first_special) {      kdprintf(KR_OSTREAM,	       "LineDisc_Buddy: HEY! I can't find the "	       "special character to end the line!\n");      /* for now, send the whole thing, I guess */      numBytes = BUDDY.buffPos - DATABUFF;          } else {      numBytes = BUDDY.first_special - DATABUFF + 1; /* include first							special */    }  } else {    numBytes = 0; /* Don't have a full line yet. */  }  DEBUG(waitevent)    kprintf(KR_OSTREAM,	    "                 actualBytes: %d\n",numBytes);    fork_reader(numBytes); /* do the fork and update the buffer */    /* update the first_special pointer */  BUDDY.first_special = linemode_find_first_special_char();  if (BUDDY.first_special) POST_EVENT(CharSrc_SpecialCharEvent);}voidlinemode_echo(uint8_t theChar) {  uint8_t theOut[3] = {theChar,0,0};  if ( !ISSET(BUDDY.curInpFlags, LD_In_Echo) )    return;  if (CCLASS(theChar) != 0      && ISSET(BUDDY.curInpFlags, LD_In_EchoCtrl)      && CCLASS(theChar) != CC_NEWLINE      && CCLASS(theChar) != CC_TAB) {    theOut[0] = '^';    theOut[1] = (theChar == 0x7F)? '?':theChar + 'A' - 1;  }   write_string(theOut);}voidlineModeProcess(uint32_t numRet) /* process chars in linemode */{  register uint8_t *curChar = BUDDY.buffPos;  for (; numRet > 0; numRet--,curChar++) {    /* basically a large case statement. Continue when done with       character (make sure to increment buffPos if necessary */    uint32_t pos = BUDDY.buffPos - DATABUFF;    assert(pos < EROS_PAGE_SIZE);    if (pos == EROS_PAGE_SIZE - 1) {      write_beep();      continue;    }    if (ISSET(BUDDY.curInpFlags,LD_In_SwapCRNL)) {      switch (*curChar) {      case '\n':	*curChar = '\r';	break;      case '\r':	*curChar = '\n';	break;      }    }    if (pos == EROS_PAGE_SIZE - 2) {      /* we are running out of space -- Accept a special character for	 the 2nd to last character, and nothing for the last (we must	 wait until the data is returned */      if (BUDDY.quoteNext == 1	  || (CCLASS(*curChar) != CC_NEWLINE	      && CHECK_CHAR(BUDDY.cur_char_mask,*curChar))) {	write_beep();	BUDDY.quoteNext = 0;	continue;      }    }    if (BUDDY.quoteNext) {      BUDDY.quoteNext = 0;      linemode_echo(*curChar);      *BUDDY.buffPos++ = *curChar;      continue;    } else { /* not quoted */      if (CCLASS(*curChar) == CC_NEWLINE) 	goto is_special_character; /* goto the real routine */            if (*curChar != 0) {	/* possibly a controlling character -- this way, we don't have	   to check if the control character is set.	*/	if (*curChar == BUDDY.current_CC[LD_CC_Erase]	    || *curChar == BUDDY.current_CC[LD_CC_AltErase]) {	  if (pos == 0) continue;	  BUDDY.buffPos--; /* remove the previous character */	  if (ISSET(BUDDY.curInpFlags,LD_In_VisErase)) {#if 0	    linemode_rubout(*BUDDY.buffPos);#else	    char str[2] = {BUDDY.current_CC[LD_CC_Erase],0};	    write_string(str);#endif	  } else {	    linemode_echo(BUDDY.current_CC[LD_CC_Erase]);	  }	  if (BUDDY.buffPos > DATABUFF	      && BUDDY.current_CC[LD_CC_Quote]	      && *(BUDDY.buffPos - 1) == BUDDY.current_CC[LD_CC_Quote]) {#if 0	    /* we need to check if this is quoted.  What we do is	       count the number of consecutive quote chars before	       this character, and if it is odd, eat the first one.	    */#else	    BUDDY.buffPos--; /* for now, just assume no-one quotes the				Quote character */#endif	  } 	  continue;	}	if (*curChar == BUDDY.current_CC[LD_CC_EraseWord]) {	  continue; /* FIXME: implement */	}	if (*curChar == BUDDY.current_CC[LD_CC_KillLine]) {	  continue; /* FIXME: implement */	}	if (*curChar == BUDDY.current_CC[LD_CC_Reprint]) {	  continue; /* FIXME: implement */	}	if (*curChar == BUDDY.current_CC[LD_CC_Quote]) {	  if (ISSET(BUDDY.curInpFlags,LD_In_Echo)) {	    if (ISSET(BUDDY.curInpFlags,LD_In_EchoCtrl)		&& ISSET(BUDDY.curInpFlags,LD_In_VisErase)) {	      uint8_t toSend[] = {'^',				  BUDDY.current_CC[LD_CC_Erase],				  0};	      write_string(toSend);			     	    } else {	      linemode_echo(*curChar);	    }	  }	    	  *BUDDY.buffPos++ = *curChar;	  BUDDY.quoteNext = 1;	  continue;	}       } /* if (*curChar != 0) */            if (CHECK_CHAR(BUDDY.cur_char_mask,*curChar)) {	/* this is a special character */	linemode_echo(*curChar); /* echo it */      is_special_character: /* from '\n' check */	*BUDDY.buffPos = *curChar;	POST_EVENT(CharSrc_SpecialCharEvent);	if (!BUDDY.first_special) {	  BUDDY.first_special = BUDDY.buffPos;	}	BUDDY.buffPos++;	/* no matter what character it was, afterwards we echo	   carriage return */	if (ISSET(BUDDY.curInpFlags,LD_In_AlwEchoNL)	    || ISSET(BUDDY.curInpFlags,LD_In_Echo))	  write_string("\n");      } else {        /* this is a normal character */        linemode_echo(*curChar);        BUDDY.buffPos++;      }    }  }}/* FIXME:  Currently, linemode makes assumptions that come down to the           calling person is expected to be able to handle the full	   buffer size -- EROS_PAGE_SIZE.  */voidlineModeLoop(void){  uint32_t event_mask = CharSrc_ALL_Events;  uint32_t numRet;  uint32_t numToGet;    if (SHARED.readerWants != UINT32_MAX) {    /* there is a reader -- check if he we're ready */    if (READER_READY()) {      linemode_fork_reader();      return;    }  }  /* no timeouts for now -- read input a character at a time. */  /* NOTE: we must never let BUDDY.buffPos get out of the page */  numToGet = 1;  while (RC_OK == charsrc_wait_for_event(KR_CHRSRC,					 numToGet,					 BUDDY.buffPos,					 &numRet,					 event_mask,					 &BUDDY.chrSrcEvents)) {    DEBUG(waitevent)      kprintf(KR_OSTREAM,	      "LineDiscBuddy: WaitForEvent returned. (numRet %03x, "	      "events %08x, %sreader)\n",	      numRet,	      BUDDY.chrSrcEvents,              (SHARED.readerWants == UINT32_MAX)?"no ":"");        BUDDY.wakeupEvents |= (BUDDY.chrSrcEvents & CharSrc_UserEventMask);        if (SHARED.postedEvents) {      DEBUG(postevent)	kprintf(KR_OSTREAM,		"LineDiscBuddy: Posting events %02x\n",SHARED.postedEvents);            BUDDY.currentLDEvents |= SHARED.postedEvents;      SHARED.postedEvents = 0u;    }    BUDDY.wakeupEvents &= ~LD_Wakeup_EventPosted;        if (WBUFF_NUM_WRITTEN(&SHARED.wrt_buff) != 0u) {      DEBUG(write)	kprintf(KR_OSTREAM, "LineDiscBuddy: Calling tty_write\n");      try_write();    } else if (BUDDY.chrSrcEvents & CharSrc_WriteSpaceAvailEvent) {      POST_EVENT(CharSrc_WriteSpaceAvailEvent);    }    BUDDY.wakeupEvents &= ~LD_Wakeup_WriteRequest;    lineModeProcess(numRet); /* process the characters */    /* BUDDY.buffPos now points to the end of the characters. */    /* any applicable events have been posted. */    /*    POST_EVENT(BUDDY.chrSrcEvents	       & ~(CharSrc_FilledBufferEvent | CharSrc_UserEventMask));    */    if (WBUFF_NUM_WRITTEN(&SHARED.wrt_buff) != 0u)       try_write();    if (READER_READY())       linemode_fork_reader();    if (BUDDY.wakeupEvents)      break;    /* FIXME: flush buffer? */  }  kprintf(KR_OSTREAM,	  "Linedisc_buddy -- end of loop!\n");    return;}voidraw_update_specialChars(void){  uint16_t buff[256];  uint16_t *buffp = buff;  uint32_t idx;  for (idx = 0; idx < 256; idx++) {    if (CHECK_CHAR(BUDDY.cur_char_mask,idx))      *buffp++ = idx;  }  charsrc_set_special_chars(KR_CHRSRC, buff, buffp - buff);}voidline_update_specialChars(void){  uint16_t buff[256 + LD_Num_CC + 1]; /* overkill, but guarenteed to work */  uint16_t *buffp = buff;  uint32_t idx;  DEBUG(control)    kprintf(KR_OSTREAM,"LineDisc_buddy: Updating line-mode special chars:");  for (idx = 0; idx < 256; idx++) {    if (CHECK_CHAR(BUDDY.cur_char_mask,idx)) {      DEBUG(control)	kprintf(KR_OSTREAM," 0x%02x",idx);      *buffp++ = idx;    }  }  for (idx = 0; idx < LD_Num_CC; idx++) {    uint16_t curChar = BUDDY.current_CC[idx];    if (curChar) {      /* the control character is active */      if (((curChar & 0xFF) == curChar)	  && CHECK_CHAR(BUDDY.cur_char_mask,(uint8_t)curChar)) {	DEBUG(control)	  kprintf(KR_OSTREAM," *0x%02x*",curChar);      } else {	DEBUG(control)	  kprintf(KR_OSTREAM," 0x%02x",curChar);	*buffp++ = curChar;      }    }  }  if (!CHECK_CHAR(BUDDY.cur_char_mask,'\r')) {    DEBUG(control)      kprintf(KR_OSTREAM," \\r");    *buffp++ = '\r';  }  DEBUG(control)    kdprintf(KR_OSTREAM," total %d\n",buffp-buff);    charsrc_set_special_chars(KR_CHRSRC, buff, buffp - buff);}int main(void){  initialize_linedisc_buddy(); /* either successful or destroys me. */  DEBUG(init)    kprintf(KR_OSTREAM,	    "LineDiscBuddy: Initialization successful\n");    while (1) {    uint32_t update_special_chars = 0;    uint32_t new_flags = SHARED.inpProcFlags;        if (ISSET(BUDDY.wakeupEvents,LD_Wakeup_Chars)) {      DEBUG(control)	kdprintf(KR_OSTREAM,		 "Linedisc_buddy: Copying control_chars and char_mask\n");      memcpy(BUDDY.current_CC,	     (const char *)SHARED.control_chars, /* cast away volatile */	     sizeof(SHARED.control_chars));      memcpy(BUDDY.cur_char_mask,	     (const char *)SHARED.char_mask, /* cast away volatile */	     sizeof(SHARED.control_chars));      update_special_chars = 1;      BUDDY.wakeupEvents &= ~LD_Wakeup_Chars;          }    if (BUDDY.curInpFlags != new_flags) {      uint32_t inpProc = (BUDDY.curInpFlags & LD_In_DoInpProc);      uint32_t nowInpProc = (new_flags & LD_In_DoInpProc);            uint32_t lineMode = (BUDDY.curInpFlags & LD_In_LineMode);      uint32_t nowLineMode = (new_flags & LD_In_LineMode);            if ((inpProc && lineMode) && (!nowInpProc || !nowLineMode)) {	/* line-mode to raw-mode */	update_special_chars = 1;	/* for now, flush all of the data */	BUDDY.buffPos = DATABUFF;	write_string("\r\nNow in raw mode\r\n");      }      if ((!inpProc || !lineMode) && (nowInpProc && nowLineMode)) {	/* raw -> line mode */	update_special_chars = 1;	BUDDY.buffPos = DATABUFF;	BUDDY.quoteNext = 0;	BUDDY.topWrote = 0;	BUDDY.first_special = NULL;	write_string("\r\nNow in line mode\r\n");      }      /* assume for now that any other changes are safe */      BUDDY.curInpFlags = new_flags;      BUDDY.wakeupEvents &= ~LD_Wakeup_ProcFlags;    }    BUDDY.curInpFlags = new_flags;    DEBUG(control)      kprintf(KR_OSTREAM,	      "Linedisc_buddy: entering main loop. %s spc_chars_upd\n",	      update_special_chars?"YES":"no");    if (!(BUDDY.curInpFlags & LD_In_DoInpProc)	|| !(BUDDY.curInpFlags & LD_In_LineMode)) {      DEBUG(inpproc)	kdprintf(KR_OSTREAM,"Hey!  We're in raw mode!\n");      if (update_special_chars) 	raw_update_specialChars();      rawLoop();    } else {      if (update_special_chars) 	line_update_specialChars();      lineModeLoop();     }    /* we've checked it */    BUDDY.wakeupEvents &= ~LD_Wakeup_TearDown;    if (SHARED.linedisc_status == LD_Stat_TearDown) {      SHARED.linedisc_status = LD_Stat_Gone;      destroy_self(RC_OK);      /* NOTREACHED */      break;    }      }  kdprintf(KR_OSTREAM,	   "Linedisc_buddy -- broke out of main!\n");  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -