]> granicus.if.org Git - procps-ng/commitdiff
top: add '!' toggle for combined cpus display, program
authorJim Warner <james.warner@comcast.net>
Thu, 21 May 2020 05:00:00 +0000 (00:00 -0500)
committerCraig Small <csmall@dropbear.xyz>
Thu, 28 May 2020 09:37:58 +0000 (19:37 +1000)
When implementing that earlier '4' toggle, in response
to the issue referenced below, I got to thinking about
those environments with massively parallel processors.

Such environments may not benefit from the '4' toggle.

So, I decided to implement a feature that could enable
use of those '1' and/or '4' toggles no matter how many
active processors top may have ultimately encountered.

With the new '!' toggle, adjacent cpus can be combined
to any degree, represented as a single cpu group/line.

Reference(s):
https://gitlab.com/procps-ng/procps/-/issues/172

Signed-off-by: Jim Warner <james.warner@comcast.net>
top/top.c
top/top.h
top/top_nls.c
top/top_nls.h

index ff701861247ba11893fa9a78ec301a9e3b0dc208..9a0ce86eb38b6778e94b8ee2f62ea14bb7901ff0 100644 (file)
--- a/top/top.c
+++ b/top/top.c
@@ -4412,6 +4412,7 @@ static void win_reset (WIN_t *q) {
          // NOHISEL_xxx is redundant (already turned off by osel_clear)
          OFFw(q, NOHIFND_xxx | NOHISEL_xxx);
 #endif
+         q->combine_cpus = 0;
 } // end: win_reset
 
 
@@ -5224,6 +5225,15 @@ static void keys_summary (int ch) {
    WIN_t *w = Curwin;             // avoid gcc bloat with a local copy
 
    switch (ch) {
+      case '!':
+         if (CHKw(w, View_CPUSUM) || CHKw(w, View_CPUNOD))
+            show_msg(N_txt(XTRA_modebad_txt));
+         else {
+            if (!w->combine_cpus) w->combine_cpus = 1;
+            else w->combine_cpus *= 2;
+            if (w->combine_cpus >= Cpu_faux_tot) w->combine_cpus = 0;
+         }
+         break;
       case '1':
          if (CHKw(w, View_CPUNOD)) OFFw(w, View_CPUSUM);
          else TOGw(w, View_CPUSUM);
@@ -5673,84 +5683,12 @@ static void keys_xtra (int ch) {
 // show_msg(fmtmk("%s sort compatibility key honored", xmsg));
 } // end: keys_xtra
 \f
-/*######  Main Screen routines  ##########################################*/
-
-        /*
-         * Process keyboard input during the main loop */
-static void do_key (int ch) {
-   static struct {
-      void (*func)(int ch);
-      char keys[SMLBUFSIZ];
-   } key_tab[] = {
-      { keys_global,
-         { '?', 'B', 'd', 'E', 'e', 'F', 'f', 'g', 'H', 'h'
-         , 'I', 'k', 'r', 's', 'X', 'Y', 'Z', '0'
-         , kbd_ENTER, kbd_SPACE, '\0' } },
-      { keys_summary,
-         { '1', '2', '3', '4', 'C', 'l', 'm', 't', '\0' } },
-      { keys_task,
-         { '#', '<', '>', 'b', 'c', 'i', 'J', 'j', 'n', 'O', 'o'
-         , 'R', 'S', 'U', 'u', 'V', 'v', 'x', 'y', 'z'
-         , kbd_CtrlO, '\0' } },
-      { keys_window,
-         { '+', '-', '=', '_', '&', 'A', 'a', 'G', 'L', 'w'
-         , kbd_UP, kbd_DOWN, kbd_LEFT, kbd_RIGHT, kbd_PGUP, kbd_PGDN
-         , kbd_HOME, kbd_END, '\0' } },
-      { keys_xtra,
-         { 'M', 'N', 'P', 'T', '\0'} }
-   };
-   int i;
-
-   switch (ch) {
-      case 0:                // ignored (always)
-      case kbd_ESC:          // ignored (sometimes)
-         goto all_done;
-      case 'q':              // no return from this guy
-         bye_bye(NULL);
-      case 'W':              // no need for rebuilds
-         write_rcfile();
-         goto all_done;
-      default:               // and now, the real work...
-         for (i = 0; i < MAXTBL(key_tab); ++i)
-            if (strchr(key_tab[i].keys, ch)) {
-               key_tab[i].func(ch);
-               Frames_signal = BREAK_kbd;
-               goto all_done;
-            }
-   };
-   /* Frames_signal above will force a rebuild of all column headers and
-      the PROC_FILLxxx flags.  It's NOT simply lazy programming.  Here are
-      some keys that COULD require new column headers and/or libproc flags:
-         'A' - likely
-         'c' - likely when !Mode_altscr, maybe when Mode_altscr
-         'F' - likely
-         'f' - likely
-         'g' - likely
-         'H' - likely
-         'I' - likely
-         'J' - always
-         'j' - always
-         'Z' - likely, if 'Curwin' changed when !Mode_altscr
-         '-' - likely (restricted to Mode_altscr)
-         '_' - likely (restricted to Mode_altscr)
-         '=' - maybe, but only when Mode_altscr
-         '+' - likely (restricted to Mode_altscr)
-         PLUS, likely for FOUR of the EIGHT cursor motion keys (scrolled)
-      ( At this point we have a human being involved and so have all the time )
-      ( in the world.  We can afford a few extra cpu cycles every now & then! )
-    */
-
-   show_msg(N_txt(UNKNOWN_cmds_txt));
-all_done:
-   sysinfo_refresh(1);       // let's be more responsive to hot-pluggin'
-   putp((Cursor_state = Cap_curs_hide));
-} // end: do_key
-
+/*######  Cpu Display Secondary support (summary_show helpers)  ##########*/
 
         /*
          * Cpu *Helper* function to combine and or show the state
          * percentages for 1 cpu or 2 adjacent cpus (one single line). */
-static inline int sum_cpu (const char *str, int nobuf) {
+static inline int cpu_prt (const char *str, int nobuf) {
    static char row[ROWMINSIZ];
    static int tog;
    char *p;
@@ -5769,7 +5707,7 @@ flush_it:
    row[0] = '\0';
    tog = 0;
    return 1;
-} // end: sum_cpu
+} // end: cpu_prt
 
 
         /*
@@ -5780,7 +5718,7 @@ flush_it:
          *    2) modest smp boxes with room for each cpu's percentages
          *    3) massive smp guys leaving little or no room for process
          *       display and thus requiring the cpu summary toggle */
-static int summary_hlp (CPU_t *cpu, const char *pfx, int nobuf) {
+static int cpu_tics (CPU_t *cpu, const char *pfx, int nobuf) {
    /* we'll trim to zero if we get negative time ticks,
       which has happened with some SMP kernels (pre-2.4?)
       and when cpus are dynamically added or removed */
@@ -5830,10 +5768,10 @@ static int summary_hlp (CPU_t *cpu, const char *pfx, int nobuf) {
       snprintf(syst, sizeof(syst), gtab[ix].syst, (int)((pct_syst * Graph_adj) + .4), gtab[ix].type);
 #endif
       snprintf(dual, sizeof(dual), "%s%s", user, syst);
-      n = sum_cpu(fmtmk("%%%s ~3%#5.1f~2/%-#5.1f~3 %3.0f[~1%-*s]~1"
+      n = cpu_prt(fmtmk("%s ~3%#5.1f~2/%-#5.1f~3 %3.0f[~1%-*s]~1"
          , pfx, pct_user, pct_syst, pct_user + pct_syst, Graph_len +4, dual), nobuf);
    } else {
-      n = sum_cpu(fmtmk(Cpu_States_fmts, pfx
+      n = cpu_prt(fmtmk(Cpu_States_fmts, pfx
          , (float)u_frme * scale, (float)s_frme * scale
          , (float)n_frme * scale, (float)i_frme * scale
          , (float)w_frme * scale, (float)x_frme * scale
@@ -5841,7 +5779,112 @@ static int summary_hlp (CPU_t *cpu, const char *pfx, int nobuf) {
    }
    return n;
  #undef TRIMz
-} // end: summary_hlp
+} // end: cpu_tics
+
+
+        /*
+         * Cpu *Helper* function to combine adjacent cpu stats
+         * in an effort to reduce total number of processors shown */
+static int cpu_unify (CPU_t *cpu, int nobuf) {
+   static CPU_t accum;
+   static int ix, beg;
+   char pfx[16];
+   int n;
+
+   accum.cur.u += cpu->cur.u; accum.cur.s += cpu->cur.s;
+   accum.cur.n += cpu->cur.n; accum.cur.i += cpu->cur.i;
+   accum.cur.w += cpu->cur.w; accum.cur.x += cpu->cur.x;
+   accum.cur.y += cpu->cur.y; accum.cur.z += cpu->cur.z;
+   accum.sav.u += cpu->sav.u; accum.sav.s += cpu->sav.s;
+   accum.sav.n += cpu->sav.n; accum.sav.i += cpu->sav.i;
+   accum.sav.w += cpu->sav.w; accum.sav.x += cpu->sav.x;
+   accum.sav.y += cpu->sav.y; accum.sav.z += cpu->sav.z;
+
+   if (!ix) beg = cpu->id;
+   if (nobuf || ix >= Curwin->combine_cpus) {
+      snprintf(pfx, sizeof(pfx), "%-7.7s:", fmtmk("%d-%d", beg, cpu->id));
+      n = cpu_tics(&accum, pfx, nobuf);
+      memset(&accum, 0, sizeof(CPU_t));
+      ix = beg = 0;
+      return n;
+   }
+   ++ix;
+
+   return 0;
+} // end: cpu_unify
+\f
+/*######  Main Screen routines  ##########################################*/
+
+        /*
+         * Process keyboard input during the main loop */
+static void do_key (int ch) {
+   static struct {
+      void (*func)(int ch);
+      char keys[SMLBUFSIZ];
+   } key_tab[] = {
+      { keys_global,
+         { '?', 'B', 'd', 'E', 'e', 'F', 'f', 'g', 'H', 'h'
+         , 'I', 'k', 'r', 's', 'X', 'Y', 'Z', '0'
+         , kbd_ENTER, kbd_SPACE, '\0' } },
+      { keys_summary,
+         { '!', '1', '2', '3', '4', 'C', 'l', 'm', 't', '\0' } },
+      { keys_task,
+         { '#', '<', '>', 'b', 'c', 'i', 'J', 'j', 'n', 'O', 'o'
+         , 'R', 'S', 'U', 'u', 'V', 'v', 'x', 'y', 'z'
+         , kbd_CtrlO, '\0' } },
+      { keys_window,
+         { '+', '-', '=', '_', '&', 'A', 'a', 'G', 'L', 'w'
+         , kbd_UP, kbd_DOWN, kbd_LEFT, kbd_RIGHT, kbd_PGUP, kbd_PGDN
+         , kbd_HOME, kbd_END, '\0' } },
+      { keys_xtra,
+         { 'M', 'N', 'P', 'T', '\0'} }
+   };
+   int i;
+
+   switch (ch) {
+      case 0:                // ignored (always)
+      case kbd_ESC:          // ignored (sometimes)
+         goto all_done;
+      case 'q':              // no return from this guy
+         bye_bye(NULL);
+      case 'W':              // no need for rebuilds
+         write_rcfile();
+         goto all_done;
+      default:               // and now, the real work...
+         for (i = 0; i < MAXTBL(key_tab); ++i)
+            if (strchr(key_tab[i].keys, ch)) {
+               key_tab[i].func(ch);
+               Frames_signal = BREAK_kbd;
+               goto all_done;
+            }
+   };
+   /* Frames_signal above will force a rebuild of all column headers and
+      the PROC_FILLxxx flags.  It's NOT simply lazy programming.  Here are
+      some keys that COULD require new column headers and/or libproc flags:
+         'A' - likely
+         'c' - likely when !Mode_altscr, maybe when Mode_altscr
+         'F' - likely
+         'f' - likely
+         'g' - likely
+         'H' - likely
+         'I' - likely
+         'J' - always
+         'j' - always
+         'Z' - likely, if 'Curwin' changed when !Mode_altscr
+         '-' - likely (restricted to Mode_altscr)
+         '_' - likely (restricted to Mode_altscr)
+         '=' - maybe, but only when Mode_altscr
+         '+' - likely (restricted to Mode_altscr)
+         PLUS, likely for FOUR of the EIGHT cursor motion keys (scrolled)
+      ( At this point we have a human being involved and so have all the time )
+      ( in the world.  We can afford a few extra cpu cycles every now & then! )
+    */
+
+   show_msg(N_txt(UNKNOWN_cmds_txt));
+all_done:
+   sysinfo_refresh(1);       // let's be more responsive to hot-pluggin'
+   putp((Cursor_state = Cap_curs_hide));
+} // end: do_key
 
 
         /*
@@ -5881,7 +5924,7 @@ static void summary_show (void) {
       if (CHKw(w, View_CPUNOD)) {
          if (Numa_node_sel < 0) {
             // display the 1st /proc/stat line, then the nodes (if room)
-            Msg_row += summary_hlp(&Cpu_tics[smp_num_cpus], N_txt(WORD_allcpus_txt), 1);
+            Msg_row += cpu_tics(&Cpu_tics[smp_num_cpus], N_txt(WORD_allcpus_txt), 1);
             // display each cpu node's states
             for (i = 0; i < Numa_node_tot; i++) {
                CPU_t *nod_ptr = &Cpu_tics[1 + smp_num_cpus + i];
@@ -5890,7 +5933,7 @@ static void summary_show (void) {
                if (nod_ptr->id) {
 #endif
                snprintf(tmp, sizeof(tmp), N_fmt(NUMA_nodenam_fmt), i);
-               Msg_row += summary_hlp(nod_ptr, tmp, 1);
+               Msg_row += cpu_tics(nod_ptr, tmp, 1);
 #ifndef OFF_NUMASKIP
                }
 #endif
@@ -5898,12 +5941,12 @@ static void summary_show (void) {
          } else {
             // display the node summary, then the associated cpus (if room)
             snprintf(tmp, sizeof(tmp), N_fmt(NUMA_nodenam_fmt), Numa_node_sel);
-            Msg_row += summary_hlp(&Cpu_tics[1 + smp_num_cpus + Numa_node_sel], tmp, 1);
+            Msg_row += cpu_tics(&Cpu_tics[1 + smp_num_cpus + Numa_node_sel], tmp, 1);
             for (i = 0; i < Cpu_faux_tot; i++) {
                if (Numa_node_sel == Cpu_tics[i].node) {
                   if (!isROOM(anyFLG, 1)) break;
                   snprintf(tmp, sizeof(tmp), N_fmt(WORD_eachcpu_fmt), Cpu_tics[i].id);
-                  Msg_row += summary_hlp(&Cpu_tics[i], tmp, 1);
+                  Msg_row += cpu_tics(&Cpu_tics[i], tmp, 1);
                }
             }
          }
@@ -5911,13 +5954,20 @@ static void summary_show (void) {
 numa_nope:
       if (CHKw(w, View_CPUSUM)) {
          // display just the 1st /proc/stat line
-         Msg_row += summary_hlp(&Cpu_tics[smp_num_cpus], N_txt(WORD_allcpus_txt), 1);
+         Msg_row += cpu_tics(&Cpu_tics[smp_num_cpus], N_txt(WORD_allcpus_txt), 1);
       } else {
          // display each cpu's states separately, screen height permitting...
-         for (i = 0; i < Cpu_faux_tot; i++) {
-            snprintf(tmp, sizeof(tmp), N_fmt(WORD_eachcpu_fmt), Cpu_tics[i].id);
-            Msg_row += summary_hlp(&Cpu_tics[i], tmp, (i+1 >= Cpu_faux_tot));
-            if (!isROOM(anyFLG, 1)) break;
+         if (w->combine_cpus) {
+            for (i = 0; i < Cpu_faux_tot; i++) {
+               Msg_row += cpu_unify(&Cpu_tics[i], (i+1 >= Cpu_faux_tot));
+               if (!isROOM(anyFLG, 1)) break;
+            }
+         } else {
+            for (i = 0; i < Cpu_faux_tot; i++) {
+               snprintf(tmp, sizeof(tmp), N_fmt(WORD_eachcpu_fmt), Cpu_tics[i].id);
+               Msg_row += cpu_tics(&Cpu_tics[i], tmp, (i+1 >= Cpu_faux_tot));
+               if (!isROOM(anyFLG, 1)) break;
+            }
          }
       }
    } // end: View_STATES
index 1f36957d0a7c71aa6f62609823a169782f259a8b..7ec39922b7779b98dabdd767462fd612c071b9ad 100644 (file)
--- a/top/top.h
+++ b/top/top.h
@@ -437,6 +437,7 @@ typedef struct WIN_t {
    char  *findstr;                     // window's current/active search string
    int    findlen;                     // above's strlen, without call overhead
    int    double_up;                   // show individual cpus 2 abreast
+   int    combine_cpus;                // keep combining adjacent cpus
    proc_t **ppt;                       // this window's proc_t ptr array
    struct WIN_t *next,                 // next window in window stack
                 *prev;                 // prior window in window stack
@@ -804,10 +805,12 @@ typedef struct WIN_t {
 //atic void          keys_task (int ch);
 //atic void          keys_window (int ch);
 //atic void          keys_xtra (int ch);
+/*------  Cpu Display Secondary Support (summary_show helpers)  ----------*/
+//atic inline int    cpu_prt (const char *str, int nobuf);
+//atic int           cpu_tics (CPU_t *cpu, const char *pfx, int nobuf);
+//atic int           cpu_unify (CPU_t *cpu, int nobuf);
 /*------  Main Screen routines  ------------------------------------------*/
 //atic void          do_key (int ch);
-//atic inline int    sum_cpu (const char *str, int nobuf);
-//atic int           summary_hlp (CPU_t *cpu, const char *pfx, int nobuf);
 //atic void          summary_show (void);
 //atic const char   *task_show (const WIN_t *q, const int idx);
 //atic void          window_hlp (void);
index 32f9a569f0873b64829ea52ef1a1a7b25c82b3dc..51b7a0c6690344609064e29afd7ea96c62ecac3d 100644 (file)
@@ -413,11 +413,11 @@ static void build_norm_nlstab (void) {
    Norm_nlstab[WORD_process_txt] = _("Tasks");
 /* Translation Hint: The following "word" is meant to represent either a single
    .                 cpu or all of the processors in a multi-processor computer
-   .                 (should be exactly 6 characters, not counting the colon)*/
-   Norm_nlstab[WORD_allcpus_txt] = _("Cpu(s):");
+   .                 (should be exactly 6 characters, excluding leading % & colon) */
+   Norm_nlstab[WORD_allcpus_txt] = _("%Cpu(s):");
 /* Translation Hint: The following "word" is meant to represent a single processor
-   .                 (should be exactly 3 characters) */
-   Norm_nlstab[WORD_eachcpu_fmt] = _("Cpu%-3d:");
+   .                 (should be exactly 3 characters, excluding leading %%, fmt chars & colon) */
+   Norm_nlstab[WORD_eachcpu_fmt] = _("%%Cpu%-3d:");
 /* Translation Hint: The following word "another" must have 1 trailing space */
    Norm_nlstab[WORD_another_txt] = _("another ");
    Norm_nlstab[FIND_no_next_txt] = _("Locate next inactive, use \"L\"");
@@ -487,8 +487,9 @@ static void build_norm_nlstab (void) {
    Norm_nlstab[WORD_exclude_txt] = _("exclude");
    Norm_nlstab[OSEL_statlin_fmt] = _("<Enter> to resume, filters: %s");
    Norm_nlstab[WORD_noneone_txt] = _("none");
-/* Translation Hint: The following word 'Node' should be exactly 4 characters */
-   Norm_nlstab[NUMA_nodenam_fmt] = _("Node%-2d:");
+/* Translation Hint: The following word 'Node' should be exactly
+                     4 characters, excluding leading %%, fmt chars & colon) */
+   Norm_nlstab[NUMA_nodenam_fmt] = _("%%Node%-2d:");
    Norm_nlstab[NUMA_nodeget_fmt] = _("expand which node (0-%d)");
    Norm_nlstab[NUMA_nodebad_txt] = _("invalid node");
    Norm_nlstab[NUMA_nodenot_txt] = _("sorry, NUMA extensions unavailable");
@@ -501,6 +502,7 @@ static void build_norm_nlstab (void) {
    Norm_nlstab[BAD_memscale_fmt] = _("bad memory scaling arg '%c'");
    Norm_nlstab[XTRA_vforest_fmt] = _("PID to collapse/expand [default pid = %d]");
    Norm_nlstab[XTRA_size2up_txt] = _("terminal is not wide enough");
+   Norm_nlstab[XTRA_modebad_txt] = _("wrong mode, command inactive");
 }
 
 
@@ -564,7 +566,7 @@ static void build_uniq_nlstab (void) {
       "  V,v     . Toggle: '~1V~2' forest view; '~1v~2' hide/show forest view children\n"
       "\n"
       "%s"
-      "  W,Y       Write configuration file '~1W~2'; Inspect other output '~1Y~2'\n"
+      "  W,Y,!     Write config file '~1W~2'; Inspect other output '~1Y~2'; Combine Cpus '~1!~2'\n"
       "  q         Quit\n"
       "          ( commands shown with '.' require a ~1visible~2 task display ~1window~2 ) \n"
       "Press '~1h~2' or '~1?~2' for help with ~1Windows~2,\n"
@@ -654,22 +656,22 @@ static void build_uniq_nlstab (void) {
    Uniq_nlstab[STATE_line_1_fmt] = _("%s:~3"
       " %3u ~2total,~3 %3u ~2running,~3 %3u ~2sleeping,~3 %3u ~2stopped,~3 %3u ~2zombie~3\n");
 
-   Uniq_nlstab[STATE_lin2x4_fmt] = _("%%%s~3"
+   Uniq_nlstab[STATE_lin2x4_fmt] = _("%s~3"
       " %#5.1f  ~2user,~3 %#5.1f  ~2system,~3 %#5.1f  ~2nice,~3 %#5.1f  ~2idle~3");
 
-   Uniq_nlstab[STATE_lin2x5_fmt] = _("%%%s~3"
+   Uniq_nlstab[STATE_lin2x5_fmt] = _("%s~3"
       " %#5.1f  ~2user,~3 %#5.1f  ~2system,~3 %#5.1f  ~2nice,~3 %#5.1f  ~2idle,~3 %#5.1f  ~2IO-wait~3");
 
 /* Translation Hint: Only the following abbreviations need be translated
    .                 us = user, sy = system, ni = nice, id = idle, wa = wait,
    .                 hi hardware interrupt, si = software interrupt */
-   Uniq_nlstab[STATE_lin2x6_fmt] = _("%%%s~3"
+   Uniq_nlstab[STATE_lin2x6_fmt] = _("%s~3"
       " %#5.1f ~2us,~3 %#5.1f ~2sy,~3 %#5.1f ~2ni,~3 %#5.1f ~2id,~3 %#5.1f ~2wa,~3 %#5.1f ~2hi,~3 %#5.1f ~2si~3");
 
 /* Translation Hint: Only the following abbreviations need be translated
    .                 us = user, sy = system, ni = nice, id = idle, wa = wait,
    .                 hi hardware interrupt, si = software interrupt, st = steal time */
-   Uniq_nlstab[STATE_lin2x7_fmt] = _("%%%s~3"
+   Uniq_nlstab[STATE_lin2x7_fmt] = _("%s~3"
       "%#5.1f ~2us,~3%#5.1f ~2sy,~3%#5.1f ~2ni,~3%#5.1f ~2id,~3%#5.1f ~2wa,~3%#5.1f ~2hi,~3%#5.1f ~2si,~3%#5.1f ~2st~3");
 
 /* Translation Hint: this must be translated as 2 lines with words above & below aligned */
index cf5207de25f40f5304f6a6402f29307396cbec50..2783368b7198fa89dc8560f51132ce263d6c6c92 100644 (file)
@@ -82,8 +82,8 @@ enum norm_nls {
    WORD_abv_mem_txt, WORD_abv_swp_txt, WORD_allcpus_txt, WORD_another_txt,
    WORD_eachcpu_fmt, WORD_exclude_txt, WORD_include_txt, WORD_noneone_txt,
    WORD_process_txt, WORD_threads_txt, WRITE_rcfile_fmt, WRONG_switch_fmt,
-   XTRA_badflds_fmt, XTRA_fixwide_fmt, XTRA_size2up_txt, XTRA_vforest_fmt,
-   XTRA_warncfg_txt, XTRA_winsize_txt,
+   XTRA_badflds_fmt, XTRA_fixwide_fmt, XTRA_modebad_txt, XTRA_size2up_txt,
+   XTRA_vforest_fmt, XTRA_warncfg_txt, XTRA_winsize_txt,
 #ifndef INSP_OFFDEMO
    YINSP_demo01_txt, YINSP_demo02_txt, YINSP_demo03_txt, YINSP_deqfmt_txt,
    YINSP_deqtyp_txt, YINSP_dstory_txt,