www.sas.com > Service and Support > Technical Support
 
Technical Support SAS - The power to know(tm)
  TS Home | Intro to Services | News and Info | Contact TS | Site Map | FAQ | Feedback


/*-------------------------------------------------------------------+
|                Copyright (c) 1996, SAS Institute Inc.              |
|                  Unpublished - All Rights Reserved                 |
|                      S A S / C   S A M P L E                       |
|                                                                    |
|         NAME: CMSMENU                                              |
|     LANGUAGE: C                                                    |
|      PURPOSE: Demonstrate use of the SAS/C FSSL to develop menus,  |
|               submenus, help screens, and error displays           |
| SYSTEM NOTES: Written for CMS only.  The only thing that is        |
|               operating system dependent is the CMS commands.      |
|        INPUT: via SAS/C FSSL                                       |
|       OUTPUT: via SAS/C FSSL                                       |
|                                                                    |
|   CMS -                                                            |
|      COMPILE: GLOBAL MACLIB LC370 L$FSSL                           |
|               LC370 CMSMENU                                        |
|         LINK: GLOBAL TXTLIB LC370BAS LC370STD L$FSSL               |
|               CLINK CMSMENU (GENMOD                                |
|      EXECUTE: CMSMENU                                              |
|                                                                    |
|   MISC NOTES: SAS/C FSSL *must* be installed.                      |
|               See OSMENU for an OS version of this program.        |
|                                                                    |
+-------------------------------------------------------------------*/

#include <lcio.h>
#include <lclib.h>
#include <time.h>
#include <l$fappl.h>
#define COMMAND     100

time_t  timeval;
int     field = 1000;
struct  FS_READPAN input;
struct  FS_READSCR screen;
struct  FS_TERMATTR *scr_attr;
char command[131], errmsg[132], tm[26];
char *menu = "MENU1", *submenu = "MENU2", *error = "ERROR";
char *header = "Simplified CMS Action Menu";
char msg[6][51];
char *menuline[] = {            /* max length displayed is 40 */
  " 0 - Display help on this menu          ",
  " 1 - Request general CMS help           ",
  " 2 - List all datasets on the Adisk     ",
  " 3 - List all minidisks attached        ",
  " 4 - Display all libraries globalled    ",
  " 5 - Display 'all' information          ",
  " 6 - Display files currently FILEDEFed  ",
  " 7 - Display all jobs in virtual reader ",
  " 8 - Log onto another system            ",
  " 9 - Enter any CMS command              " };

char *menucmd[] = {             /* corresponding command      */
  "n/a",
  "cms: help",
  "cms: filel",
  "cms: q disk",
  "cms: q library",
  "cms: q all",
  "cms: file",
  "cms: rdrlist",
  "n/a",
  "n/a" };

/*-------------------------------------------------------------------+
| The main is used to start the full screen environment, define each |
| of the different panels which will be displayed, and then display  |
| the main panel waiting for input.  Upon input it will decide what  |
| was requested and respond accordingly.                             |
+-------------------------------------------------------------------*/
main()
{

   /*----------------------------------------------------------------+
   | define the main menu and sub-menu panels                        |
   +----------------------------------------------------------------*/
   fsinit(errmsg);
   scr_attr = fsrttm();
   define_main();
   define_sub();
   define_error();

   /*----------------------------------------------------------------+
   | Display main menu panel, wait for input and then decide which   |
   |  command was requested.                                         |
   +----------------------------------------------------------------*/
   for (;;) {

      /* update the panel to reflect any changes                    */
      time(&timeval);
      strcpy(tm, ctime(&timeval));
      memset(command, 0, sizeof(command));
      fsdspn(menu, 0, 1, 1, COMMAND, 1, FS_FORCE);

      /* wait for input from the user                               */
      screen = fsrdsc();
      if ((screen.aid == PF_3) || (screen.aid == PF_15)) {
         fsterm();
         exit(EXIT_SUCCESS);
       }

      /* read the panel...update input from user                    */
      input = fsrdpn(menu);

      /* decide what user asked for...                              */
      if (*command == '0')                  /* menu help            */
         noop(0);
      else if (*command == '1')             /* general help         */
         system(menucmd[1]);
      else if (*command == '2')             /* list user datasets   */
         system(menucmd[2]);
      else if (*command == '3')             /* list allocated dsn   */
         system(menucmd[3]);
      else if (*command == '4')             /* display user profile */
         system(menucmd[4]);
      else if (*command == '5')             /* receive messages     */
         system(menucmd[5]);
      else if (*command == '6')             /* list broadcast msgs  */
         system(menucmd[6]);
      else if (*command == '7')             /* display job status   */
         system(menucmd[7]);
      else if (*command == '8')             /* log onto system      */
         noop(1);
      else if (*command == '9')             /* submenu selection    */
      {
         memset(command, '\0', 130);
         /* display new menu and wait for user response             */
         fsdspn(submenu, 0, 1, 1, 0, 0, FS_FORCE);
         screen = fsrdsc();
         if (screen.aid == ENTER_KEY) {
            input = fsrdpn(submenu);
            memcpy(command, "CMS:", 4);    /* make it one command    */
            strcat(command, command+5);
            strcat(command, command+46);
            strcat(command, command+86);
            system(command);
          }
         else input = fsrdpn(submenu);     /* clear input pending    */
       }

    }

return(0);
}

/*-------------------------------------------------------------------+
| This routine will decide which display to generate and then store  |
| the message into the error/message display panel fields            |
+-------------------------------------------------------------------*/
noop(code)
 int code;
 {
  int i;

   /*----------------------------------------------------------------+
   | clear message display area and then set error (or message)      |
   | display.                                                        |
   +----------------------------------------------------------------*/
   for (i=0; i<6; i++)
      memset(msg[i], ' ', 50);
   if (code == 1)
   {
      strcpy(msg[0],
             "----------------> W A R N I N G <-----------------");
      strcpy(msg[1],
             "It has been determined that you are not authorized");
      strcpy(msg[2],
             "for the action requested.  Information concerning ");
      strcpy(msg[3],
             "your userid, name, location, and phone have been  ");
      strcpy(msg[4],
             "entered into an access violation database.        ");
      strcpy(msg[5],
             "----------------> W A R N I N G <-----------------");
   }

   /*----------------------------------------------------------------+
   | display message and wait for user to read and press PF/enter key|
   +----------------------------------------------------------------*/
   fsdspn(error, 0, 1, 1, 0, 0, FS_FORCE | FS_IGNINPUT);
   screen = fsrdsc();
   input = fsrdpn(error);

 return(0);
 }



/*-------------------------------------------------------------------+
|+------------------------------------------------------------------+|
||NOTE:  The following routines are used only to define the display ||
||       panels.  They could be dynamically loaded at the beginning ||
||       of the program and then unloaded since they are needed only||
||       at that time.  This would then free up this memory.        ||
|+------------------------------------------------------------------+|
+-------------------------------------------------------------------*/

/*-------------------------------------------------------------------+
| This routine is used to define the main menu screen.               |
+-------------------------------------------------------------------*/
define_main()
 {
 int  i, len, row, col, color;
 static char userid[L_cuserid+1], sname[11], ename[11];
 static int  battr, sattr, sattr2, mattr, battr2, tattr;
 static char *mtitle, *tb1, *tb2;

   /*----------------------------------------------------------------+
   | define panel and size                                           |
   +----------------------------------------------------------------*/
   fsdfpn(menu, scr_attr->prim_row,
                scr_attr->prim_col);

   /*----------------------------------------------------------------+
   | define fields for the border                                    |
   +----------------------------------------------------------------*/
   battr = PROTECTED | REVERSE_VIDEO | BRIGHT;
   color = RED;
   len = (scr_attr->prim_col - 2) + 1;
   tb1 = malloc(len + 3);
   border(menu, tb1, 1, scr_attr->prim_row, 2, scr_attr->prim_col,
          battr, color, len, " ", " ", " ");
   len -= 4;

   /*----------------------------------------------------------------+
   | define field for title                                          |
   +----------------------------------------------------------------*/
   tattr = PROTECTED | BRIGHT;
   color = MAGENTA;
   mtitle = malloc(len + 3);
   title(menu, header, mtitle, 2, 4, tattr, color, len);

   /*----------------------------------------------------------------+
   | define selection line fields                                    |
   +----------------------------------------------------------------*/
   row = 3;
   col = 4;
   sattr = PROTECTED;
   color = BLUE;
   fsdffd(menu, field++, row, col, 12, "SELECTION==>",
          &sattr, color, BLANK);
   col += 13;
   sattr2= BRIGHT | AUTOREAD;
   color = WHITE;
   fsdffd(menu, COMMAND, row, col, 2, command,
          &sattr2, color, BLANK);

   /*----------------------------------------------------------------+
   | define fields on menu                                           |
   +----------------------------------------------------------------*/
   row += 3;
   col  = 20;
   mattr = PROTECTED;
   color = YELLOW;
   for (i=0; i<=9; i++) {
      fsdffd(menu, field++, row, col, 40, menuline[i],
             &mattr, color, BLANK);
      row += 1;
    }

   /*----------------------------------------------------------------+
   | define fields for misc information (at bottom of screen)        |
   +----------------------------------------------------------------*/
   row = scr_attr->prim_row - 3;
   col = 4;
   battr2= PROTECTED;
   color = GREEN;
   len = (scr_attr->prim_col - (col * 2)) + 3;
   tb2 = malloc(len + 3);
   border(menu, tb2, row, (scr_attr->prim_row-1), col,
          (scr_attr->prim_col-2), battr2, color, len, "+", "-", "|");
   row++;
   strcpy(sname, sysname());
   fsdffd(menu, field++, row, 6, 10, sname, &battr2, color, BLANK);
   strcpy(ename, envname());
   fsdffd(menu, field++, row, 20, 10, ename, &battr2, color, BLANK);
   cuserid(userid);
   fsdffd(menu, field++, row, 35, L_cuserid, userid,
          &battr2, color, BLANK);
   time(&timeval);
   strcpy(tm, ctime(&timeval));
   fsdffd(menu, field++, row, 40+L_cuserid, 24, tm,
          &battr2, color, BLANK);

 return(0);
 }

/*-------------------------------------------------------------------+
| This routine creates the CMS command entry screen                  |
+-------------------------------------------------------------------*/
define_sub()
 {
 int color, len;
 static int tsoattr, cmdattr, tattr;
 static char *stitle;

   /*----------------------------------------------------------------+
   | define panel and size                                           |
   +----------------------------------------------------------------*/
   fsdfpn(submenu, scr_attr->prim_row,
                   scr_attr->prim_col);

   /*----------------------------------------------------------------+
   | define field for title of submenu                               |
   +----------------------------------------------------------------*/
   len = scr_attr->prim_col - 1;
   tattr = PROTECTED | BRIGHT;
   color = GREEN;
   stitle = malloc(len + 4);
   title(submenu, "CMS Command Entry Screen", stitle,
         1, 2, tattr, color, len);

   /*----------------------------------------------------------------+
   | define field for CMS input                                      |
   +----------------------------------------------------------------*/
   tsoattr = BRIGHT | PROTECTED;
   color = MAGENTA;
   fsdffd(submenu, field++, 8,  2,  20, "Enter CMS Command==>",
          &tsoattr, color, BLANK);
   cmdattr = BRIGHT | AUTOREAD | REVERSE_VIDEO;
   color = YELLOW;
   fsdffd(submenu, field++, 8,  25, 40, command+5,
          &cmdattr, color, NULL);
   fsdffd(submenu, field++, 9,  25, 40, command+46,
          &cmdattr, color, NULL);
   fsdffd(submenu, field++, 10, 25, 40, command+86,
          &cmdattr, color, NULL);

 return(0);
 }

/*-------------------------------------------------------------------+
| This routine defines the error/message display panel               |
+-------------------------------------------------------------------*/
define_error()
 {
 int len, color;
 static int errbattr, errmattr, rattr;
 static char *etb1;

   /*----------------------------------------------------------------+
   | define panel and size                                           |
   +----------------------------------------------------------------*/
   fsdfpn(error, scr_attr->prim_row,
                 scr_attr->prim_col);

   /*----------------------------------------------------------------+
   | define fields for the border                                    |
   +----------------------------------------------------------------*/
   errbattr = PROTECTED | REVERSE_VIDEO | BRIGHT;
   color = RED;
   len = (scr_attr->prim_col - 2) + 1;
   etb1 = malloc(len + 3);
   border(error, etb1, 1, scr_attr->prim_row, 2, scr_attr->prim_col,
          errbattr, color, len, " ", " ", " ");

   /*----------------------------------------------------------------+
   | define fields for message display                               |
   +----------------------------------------------------------------*/
   errmattr = PROTECTED | BRIGHT;
   color = WHITE;
   fsdffd(error, field++, 10, 15, 50, msg[0],
          &errmattr, color, BLANK);
   fsdffd(error, field++, 11, 15, 50, msg[1],
          &errmattr, color, BLANK);
   fsdffd(error, field++, 12, 15, 50, msg[2],
          &errmattr, color, BLANK);
   fsdffd(error, field++, 13, 15, 50, msg[3],
          &errmattr, color, BLANK);
   fsdffd(error, field++, 14, 15, 50, msg[4],
          &errmattr, color, BLANK);
   fsdffd(error, field++, 15, 15, 50, msg[5],
          &errmattr, color, BLANK);

   /*----------------------------------------------------------------+
   | tell user how to get rid of current display                     |
   +----------------------------------------------------------------*/
   rattr = PROTECTED | BRIGHT;
   color = BLUE;
   fsdffd(error, field++, scr_attr->prim_row-3, 14,
          52, "Press any PF key or enter to return to the main menu",
          &rattr, color, BLANK);

 return(0);
 }

/*-------------------------------------------------------------------+
| This routine is used to define all the fields needed to create the |
|  look of a border.                                                 |
+-------------------------------------------------------------------*/
border(panel, tb, r1, r2, c1, c2, attr, color, len, cor, hor, ver)
 char *panel, *tb;
 int r1, r2, c1, c2, attr, color, len;
 char *cor, *hor, *ver;
 {
  int  row;

   /*----------------------------------------------------------------+
   | define fields to create the border                              |
   +----------------------------------------------------------------*/
   memset(tb, '\0', (len+2));
   memset(tb, *hor, len);     /* create the horizontal field        */
   *tb = *cor;
   *(tb+len-1) = *cor;
   /* define field on top - only one needed                         */
   fsdffd(panel, field++, r1, c1, len, tb,
          &attr, color, BLANK);
   /* define field on bottom - only one needed                      */
   fsdffd(panel, field++, r2, c1, len,
          tb, &attr, color, BLANK);
   /* define fields on left/right - one field needed for each row   */
   /* and each side.                                                */
   for (row=r1+1; row
Copyright (c) 2000 SAS Institute Inc. All Rights Reserved.
Terms of Use & Legal Information | Privacy Statement