cfunc.introduction Introductory/C Functions

cfunc.introduction

Command cfunc.introduction Introductory/C Functions
Applicable release versions: AP 6.1
Category C Functions (120)
Description outlines how to access the Pick environment from the "C" programming language.

The functionality of the Pick environment is available from the C programming language. This is made available through a set of functions and macros defined in the include file "CPuser.h".

Library Format

Functions within the library have the following general structure:

{rc=}_CP_xxx({arg0{,arg1{,...}}});

where:

_CP_xxx is a general pattern for the name. It is always prefixed with _CP_ to avoid naming conflicts with standard libraries and is suffixed with an entirely lower-case tag like _CP_execute. Macros are provided using the same model, but they use uppercase tags like _CP_SLEN.

arg0 - argi are arguments.

rc is the result code. Almost all functions return an integer result. This result is -1 if an error occurs, and the global variable _CP_errno is set to one of the following error codes:

PE_NFILE Not enough memory to open more files
PE_ACCESS Cannot access file
PE_TRUNC String trunctated due to lack of memory
PE_NOSPACE Could not allocate workspace
PE_LOCK Item is locked
PE_INVAL Invalid call
PE_NONUM Not a number
PE_BADF File not opened
PE_MISSING File not found
PE_CONV Conversion error
PE_BADATTR Bad attribute
PE_TMOUT Input time out
PE_TAPE Tape error
PE_PROC Proc read error
PE_EOF End of file/item
PE_CALLMAIN Tried to call a main as a subroutine
PE_NOTROOT Bad root variable
PE_ILL_KEY Bad key operator
PE_LONG_STR Too long a string for heading
PE_LEVEL Debugger entered
PE_DEBUG Debugger entered
PE_BAD_PARAMS Too many parameters on a call
PE_LOAD_ERR Unable to load Flash subroutine
PE_END_LIST No more items on select
PE_GETSEND Bad pib on get/send
PE_MISCERR Miscellaneous logon error
PE_INIT Virtual machine not booted or attached
PE_BADUSER Bad user ID or user password
PE_BADMD Bad MD or MD password

General Usage

To use this library, the user makes a call to _CP_logon() at the beginning of the C program to connect to the Pick virtual machine. This call goes through the normal Pick logon activities, but suppress all user prompts and messages. Note that neither the user nor the MD macro will be executed. After logging on, the user has full access to the Pick database using C calls which provide functionality previously available only through Pick/BASIC. When the C program completes, the user must issue a _CP_logoff() call to terminate the Pick connection.

String Handling

The standard C string type is not sufficient for handling the dynamic nature of Pick strings, so a hybrid data type has been created called CPSTR. This data type provides allocation, deallocation, and resizing of strings at a much higher performance level than that obtained using malloc(), and free() with C strings. The internal structure of a CPSTR is reserved and SHOULD NOT BE ACCESSED DIRECTLY. Failure to abide by this rule will DEFINITELY GUARANTEE INCOMPATIBILITY WITH FUTURE RELEASES. The structure of a CPSTR is as follows:

Header Internal use only - DO NOT MODIFY
String - Character array containing the actual string
Terminator - A single character used for termination
Footer Internal use only - DO NOT MODIFY

The following macros are provided to access all desired portions of a CPSTR structure.

_CP_SLEN(s) returns the current length of a string. This length does not include any terminating character like a segment mark or a null character.

_CP_SADDR(s) returns a (char *) to the actual string data which may or may not be terminated by a 0x00. Note that this (char *) MUST NOT be passed to the free() C function or to any C function which may try to use free() on the (char *).

Allocation of CPSTR strings is accomplished via special allocation routines. CPSTR strings MUST NOT be allocated with the C function malloc(). The allocation routines provided set necessary internal flags, and they are much more efficient than malloc. Note that these routines create dynamic structures which must be deallocated with the routines listed below.

_CP_str_alloc(l) returns a CPSTR of length l. The actual string data portion of the string is undefined.

_CP_mkstrl(char *s, int l) Returns a CPSTR from a C string s, of length l. The string portion of the CPSTR will contain a copy of the C string's data.

_CP_mkstr(char *s) Returns a CPSTR from a C string s terminated by a 0x00. The string portion of the CPSTR will contain a copy of the C string's data. This function is less efficient than _CP_mkstrl as it must scan the C string to determine its length.

_CP_str_realloc(CPSTR **s, int l) Resizes the CPSTR s.

_CP_str_free(CPSTR ** s) Frees the desired string s.

Note that when the _CP_logoff call is executed, all CPSTR's remain valid, but they may not be passed to any of the _CP_ routines. All CPSTR's are properly cleaned up when the C program exits.

The user must be careful with termination. Any _CP_ routine may modify the termination character. Therefore, the user must use the _CP_TERM() macro to terminate CPSTR's with a 0x00 if it is necessary to pass the string portion of it to a standard Unix routine.

Note that it is necessary to free strings only when the user has finished with them completely. All resizing of strings is accomplished automatically by the _CP_routines. For example, if a process repeatedly reads data into a buffer via the _CP_read call, this buffer will be automatically resized to fit the new data within the _CP_read call at every read.

Environment Setting

To make it easier to handle the differences between the standard behavior of Unix programs and the standard behavior of Pick programs, two calls are provided that set the "environment" to either Pick or Unix.

_CP_pick_env() sets the application to a standard "Pick" environment. When using this setting, all terminal input and output must be done via Pick routines ONLY.

_CP_unix_env() sets the application to a standard "Unix" environment. With this setting, all terminal input and output must be done directly from "C". The program must not "execute" or "call" any Pick routines which may "crt" or "print" something through Pick.

The original logon to Pick calls _CP_pick_env(). After that, the user may use these routines to switch environments as often as desired, but the environment functions are fairly expensive so they should only be used when switching environments is absolutely necessary. To ensure the correct functionality of the Unix shell, the system automatically calls _CP_unix_env() when the user logs off the of the Pick virtual machine.

Break Key Handling

When logged into Pick, the default action for the break key is set to push a level or drop into the debugger as is standard in Pick. This behavior may be changed however by using the following calls:

_CP_unix_break() causes the break key to force a logoff from Pick and terminate the C program with an exit() call. This simulates the standard behavior of the break key in a Unix application.

_CP_pick_break() causes the break key to behave in the Pick manner.

Handling General Pick Interrupts

Pick interrupts, besides breaks, such as messages, may not be masked, but they may be detected (after the occurence) by interrogating the _CP_interrupt variable. This integer location contains the same information available in BASIC from the system(37) function. However, examination of _CP_interrupt is much more efficient when programming in C.

Custom Signal Processing

The Pick libraries make extensive use of signal processing. Because of this, the practice of reprogramming signals within a C application using Pick C routines is strongly discouraged. However, if it is absolutely necessary, there are several rules which must be followed.

When calling _CP_logon, all signals are re-routed to Pick signal handlers.

When calling _CP_logoff, all signals are re-routed to Unix defaults. Note that they are not necessarily reset to the values they held before the _CP_logon call.

The signal SIGUSR2 must never be reprogrammed as it is used by Pick for logging off and sending messages.

Because interrupts may occur within critical code, the user may not make calls to _CP_ functions within signal handlers.
Syntax
Options
Example
The following program prints the name of all users in the users file.

#include "CPuser.h"

main()
{
  CPSTR * machine = _CP_mkstrl("pick0",5); /* default */
  CPSTR * user = _CP_mkstrl("dm",2);
  CPSTR * md = _CP_mkstrl("dm",2);

  CPSTR * filename = _CP_mkstrl("users",5);
  int     fd = -1;
  int     sl = -1; /* initialize select list */

  CPSTR * item_id = _CP_str_null;

/* Logon onto "pick0" as "dm" in the "dm" md */

  if (_CP_logon(machine, user, _CP_str_null, 
      md, _CP_str_null, -1, 0) < 0)
  {
    printf("Logon error %dn", _CP_errno);
    exit(1);   
  }

  /* done with machine, user, and md */

  _CP_str_free(machine);
  _CP_str_free(user);
  _CP_str_free(md);

  /* Make the break key terminate the program */

  _CP_unix_break();

  /* Open the users file into the file descriptor fd */

  if (_CP_open(&fd, _CP_str_null, filename) < 0)
  {
    _CP_logoff();
    printf("Could not open users file n");
    exit(2);
  }

  /* done with filename */

  _CP_str_free(filename);
  
  /* Do a raw select of "users" and store that select
     list in the select list descriptor sl */

  _CP_select(fd, &sl, 0);

  /* Switch to Unix-type I/O so we can use printf */

  _CP_unix_env();

  /* repeatedly read item-ids and print them as a list */

  /* Note how item_id is repeatedly passed to _CP_readnext.
     Each time, _CP_readnext will resize it if necessary,
     and write the next item-id into that CPSTR  */

  while (_CP_readnext(&item_id, &sl, 0, 0) >= 0)
  {
    _CP_TERM(item_id); /* terminate for printf */
    printf("%sn", _CP_SADDR(item_id));
  }

  /* done with item_id - Not absolutely necessary since */
  /*   it will be cleaned up when we exit               */

  _CP_str_free(item_id);

  /* logoff and return */

  _CP_logoff();
  return 0;
}
Purpose
Related cpstr*
cfunc.alpha
cfunc.ascii
cfunc.ati
cfunc.at2
cfunc.break
cfunc.call
cfunc.casing
cfunc.cat
cfunc.clearfile
cfunc.close
cfunc.col1
cfunc.col2
cfunc.compare
cfunc.convert
cfunc.count
cfunc.crt
cfunc.crtn
cfunc.data
cfunc.date
cfunc.dcount
cfunc.debug
cfunc.delete
cfunc.delete_item
cfunc.dtx
cfunc.ebcdic
cfunc.echo
cfunc.execute
cfunc.extract
cfunc.field
cfunc.field_store
cfunc.fold
cfunc.footing
cfunc.get
cfunc.heading
cfunc.iconv
cfunc.in
cfunc.index
cfunc.insert
cfunc.interrupt
cfunc.key
cfunc.load
cfunc.locate
cfunc.lock
cfunc.logon
cfunc.match
cfunc.mkstr
cfunc.mkstrl
cfunc.num
cfunc.occurs
cfunc.oconv
cfunc.open
cfunc.out
cfunc.ovly_subs
cfunc.page
cfunc.page_n
cfunc.pick_break
cfunc.pick_env
cfunc.print
cfunc.printer
cfunc.printn
cfunc.print_on
cfunc.prompt
cfunc.read
cfunc.readnext
cfunc.readt
cfunc.readv
cfunc.release
cfunc.release_all
cfunc.replace
cfunc.replace_bridge
cfunc.rewind
cfunc.root
cfunc.saddr
cfunc.select
cfunc.send
cfunc.sleep
cfunc.slen
cfunc.sort
cfunc.soundex
cfunc.space
cfunc.str
cfunc.str0
cfunc.str_alloc
cfunc.str_free
cfunc.str_null
cfunc.str_realloc
cfunc.substr
cfunc.sum
cfunc.system
cfunc.term
cfunc.time
cfunc.timedate
cfunc.trim
cfunc.unix_break
cfunc.unix_env
cfunc.unlock
cfunc.unlock_all
cfunc.weof
cfunc.write
cfunc.writet
cfunc.writev
cfunc.xtd
cpstr
cfunc.integration
cfunc.precision
cfunc.rs
cfunc.sr
cfunc.si
cfunc.is
cfunc.str_copy
cfunc.filelock
cfunc.fileunlock
cfunc.trans
cfunc.clearselect
cfunc.build_msg
cfunc.out_msg