http://git-wip-us.apache.org/repos/asf/metamodel/blob/3f4c6d38/fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthConfigurationReader.java ---------------------------------------------------------------------- diff --git a/fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthConfigurationReader.java b/fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthConfigurationReader.java index 264287f..71a2640 100644 --- a/fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthConfigurationReader.java +++ b/fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthConfigurationReader.java @@ -1,176 +1,176 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.metamodel.fixedwidth; - -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.metamodel.csv.CsvConfiguration; -import org.apache.metamodel.csv.CsvDataContext; -import org.apache.metamodel.data.DataSet; -import org.apache.metamodel.schema.Table; -import org.apache.metamodel.util.Action; -import org.apache.metamodel.util.Resource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Object capable of reading fixed width metadata from external sources and - * thereby producing an appropriate {@link FixedWidthConfiguration} to use with - * a {@link FixedWidthDataContext}. - */ -public class FixedWidthConfigurationReader { - - private static final Logger logger = LoggerFactory.getLogger(FixedWidthConfigurationReader.class); - - // example: @1 COL1 $char1. - private final Pattern PATTERN_SAS_INPUT_LINE = Pattern.compile("\\@(\\d+) (.+) .*?(\\d+)\\."); - - // example: COL1 "Record type" - private final Pattern PATTERN_SAS_LABEL_LINE = Pattern.compile("(.+) \\\"(.+)\\\""); - - /** - * Reads a {@link FixedWidthConfiguration} based on a SAS 'format file', - * <a href= - * "http://support.sas.com/documentation/cdl/en/etlug/67323/HTML/default/viewer.htm#p0h03yig7fp1qan1arghp3lwjqi6.htm"> - * described here</a>. - * - * @param encoding the format file encoding - * @param resource the format file resource - * @param failOnInconsistentLineWidth flag specifying whether inconsistent line should stop processing or not - * @return a {@link FixedWidthConfiguration} object to use - */ - public FixedWidthConfiguration readFromSasFormatFile(String encoding, Resource resource, - boolean failOnInconsistentLineWidth) { - final List<FixedWidthColumnSpec> columnSpecs = new ArrayList<>(); - - final CsvDataContext dataContext = new CsvDataContext(resource, new CsvConfiguration()); - final Table table = dataContext.getDefaultSchema().getTable(0); - try (final DataSet dataSet = dataContext.query().from(table).select("Name", "BeginPosition", "EndPosition") - .execute()) { - while (dataSet.next()) { - final String name = (String) dataSet.getRow().getValue(0); - final int beginPosition = Integer.parseInt((String) dataSet.getRow().getValue(1)); - final int endPosition = Integer.parseInt((String) dataSet.getRow().getValue(2)); - final int width = 1 + endPosition - beginPosition; - columnSpecs.add(new FixedWidthColumnSpec(name, width)); - } - } - - return new FixedWidthConfiguration(encoding, columnSpecs, failOnInconsistentLineWidth); - } - - /** - * Reads a {@link FixedWidthConfiguration} based on a SAS INPUT declaration. - * The reader method also optionally will look for a LABEL definition for column naming. - * - * @param encoding the format file encoding - * @param resource the format file resource - * @param failOnInconsistentLineWidth flag specifying whether inconsistent line should stop processing or not - * @return a {@link FixedWidthConfiguration} object to use - */ - public FixedWidthConfiguration readFromSasInputDefinition(String encoding, Resource resource, - boolean failOnInconsistentLineWidth) { - - final Map<String, Integer> inputWidthDeclarations = new LinkedHashMap<>(); - final Map<String, String> labelDeclarations = new HashMap<>(); - - resource.read(new Action<InputStream>() { - - private boolean inInputSection = false; - private boolean inLabelSection = false; - - @Override - public void run(InputStream in) throws Exception { - try (final BufferedReader reader = new BufferedReader(new InputStreamReader(in))) { - for (String line = reader.readLine(); line != null; line = reader.readLine()) { - processLine(line); - } - } - } - - private void processLine(String line) { - line = line.trim(); - if (line.isEmpty()) { - return; - } - if (";".equals(line)) { - inInputSection = false; - inLabelSection = false; - return; - } else if ("INPUT".equals(line)) { - inInputSection = true; - return; - } else if ("LABEL".equals(line)) { - inLabelSection = true; - return; - } - - if (inInputSection) { - final Matcher matcher = PATTERN_SAS_INPUT_LINE.matcher(line); - if (matcher.matches()) { - final String positionSpec = matcher.group(1); - final String nameSpec = matcher.group(2); - final int width = Integer.parseInt(matcher.group(3)); - logger.debug("Parsed INPUT line \"{}\": position={}, name={}, width={}", line, positionSpec, - nameSpec, width); - inputWidthDeclarations.put(nameSpec, width); - } else { - logger.debug("Failed to parse/recognize INPUT line \"{}\"", line); - } - } else if (inLabelSection) { - final Matcher matcher = PATTERN_SAS_LABEL_LINE.matcher(line); - if (matcher.matches()) { - final String nameSpec = matcher.group(1); - final String labelSpec = matcher.group(2); - logger.debug("Parsed LABEL line \"{}\": name={}, label={}", line, nameSpec, labelSpec); - labelDeclarations.put(nameSpec, labelSpec); - } else { - logger.debug("Failed to parse/recognize LABEL line \"{}\"", line); - } - } - - if (line.endsWith(";")) { - inInputSection = false; - inLabelSection = false; - } - } - }); - - final List<FixedWidthColumnSpec> columnSpecs = new ArrayList<>(); - for (Entry<String, Integer> entry : inputWidthDeclarations.entrySet()) { - final String columnKey = entry.getKey(); - final Integer columnWidth = entry.getValue(); - final String columnLabel = labelDeclarations.get(columnKey); - final String columnName = columnLabel == null ? columnKey : columnLabel; - columnSpecs.add(new FixedWidthColumnSpec(columnName, columnWidth)); - } - - return new FixedWidthConfiguration(encoding, columnSpecs, failOnInconsistentLineWidth); - } -} +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.metamodel.fixedwidth; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.metamodel.csv.CsvConfiguration; +import org.apache.metamodel.csv.CsvDataContext; +import org.apache.metamodel.data.DataSet; +import org.apache.metamodel.schema.Table; +import org.apache.metamodel.util.Action; +import org.apache.metamodel.util.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Object capable of reading fixed width metadata from external sources and + * thereby producing an appropriate {@link FixedWidthConfiguration} to use with + * a {@link FixedWidthDataContext}. + */ +public class FixedWidthConfigurationReader { + + private static final Logger logger = LoggerFactory.getLogger(FixedWidthConfigurationReader.class); + + // example: @1 COL1 $char1. + private final Pattern PATTERN_SAS_INPUT_LINE = Pattern.compile("\\@(\\d+) (.+) .*?(\\d+)\\."); + + // example: COL1 "Record type" + private final Pattern PATTERN_SAS_LABEL_LINE = Pattern.compile("(.+) \\\"(.+)\\\""); + + /** + * Reads a {@link FixedWidthConfiguration} based on a SAS 'format file', + * <a href= + * "http://support.sas.com/documentation/cdl/en/etlug/67323/HTML/default/viewer.htm#p0h03yig7fp1qan1arghp3lwjqi6.htm"> + * described here</a>. + * + * @param encoding the format file encoding + * @param resource the format file resource + * @param failOnInconsistentLineWidth flag specifying whether inconsistent line should stop processing or not + * @return a {@link FixedWidthConfiguration} object to use + */ + public FixedWidthConfiguration readFromSasFormatFile(String encoding, Resource resource, + boolean failOnInconsistentLineWidth) { + final List<FixedWidthColumnSpec> columnSpecs = new ArrayList<>(); + + final CsvDataContext dataContext = new CsvDataContext(resource, new CsvConfiguration()); + final Table table = dataContext.getDefaultSchema().getTable(0); + try (final DataSet dataSet = dataContext.query().from(table).select("Name", "BeginPosition", "EndPosition") + .execute()) { + while (dataSet.next()) { + final String name = (String) dataSet.getRow().getValue(0); + final int beginPosition = Integer.parseInt((String) dataSet.getRow().getValue(1)); + final int endPosition = Integer.parseInt((String) dataSet.getRow().getValue(2)); + final int width = 1 + endPosition - beginPosition; + columnSpecs.add(new FixedWidthColumnSpec(name, width)); + } + } + + return new FixedWidthConfiguration(encoding, columnSpecs, failOnInconsistentLineWidth); + } + + /** + * Reads a {@link FixedWidthConfiguration} based on a SAS INPUT declaration. + * The reader method also optionally will look for a LABEL definition for column naming. + * + * @param encoding the format file encoding + * @param resource the format file resource + * @param failOnInconsistentLineWidth flag specifying whether inconsistent line should stop processing or not + * @return a {@link FixedWidthConfiguration} object to use + */ + public FixedWidthConfiguration readFromSasInputDefinition(String encoding, Resource resource, + boolean failOnInconsistentLineWidth) { + + final Map<String, Integer> inputWidthDeclarations = new LinkedHashMap<>(); + final Map<String, String> labelDeclarations = new HashMap<>(); + + resource.read(new Action<InputStream>() { + + private boolean inInputSection = false; + private boolean inLabelSection = false; + + @Override + public void run(InputStream in) throws Exception { + try (final BufferedReader reader = new BufferedReader(new InputStreamReader(in))) { + for (String line = reader.readLine(); line != null; line = reader.readLine()) { + processLine(line); + } + } + } + + private void processLine(String line) { + line = line.trim(); + if (line.isEmpty()) { + return; + } + if (";".equals(line)) { + inInputSection = false; + inLabelSection = false; + return; + } else if ("INPUT".equals(line)) { + inInputSection = true; + return; + } else if ("LABEL".equals(line)) { + inLabelSection = true; + return; + } + + if (inInputSection) { + final Matcher matcher = PATTERN_SAS_INPUT_LINE.matcher(line); + if (matcher.matches()) { + final String positionSpec = matcher.group(1); + final String nameSpec = matcher.group(2); + final int width = Integer.parseInt(matcher.group(3)); + logger.debug("Parsed INPUT line \"{}\": position={}, name={}, width={}", line, positionSpec, + nameSpec, width); + inputWidthDeclarations.put(nameSpec, width); + } else { + logger.debug("Failed to parse/recognize INPUT line \"{}\"", line); + } + } else if (inLabelSection) { + final Matcher matcher = PATTERN_SAS_LABEL_LINE.matcher(line); + if (matcher.matches()) { + final String nameSpec = matcher.group(1); + final String labelSpec = matcher.group(2); + logger.debug("Parsed LABEL line \"{}\": name={}, label={}", line, nameSpec, labelSpec); + labelDeclarations.put(nameSpec, labelSpec); + } else { + logger.debug("Failed to parse/recognize LABEL line \"{}\"", line); + } + } + + if (line.endsWith(";")) { + inInputSection = false; + inLabelSection = false; + } + } + }); + + final List<FixedWidthColumnSpec> columnSpecs = new ArrayList<>(); + for (Entry<String, Integer> entry : inputWidthDeclarations.entrySet()) { + final String columnKey = entry.getKey(); + final Integer columnWidth = entry.getValue(); + final String columnLabel = labelDeclarations.get(columnKey); + final String columnName = columnLabel == null ? columnKey : columnLabel; + columnSpecs.add(new FixedWidthColumnSpec(columnName, columnWidth)); + } + + return new FixedWidthConfiguration(encoding, columnSpecs, failOnInconsistentLineWidth); + } +}
http://git-wip-us.apache.org/repos/asf/metamodel/blob/3f4c6d38/fixedwidth/src/test/java/org/apache/metamodel/fixedwidth/FixedWidthConfigurationReaderTest.java ---------------------------------------------------------------------- diff --git a/fixedwidth/src/test/java/org/apache/metamodel/fixedwidth/FixedWidthConfigurationReaderTest.java b/fixedwidth/src/test/java/org/apache/metamodel/fixedwidth/FixedWidthConfigurationReaderTest.java index eb57233..c34b294 100644 --- a/fixedwidth/src/test/java/org/apache/metamodel/fixedwidth/FixedWidthConfigurationReaderTest.java +++ b/fixedwidth/src/test/java/org/apache/metamodel/fixedwidth/FixedWidthConfigurationReaderTest.java @@ -1,89 +1,89 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.metamodel.fixedwidth; - -import static org.junit.Assert.*; - -import java.util.Arrays; - -import org.apache.metamodel.DataContext; -import org.apache.metamodel.data.DataSet; -import org.apache.metamodel.schema.Table; -import org.apache.metamodel.util.FileResource; -import org.apache.metamodel.util.Resource; -import org.junit.Test; - -public class FixedWidthConfigurationReaderTest { - - private final FileResource dataResource = new FileResource("src/test/resources/metadata_spec1/data.txt"); - - @Test - public void testReadConfigurationFromSasFormatFile() throws Exception { - final FixedWidthConfigurationReader reader = new FixedWidthConfigurationReader(); - final Resource resource = new FileResource("src/test/resources/metadata_spec1/sas-formatfile-metadata.txt"); - assertTrue(resource.isExists()); - - final FixedWidthConfiguration configuration = reader.readFromSasFormatFile("UTF8", resource, false); - assertEquals("[1, 20, 2]", Arrays.toString(configuration.getValueWidths())); - - final FixedWidthDataContext dataContext = new FixedWidthDataContext(dataResource, configuration); - - performAssertionsOnSpec1(dataContext); - } - - @Test - public void testReadConfigurationFromSasInputMetadata() throws Exception { - final FixedWidthConfigurationReader reader = new FixedWidthConfigurationReader(); - final Resource resource = new FileResource("src/test/resources/metadata_spec1/sas-input-metadata.txt"); - assertTrue(resource.isExists()); - - final FixedWidthConfiguration configuration = reader.readFromSasInputDefinition("UTF8", resource, false); - assertEquals("[1, 20, 2]", Arrays.toString(configuration.getValueWidths())); - - final FixedWidthDataContext dataContext = new FixedWidthDataContext(dataResource, configuration); - - performAssertionsOnSpec1(dataContext); - } - - /** - * Shared assertions section once the 'metadata_spec1' {@link DataContext} - * has been loaded. - * - * @param dataContext - */ - private void performAssertionsOnSpec1(FixedWidthDataContext dataContext) { - final Table table = dataContext.getDefaultSchema().getTable(0); - final String[] columnNames = table.getColumnNames(); - assertEquals("[Record type, Description, Initials]", Arrays.toString(columnNames)); - - try (final DataSet dataSet = dataContext.query().from(table).selectAll().execute()) { - assertTrue(dataSet.next()); - assertEquals("Row[values=[P, Kasper Sorensen, KS]]", dataSet.getRow().toString()); - assertTrue(dataSet.next()); - assertEquals("Row[values=[C, Human Inference, HI]]", dataSet.getRow().toString()); - assertTrue(dataSet.next()); - assertEquals("Row[values=[P, Ankit Kumar, AK]]", dataSet.getRow().toString()); - assertTrue(dataSet.next()); - assertEquals("Row[values=[C, Stratio, S]]", dataSet.getRow().toString()); - assertTrue(dataSet.next()); - assertEquals("Row[values=[U, Unknown, ]]", dataSet.getRow().toString()); - assertFalse(dataSet.next()); - } - } -} +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.metamodel.fixedwidth; + +import static org.junit.Assert.*; + +import java.util.Arrays; + +import org.apache.metamodel.DataContext; +import org.apache.metamodel.data.DataSet; +import org.apache.metamodel.schema.Table; +import org.apache.metamodel.util.FileResource; +import org.apache.metamodel.util.Resource; +import org.junit.Test; + +public class FixedWidthConfigurationReaderTest { + + private final FileResource dataResource = new FileResource("src/test/resources/metadata_spec1/data.txt"); + + @Test + public void testReadConfigurationFromSasFormatFile() throws Exception { + final FixedWidthConfigurationReader reader = new FixedWidthConfigurationReader(); + final Resource resource = new FileResource("src/test/resources/metadata_spec1/sas-formatfile-metadata.txt"); + assertTrue(resource.isExists()); + + final FixedWidthConfiguration configuration = reader.readFromSasFormatFile("UTF8", resource, false); + assertEquals("[1, 20, 2]", Arrays.toString(configuration.getValueWidths())); + + final FixedWidthDataContext dataContext = new FixedWidthDataContext(dataResource, configuration); + + performAssertionsOnSpec1(dataContext); + } + + @Test + public void testReadConfigurationFromSasInputMetadata() throws Exception { + final FixedWidthConfigurationReader reader = new FixedWidthConfigurationReader(); + final Resource resource = new FileResource("src/test/resources/metadata_spec1/sas-input-metadata.txt"); + assertTrue(resource.isExists()); + + final FixedWidthConfiguration configuration = reader.readFromSasInputDefinition("UTF8", resource, false); + assertEquals("[1, 20, 2]", Arrays.toString(configuration.getValueWidths())); + + final FixedWidthDataContext dataContext = new FixedWidthDataContext(dataResource, configuration); + + performAssertionsOnSpec1(dataContext); + } + + /** + * Shared assertions section once the 'metadata_spec1' {@link DataContext} + * has been loaded. + * + * @param dataContext + */ + private void performAssertionsOnSpec1(FixedWidthDataContext dataContext) { + final Table table = dataContext.getDefaultSchema().getTable(0); + final String[] columnNames = table.getColumnNames(); + assertEquals("[Record type, Description, Initials]", Arrays.toString(columnNames)); + + try (final DataSet dataSet = dataContext.query().from(table).selectAll().execute()) { + assertTrue(dataSet.next()); + assertEquals("Row[values=[P, Kasper Sorensen, KS]]", dataSet.getRow().toString()); + assertTrue(dataSet.next()); + assertEquals("Row[values=[C, Human Inference, HI]]", dataSet.getRow().toString()); + assertTrue(dataSet.next()); + assertEquals("Row[values=[P, Ankit Kumar, AK]]", dataSet.getRow().toString()); + assertTrue(dataSet.next()); + assertEquals("Row[values=[C, Stratio, S]]", dataSet.getRow().toString()); + assertTrue(dataSet.next()); + assertEquals("Row[values=[U, Unknown, ]]", dataSet.getRow().toString()); + assertFalse(dataSet.next()); + } + } +} http://git-wip-us.apache.org/repos/asf/metamodel/blob/3f4c6d38/fixedwidth/src/test/resources/metadata_spec1/data.txt ---------------------------------------------------------------------- diff --git a/fixedwidth/src/test/resources/metadata_spec1/data.txt b/fixedwidth/src/test/resources/metadata_spec1/data.txt index 785a539..ac055c9 100644 --- a/fixedwidth/src/test/resources/metadata_spec1/data.txt +++ b/fixedwidth/src/test/resources/metadata_spec1/data.txt @@ -1,5 +1,5 @@ -PKasper Sorensen KS -CHuman Inference HI -PAnkit Kumar AK -CStratio S -UUnknown +PKasper Sorensen KS +CHuman Inference HI +PAnkit Kumar AK +CStratio S +UUnknown http://git-wip-us.apache.org/repos/asf/metamodel/blob/3f4c6d38/fixedwidth/src/test/resources/metadata_spec1/sas-formatfile-metadata.txt ---------------------------------------------------------------------- diff --git a/fixedwidth/src/test/resources/metadata_spec1/sas-formatfile-metadata.txt b/fixedwidth/src/test/resources/metadata_spec1/sas-formatfile-metadata.txt index 9bbe411..38b0e04 100644 --- a/fixedwidth/src/test/resources/metadata_spec1/sas-formatfile-metadata.txt +++ b/fixedwidth/src/test/resources/metadata_spec1/sas-formatfile-metadata.txt @@ -1,4 +1,4 @@ -Name,SASColumnType,BeginPosition,EndPosition,ReadFlag,Desc,SASFormat,SASInformat -Record type,C,1,1,y,Record Type,$char.,$char. -Description,C,2,21,y,Description of record,$char.,$char. -Initials,C,22,23,y,Initials of record,, +Name,SASColumnType,BeginPosition,EndPosition,ReadFlag,Desc,SASFormat,SASInformat +Record type,C,1,1,y,Record Type,$char.,$char. +Description,C,2,21,y,Description of record,$char.,$char. +Initials,C,22,23,y,Initials of record,, http://git-wip-us.apache.org/repos/asf/metamodel/blob/3f4c6d38/fixedwidth/src/test/resources/metadata_spec1/sas-input-metadata.txt ---------------------------------------------------------------------- diff --git a/fixedwidth/src/test/resources/metadata_spec1/sas-input-metadata.txt b/fixedwidth/src/test/resources/metadata_spec1/sas-input-metadata.txt index f12e418..6839a9b 100644 --- a/fixedwidth/src/test/resources/metadata_spec1/sas-input-metadata.txt +++ b/fixedwidth/src/test/resources/metadata_spec1/sas-input-metadata.txt @@ -1,19 +1,19 @@ -INPUT - - @1 COL1 $char1. - - @2 COL2 $char20. - - @22 COL3 $char2. - -; - -LABEL - - COL1 "Record type" - - COL2 "Description" - - COL3 "Initials" - -; +INPUT + + @1 COL1 $char1. + + @2 COL2 $char20. + + @22 COL3 $char2. + +; + +LABEL + + COL1 "Record type" + + COL2 "Description" + + COL3 "Initials" + +;