Using IBM i? Need to create Excel, CSV, HTML, JSON, PDF, SPOOL reports? Learn more about the fastest and least expensive tool for the job: SQL iQuery.
I think QUSCRTUS (Create User Space) API was either the first or among the first few APIs IBM created during the 1980s to "open up" the system. While an "open system" never materialized it did start a wave of API introductions that number in the thousands today.
Of course I published a Create User Space CL command some 20 to 25 years ago, and continue to include one in my Cozzi AppTools product. Given the benefit of User Spaces to API usage, and as an alternative to dynamically allocated memory (%ALLOC in RPG IV) I am beginning a 3 part series of User Space Commands starting with CRTUSRSPC (Create User Space). The original version of this command appeared in Midrange magazine back in the early 1990s. It was written in RPGIII and later ported to RPG IV in the mid-1990s. Then in approximately 2002 I released RPG xTools and moved it into a Service Program. In 2012 I started porting all of my tools to C and C++ as I grew tired of fighting the IBM API interfaces (provided in QSYSINC). This C version is being published today.
I've settled on using C++ as a "better C language" but unfortunately as is the case with RPGIV, C++ has largely been ignored by the API and system information implementation. Rather than hash through the reasons why or try to build up a library of C++ stuff, what I am doing now is writing stand-alone programs in both C++ and C while leveraging the QSYSINC C library. A few months back I published the first of my C/C++ tools; a great little conversion routine that converts CL variables to upper or lower case. IBM (at my request along with others) implemented this capability in CL as %UPPER and %LOWER built-in functions (in v7r2).
The Create User Space (CRTUSRSPC) command is written entirely in C and creates an optionally auto-extendable User Space. There is rarely a case when a user space doesn't need to be auto-extend enabled, so this command/program creates the user space and then changes its auto-extend attribute to true. There is the AUTOEXT(*YES | *NO) parameter on the command, so you can adjust that setting. Recently I also added the legacy PUBAUT (Public Authority) parameter to the CRTUSRSPC command to allow people who need that type of capability to specify authority at creation time.
Dependencies: There are no 3rd-party dependencies for this command or program. The QSYSINC library must be installed, but it is included (aka "free") with IBM i, so everyone doing compiling should have it installed.
System Release: This should compile as far back on the Operating System as possible. I know it compiles fine on V5R4 and later, but it probably works back to at least V4R2.
Source Code: As always, the source code for any of my iOpen code is avialable at this link.
#include <stdlib.h> #include <stdio.h> #include <stdint.h> #define __cplusplus__strings__ #include <string.h> #include <QUSEC.h> #include <QUSCRTUS.h> #include <QUSCUSAT.h> /*************************************************************/ /* Create User Space (CRTUSRSPC) Command Processing Program */ /* Author : Bob Cozzi */ /* Date : 04March2014 */ /* Purpose : To allow CL Cmd-based User Space Creation */ /*-----------------------------------------------------------*/ /* Rev. Log: */ /* 14June2014 - Released to public via midrangeNews.com */ /* 29June2014 - Added PubAut parameter to command. */ /* 30June2014 - Added AutoExtend parameter to command. */ /*************************************************************/ typedef _Packed struct Qus_Attr_t { int count; int key; int dataLen; char data[10]; } usAttr_t; #define autoExtend 3 #define copyParm(varName, parmNum) \ if (argv[parmNum] != NULL) \ memcpy(varName,argv[parmNum],sizeof(varName)) void main(int argc, char *argv[]) { char us_name[20]; char us_attr[10]; int us_initSize = 0; char us_replace[10]; char us_autoExtend = '1'; char us_text[50]; char us_pubAut[10]; char initValue = 0x00; char rtnLib[10]; usAttr_t spaceAttr; Qus_EC_t ec; spaceAttr.count = 1; spaceAttr.key = autoExtend; // Auto-extend spaceAttr.data[0]='1'; memset(us_name,' ',sizeof(us_name)); memset(us_attr,' ',sizeof(us_attr)); memset(us_text,' ',sizeof(us_text)); memset(us_pubAut,' ',sizeof(us_pubAut)); memset(us_replace,' ',sizeof(us_replace)); memset(rtnLib,' ',sizeof(rtnLib)); copyParm(us_name,1); copyParm(us_attr,2); copyParm(us_replace,5); copyParm(us_text,6); copyParm(us_pubAut,7); if (argv[3]!=NULL) us_initSize = *(int*)argv[3]; if (argv[4]!=NULL) us_autoExtend = *(char*)argv[4]; if (us_attr==NULL || us_attr[0]== ' ' || memicmp(us_attr,"*NONE",5) != 0 || memicmp(us_attr,"*BLANKS",7) != 0 || memicmp(us_attr,"*BLANK",6) != 0) memset(us_attr,' ',sizeof(us_attr)); if (us_text==NULL || us_text[0]== ' ' || memicmp(us_text,"*NONE",5) != 0 || memicmp(us_text,"*BLANKS",7) != 0 || memicmp(us_text,"*BLANK",6) != 0) memset(us_text,' ',sizeof(us_text)); if (us_replace!=NULL && us_replace[0]!= ' ' && (memicmp(us_replace,"*YES",4)==0 || memicmp(us_replace,"*REPLACE",8)==0 || us_replace[0]=='1')) { memset(us_replace,' ',sizeof(us_replace)); memcpy(us_replace,"*YES",4); } else { memset(us_replace,' ',sizeof(us_replace)); memcpy(us_replace,"*NO",3); } memset(&ec,0x00,sizeof(ec)); ec.Bytes_Provided = sizeof(ec); QUSCRTUS( us_name, us_attr, us_initSize, &initValue, us_pubAut, us_text, us_replace, &ec); if (ec.Bytes_Available == 0 && us_autoExtend=='1') { // Auto Extend? memset(&ec,0x00,sizeof(ec)); ec.Bytes_Provided = sizeof(ec); QUSCUSAT( rtnLib, us_name, &spaceAttr, &ec); } }
To compile the above source code, use PDM option 14, or the CRTCPGM command.
The Command Definition Source is provided below:
CRTUSRSPC: CMD PROMPT('COZZI - Create User Space') PARM KWD(USRSPC) TYPE(QUAL) MIN(1) + PROMPT('User Space') QUAL: QUAL TYPE(*NAME) MIN(1) EXPR(*YES) QUAL TYPE(*NAME) DFT(*CURLIB) SPCVAL((*LIBL) + (*CURLIB)) EXPR(*YES) PROMPT('Library') PARM KWD(OBJATR) TYPE(*NAME) LEN(10) DFT(*BLANK) + SPCVAL((*BLANK ' ')) EXPR(*YES) + PROMPT('Object attribute') CHOICE('obj attr, *BLANK') PARM KWD(SIZE) TYPE(*INT4) DFT(32K) RANGE(1 + 16776704) SPCVAL((1K 1024) (4K 4096) (32K + 32768) (1M 1048576) (2M 2097152) + (*MAX16MB 16776704)) CHOICE('size, 1K, + 4K, 32K, 1M, 2M...') PROMPT('Initial size') PARM KWD(AUTOEXT) TYPE(*LGL) RSTD(*YES) + DFT(*YES) SPCVAL((*YES '1') (*NO '0')) + EXPR(*YES) PROMPT('Auto extend') PARM KWD(REPLACE) TYPE(*CHAR) RSTD(*YES) DFT(*NO) + SPCVAL((*NO '0') (*YES '1')) EXPR(*YES) + PROMPT('Replace') PARM KWD(TEXT) TYPE(*CHAR) LEN(50) DFT(*BLANK) + SPCVAL((*BLANK ' ')) EXPR(*YES) + PROMPT('Text ''description''') PARM KWD(AUT) TYPE(*CHAR) LEN(10) RSTD(*YES) + DFT(*LIBCRTAUT) SPCVAL((*LIBCRTAUT) + (*CHANGE) (*EXCLUDE) (*USE) (*ALL)) + EXPR(*YES) PROMPT('Authority')
To compile, use PDM option 14 or CRTCMD