2180 lines
46 KiB
C
2180 lines
46 KiB
C
/*
|
|
* CDE - Common Desktop Environment
|
|
*
|
|
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
|
|
*
|
|
* These libraries and programs are free software; you can
|
|
* redistribute them and/or modify them under the terms of the GNU
|
|
* Lesser General Public License as published by the Free Software
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* These libraries and programs are distributed in the hope that
|
|
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU Lesser General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with these librararies and programs; if not, write
|
|
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
* Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
/* $TOG: PdmOid.c /main/12 1997/11/20 16:37:12 bill $ */
|
|
/*
|
|
* dtpdm/PdmOid.c
|
|
*/
|
|
/*
|
|
* (c) Copyright 1996 Digital Equipment Corporation.
|
|
* (c) Copyright 1996 Hewlett-Packard Company.
|
|
* (c) Copyright 1996 International Business Machines Corp.
|
|
* (c) Copyright 1996 Sun Microsystems, Inc.
|
|
* (c) Copyright 1996 Novell, Inc.
|
|
* (c) Copyright 1996 FUJITSU LIMITED.
|
|
* (c) Copyright 1996 Hitachi.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "PdmOid.h"
|
|
|
|
#include <Dt/DtNlUtils.h>
|
|
|
|
#include "PdmMsgs.h"
|
|
|
|
/*
|
|
* PdmOidNotify value strings
|
|
*/
|
|
#define NOTIFY_EMAIL_STR "{{event-report-job-completed} electronic-mail}"
|
|
#define NOTIFY_NONE_STR "{}"
|
|
|
|
/*
|
|
* entry type for the object identifier string map
|
|
*/
|
|
typedef struct _PdmOidStringMapEntry
|
|
{
|
|
const char* string;
|
|
int length;
|
|
int msg_set;
|
|
int msg_number;
|
|
const char* default_message;
|
|
|
|
} PdmOidStringMapEntry;
|
|
|
|
/*
|
|
* include the auto-generated static PdmOidStringMap
|
|
*/
|
|
#include "PdmOidStrs.h"
|
|
|
|
/*
|
|
* PdmOid static function declarations
|
|
*/
|
|
static PdmOid PdmOidParse(const char* value_string,
|
|
const char** ptr_return);
|
|
/*
|
|
* PdmOidList static function declarations
|
|
*/
|
|
static PdmOidList* PdmOidListParse(const char* value_string,
|
|
const char** ptr_return, int i);
|
|
|
|
|
|
/*
|
|
* PdmOidMediumSourceSize static function declarations
|
|
*/
|
|
static PdmOidMediumSS* MediumSSParse(const char* value_string,
|
|
const char** ptr_return, int i);
|
|
static PdmOidMediumContinuousSize* MediumContinuousSizeParse(const char*,
|
|
const char**);
|
|
static void MediumContinuousSizeDelete(PdmOidMediumContinuousSize* me);
|
|
static PdmOidMediumDiscreteSizeList* MediumDiscreteSizeListParse(const char*,
|
|
const char**,
|
|
int i);
|
|
static void MediumDiscreteSizeListDelete(PdmOidMediumDiscreteSizeList* list);
|
|
|
|
static Boolean ParseArea(const char* value_string,
|
|
const char** ptr_return,
|
|
PdmOidArea* area_return);
|
|
static Boolean ParseUnsignedRange(const char* value_string,
|
|
const char** ptr_return,
|
|
PdmOidUnsignedRange* range_return);
|
|
|
|
/*
|
|
* PdmOidTrayMediumList static function declarations
|
|
*/
|
|
static PdmOidTrayMediumList* TrayMediumListParse(const char* value_string,
|
|
const char** ptr_return,
|
|
int i);
|
|
|
|
/*
|
|
* PdmOidDocumentFormat
|
|
*/
|
|
static char* PdmOidDocumentFormatNext(const char* value_string,
|
|
const char** ptr_return);
|
|
/*
|
|
* misc. parsing static function declarations
|
|
*/
|
|
static Boolean ParseBooleanValue(const char* value_string,
|
|
const char** ptr_return,
|
|
Boolean* boolean_return);
|
|
static Boolean ParseUnsignedValue(const char* value_string,
|
|
const char** ptr_return,
|
|
unsigned long* unsigned_return);
|
|
static Boolean ParseRealValue(const char* value_string,
|
|
const char** ptr_return,
|
|
float* real_return);
|
|
static Boolean ParseSeqEnd(
|
|
const char* value_string,
|
|
const char** ptr_return);
|
|
static Boolean ParseSeqStart(
|
|
const char* value_string,
|
|
const char** ptr_return);
|
|
static Boolean ParseUnspecifiedValue(
|
|
const char* value_string,
|
|
const char** ptr_return);
|
|
static int SpanToken(
|
|
const char* string);
|
|
static int SpanWhitespace(
|
|
const char* string);
|
|
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidString
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*/
|
|
const char*
|
|
PdmOidString(PdmOid pdm_oid)
|
|
{
|
|
/*
|
|
* PdmOid enum values are index values into the string map
|
|
*/
|
|
return PdmOidStringMap[pdm_oid].string;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidMsgSet
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*/
|
|
int
|
|
PdmOidMsgSet(PdmOid pdm_oid)
|
|
{
|
|
/*
|
|
* PdmOid enum values are index values into the string map
|
|
*/
|
|
return PdmOidStringMap[pdm_oid].msg_set;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidMsgNum
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*/
|
|
int
|
|
PdmOidMsgNum(PdmOid pdm_oid)
|
|
{
|
|
/*
|
|
* PdmOid enum values are index values into the string map
|
|
*/
|
|
return PdmOidStringMap[pdm_oid].msg_number;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidDefaultMsg
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*/
|
|
const char*
|
|
PdmOidDefaultMsg(PdmOid pdm_oid)
|
|
{
|
|
if(PdmOidStringMap[pdm_oid].default_message == (const char*)NULL)
|
|
return PdmOidStringMap[pdm_oid].string;
|
|
else
|
|
return PdmOidStringMap[pdm_oid].default_message;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidStringLength
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*/
|
|
int
|
|
PdmOidStringLength(PdmOid pdm_oid)
|
|
{
|
|
/*
|
|
* PdmOid enum values are index values into the string map
|
|
*/
|
|
return PdmOidStringMap[pdm_oid].length;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidFromString
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*/
|
|
PdmOid
|
|
PdmOidFromString(const char* value)
|
|
{
|
|
if(value == (const char*)NULL)
|
|
return pdmoid_none;
|
|
else
|
|
return PdmOidParse(value, (const char**)NULL);
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidParse
|
|
*
|
|
* Description:
|
|
*
|
|
* Parse the next whitespace-delimited string from 'value_string'
|
|
* updating 'ptr_return' to point to the next unparsed location in
|
|
* 'value_string'. 'ptr_return' can be NULL.
|
|
*
|
|
* Return value:
|
|
*
|
|
* The corresponding PdmOid for the parsed name string.
|
|
* A return value of pdmoid_none is returned if the parsed name
|
|
* was not a valid oid or if no name was found.
|
|
*
|
|
*/
|
|
static PdmOid
|
|
PdmOidParse(const char* value_string,
|
|
const char** ptr_return)
|
|
{
|
|
const char* ptr;
|
|
int length;
|
|
int i;
|
|
|
|
/*
|
|
* skip leading whitespace
|
|
*/
|
|
ptr = value_string + SpanWhitespace(value_string);
|
|
/*
|
|
* get the whitespace-delimited token length
|
|
*/
|
|
length = SpanToken(ptr);
|
|
/*
|
|
* match the oid string in the map
|
|
*/
|
|
for(i = 0; i < PdmOidStringMapCount; i++)
|
|
if(length == PdmOidStringMap[i].length)
|
|
if(strncmp(ptr, PdmOidStringMap[i].string, length) == 0)
|
|
break;
|
|
if(i == PdmOidStringMapCount)
|
|
i = pdmoid_none;
|
|
/*
|
|
* update the return pointer and return
|
|
*/
|
|
if(ptr_return != (const char**)NULL)
|
|
*ptr_return = ptr+length;
|
|
return i;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidListNew
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
PdmOidList*
|
|
PdmOidListNew(const char* value_string)
|
|
{
|
|
if(value_string == (const char*)NULL)
|
|
return (PdmOidList*)NULL;
|
|
else
|
|
{
|
|
const char* ptr;
|
|
return PdmOidListParse(value_string, &ptr, 0);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidListParse
|
|
*
|
|
* Description:
|
|
*
|
|
* 'ptr_return' *cannot* be NULL.
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
static PdmOidList*
|
|
PdmOidListParse(const char* value_string,
|
|
const char** ptr_return, int i)
|
|
{
|
|
PdmOid oid = pdmoid_none;
|
|
PdmOidList* list;
|
|
/*
|
|
* parse the next valid oid out of the value string
|
|
*/
|
|
ptr_return = &value_string;
|
|
while(**ptr_return != '\0' &&
|
|
(oid = PdmOidParse(*ptr_return, ptr_return)) == pdmoid_none);
|
|
if(oid == pdmoid_none)
|
|
{
|
|
/*
|
|
* end of value string; allocate the list structure
|
|
*/
|
|
list = (PdmOidList*)XtCalloc(1, sizeof(PdmOidList));
|
|
list->count = i;
|
|
list->list = (PdmOid*)XtCalloc(i, sizeof(PdmOid));
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* recurse
|
|
*/
|
|
list = PdmOidListParse(*ptr_return, ptr_return, i+1);
|
|
/*
|
|
* set the oid in the list
|
|
*/
|
|
list->list[i] = oid;
|
|
}
|
|
/*
|
|
* return
|
|
*/
|
|
return list;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidListHasOid
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
Boolean
|
|
PdmOidListHasOid(const PdmOidList* list, PdmOid oid)
|
|
{
|
|
int i;
|
|
if(list != (PdmOidList*)NULL)
|
|
for(i = 0; i < list->count; i++)
|
|
if(list->list[i] == oid)
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidListGetIndex
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
int
|
|
PdmOidListGetIndex(const PdmOidList* list, PdmOid oid)
|
|
{
|
|
int i;
|
|
if(list != (PdmOidList*)NULL)
|
|
for(i = 0; i < list->count; i++)
|
|
if(list->list[i] == oid)
|
|
return i;
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidListDelete
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
void
|
|
PdmOidListDelete(PdmOidList* list)
|
|
{
|
|
if(list != (PdmOidList*)NULL)
|
|
{
|
|
XtFree((char*)list->list);
|
|
XtFree((char*)list);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidLinkedListNew
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*/
|
|
PdmOidLinkedList*
|
|
PdmOidLinkedListNew()
|
|
{
|
|
return (PdmOidLinkedList*)XtCalloc(1, sizeof(PdmOidLinkedList));
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidLinkedListDelete
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*/
|
|
void
|
|
PdmOidLinkedListDelete(PdmOidLinkedList* me)
|
|
{
|
|
if(me != (PdmOidLinkedList*)NULL)
|
|
{
|
|
while(me->head)
|
|
{
|
|
me->current = me->head;
|
|
me->head = me->current->next;
|
|
XtFree((char*)me->current);
|
|
}
|
|
XtFree((char*)me);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidLinkedListGetOid
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*/
|
|
PdmOid
|
|
PdmOidLinkedListGetOid(PdmOidLinkedList* me, int i)
|
|
{
|
|
if(i < 0 || i >= me->count) return pdmoid_none;
|
|
me->current = me->head;
|
|
while(i--) me->current = me->current->next;
|
|
return me->current->oid;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidLinkedListAddOid
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*/
|
|
void
|
|
PdmOidLinkedListAddOid(PdmOidLinkedList* me, PdmOid oid)
|
|
{
|
|
me->current = (PdmOidNode)XtCalloc(1, sizeof(struct PdmOidNodeStruct));
|
|
me->current->oid = oid;
|
|
++me->count;
|
|
if(me->tail)
|
|
{
|
|
me->tail->next = me->current;
|
|
me->tail = me->current;
|
|
}
|
|
else
|
|
me->head = me->tail = me->current;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidLinkedListGetIndex
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*/
|
|
int
|
|
PdmOidLinkedListGetIndex(PdmOidLinkedList* me, PdmOid oid)
|
|
{
|
|
int i = 0;
|
|
me->current = me->head;
|
|
while(me->current)
|
|
if(me->current->oid == oid)
|
|
return i;
|
|
else
|
|
{
|
|
++i;
|
|
me->current = me->current->next;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidLinkedListHasOid
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*/
|
|
Boolean
|
|
PdmOidLinkedListHasOid(PdmOidLinkedList* me,
|
|
PdmOid oid)
|
|
{
|
|
me->current = me->head;
|
|
while(me->current)
|
|
if(me->current->oid == oid)
|
|
return True;
|
|
else
|
|
me->current = me->current->next;
|
|
return False;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidLinkedListFirstOid
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*/
|
|
PdmOid
|
|
PdmOidLinkedListFirstOid(PdmOidLinkedList* me)
|
|
{
|
|
if(me->current = me->head)
|
|
return me->current->oid;
|
|
else
|
|
return pdmoid_none;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidLinkedListNextOid
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*/
|
|
PdmOid
|
|
PdmOidLinkedListNextOid(PdmOidLinkedList* me)
|
|
{
|
|
if(me->current ? me->current = me->current->next : False)
|
|
return me->current->oid;
|
|
else
|
|
return pdmoid_none;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidLocalString
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*/
|
|
const char*
|
|
PdmOidLocalString(PdmOid pdm_oid)
|
|
{
|
|
/*
|
|
* PdmOid enum values are index values into the string map
|
|
*/
|
|
if(PdmOidStringMap[pdm_oid].msg_set != -1)
|
|
{
|
|
return DTPDM_GETMESSAGE(PdmOidStringMap[pdm_oid].msg_set,
|
|
PdmOidStringMap[pdm_oid].msg_number,
|
|
PdmOidStringMap[pdm_oid].string);
|
|
}
|
|
else
|
|
return PdmOidStringMap[pdm_oid].string;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidMediumSSNew
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
PdmOidMediumSS*
|
|
PdmOidMediumSSNew(const char* value_string)
|
|
{
|
|
if(value_string == (const char*)NULL)
|
|
return (PdmOidMediumSS*)NULL;
|
|
else
|
|
{
|
|
const char* ptr;
|
|
return MediumSSParse(value_string, &ptr, 0);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: MediumSSParse
|
|
*
|
|
* Description:
|
|
*
|
|
* 'ptr_return' *cannot* be NULL.
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
static PdmOidMediumSS*
|
|
MediumSSParse(const char* value_string,
|
|
const char** ptr_return, int i)
|
|
{
|
|
PdmOidMediumSS* medium_ss;
|
|
PdmOidMediumSourceSize mss;
|
|
/*
|
|
* check for the start of a new MediumSourceSize sequence
|
|
*/
|
|
if(ParseSeqStart(value_string, ptr_return))
|
|
{
|
|
/*
|
|
* check for an unspecified tray value
|
|
*/
|
|
if(ParseUnspecifiedValue(*ptr_return, ptr_return))
|
|
mss.input_tray = pdmoid_unspecified;
|
|
else
|
|
{
|
|
/*
|
|
* parse out the input tray
|
|
*/
|
|
mss.input_tray = PdmOidParse(*ptr_return, ptr_return);
|
|
}
|
|
/*
|
|
* attempt to parse a Continuous MediumSize sequence
|
|
*/
|
|
mss.ms.continuous_size =
|
|
MediumContinuousSizeParse(*ptr_return, ptr_return);
|
|
if(mss.ms.continuous_size != (PdmOidMediumContinuousSize*)NULL)
|
|
{
|
|
mss.mstag = PdmOidMediumSS_CONTINUOUS;
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* not continuous, try Discrete MediumSize
|
|
*/
|
|
mss.ms.discrete =
|
|
MediumDiscreteSizeListParse(*ptr_return, ptr_return, 0);
|
|
if(mss.ms.discrete == (PdmOidMediumDiscreteSizeList*)NULL)
|
|
{
|
|
/*
|
|
* syntax error (MediumDiscreteSizeListParse reports error)
|
|
*/
|
|
return NULL;
|
|
}
|
|
mss.mstag = PdmOidMediumSS_DISCRETE;
|
|
}
|
|
/*
|
|
* parse out the MediumSourceSize sequence end
|
|
*/
|
|
if(!ParseSeqEnd(*ptr_return, ptr_return))
|
|
{
|
|
/*
|
|
* syntax error
|
|
*/
|
|
fprintf(stderr, "%s\n", PDM_MSG_WARN_MSS);
|
|
return NULL;
|
|
}
|
|
/*
|
|
* recurse to parse the next MediumSourceSize sequence
|
|
*/
|
|
medium_ss = MediumSSParse(*ptr_return, ptr_return, i+1);
|
|
if(medium_ss == (PdmOidMediumSS*)NULL)
|
|
{
|
|
/*
|
|
* syntax error - clean up and return
|
|
*/
|
|
switch(mss.mstag)
|
|
{
|
|
case PdmOidMediumSS_CONTINUOUS:
|
|
MediumContinuousSizeDelete(mss.ms.continuous_size);
|
|
break;
|
|
case PdmOidMediumSS_DISCRETE:
|
|
MediumDiscreteSizeListDelete(mss.ms.discrete);
|
|
break;
|
|
}
|
|
return NULL;
|
|
}
|
|
/*
|
|
* copy the current MediumSourceSize into the array
|
|
*/
|
|
memmove((medium_ss->mss)+i, &mss, sizeof(PdmOidMediumSourceSize));
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* MediumSourceSize sequence start not found
|
|
*/
|
|
if(**ptr_return == '\0')
|
|
{
|
|
/*
|
|
* end of value string; allocate the MediumSS structure
|
|
*/
|
|
medium_ss = (PdmOidMediumSS*)XtCalloc(1, sizeof(PdmOidMediumSS));
|
|
medium_ss->count = i;
|
|
medium_ss->mss = (PdmOidMediumSourceSize*)
|
|
XtCalloc(i, sizeof(PdmOidMediumSourceSize));
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* syntax error
|
|
*/
|
|
fprintf(stderr, "%s\n", PDM_MSG_WARN_MSS);
|
|
return NULL;
|
|
}
|
|
}
|
|
return medium_ss;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidMediumSSDelete
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
void
|
|
PdmOidMediumSSDelete(PdmOidMediumSS* me)
|
|
{
|
|
if(me != (PdmOidMediumSS*)NULL)
|
|
{
|
|
int i;
|
|
for(i = 0; i < me->count; i++)
|
|
{
|
|
switch((me->mss)[i].mstag)
|
|
{
|
|
case PdmOidMediumSS_CONTINUOUS:
|
|
MediumContinuousSizeDelete((me->mss)[i].ms.continuous_size);
|
|
break;
|
|
case PdmOidMediumSS_DISCRETE:
|
|
MediumDiscreteSizeListDelete((me->mss)[i].ms.discrete);
|
|
break;
|
|
}
|
|
}
|
|
XtFree((char*)me);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidMediumSSGetAllSizes
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
PdmOidLinkedList*
|
|
PdmOidMediumSSGetAllSizes(PdmOidMediumSS* me)
|
|
{
|
|
PdmOidLinkedList* all_sizes;
|
|
int i_mss, i_ds;
|
|
PdmOidMediumDiscreteSizeList* ds_list;
|
|
PdmOid page_size;
|
|
|
|
if(me == (PdmOidMediumSS*)NULL)
|
|
return (PdmOidLinkedList*)NULL;
|
|
|
|
all_sizes = PdmOidLinkedListNew();
|
|
/*
|
|
* loop through the MediumSourceSizes
|
|
*/
|
|
for(i_mss = 0; i_mss < me->count; i_mss++)
|
|
{
|
|
switch((me->mss)[i_mss].mstag)
|
|
{
|
|
case PdmOidMediumSS_DISCRETE:
|
|
/*
|
|
* add unique discrete sizes to the size list
|
|
*/
|
|
ds_list = (me->mss)[i_mss].ms.discrete;
|
|
for(i_ds = 0; i_ds < ds_list->count; i_ds++)
|
|
{
|
|
page_size = (ds_list->list)[i_ds].page_size;
|
|
if(page_size == pdmoid_none)
|
|
continue;
|
|
if(!PdmOidLinkedListHasOid(all_sizes, page_size))
|
|
{
|
|
PdmOidLinkedListAddOid(all_sizes, page_size);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case PdmOidMediumSS_CONTINUOUS:
|
|
/*
|
|
* unsupported
|
|
*/
|
|
break;
|
|
}
|
|
}
|
|
/*
|
|
* return
|
|
*/
|
|
return all_sizes;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidMediumSSGetTraysSizes
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
void
|
|
PdmOidMediumSSGetTraysSizes(PdmOidMediumSS* me,
|
|
PdmOidTrayMediumList* trays_medium,
|
|
PdmOidList** trays,
|
|
PdmOidList** sizes)
|
|
{
|
|
int i_mss, i_ds, i_itm, i_its;
|
|
PdmOidMediumDiscreteSizeList* ds_list;
|
|
int tray_count;
|
|
PdmOid current_tray, current_medium;
|
|
PdmOidMediumDiscreteSizeList* unspecified_tray_ds;
|
|
PdmOidMediumDiscreteSizeList* tray_ds;
|
|
|
|
if(me == (PdmOidMediumSS*)NULL
|
|
||
|
|
trays_medium == (PdmOidTrayMediumList*)NULL)
|
|
{
|
|
if(trays != (PdmOidList**)NULL) *trays = (PdmOidList*)NULL;
|
|
if(sizes != (PdmOidList**)NULL) *sizes = (PdmOidList*)NULL;
|
|
return;
|
|
}
|
|
/*
|
|
* allocate the trays and sizes lists
|
|
*/
|
|
tray_count = PdmOidTrayMediumListCount(trays_medium);
|
|
if(tray_count == 0)
|
|
{
|
|
if(trays != (PdmOidList**)NULL) *trays = (PdmOidList*)NULL;
|
|
if(sizes != (PdmOidList**)NULL) *sizes = (PdmOidList*)NULL;
|
|
return;
|
|
}
|
|
if(trays != (PdmOidList**)NULL)
|
|
{
|
|
*trays = (PdmOidList*)XtCalloc(1, sizeof(PdmOidList));
|
|
(*trays)->list = (PdmOid*)XtCalloc(tray_count, sizeof(PdmOid));
|
|
}
|
|
if(sizes != (PdmOidList**)NULL)
|
|
{
|
|
*sizes = (PdmOidList*)XtCalloc(1, sizeof(PdmOidList));
|
|
(*sizes)->list = (PdmOid*)XtCalloc(tray_count, sizeof(PdmOid));
|
|
}
|
|
/*
|
|
* loop through the input trays medium list
|
|
*/
|
|
i_its = 0;
|
|
for(i_itm = 0; i_itm < tray_count; i_itm++)
|
|
{
|
|
current_tray = PdmOidTrayMediumListTray(trays_medium, i_itm);
|
|
if(current_tray == pdmoid_none)
|
|
continue;
|
|
current_medium = PdmOidTrayMediumListMedium(trays_medium, i_itm);
|
|
if(current_medium == pdmoid_none)
|
|
continue;
|
|
/*
|
|
* loop through the MediumSourceSizes, looking for an appropriate
|
|
* discrete sizes spec for the current tray
|
|
*/
|
|
unspecified_tray_ds = (PdmOidMediumDiscreteSizeList*)NULL;
|
|
tray_ds = (PdmOidMediumDiscreteSizeList*)NULL;
|
|
for(i_mss = 0;
|
|
i_mss < me->count
|
|
&& tray_ds == (PdmOidMediumDiscreteSizeList*)NULL;
|
|
i_mss++)
|
|
{
|
|
switch((me->mss)[i_mss].mstag)
|
|
{
|
|
case PdmOidMediumSS_DISCRETE:
|
|
if((me->mss)[i_mss].input_tray == current_tray)
|
|
tray_ds = (me->mss)[i_mss].ms.discrete;
|
|
else if ((me->mss)[i_mss].input_tray == pdmoid_unspecified)
|
|
unspecified_tray_ds = (me->mss)[i_mss].ms.discrete;
|
|
break;
|
|
|
|
case PdmOidMediumSS_CONTINUOUS:
|
|
/*
|
|
* unsupported
|
|
*/
|
|
break;
|
|
}
|
|
}
|
|
/*
|
|
* if the tray was not matched, use the unspecifed tray size list
|
|
*/
|
|
if(tray_ds == (PdmOidMediumDiscreteSizeList*)NULL)
|
|
if(unspecified_tray_ds == (PdmOidMediumDiscreteSizeList*)NULL)
|
|
{
|
|
/*
|
|
* not even an unspecified tray, skip this
|
|
* input-trays-medium entry.
|
|
*/
|
|
continue;
|
|
}
|
|
else
|
|
tray_ds = unspecified_tray_ds;
|
|
/*
|
|
* loop through the discrete sizes list, looking for a size that
|
|
* matches the medium for the current input tray
|
|
*/
|
|
for(i_ds = 0; i_ds < tray_ds->count; i_ds++)
|
|
{
|
|
/*
|
|
* check to see if the current input tray's medium size
|
|
* matches the current discrete size
|
|
*
|
|
* Note: in the CDEnext SI, medium identifiers coincide with
|
|
* medium-size identifiers. If the DP-Medium object is
|
|
* ever implemented, this check would need to be
|
|
* changed so that the input tray's medium size is
|
|
* obtained from the indicated Medium object, and not
|
|
* inferred from the medium identifier itself.
|
|
*/
|
|
if((tray_ds->list)[i_ds].page_size == current_medium)
|
|
{
|
|
/*
|
|
* the current input tray's medium size matches the
|
|
* current discrete size; add the tray and medium size
|
|
* Oids to the return lists.
|
|
*/
|
|
if(trays != (PdmOidList**)NULL)
|
|
(*trays)->list[i_its] = current_tray;
|
|
if(sizes != (PdmOidList**)NULL)
|
|
(*sizes)->list[i_its] = (tray_ds->list)[i_ds].page_size;
|
|
++i_its;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if(trays != (PdmOidList**)NULL) (*trays)->count = i_its;
|
|
if(sizes != (PdmOidList**)NULL) (*sizes)->count = i_its;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: MediumContinuousSizeParse
|
|
*
|
|
* Description:
|
|
*
|
|
* 'ptr_return' *cannot* be NULL.
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
static PdmOidMediumContinuousSize*
|
|
MediumContinuousSizeParse(const char* value_string,
|
|
const char** ptr_return)
|
|
{
|
|
const char* first_nonws_ptr;
|
|
PdmOidMediumContinuousSize* mcs = NULL;
|
|
/*
|
|
* skip leading whitespace
|
|
*/
|
|
first_nonws_ptr = value_string + SpanWhitespace(value_string);
|
|
/*
|
|
* parse out the MediumSize sequence start char
|
|
*/
|
|
if(!ParseSeqStart(first_nonws_ptr, ptr_return))
|
|
goto MediumContinuousSizeParse_error;
|
|
/*
|
|
* peek ahead to see if it looks like we actually have a continuous
|
|
* size spec (looking for the sequence start char on the 1st range spec)
|
|
*/
|
|
if(!ParseSeqStart(*ptr_return, (const char**)NULL))
|
|
goto MediumContinuousSizeParse_error;
|
|
/*
|
|
* Ok, let's go for it
|
|
*/
|
|
mcs = (PdmOidMediumContinuousSize*)
|
|
XtCalloc(1, sizeof(PdmOidMediumContinuousSize));
|
|
/*
|
|
* "range across the feed direction"
|
|
*/
|
|
if(!ParseUnsignedRange(*ptr_return, ptr_return, &mcs->range_across_feed))
|
|
goto MediumContinuousSizeParse_error;
|
|
/*
|
|
* "increment across the feed direction" (optional, default 0)
|
|
*/
|
|
if(!ParseUnspecifiedValue(*ptr_return, ptr_return))
|
|
if(!ParseUnsignedValue(*ptr_return, ptr_return,
|
|
&mcs->increment_across_feed))
|
|
goto MediumContinuousSizeParse_error;
|
|
/*
|
|
* "range in the feed direction"
|
|
*/
|
|
if(!ParseUnsignedRange(*ptr_return, ptr_return, &mcs->range_in_feed))
|
|
goto MediumContinuousSizeParse_error;
|
|
/*
|
|
* "increment in the feed direction" (optional, default 0)
|
|
*/
|
|
if(!ParseUnspecifiedValue(*ptr_return, ptr_return))
|
|
if(!ParseUnsignedValue(*ptr_return, ptr_return,
|
|
&mcs->increment_in_feed))
|
|
goto MediumContinuousSizeParse_error;
|
|
/*
|
|
* "long edge feeds" flag (default TRUE)
|
|
*/
|
|
if(ParseUnspecifiedValue(*ptr_return, ptr_return))
|
|
mcs->long_edge_feeds = True;
|
|
else
|
|
if(!ParseBooleanValue(*ptr_return, ptr_return, &mcs->long_edge_feeds))
|
|
goto MediumContinuousSizeParse_error;
|
|
/*
|
|
* "generic assured reproduction area"
|
|
*/
|
|
if(!ParseArea(*ptr_return, ptr_return, &mcs->assured_reproduction_area))
|
|
goto MediumContinuousSizeParse_error;
|
|
/*
|
|
* parse out the MediumSize sequence end character
|
|
*/
|
|
if(!ParseSeqEnd(*ptr_return, ptr_return))
|
|
goto MediumContinuousSizeParse_error;
|
|
/*
|
|
* return
|
|
*/
|
|
return mcs;
|
|
|
|
|
|
MediumContinuousSizeParse_error:
|
|
/*
|
|
* syntax error - don't log since this function may be called
|
|
* as a lookahead
|
|
*/
|
|
*ptr_return = first_nonws_ptr;
|
|
XtFree((char*)mcs);
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: MediumContinuousSizeDelete
|
|
*
|
|
* Description:
|
|
*
|
|
* 'ptr_return' *cannot* be NULL.
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
static void
|
|
MediumContinuousSizeDelete(PdmOidMediumContinuousSize* me)
|
|
{
|
|
XtFree((char*)me);
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: MediumDiscreteSizeListParse
|
|
*
|
|
* Description:
|
|
*
|
|
* 'ptr_return' *cannot* be NULL.
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
static PdmOidMediumDiscreteSizeList*
|
|
MediumDiscreteSizeListParse(const char* value_string,
|
|
const char** ptr_return, int i)
|
|
{
|
|
PdmOidMediumDiscreteSizeList* list;
|
|
PdmOidMediumDiscreteSize mds;
|
|
/*
|
|
* check for the start of a new MediumSize sequence
|
|
*/
|
|
if(ParseSeqStart(value_string, ptr_return))
|
|
{
|
|
/*
|
|
* "page size"
|
|
*/
|
|
mds.page_size = PdmOidParse(*ptr_return, ptr_return);
|
|
/*
|
|
* "long edge feeds" flag (default TRUE)
|
|
*/
|
|
if(ParseUnspecifiedValue(*ptr_return, ptr_return))
|
|
mds.long_edge_feeds = True;
|
|
else
|
|
if(!ParseBooleanValue(*ptr_return, ptr_return,
|
|
&mds.long_edge_feeds))
|
|
{
|
|
/*
|
|
* syntax error
|
|
*/
|
|
fprintf(stderr, "%s\n", PDM_MSG_WARN_MSS);
|
|
return NULL;
|
|
}
|
|
/*
|
|
* "assured reproduction area"
|
|
*/
|
|
if(!ParseArea(*ptr_return, ptr_return,
|
|
&mds.assured_reproduction_area))
|
|
{
|
|
/*
|
|
* syntax error
|
|
*/
|
|
fprintf(stderr, "%s\n", PDM_MSG_WARN_MSS);
|
|
return NULL;
|
|
}
|
|
/*
|
|
* parse out the MediumSize sequence end character
|
|
*/
|
|
if(!ParseSeqEnd(*ptr_return, ptr_return))
|
|
{
|
|
fprintf(stderr, "%s\n", PDM_MSG_WARN_MSS);
|
|
return NULL;
|
|
}
|
|
/*
|
|
* recurse to parse the next Discrete MediumSize sequence
|
|
*/
|
|
list = MediumDiscreteSizeListParse(*ptr_return, ptr_return, i+1);
|
|
if(list != (PdmOidMediumDiscreteSizeList*)NULL)
|
|
{
|
|
/*
|
|
* copy the current discrete MediumSize into the list
|
|
*/
|
|
memmove((list->list)+i, &mds, sizeof(PdmOidMediumDiscreteSize));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* MediumSize sequence start not found; end of the discrete sizes
|
|
* list
|
|
*/
|
|
list = (PdmOidMediumDiscreteSizeList*)
|
|
XtCalloc(1, sizeof(PdmOidMediumDiscreteSizeList));
|
|
list->count = i;
|
|
list->list = (PdmOidMediumDiscreteSize*)
|
|
XtCalloc(i, sizeof(PdmOidMediumDiscreteSize));
|
|
}
|
|
return list;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: MediumDiscreteSizeListDelete
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
static void
|
|
MediumDiscreteSizeListDelete(PdmOidMediumDiscreteSizeList* list)
|
|
{
|
|
if(list != (PdmOidMediumDiscreteSizeList*)NULL)
|
|
{
|
|
XtFree((char*)list->list);
|
|
XtFree((char*)list);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidTrayMediumListNew
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
PdmOidTrayMediumList*
|
|
PdmOidTrayMediumListNew(const char* value_string)
|
|
{
|
|
if(value_string == (const char*)NULL)
|
|
return (PdmOidTrayMediumList*)NULL;
|
|
else
|
|
{
|
|
const char* ptr;
|
|
return TrayMediumListParse(value_string, &ptr, 0);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: TrayMediumListParse
|
|
*
|
|
* Description:
|
|
*
|
|
* 'ptr_return' *cannot* be NULL.
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
static PdmOidTrayMediumList*
|
|
TrayMediumListParse(const char* value_string,
|
|
const char** ptr_return, int i)
|
|
{
|
|
PdmOidTrayMedium tm;
|
|
PdmOidTrayMediumList* list;
|
|
/*
|
|
* check for the start of a new InputTrayMedium sequence
|
|
*/
|
|
if(ParseSeqStart(value_string, ptr_return))
|
|
{
|
|
/*
|
|
* "input tray"
|
|
*/
|
|
tm.input_tray = PdmOidParse(*ptr_return, ptr_return);
|
|
/*
|
|
* "medium"
|
|
*/
|
|
tm.medium = PdmOidParse(*ptr_return, ptr_return);
|
|
/*
|
|
* parse out the InputTrayMedium sequence end character
|
|
*/
|
|
if(!ParseSeqEnd(*ptr_return, ptr_return))
|
|
{
|
|
fprintf(stderr, "%s\n", PDM_MSG_WARN_ITM);
|
|
return NULL;
|
|
}
|
|
/*
|
|
* recurse to parse the next InputTrayMedium sequence
|
|
*/
|
|
list = TrayMediumListParse(*ptr_return, ptr_return, i+1);
|
|
if(list != (PdmOidTrayMediumList*)NULL)
|
|
{
|
|
/*
|
|
* copy the current InputTrayMedium into the list
|
|
*/
|
|
memmove((list->list)+i, &tm, sizeof(PdmOidTrayMedium));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* InputTrayMedium sequence start not found
|
|
*/
|
|
if(**ptr_return == '\0')
|
|
{
|
|
/*
|
|
* end of the list
|
|
*/
|
|
list = (PdmOidTrayMediumList*)
|
|
XtCalloc(1, sizeof(PdmOidTrayMediumList));
|
|
list->count = i;
|
|
if (i == 0)
|
|
list->list = NULL;
|
|
else
|
|
list->list = (PdmOidTrayMedium*)
|
|
XtCalloc(i, sizeof(PdmOidTrayMedium));
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* syntax error
|
|
*/
|
|
fprintf(stderr, "%s\n", PDM_MSG_WARN_ITM);
|
|
return NULL;
|
|
}
|
|
}
|
|
/*
|
|
* return
|
|
*/
|
|
return list;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidTrayMediumListDelete
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
void
|
|
PdmOidTrayMediumListDelete(PdmOidTrayMediumList* list)
|
|
{
|
|
if(list != (PdmOidTrayMediumList*)NULL)
|
|
{
|
|
XtFree((char*)list->list);
|
|
XtFree((char*)list);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: ParseArea
|
|
*
|
|
* Description:
|
|
*
|
|
* Skips leading whitespace and parses out and returns a PdmOidArea.
|
|
*
|
|
* Return value:
|
|
*
|
|
* True if the PdmOidArea was successfully parsed. ptr_return is
|
|
* updated to point to location where the parsing ended.
|
|
*
|
|
* False if a PdmOidArea was not found; ptr_return is updated
|
|
* to point to the first non-whitespace char in value_string.
|
|
*
|
|
*/
|
|
static Boolean
|
|
ParseArea(const char* value_string,
|
|
const char** ptr_return,
|
|
PdmOidArea* area_return)
|
|
{
|
|
const char* first_nonws_ptr;
|
|
const char* ptr;
|
|
/*
|
|
* skip leading whitespace
|
|
*/
|
|
first_nonws_ptr = value_string + SpanWhitespace(value_string);
|
|
/*
|
|
* parse out the area sequence start
|
|
*/
|
|
if(!ParseSeqStart(first_nonws_ptr, &ptr))
|
|
goto ParseArea_error;
|
|
/*
|
|
* parse the minimum x value
|
|
*/
|
|
if(!ParseRealValue(ptr, &ptr,
|
|
area_return ? &area_return->minimum_x : NULL))
|
|
goto ParseArea_error;
|
|
/*
|
|
* parse the maximum x value
|
|
*/
|
|
if(!ParseRealValue(ptr, &ptr,
|
|
area_return ? &area_return->maximum_x : NULL))
|
|
goto ParseArea_error;
|
|
/*
|
|
* parse the minimum y value
|
|
*/
|
|
if(!ParseRealValue(ptr, &ptr,
|
|
area_return ? &area_return->minimum_y : NULL))
|
|
goto ParseArea_error;
|
|
/*
|
|
* parse the maximum y value
|
|
*/
|
|
if(!ParseRealValue(ptr, &ptr,
|
|
area_return ? &area_return->maximum_y : NULL))
|
|
goto ParseArea_error;
|
|
/*
|
|
* parse out the area sequence end
|
|
*/
|
|
if(!ParseSeqEnd(ptr, &ptr))
|
|
goto ParseArea_error;
|
|
/*
|
|
* update the return pointer
|
|
*/
|
|
if(ptr_return != (const char**)NULL)
|
|
*ptr_return = ptr;
|
|
/*
|
|
* return
|
|
*/
|
|
return True;
|
|
|
|
|
|
ParseArea_error:
|
|
/*
|
|
* syntax error
|
|
*/
|
|
if(ptr_return != (const char**)NULL)
|
|
*ptr_return = first_nonws_ptr;
|
|
return False;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: ParseUnsignedRange
|
|
*
|
|
* Description:
|
|
*
|
|
* Skips leading whitespace and parses out and returns a
|
|
* PdmOidUnsignedRange.
|
|
*
|
|
* Return value:
|
|
*
|
|
* True if the PdmOidUnsignedRange was successfully
|
|
* parsed. ptr_return is updated to point to location where the
|
|
* parsing ended.
|
|
*
|
|
* False if a PdmOidUnsignedRange was not found; ptr_return is
|
|
* updated to point to the first non-whitespace char in value_string.
|
|
*
|
|
*/
|
|
static Boolean
|
|
ParseUnsignedRange(const char* value_string,
|
|
const char** ptr_return,
|
|
PdmOidUnsignedRange* range_return)
|
|
{
|
|
const char* first_nonws_ptr;
|
|
const char* ptr;
|
|
/*
|
|
* skip leading whitespace
|
|
*/
|
|
first_nonws_ptr = value_string + SpanWhitespace(value_string);
|
|
/*
|
|
* parse out the range sequence start
|
|
*/
|
|
if(!ParseSeqStart(first_nonws_ptr, &ptr))
|
|
goto ParseUnsignedRange_error;
|
|
/*
|
|
* parse the lower bound
|
|
*/
|
|
if(!ParseUnsignedValue(ptr, &ptr,
|
|
range_return ? &range_return->lower_bound : NULL))
|
|
goto ParseUnsignedRange_error;
|
|
/*
|
|
* parse the upper bound
|
|
*/
|
|
if(!ParseUnsignedValue(ptr, &ptr,
|
|
range_return ? &range_return->upper_bound : NULL))
|
|
goto ParseUnsignedRange_error;
|
|
/*
|
|
* parse out the range sequence end
|
|
*/
|
|
if(!ParseSeqEnd(ptr, &ptr))
|
|
goto ParseUnsignedRange_error;
|
|
/*
|
|
* update the return pointer
|
|
*/
|
|
if(ptr_return != (const char**)NULL)
|
|
*ptr_return = ptr;
|
|
/*
|
|
* return
|
|
*/
|
|
return True;
|
|
|
|
|
|
ParseUnsignedRange_error:
|
|
/*
|
|
* syntax error
|
|
*/
|
|
if(ptr_return != (const char**)NULL)
|
|
*ptr_return = first_nonws_ptr;
|
|
return False;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidNotifyParse
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*/
|
|
PdmOidNotify PdmOidNotifyParse(const char* value_string)
|
|
{
|
|
const char* ptr = value_string;
|
|
|
|
if(value_string == (const char*)NULL)
|
|
return PDMOID_NOTIFY_NONE;
|
|
/*
|
|
* look for an event handling profile sequence start
|
|
*/
|
|
if(!ParseSeqStart(value_string, &ptr))
|
|
{
|
|
if('\0' == *ptr)
|
|
/*
|
|
* empty value is valid
|
|
*/
|
|
return PDMOID_NOTIFY_NONE;
|
|
else
|
|
return PDMOID_NOTIFY_UNSUPPORTED;
|
|
}
|
|
/*
|
|
* look for an event set sequence start
|
|
*/
|
|
if(!ParseSeqStart(ptr, &ptr))
|
|
{
|
|
/*
|
|
* check for an empty event handling profile
|
|
*/
|
|
if(ParseSeqEnd(ptr, &ptr))
|
|
{
|
|
ptr += SpanWhitespace(ptr);
|
|
if(*ptr == '\0')
|
|
/*
|
|
* valid empty event handling profile sequence
|
|
*/
|
|
return PDMOID_NOTIFY_NONE;
|
|
}
|
|
return PDMOID_NOTIFY_UNSUPPORTED;
|
|
}
|
|
/*
|
|
* the only event in the set should be report job completed
|
|
*/
|
|
if(pdmoid_val_event_report_job_completed != PdmOidParse(ptr, &ptr))
|
|
return PDMOID_NOTIFY_UNSUPPORTED;
|
|
/*
|
|
* event set sequence end
|
|
*/
|
|
if(!ParseSeqEnd(ptr, &ptr))
|
|
return PDMOID_NOTIFY_UNSUPPORTED;
|
|
/*
|
|
* delivery method of electronic mail
|
|
*/
|
|
if(pdmoid_val_delivery_method_electronic_mail != PdmOidParse(ptr, &ptr))
|
|
return PDMOID_NOTIFY_UNSUPPORTED;
|
|
/*
|
|
* event handling profile sequence end
|
|
*/
|
|
if(!ParseSeqEnd(ptr, &ptr))
|
|
return PDMOID_NOTIFY_UNSUPPORTED;
|
|
/*
|
|
* end of value
|
|
*/
|
|
ptr += SpanWhitespace(ptr);
|
|
if('\0' == *ptr)
|
|
/*
|
|
* valid supported notification profile
|
|
*/
|
|
return PDMOID_NOTIFY_EMAIL;
|
|
else
|
|
return PDMOID_NOTIFY_UNSUPPORTED;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidNotifyString
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*/
|
|
const char* PdmOidNotifyString(PdmOidNotify notify)
|
|
{
|
|
switch(notify)
|
|
{
|
|
case PDMOID_NOTIFY_UNSUPPORTED:
|
|
return (const char*)NULL;
|
|
break;
|
|
case PDMOID_NOTIFY_NONE:
|
|
return NOTIFY_NONE_STR;
|
|
break;
|
|
case PDMOID_NOTIFY_EMAIL:
|
|
return NOTIFY_EMAIL_STR;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidDocumentFormatParse
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*/
|
|
char*
|
|
PdmOidDocumentFormatParse(const char* value_string)
|
|
{
|
|
char* document_format;
|
|
const char* ptr;
|
|
|
|
/*
|
|
* get the document format from the value string
|
|
*/
|
|
document_format =
|
|
PdmOidDocumentFormatNext(value_string, &ptr);
|
|
if((char*)NULL != document_format)
|
|
{
|
|
/*
|
|
* verify that the document format is the only value specified
|
|
*/
|
|
ptr += SpanWhitespace(ptr);
|
|
if('\0' == *ptr)
|
|
/*
|
|
* valid document-format value
|
|
*/
|
|
return document_format;
|
|
else
|
|
/*
|
|
* invalid; clean up
|
|
*/
|
|
XtFree(document_format);
|
|
}
|
|
return (char*)NULL;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidDocumentFormatDefault
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*/
|
|
char*
|
|
PdmOidDocumentFormatDefault(const char* value_string)
|
|
{
|
|
/*
|
|
* return the first document format from the value string
|
|
*/
|
|
return PdmOidDocumentFormatNext(value_string, (const char**)NULL);
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: PdmOidDocumentFormatNext
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*/
|
|
static char*
|
|
PdmOidDocumentFormatNext(const char* value_string,
|
|
const char** ptr_return)
|
|
{
|
|
const char* ptr;
|
|
const char* first_nonws_ptr;
|
|
const char* document_format_start;
|
|
char* document_format;
|
|
int document_format_len;
|
|
int token_len;
|
|
|
|
if((const char*)NULL == value_string)
|
|
return (char*)NULL;
|
|
/*
|
|
* skip leading whitespace
|
|
*/
|
|
ptr = value_string + SpanWhitespace(value_string);
|
|
first_nonws_ptr = ptr;
|
|
/*
|
|
* sequence start
|
|
*/
|
|
if(!ParseSeqStart(ptr, &ptr))
|
|
goto PdmOidDocumentFormatNext_error;
|
|
/*
|
|
* skip whitepace to the start of the document format, and save the
|
|
* location
|
|
*/
|
|
ptr += SpanWhitespace(ptr);
|
|
document_format_start = ptr;
|
|
/*
|
|
* document format
|
|
*/
|
|
if(0 == (token_len = SpanToken(ptr)))
|
|
goto PdmOidDocumentFormatNext_error;
|
|
ptr += token_len;
|
|
/*
|
|
* optional variant
|
|
*/
|
|
ptr += SpanWhitespace(ptr);
|
|
if(0 != (token_len = SpanToken(ptr)))
|
|
{
|
|
ptr += token_len;
|
|
/*
|
|
* optional version
|
|
*/
|
|
ptr += SpanWhitespace(ptr);
|
|
ptr += SpanToken(ptr);
|
|
}
|
|
/*
|
|
* determine the length of the document format, excluding the
|
|
* sequence delimeters
|
|
*/
|
|
document_format_len = ptr - document_format_start;
|
|
/*
|
|
* sequence end
|
|
*/
|
|
if(!ParseSeqEnd(ptr, &ptr))
|
|
goto PdmOidDocumentFormatNext_error;
|
|
/*
|
|
* update return pointer
|
|
*/
|
|
if((const char**)NULL != ptr_return)
|
|
*ptr_return = ptr;
|
|
/*
|
|
* build the return document format string, and return it
|
|
*/
|
|
document_format = XtMalloc(document_format_len+1);
|
|
strncpy(document_format, document_format_start, document_format_len);
|
|
document_format[document_format_len] = '\0';
|
|
return document_format;
|
|
|
|
PdmOidDocumentFormatNext_error:
|
|
fprintf(stderr, "%s\n", PDM_MSG_WARN_DOC_FMT);
|
|
if((const char**)NULL != ptr_return)
|
|
*ptr_return = first_nonws_ptr;
|
|
return (char*)NULL;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: ParseBooleanValue
|
|
*
|
|
* Description:
|
|
*
|
|
*
|
|
* Return value:
|
|
*
|
|
*
|
|
*/
|
|
static Boolean
|
|
ParseBooleanValue(const char* value_string,
|
|
const char** ptr_return,
|
|
Boolean* boolean_return)
|
|
{
|
|
const char* ptr;
|
|
int length;
|
|
Boolean status;
|
|
/*
|
|
* skip leading whitespace
|
|
*/
|
|
ptr = value_string + SpanWhitespace(value_string);
|
|
/*
|
|
* get the whitespace-delimited token length
|
|
*/
|
|
length = SpanToken(ptr);
|
|
/*
|
|
* determine if true or false or bad
|
|
*/
|
|
if(strncasecmp(ptr, "TRUE", length) == 0)
|
|
{
|
|
if(boolean_return != (Boolean*)NULL)
|
|
*boolean_return = True;
|
|
status = True;
|
|
}
|
|
else if(strncasecmp(ptr, "FALSE", length) == 0)
|
|
{
|
|
if(boolean_return != (Boolean*)NULL)
|
|
*boolean_return = False;
|
|
status = True;
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* syntax error
|
|
*/
|
|
status = False;
|
|
}
|
|
/*
|
|
* update the return pointer and return
|
|
*/
|
|
if(ptr_return != (const char**)NULL)
|
|
*ptr_return = status ? ptr+length : ptr;
|
|
return status;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: ParseUnsignedValue
|
|
*
|
|
* Description:
|
|
*
|
|
* Skips leading whitespace and parses out and returns a unsigned number.
|
|
*
|
|
* Return value:
|
|
*
|
|
* True if a unsigned number was successfully parsed. ptr_return is
|
|
* updated to point to location where the unsigned number parsing
|
|
* ended.
|
|
*
|
|
* False if a unsigned number was not found; ptr_return is updated
|
|
* to point to the first non-whitespace char in value_string.
|
|
*
|
|
*/
|
|
static Boolean
|
|
ParseUnsignedValue(const char* value_string,
|
|
const char** ptr_return,
|
|
unsigned long* unsigned_return)
|
|
{
|
|
unsigned long unsigned_value;
|
|
Boolean status;
|
|
const char* first_nonws_ptr;
|
|
const char* ptr;
|
|
/*
|
|
* skip leading whitespace
|
|
*/
|
|
first_nonws_ptr = value_string + SpanWhitespace(value_string);
|
|
unsigned_value = strtoul(first_nonws_ptr, (char**)(&ptr), 0);
|
|
if(ptr == first_nonws_ptr)
|
|
status = False;
|
|
else
|
|
status = True;
|
|
/*
|
|
* update return parms
|
|
*/
|
|
if(ptr_return != (const char**)NULL)
|
|
*ptr_return = ptr;
|
|
if(unsigned_return != (unsigned long*)NULL)
|
|
*unsigned_return = unsigned_value;
|
|
/*
|
|
* return
|
|
*/
|
|
return status;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: ParseRealValue
|
|
*
|
|
* Description:
|
|
*
|
|
* Skips leading whitespace and parses out and returns a real number.
|
|
*
|
|
* Return value:
|
|
*
|
|
* xTrue if a real number was successfully parsed. ptr_return is
|
|
* updated to point to location where the real number parsing
|
|
* ended.
|
|
*
|
|
* xFalse if a real number was not found; ptr_return is updated
|
|
* to point to the first non-whitespace char in value_string.
|
|
*
|
|
*/
|
|
static Boolean
|
|
ParseRealValue(const char* value_string,
|
|
const char** ptr_return,
|
|
float* real_return)
|
|
{
|
|
float real_value;
|
|
Boolean status;
|
|
const char* first_nonws_ptr;
|
|
const char* ptr;
|
|
/*
|
|
* skip leading whitespace
|
|
*/
|
|
first_nonws_ptr = value_string + SpanWhitespace(value_string);
|
|
real_value = (float)strtod(first_nonws_ptr, (char**)(&ptr));
|
|
if(ptr == first_nonws_ptr)
|
|
status = False;
|
|
else
|
|
status = True;
|
|
/*
|
|
* update return parms
|
|
*/
|
|
if(ptr_return != (const char**)NULL)
|
|
*ptr_return = ptr;
|
|
if(real_return != (float*)NULL)
|
|
*real_return = real_value;
|
|
/*
|
|
* return
|
|
*/
|
|
return status;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: ParseSeqEnd
|
|
*
|
|
* Description:
|
|
*
|
|
* Description:
|
|
*
|
|
* Skips leading whitespace and parses out the sequence end
|
|
* character '}'.
|
|
*
|
|
* Return value:
|
|
*
|
|
* True if the sequence end character was parsed; ptr_return is
|
|
* updated to point to the first char following the sequence end
|
|
* character.
|
|
*
|
|
* False if the sequence end character was not found; ptr_return is
|
|
* updated to point to the first non-whitespace char in value_string.
|
|
*
|
|
*/
|
|
static Boolean
|
|
ParseSeqEnd(const char* value_string,
|
|
const char** ptr_return)
|
|
{
|
|
const char* ptr;
|
|
Boolean status;
|
|
/*
|
|
* skip leading whitespace
|
|
*/
|
|
ptr = value_string + SpanWhitespace(value_string);
|
|
/*
|
|
* parse out the sequence end character
|
|
*/
|
|
if(*ptr == '}')
|
|
{
|
|
status = True;
|
|
++ptr;
|
|
}
|
|
else
|
|
status = False;
|
|
/*
|
|
* update the return pointer
|
|
*/
|
|
if(ptr_return != (const char**)NULL)
|
|
*ptr_return = ptr;
|
|
/*
|
|
* return
|
|
*/
|
|
return status;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: ParseSeqStart
|
|
*
|
|
* Description:
|
|
*
|
|
* Skips leading whitespace and parses out the sequence start
|
|
* character '{'.
|
|
*
|
|
* Return value:
|
|
*
|
|
* True if the sequence start character was parsed; ptr_return is
|
|
* updated to point to the first char following the sequence start
|
|
* character.
|
|
*
|
|
* False if the sequence start character was not found; ptr_return is
|
|
* updated to point to the first non-whitespace char in value_string.
|
|
*
|
|
*/
|
|
static Boolean
|
|
ParseSeqStart(const char* value_string,
|
|
const char** ptr_return)
|
|
{
|
|
const char* ptr;
|
|
Boolean status;
|
|
/*
|
|
* skip leading whitespace
|
|
*/
|
|
ptr = value_string + SpanWhitespace(value_string);
|
|
/*
|
|
* parse out the sequence start character
|
|
*/
|
|
if(*ptr == '{')
|
|
{
|
|
status = True;
|
|
++ptr;
|
|
}
|
|
else
|
|
status = False;
|
|
/*
|
|
* update the return pointer
|
|
*/
|
|
if(ptr_return != (const char**)NULL)
|
|
*ptr_return = ptr;
|
|
/*
|
|
* return
|
|
*/
|
|
return status;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: ParseUnspecifiedValue
|
|
*
|
|
* Description:
|
|
*
|
|
* Skips leading whitespace and parses out an unspecified optional
|
|
* value (i.e. matching '' or "" - skips all data between the set of
|
|
* quotes).
|
|
*
|
|
* Return value:
|
|
*
|
|
* True if an unspecified value was parsed; ptr_return is updated to
|
|
* point to the first char following the trailing quote.
|
|
*
|
|
* False if an unspecified value was not found; ptr_return is updated
|
|
* to point to the first non-whitespace char in value_string.
|
|
*
|
|
*/
|
|
static Boolean
|
|
ParseUnspecifiedValue(const char* value_string,
|
|
const char** ptr_return)
|
|
{
|
|
Boolean status;
|
|
const char* ptr;
|
|
/*
|
|
* skip leading whitespace
|
|
*/
|
|
ptr = value_string + SpanWhitespace(value_string);
|
|
/*
|
|
* parse out an unspecified optional value ('' or "")
|
|
*/
|
|
if(*ptr == '\'' || *ptr == '"')
|
|
{
|
|
char delim[2];
|
|
|
|
if(ptr_return != (const char**)NULL)
|
|
{
|
|
delim[0] = *ptr;
|
|
delim[1] = '\0';
|
|
/*
|
|
* skip over the matching delimiter
|
|
*/
|
|
++ptr;
|
|
ptr += strcspn(ptr, delim);
|
|
if(*ptr != '\0')
|
|
++ptr;
|
|
}
|
|
status = True;
|
|
}
|
|
else
|
|
status = False;
|
|
/*
|
|
* update the return pointer
|
|
*/
|
|
if(ptr_return != (const char**)NULL)
|
|
*ptr_return = ptr;
|
|
/*
|
|
* return
|
|
*/
|
|
return status;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: SpanToken
|
|
*
|
|
* Description:
|
|
*
|
|
* Returns the length of the initial segment of the passed string
|
|
* that consists entirely of non-whitespace and non-sequence
|
|
* delimiter characters.
|
|
*
|
|
*
|
|
*/
|
|
static int
|
|
SpanToken(const char* string)
|
|
{
|
|
const char* ptr;
|
|
for(ptr = string;
|
|
*ptr != '\0' && !DtIsspace((char*)ptr) && *ptr != '{' && *ptr != '}';
|
|
ptr = DtNextChar((char*)ptr));
|
|
return ptr - string;
|
|
}
|
|
|
|
/*
|
|
* ------------------------------------------------------------------------
|
|
* Name: SpanWhitespace
|
|
*
|
|
* Description:
|
|
*
|
|
* Returns the length of the initial segment of the passed string
|
|
* that consists entirely of whitespace characters.
|
|
*
|
|
*
|
|
*/
|
|
static int
|
|
SpanWhitespace(const char* string)
|
|
{
|
|
const char* ptr;
|
|
for(ptr = string;
|
|
*ptr != '\0' && DtIsspace((char*)ptr);
|
|
ptr = DtNextChar((char*)ptr));
|
|
return ptr - string;
|
|
}
|