gather typed digits into a number in *count; return the next non-digit */
| 5007 | |
| 5008 | /* gather typed digits into a number in *count; return the next non-digit */ |
| 5009 | char |
| 5010 | get_count( |
| 5011 | const char *allowchars, /* what comes after digits; if Null, anything */ |
| 5012 | char inkey, /* if caller already got first digit, this is it */ |
| 5013 | long maxcount, /* if user tries to enter a bigger count, use this */ |
| 5014 | cmdcount_nht *count, /* primary output */ |
| 5015 | unsigned gc_flags) /* control flags: GC_SAVEHIST, GC_ECHOFIRST */ |
| 5016 | { |
| 5017 | char qbuf[QBUFSZ]; |
| 5018 | int key, save_input_state = program_state.input_state; |
| 5019 | long cnt = 0L, first = inkey ? (long) (inkey - '0') : 0L; |
| 5020 | boolean backspaced = FALSE, showzero = TRUE, |
| 5021 | /* should "Count: 123" go into message history? */ |
| 5022 | historicmsg = (gc_flags & GC_SAVEHIST) != 0, |
| 5023 | /* put "Count: N" into mesg hist unless N is the same as the |
| 5024 | [first digit] value passed in via 'inkey' */ |
| 5025 | conditionalmsg = (gc_flags & GC_CONDHIST) != 0, |
| 5026 | /* normally "Count: 12" isn't echoed until the second digit */ |
| 5027 | echoalways = (gc_flags & GC_ECHOFIRST) != 0; |
| 5028 | /* this should be done in port code so that we have erase_char |
| 5029 | and kill_char available; we can at least fake erase_char */ |
| 5030 | #define STANDBY_erase_char '\177' |
| 5031 | |
| 5032 | *count = 0; |
| 5033 | for (;;) { |
| 5034 | if (inkey) { |
| 5035 | key = inkey; |
| 5036 | inkey = '\0'; |
| 5037 | } else { |
| 5038 | /* if readchar() has already been called in this loop, it will |
| 5039 | have reset input_state; put that back to its previous value */ |
| 5040 | program_state.input_state = save_input_state; |
| 5041 | key = readchar(); |
| 5042 | } |
| 5043 | |
| 5044 | if (digit(key)) { |
| 5045 | long dgt = (long) (key - '0'); |
| 5046 | |
| 5047 | /* cnt = (10 * cnt) + (key - '0'); */ |
| 5048 | cnt = AppendLongDigit(cnt, dgt); |
| 5049 | if (cnt < 0L) |
| 5050 | cnt = 0L; |
| 5051 | else if (maxcount > 0L && cnt > maxcount) |
| 5052 | cnt = maxcount; |
| 5053 | /* if we've backed up to nothing, then typed 0, show that 0 */ |
| 5054 | showzero = (key == '0'); |
| 5055 | } else if (key == '\b' || key == STANDBY_erase_char) { |
| 5056 | if (!cnt && !echoalways) |
| 5057 | break; |
| 5058 | showzero = FALSE; |
| 5059 | cnt = cnt / 10L; |
| 5060 | backspaced = TRUE; |
| 5061 | } else if (key == gc.Cmd.spkeys[NHKF_ESC]) { |
| 5062 | break; |
| 5063 | } else if (!allowchars || strchr(allowchars, key)) { |
| 5064 | *count = (cmdcount_nht) cnt; |
| 5065 | if ((long) *count != cnt) |
| 5066 | impossible("get_count: cmdcount_nht"); |
no test coverage detected