Merge "Fix build errors with GCC4.8." into tizen
[platform/core/uifw/dali-adaptor.git] / adaptors / common / command-line-options.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include "command-line-options.h"
20
21 // EXTERNAL INCLUDES
22 #include <getopt.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <iostream>
26
27 #include <dali/public-api/common/vector-wrapper.h>
28
29 using namespace std;
30
31 namespace Dali
32 {
33
34 namespace Internal
35 {
36
37 namespace Adaptor
38 {
39
40 namespace
41 {
42 struct Argument
43 {
44   const char * const opt;
45   const char * const optDescription;
46
47   void Print()
48   {
49     const ios_base::fmtflags flags = cout.flags();
50     cout << left << "  --";
51     cout.width( 18 );
52     cout << opt;
53     cout << optDescription;
54     cout << endl;
55     cout.flags( flags );
56   }
57 };
58
59 Argument EXPECTED_ARGS[] =
60 {
61   { "no-vsync",    "Disable VSync on Render" },
62   { "width",       "Stage Width"             },
63   { "height",      "Stage Height"            },
64   { "dpi",         "Emulated DPI"            },
65   { "view",        "Stereocopic 3D view mode ([0]=MONO, 1=STEREO_HORZ, 2=STEREO_VERT, 3=STEREO_INTERLACED)" },
66   { "stereo-base", "Distance in millimeters between left/right cameras [65.0]" },
67   { "help",        "Help"                    },
68   { NULL,          NULL                      }
69 };
70
71 enum Option
72 {
73   OPTION_NO_VSYNC = 0,
74   OPTION_STAGE_WIDTH,
75   OPTION_STAGE_HEIGHT,
76   OPTION_DPI,
77   OPTION_STEREO_MODE,
78   OPTION_STEREO_BASE,
79   OPTION_HELP
80 };
81
82 typedef vector< int > UnhandledContainer;
83
84 void ShowHelp()
85 {
86   cout << "Available options:" << endl;
87   Argument* arg = EXPECTED_ARGS;
88   while ( arg->opt )
89   {
90     arg->Print();
91     ++arg;
92   }
93 }
94
95 } // unnamed namespace
96
97 CommandLineOptions::CommandLineOptions(int *argc, char **argv[])
98 : noVSyncOnRender(0),
99   stageWidth(0), stageHeight(0),
100   viewMode(0),
101   stereoBase(65)
102 {
103   if ( *argc > 1 )
104   {
105     // We do not want to print out errors.
106     int origOptErrValue( opterr );
107     opterr = 0;
108
109     int help( 0 );
110
111     const struct option options[]=
112     {
113       { EXPECTED_ARGS[OPTION_NO_VSYNC].opt,     no_argument,       &noVSyncOnRender, 1   },  // "--no-vsync"
114       { EXPECTED_ARGS[OPTION_STAGE_WIDTH].opt,  required_argument, NULL,             'w' },  // "--width"
115       { EXPECTED_ARGS[OPTION_STAGE_HEIGHT].opt, required_argument, NULL,             'h' },  // "--height"
116       { EXPECTED_ARGS[OPTION_DPI].opt,          required_argument, NULL,             'd' },  // "--dpi"
117       { EXPECTED_ARGS[OPTION_STEREO_MODE].opt,  required_argument, NULL,             'v' },  // "--view"
118       { EXPECTED_ARGS[OPTION_STEREO_BASE].opt,  required_argument, NULL,             's' },  // "--stereo-base"
119       { EXPECTED_ARGS[OPTION_HELP].opt,         no_argument,       &help,            '?' },  // "--help"
120       { 0, 0, 0, 0 } // end of options
121     };
122
123     int shortOption( 0 );
124     int optionIndex( 0 );
125
126     const char* optString = "-w:h:d:v:s:"; // The '-' ensures that argv is NOT permuted
127     bool optionProcessed( false );
128
129     UnhandledContainer unhandledOptions; // We store indices of options we do not handle here
130
131     do
132     {
133       shortOption = getopt_long( *argc, *argv, optString, options, &optionIndex );
134
135       switch ( shortOption )
136       {
137         case 0:
138         {
139           // Check if we want help
140           if ( help )
141           {
142             ShowHelp();
143             optionProcessed = true;
144           }
145           break;
146         }
147
148         case 'w':
149         {
150           if ( optarg )
151           {
152             stageWidth = atoi( optarg );
153             optionProcessed = true;
154           }
155           break;
156         }
157
158         case 'h':
159         {
160           if ( optarg )
161           {
162             stageHeight = atoi( optarg );
163             optionProcessed = true;
164           }
165           break;
166         }
167
168         case 'd':
169         {
170           if ( optarg )
171           {
172             stageDPI.assign( optarg );
173             optionProcessed = true;
174           }
175           break;
176         }
177
178         case 'v':
179         {
180           if ( optarg )
181           {
182             viewMode = atoi(optarg);
183             optionProcessed = true;
184           }
185           break;
186         }
187
188         case 's':
189         {
190           if ( optarg )
191           {
192             stereoBase = atoi(optarg);
193             optionProcessed = true;
194           }
195           break;
196         }
197
198         case -1:
199         {
200           // All command-line options have been parsed.
201           break;
202         }
203
204         default:
205         {
206           unhandledOptions.push_back( optind - 1 );
207           break;
208         }
209       }
210     } while ( shortOption != -1 );
211
212     // Take out the options we have processed
213     if ( optionProcessed )
214     {
215       if ( !unhandledOptions.empty() )
216       {
217         int index( 1 );
218
219         // Overwrite the argv with the values from the unhandled indices
220         const UnhandledContainer::const_iterator endIter = unhandledOptions.end();
221         for ( UnhandledContainer::iterator iter = unhandledOptions.begin(); iter != endIter; ++iter )
222         {
223           (*argv)[ index++ ] = (*argv)[ *iter ];
224         }
225         *argc = unhandledOptions.size() + 1; // +1 for the program name
226       }
227       else
228       {
229         // There are no unhandled options, so we should just have the program name
230         *argc = 1;
231       }
232
233       optind = 1; // Reset to start
234     }
235
236     opterr = origOptErrValue; // Reset opterr value.
237   }
238 }
239
240 CommandLineOptions::~CommandLineOptions()
241 {
242 }
243
244 } // namespace Adaptor
245
246 } // namespace Internal
247
248 } // namespace Dali