XmStringComponentType XmStringGetNextComponent( XmStringContext context, char **text, XmStringTag *str_tag, XmStringDirection *direction, XmStringComponentType *unknown_tag, unsigned short *unknown_length, unsigned char **unknown_value ) { XmStringComponentType type; unsigned int len; XtPointer val; _XmProcessLock(); type = XmeStringGetComponent((_XmStringContext) context, True, True, &len, &val); /* Case on return type */ /* Set appropriate return value and return. */ switch (type) { case XmSTRING_COMPONENT_DIRECTION: *direction = *(XmStringDirection *)val; XtFree((char *)val); break; case XmSTRING_COMPONENT_TAG: *str_tag = (XmStringTag)val; break; case XmSTRING_COMPONENT_TEXT: case XmSTRING_COMPONENT_LOCALE_TEXT: *text = (char *)val; break; case XmSTRING_COMPONENT_SEPARATOR: case XmSTRING_COMPONENT_END: break; default: *unknown_tag = type; *unknown_length = len; *unknown_value = (unsigned char *)val; type = XmSTRING_COMPONENT_UNKNOWN; } _XmProcessUnlock(); return(type); }
/* * _XmStringGetSegment: A generalized version of XmStringGetNextSegment. * Returns char_count, and allows explicit control over peeking * and copying of data. Interleaving of calls to _XmStringGetSegment() * and XmeStringGetComponent() is supported. */ Boolean _XmStringGetSegment(_XmStringContext context, Boolean update_context, Boolean copy_data, XtPointer *text, XmStringTag *tag, XmTextType *type, XmStringTag **rendition_tags, unsigned int *tag_count, XmStringDirection *direction, Boolean *separator, unsigned char *tabs, short *char_count, XmDirection *push_before, Boolean *pop_after) { XmStringTag* perm_rends = NULL; _XmStringContextRec local_context_data; _XmStringContext local_context = context; Boolean result = FALSE; Boolean done; Boolean new_renditions; XmStringComponentType ctype; unsigned int len; XtPointer val; /* Initialize the out parameters */ if (text) *text = NULL; if (tag) *tag = NULL; if (type) *type = XmCHARSET_TEXT; if (rendition_tags) *rendition_tags = NULL; if (tag_count) *tag_count = 0; if (direction) *direction = _XmStrContDir(context); /* for BC */ if (separator) *separator = False; if (tabs) *tabs = 0; if (char_count) *char_count = 0; if (push_before) *push_before = 0; if (pop_after) *pop_after = False; /* No NULL pointers allowed. */ if (! (context && text && tag && type && rendition_tags && tag_count && direction && separator && tabs && char_count && push_before && pop_after)) return False; if (_XmStrContError(context)) return False; /* Setup a writable context. */ if (!update_context) { local_context = &local_context_data; _XmStringContextCopy(local_context, context); } /* N.B.: This code relies on the order of components from XmeStringGetComponent()! */ done = new_renditions = FALSE; while (!done) { /* Peek at components before consuming them. */ ctype = XmeStringGetComponent(local_context, FALSE, FALSE, &len, &val); switch (ctype) { case XmSTRING_COMPONENT_LAYOUT_PUSH: if (*tabs || *text) done = TRUE; else *push_before = *((XmDirection *) val); break; case XmSTRING_COMPONENT_RENDITION_BEGIN: if (*text) done = TRUE; else if (*tabs) new_renditions = TRUE; break; case XmSTRING_COMPONENT_CHARSET: case XmSTRING_COMPONENT_LOCALE: if (*text) done = TRUE; else *tag = (XmStringTag) val; break; case XmSTRING_COMPONENT_TAB: if (*text) done = TRUE; else { /* Save the renditions now. */ if ((*tag_count == 0) && _XmStrContRendCount(local_context)) { *tag_count = _XmStrContRendCount(local_context); if (copy_data) { int tmp; *rendition_tags = (XmStringTag *) XtMalloc(sizeof(XmStringTag) * *tag_count); for (tmp = 0; tmp < *tag_count; tmp++) (*rendition_tags)[tmp] = XtNewString(_XmStrContRendTags(local_context)[tmp]); } else { perm_rends = (XmStringTag *) XtMalloc(sizeof(XmStringTag) * *tag_count); memcpy((char*) perm_rends, _XmStrContRendTags(local_context), sizeof(XmStringTag) * *tag_count); *rendition_tags = perm_rends; } } /* Return at the end of this line. */ (*tabs)++; result = TRUE; } break; case XmSTRING_COMPONENT_DIRECTION: if (*text) done = TRUE; else *direction = *((XmStringDirection *) val); break; case XmSTRING_COMPONENT_TEXT: case XmSTRING_COMPONENT_LOCALE_TEXT: case XmSTRING_COMPONENT_WIDECHAR_TEXT: if (*text) done = TRUE; else if (*tabs && new_renditions) { /* Tabs had a different set of renditions than the text, */ /* so we can't return both tabs and text at once. */ done = TRUE; } else { *char_count = len; *text = val; if (ctype == XmSTRING_COMPONENT_TEXT) *type = XmCHARSET_TEXT; else if (ctype == XmSTRING_COMPONENT_LOCALE_TEXT) *type = XmMULTIBYTE_TEXT; else if (ctype == XmSTRING_COMPONENT_WIDECHAR_TEXT) *type = XmWIDECHAR_TEXT; else { assert(FALSE); } /* Force a tag for backward compatibility with Motif 1.2 */ if (! *tag) *tag = _XmStrContTag(local_context); result = TRUE; /* Save the renditions now. */ if ((*tag_count == 0) && _XmStrContRendCount(local_context)) { *tag_count = _XmStrContRendCount(local_context); if (copy_data) { int tmp; *rendition_tags = (XmStringTag*) XtMalloc(sizeof(XmStringTag) * *tag_count); for (tmp = 0; tmp < *tag_count; tmp++) (*rendition_tags)[tmp] = XtNewString(_XmStrContRendTags(local_context)[tmp]); } else { perm_rends = (XmStringTag *) XtMalloc(sizeof(XmStringTag) * *tag_count); memcpy((char*) perm_rends, _XmStrContRendTags(local_context), sizeof(XmStringTag) * *tag_count); *rendition_tags = perm_rends; } } } break; case XmSTRING_COMPONENT_RENDITION_END: break; case XmSTRING_COMPONENT_LAYOUT_POP: if (*tabs || *text) { /* We're almost done, so record this pop. */ *pop_after = TRUE; } else { /* We're ignoring this pop, so discard any recorded push. */ *push_before = 0; } break; case XmSTRING_COMPONENT_SEPARATOR: if (*tabs || *text) { *separator = TRUE; done = TRUE; } break; case XmSTRING_COMPONENT_END: default: done = TRUE; break; } /* Consume the component if we aren't done. */ if (!done) (void) XmeStringGetComponent(local_context, TRUE, FALSE, &len, &val); } if (copy_data && result) { /* Copy the tag. */ if (*tag) *tag = XtNewString(*tag); /* Copy the text. */ if (*text) { char *tmp = XtMalloc(*char_count + sizeof(wchar_t)); memcpy(tmp, *text, *char_count); bzero(tmp + *char_count, sizeof(wchar_t)); *text = (XtPointer) tmp; } } /* Free the local context. */ if (local_context == &local_context_data) _XmStringContextFree(local_context); return result; }