OSDN Git Service

広域マップで画面をスクロールすると右端の境界の外までスクロールできてしまうバグ修正。
[hengbandforosx/hengbandosx.git] / src / util.c
index c313dc4..66b3a53 100644 (file)
@@ -91,10 +91,12 @@ int usleep(huge usecs)
 
 
 /*
-* Hack -- External functions
-*/
-extern struct passwd *getpwuid();
-extern struct passwd *getpwnam();
+ * Hack -- External functions
+ */
+#ifdef SET_UID
+extern struct passwd *getpwuid(uid_t uid);
+extern struct passwd *getpwnam(const char *name);
+#endif
 
 
 /*
@@ -391,7 +393,7 @@ FILE *my_fopen_temp(char *buf, int max)
        int fd;
 
        /* Prepare the buffer for mkstemp */
-       (void)strnfmt(buf, max, "%s", "/tmp/anXXXXXX");
+       strncpy(buf, "/tmp/anXXXXXX", max);
 
        /* Secure creation of a temporary file */
        fd = mkstemp(buf);
@@ -682,9 +684,12 @@ int fd_make(cptr file, int mode)
 # if defined(MACINTOSH) && defined(MAC_MPW)
 
        /* setting file type and creator -- AR */
-       errr_tmp = open(buf, O_CREAT | O_EXCL | O_WRONLY | O_BINARY, mode);
-       fsetfileinfo(file, _fcreator, _ftype);
-       return(errr_tmp);
+       {
+               errr errr_tmp;
+               errr_tmp = open(buf, O_CREAT | O_EXCL | O_WRONLY | O_BINARY, mode);
+               fsetfileinfo(file, _fcreator, _ftype);
+               return(errr_tmp);
+       }
 
 # else
        /* Create the file, fail if exists, write-only, binary */
@@ -791,9 +796,6 @@ errr fd_seek(int fd, huge n)
        p = lseek(fd, n, SEEK_SET);
 
        /* Failure */
-       if (p < 0) return (1);
-
-       /* Failure */
        if (p != n) return (1);
 
        /* Success */
@@ -1147,7 +1149,7 @@ void text_to_ascii(char *buf, cptr str)
                        /* Skip the backslash */
                        str++;
 
-                        /* Macro Trigger */
+                       /* Macro Trigger */
                        if (*str == '[')
                        {
                                trigger_text_to_ascii(&s, &str);
@@ -1260,7 +1262,7 @@ void text_to_ascii(char *buf, cptr str)
 }
 
 
-bool trigger_ascii_to_text(char **bufptr, cptr *strptr)
+static bool trigger_ascii_to_text(char **bufptr, cptr *strptr)
 {
        char *s = *bufptr;
        cptr str = *strptr;
@@ -1610,21 +1612,6 @@ errr macro_add(cptr pat, cptr act)
 
 
 /*
- * Initialize the "macro" package
- */
-errr macro_init(void)
-{
-       /* Macro patterns */
-       C_MAKE(macro__pat, MACRO_MAX, cptr);
-
-       /* Macro actions */
-       C_MAKE(macro__act, MACRO_MAX, cptr);
-
-       /* Success */
-       return (0);
-}
-
-/*
  * Local variable -- we are inside a "macro action"
  *
  * Do not match any macros until "ascii 30" is found.
@@ -1649,7 +1636,7 @@ static bool parse_under = FALSE;
 void flush(void)
 {
        /* Do it later */
-        inkey_xtra = TRUE;
+       inkey_xtra = TRUE;
 }
 
 
@@ -1713,8 +1700,20 @@ static char inkey_aux(void)
        /* Hack : ¥­¡¼ÆþÎÏÂÔ¤Á¤Ç»ß¤Þ¤Ã¤Æ¤¤¤ë¤Î¤Ç¡¢Î®¤ì¤¿¹Ô¤Îµ­²±¤ÏÉÔÍס£ */
        num_more = 0;
 
-       /* Wait for a keypress */
-       (void)(Term_inkey(&ch, TRUE, TRUE));
+       if (parse_macro)
+       {
+               /* Scan next keypress from macro action */
+               if (Term_inkey(&ch, FALSE, TRUE))
+               {
+                       /* Over-flowed? Cancel macro action */
+                       parse_macro = FALSE;
+               }
+       }
+       else
+       {
+               /* Wait for a keypress */
+               (void) (Term_inkey(&ch, TRUE, TRUE));
+       }
 
 
        /* End "macro action" */
@@ -1729,6 +1728,8 @@ static char inkey_aux(void)
        /* Inside "macro trigger" */
        if (parse_under) return (ch);
 
+       /* Parse special key only */
+       if (inkey_special && ch != 31) return (ch);
 
        /* Save the first key, advance */
        buf[p++] = ch;
@@ -1940,7 +1941,7 @@ char inkey(void)
                ch = *inkey_next++;
 
                /* Cancel the various "global parameters" */
-               inkey_base = inkey_xtra = inkey_flag = inkey_scan = FALSE;
+               inkey_base = inkey_xtra = inkey_flag = inkey_scan = inkey_special = FALSE;
 
                /* Accept result */
                return (ch);
@@ -1956,7 +1957,7 @@ char inkey(void)
        if (inkey_hack && ((ch = (*inkey_hack)(inkey_xtra)) != 0))
        {
                /* Cancel the various "global parameters" */
-               inkey_base = inkey_xtra = inkey_flag = inkey_scan = FALSE;
+               inkey_base = inkey_xtra = inkey_flag = inkey_scan = inkey_special = FALSE;
 
                /* Accept result */
                return (ch);
@@ -2141,7 +2142,7 @@ char inkey(void)
 
 
        /* Cancel the various "global parameters" */
-       inkey_base = inkey_xtra = inkey_flag = inkey_scan = FALSE;
+       inkey_base = inkey_xtra = inkey_flag = inkey_scan = inkey_special = FALSE;
 
        /* Return the keypress */
        return (ch);
@@ -2370,7 +2371,7 @@ void message_add(cptr str)
  for (t = buf; *t && (*t != '<' || (*(t+1) != 'x' )); t++) 
      if( iskanji(*t))t++;
 #else
-                for (t = buf; *t && (*t != '<'); t++);
+               for (t = buf; *t && (*t != '<'); t++);
 #endif
 
                if (*t)
@@ -2588,7 +2589,7 @@ static void msg_flush(int x)
        }
        now_damaged = FALSE;
 
-       if (!alive || !nagasu)
+       if (!p_ptr->playing || !nagasu)
        {
                /* Pause for response */
 #ifdef JP
@@ -2963,6 +2964,8 @@ void c_roff(byte a, cptr str)
 
                        /* Clear line, move cursor */
                        Term_erase(x, y, 255);
+
+                       break;
                }
 
                /* Clean up the char */
@@ -3062,7 +3065,7 @@ void c_roff(byte a, cptr str)
 
                /* Dump */
 #ifdef JP
-                Term_addch((byte)(a|0x10), ch);
+               Term_addch((byte)(a|0x10), ch);
 #else
                Term_addch(a, ch);
 #endif
@@ -3201,28 +3204,28 @@ bool askfor_aux(char *buf, int len)
                default:
 #ifdef JP
        {                       /* ÊÒ»³¤µ¤óºîÀ® */
-                int next;
-
-                                if (iskanji (i)) {
-                                        inkey_base = TRUE;
-                                        next = inkey ();
-                                        if (k+1 < len) {
-                                                buf[k++] = i;
-                                                buf[k] = next;
-                                                k_flag[k++] = 1;
-                                        } else
-                                                bell();
-                                } else {
+               int next;
+
+                               if (iskanji (i)) {
+                                       inkey_base = TRUE;
+                                       next = inkey ();
+                                       if (k+1 < len) {
+                                               buf[k++] = i;
+                                               buf[k] = next;
+                                               k_flag[k++] = 1;
+                                       } else
+                                               bell();
+                               } else {
 #ifdef SJIS
-                    if(k<len && (isprint(i) || (0xa0<=i && i<=0xdf))){
+                   if(k<len && (isprint(i) || (0xa0<=i && i<=0xdf))){
 #else
-                    if(k<len && isprint(i)){
+                   if(k<len && isprint(i)){
 #endif
-                                                buf[k] = i;
-                                                k_flag[k++] = 0;
-                                        } else
-                                                bell();
-                              }
+                                               buf[k] = i;
+                                               k_flag[k++] = 0;
+                                       } else
+                                               bell();
+                              }
                 }
 #else
                        if ((k < len) && (isprint(i)))
@@ -3300,9 +3303,9 @@ bool get_check(cptr prompt)
 /*
  * Verify something with the user strictly
  *
- * mode & 0x01 : force user to answer "YES" or "N"
- * mode & 0x02 : don't allow ESCAPE key
- * mode & 0x04 : no message_add
+ * mode & CHECK_OKAY_CANCEL : force user to answer 'O'kay or 'C'ancel
+ * mode & CHECK_NO_ESCAPE   : don't allow ESCAPE key
+ * mode & CHECK_NO_HISTORY  : no message_add
  */
 bool get_check_strict(cptr prompt, int mode)
 {
@@ -3320,41 +3323,25 @@ bool get_check_strict(cptr prompt, int mode)
        msg_print(NULL);
 
        if (!rogue_like_commands)
-               mode &= ~1;
+               mode &= ~CHECK_OKAY_CANCEL;
 
 
        /* Hack -- Build a "useful" prompt */
-       if (mode & 1)
+       if (mode & CHECK_OKAY_CANCEL)
        {
-#ifdef JP
-               /* (79-8)¥Ð¥¤¥È¤Î»ØÄê, prompt¤¬Ä¹¤«¤Ã¤¿¾ì¹ç, 
-                  (79-9)ʸ»ú¤Î¸å½ªÃ¼Ê¸»ú¤¬½ñ¤­¹þ¤Þ¤ì¤ë.     
-                  ±Ñ¸ì¤ÎÊý¤Îstrncpy¤È¤Ï°ã¤¦¤Î¤ÇÃí°Õ.
-                  else¤ÎÊý¤Îʬ´ô¤âƱÍÍ. --henkma
-               */
-               mb_strlcpy(buf, prompt, 80-15);
-#else
-               strncpy(buf, prompt, 79-15);
-               buf[79-8]='\0';
-#endif
+               my_strcpy(buf, prompt, sizeof(buf)-15);
                strcat(buf, "[(O)k/(C)ancel]");
-
        }
        else
        {
-#ifdef JP
-               mb_strlcpy(buf, prompt, 80-5);
-#else
-               strncpy(buf, prompt, 79-5);
-               buf[79-5]='\0';
-#endif
+               my_strcpy(buf, prompt, sizeof(buf)-5);
                strcat(buf, "[y/n]");
        }
 
        /* Prompt for it */
        prt(buf, 0, 0);
 
-       if (!(mode & 4))
+       if (!(mode & CHECK_NO_HISTORY) && p_ptr->playing)
        {
                /* HACK : Add the line to message buffer */
                message_add(buf);
@@ -3366,7 +3353,7 @@ bool get_check_strict(cptr prompt, int mode)
        while (TRUE)
        {
                i = inkey();
-               if ( mode & 1 )
+               if (mode & CHECK_OKAY_CANCEL)
                {
                        if ( i == 'o' || i == 'O' )
                        {
@@ -3378,8 +3365,8 @@ bool get_check_strict(cptr prompt, int mode)
                {
                                break;
                }
-               if (!(mode & 2) && (i == ESCAPE)) break;
-               if ( mode & 1 )
+               if (!(mode & CHECK_NO_ESCAPE) && (i == ESCAPE)) break;
+               if ( mode & CHECK_OKAY_CANCEL )
                {
                        if ( i == 'c' || i == 'C' )
                        {
@@ -4040,7 +4027,7 @@ void request_command(int shopping)
        cptr act;
 
 #ifdef JP
-        int caretcmd = 0;
+       int caretcmd = 0;
 #endif
        /* Roguelike */
        if (rogue_like_commands)
@@ -4315,20 +4302,20 @@ prt(format("
        }
 
 #ifdef JP
-        for (i = 0; i < 256; i++)
-        {
-                cptr s;
-                if ((s = keymap_act[mode][i]) != NULL)
-                {
-                        if (*s == command_cmd && *(s+1) == 0)
-                        {
-                                caretcmd = i;
-                                break;
-                        }
-                }
-        }
-        if (!caretcmd)
-                caretcmd = command_cmd;
+       for (i = 0; i < 256; i++)
+       {
+               cptr s;
+               if ((s = keymap_act[mode][i]) != NULL)
+               {
+                       if (*s == command_cmd && *(s+1) == 0)
+                       {
+                               caretcmd = i;
+                               break;
+                       }
+               }
+       }
+       if (!caretcmd)
+               caretcmd = command_cmd;
 #endif
        /* Hack -- Scan equipment */
        for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
@@ -4354,7 +4341,7 @@ prt(format("
                {
                        /* Check the "restriction" character */
 #ifdef JP
-                        if ((s[1] == caretcmd) || (s[1] == '*'))
+                       if ((s[1] == caretcmd) || (s[1] == '*'))
 #else
                        if ((s[1] == command_cmd) || (s[1] == '*'))
 #endif
@@ -4478,28 +4465,50 @@ static bool insert_str(char *buf, cptr target, cptr insert)
  */
 int get_keymap_dir(char ch)
 {
-       cptr act, s;
        int d = 0;
 
-       if (rogue_like_commands)
+       /* Already a direction? */
+       if (isdigit(ch))
        {
-               act = keymap_act[KEYMAP_MODE_ROGUE][(byte)ch];
+               d = D2I(ch);
        }
        else
        {
-               act = keymap_act[KEYMAP_MODE_ORIG][(byte)ch];
-       }
+               int mode;
+               cptr act, s;
 
-       if (act)
-       {
-               /* Convert to a direction */
-               for (s = act; *s; ++s)
+               /* Roguelike */
+               if (rogue_like_commands)
+               {
+                       mode = KEYMAP_MODE_ROGUE;
+               }
+
+               /* Original */
+               else
+               {
+                       mode = KEYMAP_MODE_ORIG;
+               }
+
+               /* Extract the action (if any) */
+               act = keymap_act[mode][(byte)(ch)];
+
+               /* Analyze */
+               if (act)
                {
-                       /* Use any digits in keymap */
-                       if (isdigit(*s)) d = D2I(*s);
+                       /* Convert to a direction */
+                       for (s = act; *s; ++s)
+                       {
+                               /* Use any digits in keymap */
+                               if (isdigit(*s)) d = D2I(*s);
+                       }
                }
        }
-       return d;
+
+       /* Paranoia */
+       if (d == 5) d = 0;
+
+       /* Return direction */
+       return (d);
 }
 
 
@@ -4815,43 +4824,63 @@ void roff_to_buf(cptr str, int maxlen, char *tbuf)
        int write_pt = 0;
        int line_len = 0;
        int word_punct = 0;
-       unsigned char ch[3];
+       char ch[3];
        ch[2] = '\0';
 
        while (str[read_pt])
        {
 #ifdef JP
+               bool kinsoku = FALSE;
                bool kanji;
 #endif
+               int ch_len = 1;
+
+               /* Prepare one character */
                ch[0] = str[read_pt];
                ch[1] = '\0';
 #ifdef JP
                kanji  = iskanji(ch[0]);
+
                if (kanji)
+               {
                        ch[1] = str[read_pt+1];
-               if (!kanji && !isprint(ch[0]))
+                       ch_len = 2;
+
+                       if (strcmp(ch, "¡£") == 0 ||
+                           strcmp(ch, "¡¢") == 0 ||
+                           strcmp(ch, "¥£") == 0 ||
+                           strcmp(ch, "¡¼") == 0)
+                               kinsoku = TRUE;
+               }
+               else if (!isprint(ch[0]))
                        ch[0] = ' ';
 #else
                if (!isprint(ch[0]))
                        ch[0] = ' ';
 #endif
 
-               if (line_len >= maxlen - 1 || str[read_pt] == '\n')
+               if (line_len + ch_len > maxlen - 1 || str[read_pt] == '\n')
                {
                        int word_len;
 
                        /* return to better wrapping point. */
                        /* Space character at the end of the line need not to be printed. */
                        word_len = read_pt - word_punct;
-                       if (ch[0] != ' ' && word_len < line_len/2)
+#ifdef JP
+                       if (kanji && !kinsoku)
+                               /* nothing */ ;
+                       else
+#endif
+                       if (ch[0] == ' ' || word_len >= line_len/2)
+                               read_pt++;
+                       else
                        {
                                read_pt = word_punct;
                                if (str[word_punct] == ' ')
                                        read_pt++;
                                write_pt -= word_len;
                        }
-                       else
-                               read_pt++;
+
                        tbuf[write_pt++] = '\0';
                        line_len = 0;
                        word_punct = read_pt;
@@ -4860,10 +4889,7 @@ void roff_to_buf(cptr str, int maxlen, char *tbuf)
                if (ch[0] == ' ')
                        word_punct = read_pt;
 #ifdef JP
-               if (kanji &&
-                   strcmp((char *)ch, "¡£") != 0 && strcmp((char *)ch, "¡¢") != 0 &&
-                   strcmp((char *)ch, "¥£") != 0 && strcmp((char *)ch, "¡¼") != 0)
-                       word_punct = read_pt;
+               if (!kinsoku) word_punct = read_pt;
 #endif
                tbuf[write_pt++] = ch[0];
                line_len++;
@@ -4883,3 +4909,95 @@ void roff_to_buf(cptr str, int maxlen, char *tbuf)
        return;
 }
 
+
+/*
+ * The my_strcpy() function copies up to 'bufsize'-1 characters from 'src'
+ * to 'buf' and NUL-terminates the result.  The 'buf' and 'src' strings may
+ * not overlap.
+ *
+ * my_strcpy() returns strlen(src).  This makes checking for truncation
+ * easy.  Example: if (my_strcpy(buf, src, sizeof(buf)) >= sizeof(buf)) ...;
+ *
+ * This function should be equivalent to the strlcpy() function in BSD.
+ */
+size_t my_strcpy(char *buf, const char *src, size_t bufsize)
+{
+#ifdef JP
+
+       char *d = buf;
+       const char *s = src;
+       size_t len = 0;
+
+       /* reserve for NUL termination */
+       bufsize--;
+
+       /* Copy as many bytes as will fit */
+       while (len < bufsize)
+       {
+               if (iskanji(*s))
+               {
+                       if (len + 1 >= bufsize || !*(s+1)) break;
+                       *d++ = *s++;
+                       *d++ = *s++;
+                       len += 2;
+               }
+               else
+               {
+                       *d++ = *s++;
+                       len++;
+               }
+       }
+       *d = '\0';
+       while(*s++) len++;
+
+       return len;
+
+#else
+
+       size_t len = strlen(src);
+       size_t ret = len;
+
+       /* Paranoia */
+       if (bufsize == 0) return ret;
+
+       /* Truncate */
+       if (len >= bufsize) len = bufsize - 1;
+
+       /* Copy the string and terminate it */
+       (void)memcpy(buf, src, len);
+       buf[len] = '\0';
+
+       /* Return strlen(src) */
+       return ret;
+
+#endif
+}
+
+
+/*
+ * The my_strcat() tries to append a string to an existing NUL-terminated string.
+ * It never writes more characters into the buffer than indicated by 'bufsize' and
+ * NUL-terminates the buffer.  The 'buf' and 'src' strings may not overlap.
+ *
+ * my_strcat() returns strlen(buf) + strlen(src).  This makes checking for
+ * truncation easy.  Example:
+ * if (my_strcat(buf, src, sizeof(buf)) >= sizeof(buf)) ...;
+ *
+ * This function should be equivalent to the strlcat() function in BSD.
+ */
+size_t my_strcat(char *buf, const char *src, size_t bufsize)
+{
+       size_t dlen = strlen(buf);
+
+       /* Is there room left in the buffer? */
+       if (dlen < bufsize - 1)
+       {
+               /* Append as much as possible  */
+               return (dlen + my_strcpy(buf + dlen, src, bufsize - dlen));
+       }
+       else
+       {
+               /* Return without appending */
+               return (dlen + strlen(src));
+       }
+}