1    	/*
2    	 NL reader
3    	
4    	 Copyright (C) 2013 - 2016 AMPL Optimization Inc
5    	
6    	 Permission to use, copy, modify, and distribute this software and its
7    	 documentation for any purpose and without fee is hereby granted,
8    	 provided that the above copyright notice appear in all copies and that
9    	 both that the copyright notice and this permission notice and warranty
10   	 disclaimer appear in supporting documentation.
11   	
12   	 The author and AMPL Optimization Inc disclaim all warranties with
13   	 regard to this software, including all implied warranties of
14   	 merchantability and fitness.  In no event shall the author be liable
15   	 for any special, indirect or consequential damages or any damages
16   	 whatsoever resulting from loss of use, data or profits, whether in an
17   	 action of contract, negligence or other tortious action, arising out
18   	 of or in connection with the use or performance of this software.
19   	
20   	 Author: Victor Zverovich
21   	 */
22   	
23   	#ifndef MP_NL_
24   	#define MP_NL_
25   	
26   	#include "mp/error.h"   // MP_ASSERT
27   	#include "mp/format.h"  // fmt::CStringRef
28   	
29   	#include <cstring>  // std::strlen, std::size_t
30   	#include <string>   // std::string
31   	
32   	namespace mp {
33   	
34   	/** A reference to a null-terminated string with size. */
35   	class NLStringRef {
36   	 private:
37   	  const char *data_;
38   	  std::size_t size_;
39   	
40   	 public:
41   	  /**
42   	    \rst
43   	    Constructs a string reference object from a C string computing
44   	    the size with ``std::strlen``.
45   	    \endrst
46   	   */
47   	  NLStringRef(const char *s) : data_(s), size_(std::strlen(s)) {}
48   	
49   	  /** Constructs a string reference object from a C string and a size. */
50   	  NLStringRef(const char *s, std::size_t size) : data_(s), size_(size) {
51   	    MP_ASSERT(!s[size], "string not null-terminated");
52   	  }
53   	
54   	  /**
55   	    \rst
56   	    Constructs a string reference from an ``std::string`` object.
57   	    \endrst
58   	   */
59   	  NLStringRef(const std::string &s) : data_(s.c_str()), size_(s.size()) {}
60   	
61   	  /** Returns the pointer to a C string. */
62   	  const char *c_str() const { return data_; }
63   	
64   	  /** Returns the string size. */
65   	  std::size_t size() const { return size_; }
66   	};
67   	
68   	// Flags for ReadNLFile and ReadNLString.
69   	enum {
70   	  /** Read variable bounds before anything else. */
71   	  READ_BOUNDS_FIRST = 1
72   	};
73   	
74   	/**
75   	  \rst
76   	  Reads an optimization problem in the NL format from the string *str*
77   	  and sends notifications of the problem components to the *handler* object.
78   	  The handler class can be one of the following
79   	
80   	  * derived from `mp::NLHandler` or `mp::NullNLHandler`,
81   	  * `mp::Problem`,
82   	  * provide an interface compatible with one of the above.
83   	
84   	  Both *str* and *name* can be C strings or ``std::string`` objects.
85   	  The *name* argument is used as the name of the input when reporting errors.
86   	  *flags* can be either 0, which is the default, to read all constructs in
87   	  the order they appear in the input, or `mp::READ_BOUNDS_FIRST` to read
88   	  variable bounds after the NL header and before other constructs such as
89   	  nonlinear expressions.
90   	  \endrst
91   	 */
92   	template <typename Handler>
93   	void ReadNLString(NLStringRef str, Handler &handler,
94   	                  fmt::CStringRef name = "(input)", int flags = 0);
95   	
96   	/**
97   	  \rst
98   	  Reads an optimization problem in the NL format from the file *filename*
99   	  and sends notifications of the problem components to the *handler* object.
100  	  The handler class can be one of the following
101  	
102  	  * derived from `mp::NLHandler` or `mp::NullNLHandler`,
103  	  * `mp::Problem`,
104  	  * provide an interface compatible with one of the above.
105  	
106  	  The *filename* argument can be a C string or an ``std::string`` object.
107  	  *flags* can be either 0, which is the default, to read all constructs in
108  	  the order they appear in the input, or `mp::READ_BOUNDS_FIRST` to read
109  	  variable bounds after the NL header and before other constructs such as
110  	  nonlinear expressions.
111  	
112  	  **Example**::
113  	
114  	    // Count the number of variable references in all nonlinear expressions.
115  	    struct VarCounter : mp::NullNLHandler<int> {
116  	      int num_vars;
117  	      VarCounter() : num_vars(0) {}
118  	      Reference OnVariableRef(int) {
119  	        ++num_vars;
120  	        return Reference();
121  	      }
122  	    };
123  	    VarCounter counter;
124  	    mp::ReadNLFile("test.nl", counter);
125  	    fmt::print("The number of variable references is {}.", counter.num_vars);
126  	  \endrst
127  	 */
128  	template <typename Handler>
129  	void ReadNLFile(fmt::CStringRef filename, Handler &handler, int flags = 0);
130  	}  // namespace mp
131  	
132  	#endif  // MP_NL_
133