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

📄 char_io.c

📁 i386的bootloader源码grub
💻 C
📖 第 1 页 / 共 2 页
字号:
	      break;	    case 2:		/* C-b backward one character */	      if (lpos > 0)		cl_backward (1);	      break;	    case 21:		/* C-u kill to beginning of line */	      if (lpos == 0)		break;	      /* Copy the string being deleted to KILL_BUF.  */	      grub_memmove (kill_buf, buf, lpos);	      kill_buf[lpos] = 0;	      {		/* XXX: Not very clever.  */				int count = lpos;				cl_backward (lpos);		cl_delete (count);	      }	      break;	    case 11:		/* C-k kill to end of line */	      if (lpos == llen)		break;	      /* Copy the string being deleted to KILL_BUF.  */	      grub_memmove (kill_buf, buf + lpos, llen - lpos + 1);	      cl_delete (llen - lpos);	      break;	    case 25:		/* C-y yank the kill buffer */	      cl_insert (kill_buf);	      break;	    case 16:		/* C-p fetch the previous command */	      {		char *p;		if (history < 0)		  /* Save the working buffer.  */		  grub_strcpy (cmdline, buf);		else if (grub_strcmp (get_history (history), buf) != 0)		  /* If BUF is modified, add it into the history list.  */		  add_history (buf, history);		history++;		p = get_history (history);		if (! p)		  {		    history--;		    break;		  }		grub_strcpy (buf, p);		llen = grub_strlen (buf);		lpos = llen;		cl_refresh (1, 0);	      }	      break;	    case 14:		/* C-n fetch the next command */	      {		char *p;		if (history < 0)		  {		    break;		  }		else if (grub_strcmp (get_history (history), buf) != 0)		  /* If BUF is modified, add it into the history list.  */		  add_history (buf, history);		history--;		p = get_history (history);		if (! p)		  p = cmdline;		grub_strcpy (buf, p);		llen = grub_strlen (buf);		lpos = llen;		cl_refresh (1, 0);	      }	      break;	    }	}      /* ESC, C-d and C-h are always handled. Actually C-d is not	 functional if READLINE is zero, as the cursor cannot go	 backward, but that's ok.  */      switch (c)	{	case 27:	/* ESC immediately return 1 */	  return 1;	case 4:		/* C-d delete character under cursor */	  if (lpos == llen)	    break;	  cl_delete (1);	  break;	case 8:		/* C-h backspace */# ifdef GRUB_UTIL	case 127:	/* also backspace */# endif	  if (lpos > 0)	    {	      cl_backward (1);	      cl_delete (1);	    }	  break;	default:		/* insert printable character into line */	  if (c >= ' ' && c <= '~')	    {	      char str[2];	      str[0] = c;	      str[1] = 0;	      cl_insert (str);	    }	}    }  grub_putchar ('\n');  /* If ECHO_CHAR is NUL, remove the leading spaces.  */  lpos = 0;  if (! echo_char)    while (buf[lpos] == ' ')      lpos++;  /* Copy the working buffer to CMDLINE.  */  grub_memmove (cmdline, buf + lpos, llen - lpos + 1);  /* If the readline-like feature is turned on and CMDLINE is not     empty, add it into the history list.  */  if (readline && lpos < llen)    add_history (cmdline, 0);  return 0;}/* Don't use this with a MAXLEN greater than 1600 or so!  The problem   is that GET_CMDLINE depends on the everything fitting on the screen   at once.  So, the whole screen is about 2000 characters, minus the   PROMPT, and space for error and status lines, etc.  MAXLEN must be   at least 1, and PROMPT and CMDLINE must be valid strings (not NULL   or zero-length).   If ECHO_CHAR is nonzero, echo it instead of the typed character. */intget_cmdline (char *prompt, char *cmdline, int maxlen,	     int echo_char, int readline){  int old_cursor;  int ret;  old_cursor = setcursor (1);    /* Because it is hard to deal with different conditions simultaneously,     less functional cases are handled here. Assume that TERM_NO_ECHO     implies TERM_NO_EDIT.  */  if (current_term->flags & (TERM_NO_ECHO | TERM_NO_EDIT))    {      char *p = cmdline;      int c;            /* Make sure that MAXLEN is not too large.  */      if (maxlen > MAX_CMDLINE)	maxlen = MAX_CMDLINE;      /* Print only the prompt. The contents of CMDLINE is simply discarded,	 even if it is not empty.  */      grub_printf ("%s", prompt);      /* Gather characters until a newline is gotten.  */      while ((c = ASCII_CHAR (getkey ())) != '\n' && c != '\r')	{	  /* Return immediately if ESC is pressed.  */	  if (c == 27)	    {	      setcursor (old_cursor);	      return 1;	    }	  /* Printable characters are added into CMDLINE.  */	  if (c >= ' ' && c <= '~')	    {	      if (! (current_term->flags & TERM_NO_ECHO))		grub_putchar (c);	      /* Preceding space characters must be ignored.  */	      if (c != ' ' || p != cmdline)		*p++ = c;	    }	}      *p = 0;      if (! (current_term->flags & TERM_NO_ECHO))	grub_putchar ('\n');      setcursor (old_cursor);      return 0;    }  /* Complicated features are left to real_get_cmdline.  */  ret = real_get_cmdline (prompt, cmdline, maxlen, echo_char, readline);  setcursor (old_cursor);  return ret;}intsafe_parse_maxint (char **str_ptr, int *myint_ptr){  char *ptr = *str_ptr;  int myint = 0;  int mult = 10, found = 0;  /*   *  Is this a hex number?   */  if (*ptr == '0' && tolower (*(ptr + 1)) == 'x')    {      ptr += 2;      mult = 16;    }  while (1)    {      /* A bit tricky. This below makes use of the equivalence:	 (A >= B && A <= C) <=> ((A - B) <= (C - B))	 when C > B and A is unsigned.  */      unsigned int digit;      digit = tolower (*ptr) - '0';      if (digit > 9)	{	  digit -= 'a' - '0';	  if (mult == 10 || digit > 5)	    break;	  digit += 10;	}      found = 1;      if (myint > ((MAXINT - digit) / mult))	{	  errnum = ERR_NUMBER_OVERFLOW;	  return 0;	}      myint = (myint * mult) + digit;      ptr++;    }  if (!found)    {      errnum = ERR_NUMBER_PARSING;      return 0;    }  *str_ptr = ptr;  *myint_ptr = myint;  return 1;}#endif /* STAGE1_5 */#if !defined(STAGE1_5) || defined(FSYS_FAT)intgrub_tolower (int c){  if (c >= 'A' && c <= 'Z')    return (c + ('a' - 'A'));  return c;}#endif /* ! STAGE1_5 || FSYS_FAT */intgrub_isspace (int c){  switch (c)    {    case ' ':    case '\t':    case '\r':    case '\n':      return 1;    default:      break;    }  return 0;}#if !defined(STAGE1_5) || defined(FSYS_ISO9660)intgrub_memcmp (const char *s1, const char *s2, int n){  while (n)    {      if (*s1 < *s2)	return -1;      else if (*s1 > *s2)	return 1;      s1++;      s2++;      n--;    }  return 0;}#endif /* ! STAGE1_5 || FSYS_ISO9660 */#ifndef STAGE1_5intgrub_strncat (char *s1, const char *s2, int n){  int i = -1;  while (++i < n && s1[i] != 0);  while (i < n && (s1[i++] = *(s2++)) != 0);  s1[n - 1] = 0;  if (i >= n)    return 0;  s1[i] = 0;  return 1;}#endif /* ! STAGE1_5 *//* XXX: This below is an evil hack. Certainly, we should change the   strategy to determine what should be defined and what shouldn't be   defined for each image. For example, it would be better to create   a static library supporting minimal standard C functions and link   each image with the library. Complicated things should be left to   computer, definitely. -okuji  */#if !defined(STAGE1_5) || defined(FSYS_VSTAFS)intgrub_strcmp (const char *s1, const char *s2){  while (*s1 || *s2)    {      if (*s1 < *s2)	return -1;      else if (*s1 > *s2)	return 1;      s1 ++;      s2 ++;    }  return 0;}#endif /* ! STAGE1_5 || FSYS_VSTAFS */#ifndef STAGE1_5/* Wait for a keypress and return its code.  */intgetkey (void){  return current_term->getkey ();}/* Check if a key code is available.  */intcheckkey (void){  return current_term->checkkey ();}#endif /* ! STAGE1_5 *//* Display an ASCII character.  */voidgrub_putchar (int c){  if (c == '\n')    grub_putchar ('\r');#ifndef STAGE1_5  else if (c == '\t' && current_term->getxy)    {      int n;            n = 8 - ((current_term->getxy () >> 8) & 3);      while (n--)	grub_putchar (' ');            return;    }#endif /* ! STAGE1_5 */  #ifdef STAGE1_5    /* In Stage 1.5, only the normal console is supported.  */  console_putchar (c);  #else /* ! STAGE1_5 */  if (c == '\n')    {      /* Internal `more'-like feature.  */      if (count_lines >= 0)	{	  count_lines++;	  if (count_lines >= max_lines - 2)	    {	      int tmp;	      	      /* It's important to disable the feature temporarily, because		 the following grub_printf call will print newlines.  */	      count_lines = -1;	      if (current_term->setcolorstate)		current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);	      	      grub_printf ("\n[Hit return to continue]");	      if (current_term->setcolorstate)		current_term->setcolorstate (COLOR_STATE_NORMAL);	      	      do		{		  tmp = ASCII_CHAR (getkey ());		}	      while (tmp != '\n' && tmp != '\r');	      grub_printf ("\r                        \r");	      	      /* Restart to count lines.  */	      count_lines = 0;	      return;	    }	}    }  current_term->putchar (c);  #endif /* ! STAGE1_5 */}#ifndef STAGE1_5voidgotoxy (int x, int y){  current_term->gotoxy (x, y);}intgetxy (void){  return current_term->getxy ();}voidcls (void){  /* If the terminal is dumb, there is no way to clean the terminal.  */  if (current_term->flags & TERM_DUMB)    grub_putchar ('\n');  else    current_term->cls ();}intsetcursor (int on){  if (current_term->setcursor)    return current_term->setcursor (on);  return 1;}#endif /* ! STAGE1_5 */intsubstring (const char *s1, const char *s2){  while (*s1 == *s2)    {      /* The strings match exactly. */      if (! *(s1++))	return 0;      s2 ++;    }  /* S1 is a substring of S2. */  if (*s1 == 0)    return -1;  /* S1 isn't a substring. */  return 1;}#ifndef STAGE1_5/* Terminate the string STR with NUL.  */intnul_terminate (char *str){  int ch;    while (*str && ! grub_isspace (*str))    str++;  ch = *str;  *str = 0;  return ch;}char *grub_strstr (const char *s1, const char *s2){  while (*s1)    {      const char *ptr, *tmp;      ptr = s1;      tmp = s2;      while (*tmp && *ptr == *tmp)	ptr++, tmp++;            if (tmp > s2 && ! *tmp)	return (char *) s1;      s1++;    }  return 0;}intgrub_strlen (const char *str){  int len = 0;  while (*str++)    len++;  return len;}#endif /* ! STAGE1_5 */intmemcheck (int addr, int len){#ifdef GRUB_UTIL  static int start_addr (void)    {      int ret;# if defined(HAVE_START_SYMBOL)      asm volatile ("movl	$start, %0" : "=a" (ret));# elif defined(HAVE_USCORE_START_SYMBOL)      asm volatile ("movl	$_start, %0" : "=a" (ret));# endif      return ret;    }  static int end_addr (void)    {      int ret;# if defined(HAVE_END_SYMBOL)      asm volatile ("movl	$end, %0" : "=a" (ret));# elif defined(HAVE_USCORE_END_SYMBOL)      asm volatile ("movl	$_end, %0" : "=a" (ret));# endif      return ret;    }  if (start_addr () <= addr && end_addr () > addr + len)    return ! errnum;#endif /* GRUB_UTIL */  if ((addr < RAW_ADDR (0x1000))      || (addr < RAW_ADDR (0x100000)	  && RAW_ADDR (mbi.mem_lower * 1024) < (addr + len))      || (addr >= RAW_ADDR (0x100000)	  && RAW_ADDR (mbi.mem_upper * 1024) < ((addr - 0x100000) + len)))    errnum = ERR_WONT_FIT;  return ! errnum;}void *grub_memmove (void *to, const void *from, int len){   if (memcheck ((int) to, len))     {       /* This assembly code is stolen from	  linux-2.2.2/include/asm-i386/string.h. This is not very fast	  but compact.  */       int d0, d1, d2;       if (to < from)	 {	   asm volatile ("cld\n\t"			 "rep\n\t"			 "movsb"			 : "=&c" (d0), "=&S" (d1), "=&D" (d2)			 : "0" (len),"1" (from),"2" (to)			 : "memory");	 }       else	 {	   asm volatile ("std\n\t"			 "rep\n\t"			 "movsb\n\t"			 "cld"			 : "=&c" (d0), "=&S" (d1), "=&D" (d2)			 : "0" (len),			 "1" (len - 1 + (const char *) from),			 "2" (len - 1 + (char *) to)			 : "memory");	 }     }   return errnum ? NULL : to;}void *grub_memset (void *start, int c, int len){  char *p = start;  if (memcheck ((int) start, len))    {      while (len -- > 0)	*p ++ = c;    }  return errnum ? NULL : start;}#ifndef STAGE1_5char *grub_strcpy (char *dest, const char *src){  grub_memmove (dest, src, grub_strlen (src) + 1);  return dest;}#endif /* ! STAGE1_5 */#ifndef GRUB_UTIL# undef memcpy/* GCC emits references to memcpy() for struct copies etc.  */void *memcpy (void *dest, const void *src, int n)  __attribute__ ((alias ("grub_memmove")));#endif

⌨️ 快捷键说明

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