int
sclp_emit_buffer(struct sclp_buffer *buffer,
		 void (*callback)(struct sclp_buffer *, int))
{
	struct write_sccb *sccb;

	/* add current line if there is one */
	if (buffer->current_line != NULL)
		sclp_finalize_mto(buffer);

	/* Are there messages in the output buffer ? */
	if (buffer->mto_number == 0)
		return -EIO;

	sccb = buffer->sccb;
	if (sclp_rw_event.sclp_receive_mask & EVTYP_MSG_MASK)
		/* Use normal write message */
		sccb->msg_buf.header.type = EVTYP_MSG;
	else if (sclp_rw_event.sclp_receive_mask & EVTYP_PMSGCMD_MASK)
		/* Use write priority message */
		sccb->msg_buf.header.type = EVTYP_PMSGCMD;
	else
		return -ENOSYS;
	buffer->request.command = SCLP_CMDW_WRITE_EVENT_DATA;
	buffer->request.status = SCLP_REQ_FILLED;
	buffer->request.callback = sclp_writedata_callback;
	buffer->request.callback_data = buffer;
	buffer->request.sccb = sccb;
	buffer->callback = callback;
	return sclp_add_request(&buffer->request);
}
void
sclp_set_columns(struct sclp_buffer *buffer, unsigned short columns)
{
	buffer->columns = columns;
	if (buffer->current_line != NULL &&
	    buffer->current_length > buffer->columns)
		sclp_finalize_mto(buffer);
}
Example #3
0
/*
 * Setup the request structure in the struct sclp_buffer to do SCLP Write
 * Event Data and pass the request to the core SCLP loop.
 */
void
sclp_emit_buffer(struct sclp_buffer *buffer,
		 void (*callback)(struct sclp_buffer *, int))
{
	struct write_sccb *sccb;

	/* add current line if there is one */
	if (buffer->current_line != NULL)
		sclp_finalize_mto(buffer);

	/* Are there messages in the output buffer ? */
	if (buffer->mto_number == 0) {
		if (callback != NULL)
			callback(buffer, 0);
		return;
	}

	sccb = buffer->sccb;
	if (sclp_rw_event.sclp_send_mask & EvTyp_Msg_Mask)
		/* Use normal write message */
		sccb->msg_buf.header.type = EvTyp_Msg;
	else if (sclp_rw_event.sclp_send_mask & EvTyp_PMsgCmd_Mask)
		/* Use write priority message */
		sccb->msg_buf.header.type = EvTyp_PMsgCmd;
	else {
		if (callback != NULL)
			callback(buffer, -ENOSYS);
		return;
	}
	buffer->request.command = SCLP_CMDW_WRITEDATA;
	buffer->request.status = SCLP_REQ_FILLED;
	buffer->request.callback = sclp_writedata_callback;
	buffer->request.callback_data = buffer;
	buffer->request.sccb = sccb;
	buffer->callback = callback;
	sclp_add_request(&buffer->request);
}
int
sclp_write(struct sclp_buffer *buffer, const unsigned char *msg, int count)
{
	int spaces, i_msg;
	int rc;

	/*
	 * parse msg for escape sequences (\t,\v ...) and put formated
	 * msg into an mto (created by sclp_initialize_mto).
	 *
	 * We have to do this work ourselfs because there is no support for
	 * these characters on the native machine and only partial support
	 * under VM (Why does VM interpret \n but the native machine doesn't ?)
	 *
	 * Depending on i/o-control setting the message is always written
	 * immediately or we wait for a final new line maybe coming with the
	 * next message. Besides we avoid a buffer overrun by writing its
	 * content.
	 *
	 * RESTRICTIONS:
	 *
	 * \r and \b work within one line because we are not able to modify
	 * previous output that have already been accepted by the SCLP.
	 *
	 * \t combined with following \r is not correctly represented because
	 * \t is expanded to some spaces but \r does not know about a
	 * previous \t and decreases the current position by one column.
	 * This is in order to a slim and quick implementation.
	 */
	for (i_msg = 0; i_msg < count; i_msg++) {
		switch (msg[i_msg]) {
		case '\n':	/* new line, line feed (ASCII)	*/
			/* check if new mto needs to be created */
			if (buffer->current_line == NULL) {
				rc = sclp_initialize_mto(buffer, 0);
				if (rc)
					return i_msg;
			}
			sclp_finalize_mto(buffer);
			break;
		case '\a':	/* bell, one for several times	*/
			/* set SCLP sound alarm bit in General Object */
			buffer->sccb->msg_buf.mdb.go.general_msg_flags |=
				GNRLMSGFLGS_SNDALRM;
			break;
		case '\t':	/* horizontal tabulator	 */
			/* check if new mto needs to be created */
			if (buffer->current_line == NULL) {
				rc = sclp_initialize_mto(buffer,
							 buffer->columns);
				if (rc)
					return i_msg;
			}
			/* "go to (next htab-boundary + 1, same line)" */
			do {
				if (buffer->current_length >= buffer->columns)
					break;
				/* ok, add a blank */
				*buffer->current_line++ = 0x40;
				buffer->current_length++;
			} while (buffer->current_length % buffer->htab);
			break;
		case '\f':	/* form feed  */
		case '\v':	/* vertical tabulator  */
			/* "go to (actual column, actual line + 1)" */
			/* = new line, leading spaces */
			if (buffer->current_line != NULL) {
				spaces = buffer->current_length;
				sclp_finalize_mto(buffer);
				rc = sclp_initialize_mto(buffer,
							 buffer->columns);
				if (rc)
					return i_msg;
				memset(buffer->current_line, 0x40, spaces);
				buffer->current_line += spaces;
				buffer->current_length = spaces;
			} else {
				/* one an empty line this is the same as \n */
				rc = sclp_initialize_mto(buffer,
							 buffer->columns);
				if (rc)
					return i_msg;
				sclp_finalize_mto(buffer);
			}
			break;
		case '\b':	/* backspace  */
			/* "go to (actual column - 1, actual line)" */
			/* decrement counter indicating position, */
			/* do not remove last character */
			if (buffer->current_line != NULL &&
			    buffer->current_length > 0) {
				buffer->current_length--;
				buffer->current_line--;
			}
			break;
		case 0x00:	/* end of string  */
			/* transfer current line to SCCB */
			if (buffer->current_line != NULL)
				sclp_finalize_mto(buffer);
			/* skip the rest of the message including the 0 byte */
			i_msg = count - 1;
			break;
		default:	/* no escape character	*/
			/* do not output unprintable characters */
			if (!isprint(msg[i_msg]))
				break;
			/* check if new mto needs to be created */
			if (buffer->current_line == NULL) {
				rc = sclp_initialize_mto(buffer,
							 buffer->columns);
				if (rc)
					return i_msg;
			}
			*buffer->current_line++ = sclp_ascebc(msg[i_msg]);
			buffer->current_length++;
			break;
		}
		/* check if current mto is full */
		if (buffer->current_line != NULL &&
		    buffer->current_length >= buffer->columns)
			sclp_finalize_mto(buffer);
	}

	/* return number of processed characters */
	return i_msg;
}
/*
 * processing of a message including escape characters,
 * returns number of characters written to the output sccb
 * ("processed" means that is not guaranteed that the character have already
 *  been sent to the SCLP but that it will be done at least next time the SCLP
 *  is not busy)
 */
int
sclp_write(struct sclp_buffer *buffer, const unsigned char *msg, int count)
{
	int spaces, i_msg;
	int rc;

	/*
	 * parse msg for escape sequences (\t,\v ...) and put formated
	 * msg into an mto (created by sclp_initialize_mto).
	 *
	 * We have to do this work ourselfs because there is no support for
	 * these characters on the native machine and only partial support
	 * under VM (Why does VM interpret \n but the native machine doesn't ?)
	 *
	 * Depending on i/o-control setting the message is always written
	 * immediately or we wait for a final new line maybe coming with the
	 * next message. Besides we avoid a buffer overrun by writing its
	 * content.
	 *
	 * RESTRICTIONS:
	 *
	 * \r and \b work within one line because we are not able to modify
	 * previous output that have already been accepted by the SCLP.
	 *
	 * \t combined with following \r is not correctly represented because
	 * \t is expanded to some spaces but \r does not know about a
	 * previous \t and decreases the current position by one column.
	 * This is in order to a slim and quick implementation.
	 */
	for (i_msg = 0; i_msg < count; i_msg++) {
		switch (msg[i_msg]) {
		case '\n':	
			
			if (buffer->current_line == NULL) {
				rc = sclp_initialize_mto(buffer, 0);
				if (rc)
					return i_msg;
			}
			sclp_finalize_mto(buffer);
			break;
		case '\a':	
			
			buffer->sccb->msg_buf.mdb.go.general_msg_flags |=
				GNRLMSGFLGS_SNDALRM;
			break;
		case '\t':	
			
			if (buffer->current_line == NULL) {
				rc = sclp_initialize_mto(buffer,
							 buffer->columns);
				if (rc)
					return i_msg;
			}
			
			do {
				if (buffer->current_length >= buffer->columns)
					break;
				
				*buffer->current_line++ = 0x40;
				buffer->current_length++;
			} while (buffer->current_length % buffer->htab);
			break;
		case '\f':	
		case '\v':	
			
			
			if (buffer->current_line != NULL) {
				spaces = buffer->current_length;
				sclp_finalize_mto(buffer);
				rc = sclp_initialize_mto(buffer,
							 buffer->columns);
				if (rc)
					return i_msg;
				memset(buffer->current_line, 0x40, spaces);
				buffer->current_line += spaces;
				buffer->current_length = spaces;
			} else {
				
				rc = sclp_initialize_mto(buffer,
							 buffer->columns);
				if (rc)
					return i_msg;
				sclp_finalize_mto(buffer);
			}
			break;
		case '\b':	
			
			
			
			if (buffer->current_line != NULL &&
			    buffer->current_length > 0) {
				buffer->current_length--;
				buffer->current_line--;
			}
			break;
		case 0x00:	
			
			if (buffer->current_line != NULL)
				sclp_finalize_mto(buffer);
			
			i_msg = count - 1;
			break;
		default:	
			
			if (!isprint(msg[i_msg]))
				break;
			
			if (buffer->current_line == NULL) {
				rc = sclp_initialize_mto(buffer,
							 buffer->columns);
				if (rc)
					return i_msg;
			}
			*buffer->current_line++ = sclp_ascebc(msg[i_msg]);
			buffer->current_length++;
			break;
		}
		
		if (buffer->current_line != NULL &&
		    buffer->current_length >= buffer->columns)
			sclp_finalize_mto(buffer);
	}

	
	return i_msg;
}