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

📄 ttyio.c

📁 internich公司实现的一个非常非常小的OS
💻 C
📖 第 1 页 / 共 2 页
字号:
            varp = (void *)&w0;            break;         case 'l':            varp = (void *)&lng;            break;            default:            varp = NULL;            break;         }         fieldlen = fplen(sp, varp);#else         fieldlen = fplen(sp, vp);        /* figger display size of this var */#endif   /* PRINTF_STDARG */         if (*cp == '.')   /* do we have a max field size? */         {            cp++;       /* point to number past '.' */            maxfieldlen = setnum(&cp);         }         else         {            maxfieldlen = LINESIZE;         }         if (maxfieldlen < (int)fieldlen)         {            fieldlen = maxfieldlen;         }         if (minfieldlen > fieldlen)         {            postfill = minfieldlen - fieldlen;         }         else         {            postfill = 0;         }         if ((postfill + fieldlen) > LINESIZE)         {            postfill = 0;   /* sanity check*/         }      }      if (swap)      /* caller wanted right adjustment, swap prefill/postfill */      {         swap = (int)prefill;         prefill = postfill;         postfill = (unsigned)swap;      }      while (prefill--)      {         doputchar(fillchar); /* do any pre-field padding */      }#endif   /* FIELDWIDTH */#ifdef PRINTF_STDARG      switch (*sp)      {      case 'p':      /* '%p' - pointer */#ifdef SEG16_16   /* do seg:offset variety */         hexword(outctxp, w1);   /* display segment word */         doputchar(':');         hexword(outctxp, w0);   /* display offset word */#else /* 32 bit flat */         hexword(outctxp, (unsigned)(lng >> 16));         hexword(outctxp, (unsigned)(lng & 0x0000FFFF));#endif /* SEG16_16 */   /* else fall to 32 bit code */         break;      case 'x':      /* '%x' - this always does 0 prefill */         if (tmp > 255)            hexword(outctxp, tmp);         else            hexbyte(outctxp, tmp);         break;      case 'd':      /* '%d' */         declong(outctxp, (long) i0);         break;      case 'u':      /* '%u' */         declong(outctxp, (unsigned long) w0);         break;      case 'c':      /* '%c' */         doputchar(c);         break;      case 's':      /* '%s' */         i = 0;         while (cap  && (*cap) && (i++ < maxfieldlen))            doputchar(*cap++);         break;      case 'l':         sp++;         if (*sp == 'x')      /* '%lx' */         {            hexword(outctxp, (unsigned)(lng >> 16));            hexword(outctxp, (unsigned)(lng & 0x0000FFFF));         }         else if(*sp == 'd' || *sp == 'u')   /* '%ld' or '%lu' */         {            declong(outctxp, lng);    /* we treat %lu as %ld. */         }         /*  else   '%l?', ignore it */         break;      default:       /* %?, ignore it */         break;      }  /* end switch *sp */#else /* PRINTF_STDARG */      switch (*sp)      {      case 'p':      /* '%p' - pointer */#ifdef SEG16_16   /* do seg:offset variety */         /* display segment word */         hexword(outctxp, (unsigned)*(vp+1));         doputchar(':');         /* display offset word */         hexword(outctxp, (unsigned)*vp);         vp += 2;          /* bump var pointer past two words */#else /* 32 bit flat */         lng = *vp;         hexword(outctxp, (unsigned)(lng >> 16));         hexword(outctxp, (unsigned)(lng & 0x0000FFFF));         vp += 4/sizeof(*vp); /* 2 or 1 */ #endif /* SEG16_16 */   /* else fall to 32 bit code */         break;      case 'x':      /* '%x' - this always does 0 prefill */         tmp = *(unsigned *)vp++;         if (tmp > 255)            hexword(outctxp, tmp);         else            hexbyte(outctxp, tmp);         break;      case 'd':      /* '%d' */         declong(outctxp, (long)*vp++);         break;      case 'u':      /* '%u' */         declong(outctxp, (unsigned long)*(unsigned *)vp);         vp++;         break;      case 'c':      /* '%c' */         doputchar((unsigned char)(*vp++));         break;      case 's':      /* '%s' */         cp = *(char **)vp;         vp += sizeof(char*)/sizeof(int);            i = 0;         while (*cp && i++ < maxfieldlen)            doputchar(*cp++);         break;      case 'l':         sp++;         if (*sp == 'x')      /* '%lx' */         {            /*          lng = *vp;      */            lng = *((unsigned long *) vp);            hexword(outctxp, (unsigned)(lng >> 16));            hexword(outctxp, (unsigned)(lng & 0x0000FFFF));            vp += 4/sizeof(*vp); /* 2 or 1 */          }         else if(*sp == 'd' || *sp == 'u')   /* '%ld' or '%lu' */         {            /* we treat %lu as %ld. */            declong(outctxp, *(long  *)vp);            vp += 2;         }         /*  else   '%l?', ignore it */         break;     default:       /* %?, ignore it */         break;      }  /* end switch *sp */#endif   /* PRINTF_STDARG */#ifdef   FIELDWIDTH      while (postfill--)      {         doputchar(fillchar);   /* do any post-field padding */      }#endif   /* FIELDWIDTH */      sp++;       /* point past '%?' */   }  /* end while *sp */   if (outctxp->target)      *(outctxp->target) = '\0';   /* Null terminate the string */   return (int)(outctxp->outlen);}/* FUNCTION: hexword() * * hexword(x) - print 16 bit value as hexadecimal *  * PARAM1: char ** targ * PARAM2: unsigned x * * RETURNS:  */static voidhexword(struct output_ctx * outctxp, unsigned x){   doputchar(digits[x >> 12]);   doputchar(digits[(x >> 8) & 0x0f]);   doputchar(digits[(x >> 4) & 0x0f]);   doputchar(digits[x & 0x0f]);}/* FUNCTION: hexbyte() *  * PARAM1: char ** targ * PARAM2: unsigned  x * * RETURNS:  */static voidhexbyte(struct output_ctx * outctxp, unsigned  x){   doputchar(digits[(x >> 4) & 0x0f]);   doputchar(digits[x & 0x0f]);} /* FUNCTION: declong() * * declong(char*, long) - print a long to target as a decimal number.  * Assumes signed, prepends '-' if negative.  * *  * PARAM1: char ** targ * PARAM2: long lg * * RETURNS:  *//* This should be local to declong, but Microsoft C 5.1  * breaks if it is. They use implicit lib calls to do long integer  * math, and the calls pass pointers to the longs, which assumes the  * longs are in local data space.  */long tens;static voiddeclong(struct output_ctx * outctxp, long  lg){   int   digit;   if (lg == 0)   {      doputchar('0');      return;   }   else if(lg < 0L)   {      doputchar('-');      lg = -lg;   }   /* make "tens" the highest power of 10 smaller than lg */   tens = 1;   while ((lg/10) >= tens)       tens *= 10;   while (tens)   {      digit = (int)(lg/tens);    /* get highest digit in lg */      doputchar(digits[digit]);      lg -= ((long)digit * tens);      tens /= 10;   }}#ifdef FIELDWIDTH/* FUNCTION: setnum() * * returns the value of fieldwidth digits from a  * printf format string. fptr should be a pointer to a pointer to one  * or more fieldwidth digits. On return, is advanced past the digits  * and the value of the digits is returned as an int.  * *  * PARAM1: char ** nptr * * RETURNS: returns the value of fieldwidth digits from a  * printf format string */int      snval;   /* return value, breaks if on stack */intsetnum(char ** nptr){   snval = 0;   while (**nptr >= '0' && **nptr <= '9') /* scan through digits */   {      snval *= 10;      /* calculate return value */      snval += **nptr - '0';      /* bump pointer (not pointer to pointer) past valid digits */         (*nptr)++;   }   return(snval);}/* FUNCTION: fplen() * * fplen(sp, varp) - returns the number of chars required to print  * the value pointed to by varp when formatted accoring to the string  * pointer to by sp.  * *  * PARAM1: char * sp * PARAM2: void * varp * * RETURNS:  */long     lng1, lng2;    /* scratch value for longs */intfplen(char * sp, void * varp){   char *   cp;   /* define the maximum digits needed to display a long value in     * decimal. Say , sizeof(long) = 4. So it has 8*4=32 bits.     * 2^10=1024. So for every 10 bits, we can show 3 digits. So for     * long, this value would be 32*3/10=96/10=9. And then we add one     * more digit for the roundoff. max_long_dig is used to prevent     * long overflow in lng1. There are better ways to prevent this,     * but very difficult to verify whether we made the perfect fix.     * Hence for now, this should do.     */   static int max_long_dig = (8 * sizeof(long) * 3)/10+1;   snval = 0;     /* use this for return value */   lng1 = 1;   /* for figuring lengths of decimal numbers */   switch (*sp)      /* switch on conversion char */   {   case 's':      cp = *(char**)varp;      while   (*cp++) snval++;         return(snval);   case 'c':      return(1);   case 'x':      return(4);   case 'p':      return(9);   case 'd':   case 'u':      lng2 = *(long *)varp;      if (lng2 == 0) return(1);         if (lng2 < 0)        /* if variable value is negative... */      {   if (*sp == 'd')  /* format is signded decimal */          {   snval++;   /* add space for '-' sign */            lng2 = -lng2;         }         else     /* *sp == 'u' - format is unsigned */            lng2 &= 0xffff;      }      while (lng1 <= lng2)      {         lng1 *= 10;         snval++;         if ( snval >= max_long_dig )         {            /* If we don't stop now, there lng1 will have long overflow */            break;         }      }      return(snval);   case 'l':      switch (*(sp+1))      {      case 'x':   /* '%lx' always 8 bytes */         return(8);      case 'u':      /* treat %lu like %ld */      case 'd':         lng2 = (*(long *)(varp));         if (lng2 == 0) return(1);            if (lng2 < 0)         {            snval++;       /* add space for '-' sign */            lng2 = -lng2;         }         while (lng1 <= lng2)         {            lng1 *= 10;            snval++;            if ( snval >= max_long_dig )            {               /* If we don't stop now, there lng1 will have long overflow */               break;            }         }         return(snval);         default:         return(0);      }               default:      return(0);   }}#endif   /* FIELDWIDTH */#endif   /* NATIVE_PRINTF */

⌨️ 快捷键说明

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