📄 pollio.c
字号:
if(f_flags->mod == 'h') { val = (short) va_arg((*arg_pt), long); } else { val = (long) va_arg((*arg_pt), long); } /*---------------------------------------------------------------------*/ /* Null terminate the output string. Not included in output count. */ /*---------------------------------------------------------------------*/ pt = dec_buff + 19; /* pointer last element in array */ *(pt--) = '\0'; /* terminating char */ if (val < 0) {/* If val is negative, set the true flag and multiply by -1. */ neg = LTRUE; val = -val; } else { neg = FALSE; }/* While val is greater than zero, output characters to the string *//* from right to left. */ do { long i, tmp;/* The next two statements cause problems on the 68000, since that *//* processor does not have a 32-bit divide instruction. They are *//* replaced by functionally equivalent routines. *//* *(pt--) = val % 10 + '0'; */ tmp = val; while (tmp >= 10000) tmp -= 10000; while (tmp >= 1000) tmp -= 1000; while (tmp >= 100) tmp -= 100; while ((tmp -= 10) >= 10); if (tmp < 0) tmp += 10; *(pt--) = (UCHAR)(tmp + '0'); /* val /= (short)10; */ if (val >= 10) { for (i = 0; val >= 100000; i += 10000) val -= 100000; for ( ; val >= 10000; i += 1000) val -= 10000; for ( ; val >= 1000; i += 100) val -= 1000; for ( ; val >= 100; i += 10) val -= 100; for ( ; val >= 10; i++) val -= 10; val = i; } else val = 0; t_count++; } while (val != 0); while (t_count < f_flags->precision) { *(pt--) = '0'; t_count++; } /*---------------------------------------------------------------------*/ /* Next check to see if the 0 flag was used in the format and if the */ /* current count is less than the specified field width. If TRUE then */ /* fill in the leading zeros. Temporarily leave room in the field for */ /* an optional plus or minus sign. */ /*---------------------------------------------------------------------*/ pt++; if (f_flags->zero) { s_length = strlen(pt); while (f_flags->width > s_length + 1) { *(--pt) = '0'; s_length += 1; } } /*---------------------------------------------------------------------*/ /* Add leading plus or minus sign, and/or leading zero if needed. */ /*---------------------------------------------------------------------*/ if (neg) *(--pt) = '-'; else if (f_flags->plus) *(--pt) = '+'; else if (f_flags->space) *(--pt) = ' '; else if ((f_flags->zero) && (f_flags->width > s_length)) *(--pt) = '0'; f_flags->precision = DEFAULT; strout(f_flags, pt, strlen(pt));}/***********************************************************************//* hexout: Output a value as a hexadecimal number *//* *//* INPUTS: f_flags = ptr to format data structure *//* arg_pt = ptr to next argument in list *//* *//***********************************************************************/static void hexout(FORMAT *f_flags, va_list *arg_pt){ UCHAR c, *pt, d[16], hexbuff[16]; ULONG val, t_count; long s_length; USHORT i; t_count = 0; /* Set up the array of hex digits used in conversion. */ for (i = 0; i <= 9; i++) d[i] = '0' + i; c = (f_flags->type == 'X') ? 'A' : 'a'; for (i = 10; i <= 15; i++) d[i] = c++; /* Obtain the value to be output. */ if (f_flags->mod == 'h') { val = (USHORT) va_arg((*arg_pt), ULONG); } else { val = (ULONG) va_arg((*arg_pt), ULONG); } /* Null terminate string then process the value.*/ pt = & hexbuff[15]; *(pt--) = '\0';/* Process the value */ do { *(pt--) = d[val & 0xf]; t_count++; } while (val >>= 4); while (t_count < f_flags->precision) { *(pt--) = '0'; t_count++; } /*---------------------------------------------------------------------*/ /* Next check to see if the 0 flag was used in the format and if the */ /* current count is less than the specified field width. If TRUE then */ /* fill in the leading zeros. Temporarily leave room in the field for */ /* an optional plus or minus sign. */ /*---------------------------------------------------------------------*/ pt++; if (f_flags->zero) { s_length = strlen(pt); if (f_flags->alter) while (f_flags->width > s_length+2) { *(--pt) = '0'; s_length += 1; } else while (f_flags->width > s_length) { *(--pt) = '0'; s_length += 1; } } /*---------------------------------------------------------------------*/ /* If the "alternate form" flag is set, add 0x or 0X to the front of */ /* the string. */ /*---------------------------------------------------------------------*/ if (f_flags->alter) { if (f_flags->type == 'x') *(--pt) = 'x'; else *(--pt) = 'X'; *(--pt) = '0'; } f_flags->precision = DEFAULT; strout(f_flags, pt, strlen(pt));}/************************************************************************//* percent: Interpret a conversion specification *//* *//* INPUTS: format = ptr to current position in format string *//* arg_pt = ptr to next argument *//* *//* RETURNS: Ptr to next char in format string past this specifier. *//* OUTPUTS: *f_flags = filled in with format specification *//* *//************************************************************************/static char *percent(char *format, FORMAT *f_flags, va_list *arg_pt){ UCHAR p_flag = FALSE;/* Initialize the f_flag structure with the default values. */ f_flags->width = DEFAULT; f_flags->precision = DEFAULT_P; f_flags->right = LTRUE; // '-' to set left justified f_flags->plus = FALSE; // '+' result will always have sign (+ or -) f_flags->alter = FALSE; // '#' for alternate form f_flags->zero = FALSE; // '0' use leading zeros instead of spaces. f_flags->space = FALSE; // space for leading space f_flags->type = '\0'; f_flags->mod = '\0'; // l,L,h if (*format == '-') { f_flags->right = FALSE; format++; } if(*format == '+') { f_flags->plus = LTRUE; format++; } if(*format == ' ') { if (f_flags->plus == FALSE) f_flags->space = LTRUE; format++; } if(*format == '#') { f_flags->alter = LTRUE; format++; } if(*format == '0') { if (f_flags->right) f_flags->zero = LTRUE; format++; }/************************************************************************//* Process the width specification of the format. The width can be *//* specified by the next value in the arg_pt list. If the next *//* character is '*' then get the width from arg_pt with a call to the *//* va_arg() macro. *//* *//* The width can also be specified as a value in the format. In this *//* case the width is specified by a decimal number. *//************************************************************************/ if (*format == '*') { f_flags->width = va_arg((*arg_pt), int); if (f_flags->width < 0) { f_flags->right = FALSE; f_flags->width = -f_flags->width; } format++; } else { if(*format >= '0' && *format <= '9') { f_flags->width = 0; while(*format >= '0' && *format <= '9') { f_flags->width *= 10; f_flags->width += (*format++ - '0'); } } }/************************************************************************//* Process the precision field. The same options that are allowed for *//* the width field are permitted here. *//************************************************************************/if( *format == '.' ) { p_flag = LTRUE; format++; if( *format == '*' ) { f_flags->precision = va_arg((*arg_pt), int); format++; } else { f_flags->precision = 0; while(*format >= '0' && *format <= '9') { f_flags->precision *= 10; f_flags->precision += *format++ - '0'; } } }/************************************************************************//* Check for process modifier characters. {h, l, L} *//************************************************************************/if((*format == 'h') || (*format == 'l') || (*format == 'L')) f_flags->mod = *format++;/************************************************************************//* Based on the type of conversion it may be necessary to readjust the *//* precision flag to a default value of 0. *//************************************************************************/ if ((p_flag == FALSE) && (*format != 'c') && (*format != '%')) f_flags->precision = 0;/************************************************************************//* The final step is to read in the conversion type. *//************************************************************************/ f_flags->type = *format++; return format;}/***********************************************************************//* Print: Format output and send it to the console *//* *//* INPUTS: format = ptr to format string *//* additional inputs as specified by *format. *//* *//* RETURNS: # of characters output *//* NOTE: Format strings are explained in the header at the *//* top of this module. *//* *//***********************************************************************/ULONG Print(char *format, ...){ ULONG ip_addr; FORMAT f_flags; va_list arg_pt; va_start(arg_pt, format); f_flags.count = 0; if (format == NULL) format = (char *)"(null)"; /*---------------------------------------------------------------------*/ /* Process characters in 'format ' string until null terminator is */ /* reached. If the character is not a '%' then simply print it. */ /* Otherwise it will require further processing. */ /*---------------------------------------------------------------------*/ while (*format != '\0') { if (*format != '%') { put_byte(*format); if (*format == '\n') put_byte('\r'); format++; f_flags.count++; continue; }/* Set up the fields in the format structure.*/ format++; format = percent(format, &f_flags, &arg_pt);/*-------------------------------------------------------------*//* Continue to process based on the format type: *//* d,i - signed decimal *//* x,X - unsigned hexadecimal *//* c - print least significant character of int *//* s - argument taken to be (char *) pointer to string *//* % - A % is printed. No argument is converted. *//* I - IP address (dd.dd.dd.dd) *//*-------------------------------------------------------------*/ if(f_flags.type == 'd' || f_flags.type == 'i') { decout(&f_flags, &arg_pt); } else if(f_flags.type == 'x' || f_flags.type == 'X') { hexout(&f_flags, &arg_pt); } else if(f_flags.type == 'c') { charout(&f_flags, &arg_pt); } else if(f_flags.type == 's') { stringout(&f_flags, &arg_pt); } else if(f_flags.type == '%') { put_byte('%'); f_flags.count++; } else if(f_flags.type == 'I') { ip_addr = va_arg((arg_pt), long); Print("%d.%d.%d.%d", (ip_addr >> 24) & 0xFF, (ip_addr >> 16) & 0xFF, (ip_addr >> 8) & 0xFF, ip_addr & 0xFF); } } return f_flags.count;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -